Repository navigation
Expand file tree
/
Copy pathmodule.ae
More file actions
132 lines (111 loc) · 4.28 KB
/
Copy pathmodule.ae
File metadata and controls
132 lines (111 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// std.strarr - a growable array of string pointers whose backing IS a
// `string[]`, so it feeds std.sort directly.
//
// Import with: import std.strarr
//
// Why it exists: `string[]` is a compile-time literal (`["a","b"]`), and the
// runtime producers give other shapes — `string.split` → an opaque array
// handle, `fs.glob` → a dir_list. There was no way to build a `string[]` of
// runtime-determined length to hand to `std.sort.strings_by`. strarr is the
// string companion to `std.intarr` / `longarr` / `floatarr`, except it GROWS
// (push), because the whole point is a count you don't know up front:
//
// sa = strarr.new()
// // ... push each globbed path ...
// i = 0
// while i < dir.count(jars) {
// _p = strarr.push(sa, dir.name_at(jars, i))
// i = i + 1
// }
// sort.strings_by(strarr.array(sa), _by_version)
// newest = strarr.get(sa, strarr.size(sa) - 1) // strings_by sorts in place
// strarr.free(sa)
//
// OWNERSHIP: strarr BORROWS the strings pushed into it (like a `string[]`
// literal, which points at strings the caller owns). It never frees an element;
// `free` releases only its own spine. Keep the pushed strings alive as long as
// the strarr (or a sort result taken from it) is read.
import std.sort
exports(
new, new_hint, push, push_copy, get, set, size, array, free,
strarr_new_raw, strarr_push_raw, strarr_push_copy_raw, strarr_get_raw,
strarr_set_raw, strarr_data
)
// ---- Raw externs (also the hot-path API) ----
// Allocate an empty array with room for `hint` elements (0 = first push
// allocates). Returns null on OOM.
extern strarr_new_raw(hint: int) -> ptr
// Number of elements. -1 if null.
extern strarr_size(arr: ptr) -> int
// Append `s` (borrowed). Grows 2× when full. 1 on success, 0 on OOM.
extern strarr_push_raw(arr: ptr, s: string) -> int
// Append an OWNED reference to `s` (retains a managed string / copies a
// literal), freed at strarr.free. 1 on success, 0 on OOM.
extern strarr_push_copy_raw(arr: ptr, s: string) -> int
// Read at `i`. null if out of range.
extern strarr_get_raw(arr: ptr, i: int) -> string
// Overwrite at `i` (borrowed). No-op if out of range.
extern strarr_set_raw(arr: ptr, i: int, s: string)
// The raw `string[]` backing — a bare array of `strarr_size` elements, so
// `sort.strings_by` sorts it in place. Valid until the next push (may realloc)
// or free.
extern strarr_data(arr: ptr) -> string[]
// Free the spine only; borrowed elements are the caller's.
extern strarr_free(arr: @frees ptr)
// ---- Go-style wrappers ----
// A fresh empty growable string array.
new() -> ptr {
return strarr_new_raw(0)
}
// Empty array pre-sized for `hint` elements (avoids early regrowth when you
// know roughly how many you'll push).
new_hint(hint: int) -> ptr {
return strarr_new_raw(hint)
}
// Append `s` BORROWED — the string must outlive the array (and any sorted read
// of it). Returns "" on success, an error string on OOM.
push(arr: ptr, s: string) -> string {
ok = strarr_push_raw(arr, s)
if ok == 0 {
return "strarr.push: out of memory"
}
return ""
}
// Append an OWNED copy of `s` — the array takes its own reference and frees it
// in `free`, so you can push a string you just built (a per-iteration concat /
// basename) without keeping it alive yourself. Returns "" on success, an error
// string on OOM.
push_copy(arr: ptr, s: string) -> string {
ok = strarr_push_copy_raw(arr, s)
if ok == 0 {
return "strarr.push_copy: out of memory"
}
return ""
}
// Element at `i` (null if out of range).
get(arr: ptr, i: int) -> string {
return strarr_get_raw(arr, i)
}
// Overwrite element at `i`.
set(arr: ptr, i: int, s: string) {
strarr_set_raw(arr, i, s)
}
// Element count.
size(arr: ptr) -> int {
return strarr_size(arr)
}
// The elements as a `string[]` bounded by the size (#2301), for std.sort
// (`sort.strings_by(strarr.array(sa), cmp)` sorts them in place) or any
// `string[]` parameter. `v[i]` outside it is the slice bounds panic. Valid
// until the next push (which may reallocate) or free. A null handle is the
// empty slice.
array(arr: ptr) -> string[] {
if arr == null {
return null
}
return strarr_data(arr)[0..strarr_size(arr)]
}
// Free the spine.
free(arr: @frees ptr) {
strarr_free(arr)
}