@scriptc/runtime 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/scr_array.c +6 -12
- package/src/scr_assert.c +32 -2
- package/src/scr_bytes.c +3 -6
- package/src/scr_bytes_io.c +1 -2
- package/src/scr_closure.c +1 -2
- package/src/scr_console.c +5 -0
- package/src/scr_cycle.c +1 -2
- package/src/scr_error.c +2 -4
- package/src/scr_events_emitter.c +1 -2
- package/src/scr_exception.c +87 -2
- package/src/scr_inspect.c +83 -2
- package/src/scr_json.c +157 -20
- package/src/scr_lib.c +50 -66
- package/src/scr_library.c +222 -0
- package/src/scr_map.c +2 -4
- package/src/scr_path.c +4 -8
- package/src/scr_regex.c +16 -25
- package/src/scr_runtime.h +127 -1
- package/src/scr_string.c +2 -4
- package/src/scr_symbol.c +2 -3
- package/src/scr_url.c +9 -16
- package/src/scr_url_params.c +6 -12
- package/src/scr_zlib.c +1 -2
package/src/scr_json.c
CHANGED
|
@@ -36,8 +36,7 @@ long scr_dyn_live_count(void) { return scr_live_dyns; }
|
|
|
36
36
|
#endif
|
|
37
37
|
|
|
38
38
|
static void scr_json_oom(void) {
|
|
39
|
-
|
|
40
|
-
abort();
|
|
39
|
+
scr_trap("scriptc: out of memory\n");
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
/* ── output buffer ─────────────────────────────────────────────────────
|
|
@@ -56,6 +55,9 @@ void scr_jb_init(ScrJsonBuf *b) {
|
|
|
56
55
|
b->data = NULL;
|
|
57
56
|
b->len = 0;
|
|
58
57
|
b->cap = 0;
|
|
58
|
+
b->seen = NULL;
|
|
59
|
+
b->seen_len = 0;
|
|
60
|
+
b->seen_cap = 0;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
static void scr_jb_grow(ScrJsonBuf *b, size_t need) {
|
|
@@ -77,6 +79,7 @@ static void scr_jb_grow(ScrJsonBuf *b, size_t need) {
|
|
|
77
79
|
/* Abandon a buffer (parser error paths). */
|
|
78
80
|
static void scr_jb_dispose(ScrJsonBuf *b) {
|
|
79
81
|
if (b->data) scr_str_release(SCR_JB_STR(b));
|
|
82
|
+
free(b->seen);
|
|
80
83
|
scr_jb_init(b);
|
|
81
84
|
}
|
|
82
85
|
|
|
@@ -144,6 +147,10 @@ void scr_jb_put_json_str(ScrJsonBuf *b, const ScrStr *s) {
|
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
ScrStr *scr_jb_finish(ScrJsonBuf *b) {
|
|
150
|
+
free(b->seen);
|
|
151
|
+
b->seen = NULL;
|
|
152
|
+
b->seen_len = 0;
|
|
153
|
+
b->seen_cap = 0;
|
|
147
154
|
if (!b->data) return scr_str_new("", 0);
|
|
148
155
|
ScrStr *s = SCR_JB_STR(b);
|
|
149
156
|
s->len = b->len;
|
|
@@ -155,6 +162,144 @@ ScrStr *scr_jb_finish(ScrJsonBuf *b) {
|
|
|
155
162
|
return s;
|
|
156
163
|
}
|
|
157
164
|
|
|
165
|
+
/* ── circular-structure detection ──────────────────────────────────────
|
|
166
|
+
* RECURSIVE record types permit runtime reference cycles; JSON.stringify
|
|
167
|
+
* of a cyclic value throws V8's exact TypeError. The compiler-emitted
|
|
168
|
+
* walkers over cycle-CAPABLE containers (records whose shape carries a
|
|
169
|
+
* collector header, arrays of them, tuple shapes alike) bracket their
|
|
170
|
+
* bodies with enter/leave and stamp the current member edge before each
|
|
171
|
+
* cycle-capable member write; everything acyclic pays nothing. Detection
|
|
172
|
+
* is STACK membership (a DAG serializes the shared subtree twice, exactly
|
|
173
|
+
* like Node — only a path back to an ancestor is circular).
|
|
174
|
+
*
|
|
175
|
+
* The message mirrors V8's ConstructCircularStructureErrorMessage byte
|
|
176
|
+
* for byte: the starting object (where the repeat lands), one line per
|
|
177
|
+
* hop from it to the top of the stack ("property 'x' -> object with
|
|
178
|
+
* constructor 'Y'" / "index N -> ..."), the middle elided as "..." when
|
|
179
|
+
* there are more than three hops (first two + last one shown), and the
|
|
180
|
+
* closing edge. Constructor names are exactly 'Object'/'Array' — the only
|
|
181
|
+
* containers JSON-safe types admit. */
|
|
182
|
+
typedef struct ScrJsonSeenEnt {
|
|
183
|
+
const void *ptr;
|
|
184
|
+
bool is_array;
|
|
185
|
+
const char *prop; /* static property edge (emitted C literal) */
|
|
186
|
+
const ScrStr *prop_str; /* overflow-key edge (borrowed for the write) */
|
|
187
|
+
size_t index; /* array/tuple index edge */
|
|
188
|
+
} ScrJsonSeenEnt;
|
|
189
|
+
|
|
190
|
+
static void scr_jb_put_edge(ScrJsonBuf *m, const ScrJsonSeenEnt *e) {
|
|
191
|
+
if (e->prop || e->prop_str) {
|
|
192
|
+
scr_jb_puts(m, "property '");
|
|
193
|
+
if (e->prop) scr_jb_puts(m, e->prop);
|
|
194
|
+
else scr_jb_write(m, e->prop_str->data, e->prop_str->len);
|
|
195
|
+
scr_jb_putc(m, '\'');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
scr_jb_puts(m, "index ");
|
|
199
|
+
scr_jb_put_f64(m, (double)e->index);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static void scr_jb_put_ctor(ScrJsonBuf *m, bool is_array) {
|
|
203
|
+
scr_jb_puts(m, is_array ? "object with constructor 'Array'" : "object with constructor 'Object'");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
bool scr_jb_enter(ScrJsonBuf *b, const void *v, bool is_array) {
|
|
207
|
+
for (size_t i = 0; i < b->seen_len; i++) {
|
|
208
|
+
if (b->seen[i].ptr != v) continue;
|
|
209
|
+
ScrJsonBuf m;
|
|
210
|
+
scr_jb_init(&m);
|
|
211
|
+
scr_jb_puts(&m, "Converting circular structure to JSON\n --> starting at ");
|
|
212
|
+
scr_jb_put_ctor(&m, b->seen[i].is_array);
|
|
213
|
+
const size_t n = b->seen_len;
|
|
214
|
+
const size_t hops = n - 1 - i; /* intermediate lines (j = i+1 .. n-1) */
|
|
215
|
+
for (size_t j = i + 1; j < n; j++) {
|
|
216
|
+
if (hops > 3 && j - (i + 1) == 2) {
|
|
217
|
+
scr_jb_puts(&m, "\n | ...");
|
|
218
|
+
j = n - 2; /* the loop increment lands on the LAST hop */
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
scr_jb_puts(&m, "\n | ");
|
|
222
|
+
scr_jb_put_edge(&m, &b->seen[j - 1]);
|
|
223
|
+
scr_jb_puts(&m, " -> ");
|
|
224
|
+
scr_jb_put_ctor(&m, b->seen[j].is_array);
|
|
225
|
+
}
|
|
226
|
+
scr_jb_puts(&m, "\n --- ");
|
|
227
|
+
scr_jb_put_edge(&m, &b->seen[n - 1]);
|
|
228
|
+
scr_jb_puts(&m, " closes the circle");
|
|
229
|
+
scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&m));
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
if (b->seen_len == b->seen_cap) {
|
|
233
|
+
size_t cap = b->seen_cap ? b->seen_cap * 2 : 8;
|
|
234
|
+
ScrJsonSeenEnt *grown = realloc(b->seen, cap * sizeof *grown);
|
|
235
|
+
if (!grown) scr_json_oom();
|
|
236
|
+
b->seen = grown;
|
|
237
|
+
b->seen_cap = cap;
|
|
238
|
+
}
|
|
239
|
+
ScrJsonSeenEnt *e = &b->seen[b->seen_len++];
|
|
240
|
+
e->ptr = v;
|
|
241
|
+
e->is_array = is_array;
|
|
242
|
+
e->prop = NULL;
|
|
243
|
+
e->prop_str = NULL;
|
|
244
|
+
e->index = 0;
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
void scr_jb_leave(ScrJsonBuf *b) {
|
|
249
|
+
if (b->seen_len > 0) b->seen_len--;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
void scr_jb_edge_prop(ScrJsonBuf *b, const char *name) {
|
|
253
|
+
ScrJsonSeenEnt *e = &b->seen[b->seen_len - 1];
|
|
254
|
+
e->prop = name;
|
|
255
|
+
e->prop_str = NULL;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
void scr_jb_edge_key(ScrJsonBuf *b, const ScrStr *key) {
|
|
259
|
+
ScrJsonSeenEnt *e = &b->seen[b->seen_len - 1];
|
|
260
|
+
e->prop = NULL;
|
|
261
|
+
e->prop_str = key;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
void scr_jb_edge_idx(ScrJsonBuf *b, size_t i) {
|
|
265
|
+
ScrJsonSeenEnt *e = &b->seen[b->seen_len - 1];
|
|
266
|
+
e->prop = NULL;
|
|
267
|
+
e->prop_str = NULL;
|
|
268
|
+
e->index = i;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/* ── circular guard for the typed→dyn converters (sc_td_*) ────────────
|
|
272
|
+
* A recursive-typed value crossing into a checked-dynamic slot DEEP-
|
|
273
|
+
* COPIES into the DOM; a cyclic value has no finite copy. Node never
|
|
274
|
+
* copies (an unknown-typed binding shares the reference), so there is no
|
|
275
|
+
* Node-exact error to throw — the conversion TRAPS loudly instead
|
|
276
|
+
* (SEMANTICS.md documents the divergence). The emitted converters over
|
|
277
|
+
* cycle-capable containers bracket their walks with enter/leave; the
|
|
278
|
+
* stack is global (conversions never interleave). */
|
|
279
|
+
static const void **g_td_seen;
|
|
280
|
+
static size_t g_td_nseen;
|
|
281
|
+
static size_t g_td_cap;
|
|
282
|
+
|
|
283
|
+
void scr_dyn_from_enter(const void *v) {
|
|
284
|
+
for (size_t i = 0; i < g_td_nseen; i++) {
|
|
285
|
+
if (g_td_seen[i] == v) {
|
|
286
|
+
scr_trap("scriptc: cannot convert a circular structure into a checked-dynamic value "
|
|
287
|
+
"(unknown-typed slots deep-copy; break the cycle first)\n");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (g_td_nseen == g_td_cap) {
|
|
291
|
+
g_td_cap = g_td_cap ? g_td_cap * 2 : 8;
|
|
292
|
+
const void **grown = realloc(g_td_seen, g_td_cap * sizeof *grown);
|
|
293
|
+
if (!grown) scr_json_oom();
|
|
294
|
+
g_td_seen = grown;
|
|
295
|
+
}
|
|
296
|
+
g_td_seen[g_td_nseen++] = v;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
void scr_dyn_from_leave(void) {
|
|
300
|
+
if (g_td_nseen > 0) g_td_nseen--;
|
|
301
|
+
}
|
|
302
|
+
|
|
158
303
|
/* ── DOM lifecycle ─────────────────────────────────────────────────────
|
|
159
304
|
* Parse/release churn (a JSON round-trip loop allocates and frees every
|
|
160
305
|
* node each iteration) runs on freelists instead of calloc/free: one list
|
|
@@ -421,8 +566,7 @@ void scr_dyn_handle_install(ScrDynHandleTag tag, const ScrDynHandleOps *ops) {
|
|
|
421
566
|
static const ScrDynHandleOps *scr_dyn_handle_ops(ScrDynHandleTag tag) {
|
|
422
567
|
const ScrDynHandleOps *ops = scr_dynh_ops[tag];
|
|
423
568
|
if (!ops) {
|
|
424
|
-
|
|
425
|
-
abort();
|
|
569
|
+
scr_trap("scriptc: internal error: dyn handle ops not installed\n");
|
|
426
570
|
}
|
|
427
571
|
return ops;
|
|
428
572
|
}
|
|
@@ -501,8 +645,7 @@ static ScrDynThisEnt *scr_dyn_this_grow(void) {
|
|
|
501
645
|
size_t cap = scr_dyn_this_cap ? scr_dyn_this_cap * 2 : 8;
|
|
502
646
|
ScrDynThisEnt *s = realloc(scr_dyn_this_stack, cap * sizeof *s);
|
|
503
647
|
if (!s) {
|
|
504
|
-
|
|
505
|
-
abort();
|
|
648
|
+
scr_trap("scriptc: out of memory\n");
|
|
506
649
|
}
|
|
507
650
|
scr_dyn_this_stack = s;
|
|
508
651
|
scr_dyn_this_cap = cap;
|
|
@@ -526,8 +669,7 @@ void scr_dyn_this_push_dyn(const ScrDyn *v) {
|
|
|
526
669
|
|
|
527
670
|
void scr_dyn_this_pop(void) {
|
|
528
671
|
if (scr_dyn_this_n == 0) {
|
|
529
|
-
|
|
530
|
-
abort();
|
|
672
|
+
scr_trap("scriptc: internal error: receiver stack underflow\n");
|
|
531
673
|
}
|
|
532
674
|
ScrDynThisEnt *e = &scr_dyn_this_stack[--scr_dyn_this_n];
|
|
533
675
|
if (e->dv) scr_dyn_release(e->dv);
|
|
@@ -763,13 +905,12 @@ ScrDyn *scr_dyn_from_error(const ScrError *e) {
|
|
|
763
905
|
scr_errdyn_cap = scr_errdyn_cap ? scr_errdyn_cap * 2 : 8;
|
|
764
906
|
scr_errdyn_cache = realloc(scr_errdyn_cache, scr_errdyn_cap * sizeof *scr_errdyn_cache);
|
|
765
907
|
if (!scr_errdyn_cache) {
|
|
766
|
-
|
|
767
|
-
abort();
|
|
908
|
+
scr_trap("scriptc: out of memory\n");
|
|
768
909
|
}
|
|
769
910
|
}
|
|
770
911
|
if (!scr_errdyn_teardown_registered) {
|
|
771
912
|
scr_errdyn_teardown_registered = true;
|
|
772
|
-
|
|
913
|
+
scr_atexit(scr_errdyn_teardown);
|
|
773
914
|
}
|
|
774
915
|
scr_errdyn_cache[scr_errdyn_n].err = scr_error_retain((ScrError *)e);
|
|
775
916
|
scr_errdyn_cache[scr_errdyn_n].dyn = scr_dyn_retain(d);
|
|
@@ -824,13 +965,12 @@ void scr_errdyn_put(ScrError *e, ScrDyn *d) {
|
|
|
824
965
|
scr_errdyn_cap = scr_errdyn_cap ? scr_errdyn_cap * 2 : 8;
|
|
825
966
|
scr_errdyn_cache = realloc(scr_errdyn_cache, scr_errdyn_cap * sizeof *scr_errdyn_cache);
|
|
826
967
|
if (!scr_errdyn_cache) {
|
|
827
|
-
|
|
828
|
-
abort();
|
|
968
|
+
scr_trap("scriptc: out of memory\n");
|
|
829
969
|
}
|
|
830
970
|
}
|
|
831
971
|
if (!scr_errdyn_teardown_registered) {
|
|
832
972
|
scr_errdyn_teardown_registered = true;
|
|
833
|
-
|
|
973
|
+
scr_atexit(scr_errdyn_teardown);
|
|
834
974
|
}
|
|
835
975
|
scr_errdyn_cache[scr_errdyn_n].err = scr_error_retain(e);
|
|
836
976
|
scr_errdyn_cache[scr_errdyn_n].dyn = scr_dyn_retain(d);
|
|
@@ -1035,8 +1175,7 @@ void scr_jb_put_dyn(ScrJsonBuf *b, const ScrDyn *d) {
|
|
|
1035
1175
|
return;
|
|
1036
1176
|
}
|
|
1037
1177
|
}
|
|
1038
|
-
|
|
1039
|
-
abort();
|
|
1178
|
+
scr_trap("scriptc: internal error: invalid dyn kind\n");
|
|
1040
1179
|
}
|
|
1041
1180
|
|
|
1042
1181
|
/* ── dynCheck failure path ─────────────────────────────────────────────── */
|
|
@@ -1750,8 +1889,7 @@ static ScrDyn *scr_sc_clone(const ScrDyn *v, const ScrScParent *up) {
|
|
|
1750
1889
|
size_t len = what->len + sizeof suffix - 1;
|
|
1751
1890
|
char *msg = malloc(len + 1);
|
|
1752
1891
|
if (!msg) {
|
|
1753
|
-
|
|
1754
|
-
abort();
|
|
1892
|
+
scr_trap("scriptc: out of memory\n");
|
|
1755
1893
|
}
|
|
1756
1894
|
memcpy(msg, what->data, what->len);
|
|
1757
1895
|
memcpy(msg + what->len, suffix, sizeof suffix);
|
|
@@ -1860,8 +1998,7 @@ static ScrDyn *scr_dyn_objwalk(const ScrDyn *v, ScrObjWalk mode) {
|
|
|
1860
1998
|
bool *is_index = malloc(n ? n * sizeof *is_index : 1);
|
|
1861
1999
|
double *idx = malloc(n ? n * sizeof *idx : 1);
|
|
1862
2000
|
if (!is_index || !idx) {
|
|
1863
|
-
|
|
1864
|
-
abort();
|
|
2001
|
+
scr_trap("scriptc: out of memory\n");
|
|
1865
2002
|
}
|
|
1866
2003
|
size_t index_count = 0;
|
|
1867
2004
|
for (size_t i = 0; i < n; i++) {
|
package/src/scr_lib.c
CHANGED
|
@@ -126,11 +126,25 @@ static void scr_lib_cleanup(void) {
|
|
|
126
126
|
scr_versions_openssl_str = NULL;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
#ifndef SCR_LIB
|
|
130
|
+
/* Executable lane only: a library artifact has no argv and registers no
|
|
131
|
+
* atexit handlers (the emitted library init never calls this; keeping it out
|
|
132
|
+
* the archive's objects free of any atexit reference — the K8 ambient
|
|
133
|
+
* audit's bar). */
|
|
129
134
|
void scr_lib_init(int argc, char **argv) {
|
|
130
135
|
scr_lib_argc = argc;
|
|
131
136
|
scr_lib_argv = argv;
|
|
132
137
|
atexit(scr_lib_cleanup);
|
|
133
138
|
}
|
|
139
|
+
#endif /* !SCR_LIB */
|
|
140
|
+
|
|
141
|
+
#ifdef SCR_LIB
|
|
142
|
+
/* Library builds never call scr_lib_init (a library artifact has no argv and registers no
|
|
143
|
+
* atexit handlers); the interned process values above still intern lazily
|
|
144
|
+
* on first read, so the library reset seam releases them here instead —
|
|
145
|
+
* scr_library_reset (scr_library.c) calls this every session reset. */
|
|
146
|
+
void scr_lib_session_cleanup(void) { scr_lib_cleanup(); }
|
|
147
|
+
#endif
|
|
134
148
|
|
|
135
149
|
/* Raw argv accessors for the island's process shim (scr_island.c): the
|
|
136
150
|
* island's process.argv must match the static world's ["scriptc",
|
|
@@ -261,8 +275,7 @@ ScrStr *scr_env_get(const ScrStr *name) {
|
|
|
261
275
|
if (need == 0) return NULL; /* absent (an empty value still needs its NUL) */
|
|
262
276
|
char *buf = malloc(need);
|
|
263
277
|
if (!buf) {
|
|
264
|
-
|
|
265
|
-
abort();
|
|
278
|
+
scr_trap("scriptc: out of memory\n");
|
|
266
279
|
}
|
|
267
280
|
DWORD got = GetEnvironmentVariableA(name->data, buf, need);
|
|
268
281
|
ScrStr *s = scr_str_new(buf, got);
|
|
@@ -553,8 +566,7 @@ bool scr_process_kill_named(double pid, const ScrStr *signal) {
|
|
|
553
566
|
size_t cap = 16 + signal->len + 1;
|
|
554
567
|
char *msg = malloc(cap);
|
|
555
568
|
if (!msg) {
|
|
556
|
-
|
|
557
|
-
abort();
|
|
569
|
+
scr_trap("scriptc: out of memory\n");
|
|
558
570
|
}
|
|
559
571
|
int len = snprintf(msg, cap, "Unknown signal: %s", signal->data);
|
|
560
572
|
scr_throw_error_msg(SCR_ERR_TYPE, msg, (size_t)len);
|
|
@@ -567,8 +579,7 @@ bool scr_process_kill_named(double pid, const ScrStr *signal) {
|
|
|
567
579
|
ScrStr *scr_process_cwd(void) {
|
|
568
580
|
char buf[4096];
|
|
569
581
|
if (!getcwd(buf, sizeof buf)) {
|
|
570
|
-
|
|
571
|
-
abort();
|
|
582
|
+
scr_trap("scriptc: process.cwd() failed\n");
|
|
572
583
|
}
|
|
573
584
|
return scr_str_new(buf, strlen(buf));
|
|
574
585
|
}
|
|
@@ -612,16 +623,14 @@ bool scr_proc_stream_write(double fd, const ScrStr *data) {
|
|
|
612
623
|
ScrStr *scr_os_homedir(void) {
|
|
613
624
|
const char *home = getenv("USERPROFILE");
|
|
614
625
|
if (home && home[0] != '\0') return scr_str_new(home, strlen(home));
|
|
615
|
-
|
|
616
|
-
abort();
|
|
626
|
+
scr_trap("scriptc: os.homedir() failed\n");
|
|
617
627
|
}
|
|
618
628
|
|
|
619
629
|
ScrStr *scr_os_user_name(void) {
|
|
620
630
|
char buf[UNLEN + 1];
|
|
621
631
|
DWORD n = sizeof buf;
|
|
622
632
|
if (!GetUserNameA(buf, &n) || n == 0) {
|
|
623
|
-
|
|
624
|
-
abort();
|
|
633
|
+
scr_trap("scriptc: os.userInfo() failed\n");
|
|
625
634
|
}
|
|
626
635
|
return scr_str_new(buf, n - 1); /* n counts the NUL */
|
|
627
636
|
}
|
|
@@ -648,8 +657,7 @@ ScrStr *scr_os_release(void) {
|
|
|
648
657
|
RtlGetVersionFn fn =
|
|
649
658
|
ntdll ? (RtlGetVersionFn)(void *)GetProcAddress(ntdll, "RtlGetVersion") : NULL;
|
|
650
659
|
if (fn == NULL || fn(&info) != 0) {
|
|
651
|
-
|
|
652
|
-
abort();
|
|
660
|
+
scr_trap("scriptc: os.release() failed\n");
|
|
653
661
|
}
|
|
654
662
|
char buf[64];
|
|
655
663
|
int len = snprintf(buf, sizeof buf, "%lu.%lu.%lu", (unsigned long)info.dwMajorVersion,
|
|
@@ -676,8 +684,7 @@ ScrStr *scr_os_tmpdir(void) {
|
|
|
676
684
|
char buf[MAX_PATH + 2];
|
|
677
685
|
DWORD n = GetTempPathA(sizeof buf, buf);
|
|
678
686
|
if (n == 0 || n >= sizeof buf) {
|
|
679
|
-
|
|
680
|
-
abort();
|
|
687
|
+
scr_trap("scriptc: os.tmpdir() failed\n");
|
|
681
688
|
}
|
|
682
689
|
size_t len = n;
|
|
683
690
|
if (len > 1 && (buf[len - 1] == '\\' || buf[len - 1] == '/')) len--;
|
|
@@ -693,8 +700,7 @@ ScrStr *scr_os_homedir(void) {
|
|
|
693
700
|
struct passwd *result = NULL;
|
|
694
701
|
char buf[8192];
|
|
695
702
|
if (getpwuid_r(getuid(), &pw, buf, sizeof buf, &result) != 0 || !result || !result->pw_dir) {
|
|
696
|
-
|
|
697
|
-
abort();
|
|
703
|
+
scr_trap("scriptc: os.homedir() failed\n");
|
|
698
704
|
}
|
|
699
705
|
return scr_str_new(result->pw_dir, strlen(result->pw_dir));
|
|
700
706
|
}
|
|
@@ -706,8 +712,7 @@ ScrStr *scr_os_homedir(void) {
|
|
|
706
712
|
static const struct passwd *scr_os_passwd(char *buf, size_t cap, struct passwd *pw) {
|
|
707
713
|
struct passwd *result = NULL;
|
|
708
714
|
if (getpwuid_r(getuid(), pw, buf, cap, &result) != 0 || !result) {
|
|
709
|
-
|
|
710
|
-
abort();
|
|
715
|
+
scr_trap("scriptc: os.userInfo() failed\n");
|
|
711
716
|
}
|
|
712
717
|
return result;
|
|
713
718
|
}
|
|
@@ -740,8 +745,7 @@ ScrStr *scr_os_release(void) {
|
|
|
740
745
|
/* uname(2)'s release field — Node's uv_os_uname()-backed answer. */
|
|
741
746
|
struct utsname u;
|
|
742
747
|
if (uname(&u) != 0) {
|
|
743
|
-
|
|
744
|
-
abort();
|
|
748
|
+
scr_trap("scriptc: os.release() failed\n");
|
|
745
749
|
}
|
|
746
750
|
return scr_str_new(u.release, strlen(u.release));
|
|
747
751
|
}
|
|
@@ -750,8 +754,7 @@ ScrStr *scr_os_type(void) {
|
|
|
750
754
|
/* uname(2)'s sysname field ("Darwin", "Linux") — Node's os.type(). */
|
|
751
755
|
struct utsname u;
|
|
752
756
|
if (uname(&u) != 0) {
|
|
753
|
-
|
|
754
|
-
abort();
|
|
757
|
+
scr_trap("scriptc: os.type() failed\n");
|
|
755
758
|
}
|
|
756
759
|
return scr_str_new(u.sysname, strlen(u.sysname));
|
|
757
760
|
}
|
|
@@ -824,20 +827,20 @@ struct ScrIfaddrs {
|
|
|
824
827
|
* stance. */
|
|
825
828
|
ScrIfaddrs *scr_os_ifaddrs(void) {
|
|
826
829
|
ScrIfaddrs *s = calloc(1, sizeof *s);
|
|
827
|
-
if (!s)
|
|
830
|
+
if (!s) scr_trap("scriptc: out of memory\n");
|
|
828
831
|
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
|
|
829
832
|
GAA_FLAG_SKIP_DNS_SERVER;
|
|
830
833
|
ULONG size = 16 * 1024;
|
|
831
834
|
IP_ADAPTER_ADDRESSES *adapters = NULL;
|
|
832
835
|
for (int tries = 0; tries < 4; tries++) {
|
|
833
836
|
adapters = realloc(adapters, size);
|
|
834
|
-
if (!adapters)
|
|
837
|
+
if (!adapters) scr_trap("scriptc: out of memory\n");
|
|
835
838
|
ULONG rc = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &size);
|
|
836
839
|
if (rc == ERROR_SUCCESS) break;
|
|
837
840
|
if (rc != ERROR_BUFFER_OVERFLOW) {
|
|
838
841
|
free(adapters);
|
|
839
842
|
s->rows = calloc(1, sizeof *s->rows);
|
|
840
|
-
if (!s->rows)
|
|
843
|
+
if (!s->rows) scr_trap("scriptc: out of memory\n");
|
|
841
844
|
return s; /* empty snapshot */
|
|
842
845
|
}
|
|
843
846
|
}
|
|
@@ -850,7 +853,7 @@ ScrIfaddrs *scr_os_ifaddrs(void) {
|
|
|
850
853
|
}
|
|
851
854
|
}
|
|
852
855
|
s->rows = calloc(count ? count : 1, sizeof *s->rows);
|
|
853
|
-
if (!s->rows)
|
|
856
|
+
if (!s->rows) scr_trap("scriptc: out of memory\n");
|
|
854
857
|
for (IP_ADAPTER_ADDRESSES *a = adapters; a != NULL; a = a->Next) {
|
|
855
858
|
if (a->OperStatus != IfOperStatusUp || a->FirstUnicastAddress == NULL) continue;
|
|
856
859
|
char name[64] = "";
|
|
@@ -934,7 +937,7 @@ static int scr_netmask_prefix(const unsigned char *bytes, size_t len) {
|
|
|
934
937
|
|
|
935
938
|
ScrIfaddrs *scr_os_ifaddrs(void) {
|
|
936
939
|
ScrIfaddrs *s = calloc(1, sizeof *s);
|
|
937
|
-
if (!s)
|
|
940
|
+
if (!s) scr_trap("scriptc: out of memory\n");
|
|
938
941
|
struct ifaddrs *addrs = NULL;
|
|
939
942
|
if (getifaddrs(&addrs) != 0) return s;
|
|
940
943
|
size_t count = 0;
|
|
@@ -942,7 +945,7 @@ ScrIfaddrs *scr_os_ifaddrs(void) {
|
|
|
942
945
|
if (scr_ifaddr_row_ok(ent)) count++;
|
|
943
946
|
}
|
|
944
947
|
s->rows = calloc(count ? count : 1, sizeof *s->rows);
|
|
945
|
-
if (!s->rows)
|
|
948
|
+
if (!s->rows) scr_trap("scriptc: out of memory\n");
|
|
946
949
|
for (struct ifaddrs *ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
|
947
950
|
if (!scr_ifaddr_row_ok(ent)) continue;
|
|
948
951
|
ScrIfaddrRow *row = &s->rows[s->n++];
|
|
@@ -1419,8 +1422,7 @@ void scr_fs_throw(int e, const char *op, const ScrStr *path) {
|
|
|
1419
1422
|
size_t cap = strlen(name) + strlen(text) + strlen(op) + strlen(shown) + 8;
|
|
1420
1423
|
char *msg = malloc(cap);
|
|
1421
1424
|
if (!msg) {
|
|
1422
|
-
|
|
1423
|
-
abort();
|
|
1425
|
+
scr_trap("scriptc: out of memory\n");
|
|
1424
1426
|
}
|
|
1425
1427
|
int len = snprintf(msg, cap, "%s: %s, %s '%s'", name, text, op, shown);
|
|
1426
1428
|
/* A real Error instance (name "Error", message = Node's text) — what a
|
|
@@ -1443,16 +1445,14 @@ ScrStr *scr_fs_read_file(ScrStr *path) {
|
|
|
1443
1445
|
size_t cap = 4096, len = 0;
|
|
1444
1446
|
char *buf = malloc(cap);
|
|
1445
1447
|
if (!buf) {
|
|
1446
|
-
|
|
1447
|
-
abort();
|
|
1448
|
+
scr_trap("scriptc: out of memory\n");
|
|
1448
1449
|
}
|
|
1449
1450
|
for (;;) {
|
|
1450
1451
|
if (cap - len < 2048) {
|
|
1451
1452
|
cap *= 2;
|
|
1452
1453
|
char *grown = realloc(buf, cap);
|
|
1453
1454
|
if (!grown) {
|
|
1454
|
-
|
|
1455
|
-
abort();
|
|
1455
|
+
scr_trap("scriptc: out of memory\n");
|
|
1456
1456
|
}
|
|
1457
1457
|
buf = grown;
|
|
1458
1458
|
}
|
|
@@ -1698,8 +1698,7 @@ static void scr_fs_throw2(int e, const char *op, const ScrStr *src, const ScrStr
|
|
|
1698
1698
|
size_t cap = strlen(name) + strlen(text) + strlen(op) + strlen(shown_src) + strlen(shown_dest) + 16;
|
|
1699
1699
|
char *msg = malloc(cap);
|
|
1700
1700
|
if (!msg) {
|
|
1701
|
-
|
|
1702
|
-
abort();
|
|
1701
|
+
scr_trap("scriptc: out of memory\n");
|
|
1703
1702
|
}
|
|
1704
1703
|
int len = snprintf(msg, cap, "%s: %s, %s '%s' -> '%s'", name, text, op, shown_src, shown_dest);
|
|
1705
1704
|
scr_throw_error_msg_code(SCR_ERR_ERROR, msg, (size_t)len, name);
|
|
@@ -1856,8 +1855,7 @@ static void scr_mkdir_rec(char *path, size_t len, mode_t mode) {
|
|
|
1856
1855
|
void scr_fs_mkdir_recursive(ScrStr *path) {
|
|
1857
1856
|
char *buf = malloc(path->len + 1);
|
|
1858
1857
|
if (!buf) {
|
|
1859
|
-
|
|
1860
|
-
abort();
|
|
1858
|
+
scr_trap("scriptc: out of memory\n");
|
|
1861
1859
|
}
|
|
1862
1860
|
memcpy(buf, path->data, path->len + 1); /* ScrStr data is NUL-terminated */
|
|
1863
1861
|
scr_mkdir_rec(buf, path->len, 0777);
|
|
@@ -1869,8 +1867,7 @@ void scr_fs_mkdir_recursive(ScrStr *path) {
|
|
|
1869
1867
|
void scr_fs_mkdir_recursive_mode(ScrStr *path, double mode) {
|
|
1870
1868
|
char *buf = malloc(path->len + 1);
|
|
1871
1869
|
if (!buf) {
|
|
1872
|
-
|
|
1873
|
-
abort();
|
|
1870
|
+
scr_trap("scriptc: out of memory\n");
|
|
1874
1871
|
}
|
|
1875
1872
|
memcpy(buf, path->data, path->len + 1);
|
|
1876
1873
|
scr_mkdir_rec(buf, path->len, (mode_t)mode);
|
|
@@ -1917,8 +1914,7 @@ static void scr_rm_tree_e(const char *path, size_t len, ScrRmFail *f) {
|
|
|
1917
1914
|
size_t namelen = strlen(ent->d_name);
|
|
1918
1915
|
char *child = malloc(len + 1 + namelen + 1);
|
|
1919
1916
|
if (!child) {
|
|
1920
|
-
|
|
1921
|
-
abort();
|
|
1917
|
+
scr_trap("scriptc: out of memory\n");
|
|
1922
1918
|
}
|
|
1923
1919
|
memcpy(child, path, len);
|
|
1924
1920
|
child[len] = '/';
|
|
@@ -2021,8 +2017,7 @@ static char *scr_win_mkdtemp(char *tmpl) {
|
|
|
2021
2017
|
ScrStr *scr_fs_mkdtemp(ScrStr *prefix) {
|
|
2022
2018
|
char *tmpl = malloc(prefix->len + 7);
|
|
2023
2019
|
if (!tmpl) {
|
|
2024
|
-
|
|
2025
|
-
abort();
|
|
2020
|
+
scr_trap("scriptc: out of memory\n");
|
|
2026
2021
|
}
|
|
2027
2022
|
memcpy(tmpl, prefix->data, prefix->len);
|
|
2028
2023
|
memcpy(tmpl + prefix->len, "XXXXXX", 7);
|
|
@@ -2069,16 +2064,14 @@ static char *scr_read_fd_all(double fd, size_t *out_len) {
|
|
|
2069
2064
|
size_t cap = 4096, len = 0;
|
|
2070
2065
|
char *buf = malloc(cap);
|
|
2071
2066
|
if (!buf) {
|
|
2072
|
-
|
|
2073
|
-
abort();
|
|
2067
|
+
scr_trap("scriptc: out of memory\n");
|
|
2074
2068
|
}
|
|
2075
2069
|
for (;;) {
|
|
2076
2070
|
if (cap - len < 2048) {
|
|
2077
2071
|
cap *= 2;
|
|
2078
2072
|
char *grown = realloc(buf, cap);
|
|
2079
2073
|
if (!grown) {
|
|
2080
|
-
|
|
2081
|
-
abort();
|
|
2074
|
+
scr_trap("scriptc: out of memory\n");
|
|
2082
2075
|
}
|
|
2083
2076
|
buf = grown;
|
|
2084
2077
|
}
|
|
@@ -2286,8 +2279,7 @@ double scr_stats_mtime_ms(ScrStats *s) { return s->mtime_ms; }
|
|
|
2286
2279
|
static ScrStats *scr_stats_of(const struct stat *st) {
|
|
2287
2280
|
ScrStats *s = malloc(sizeof(ScrStats));
|
|
2288
2281
|
if (!s) {
|
|
2289
|
-
|
|
2290
|
-
abort();
|
|
2282
|
+
scr_trap("scriptc: out of memory\n");
|
|
2291
2283
|
}
|
|
2292
2284
|
s->rc = 1;
|
|
2293
2285
|
s->is_file = S_ISREG(st->st_mode);
|
|
@@ -2384,16 +2376,14 @@ ScrScandir *scr_fs_scandir(ScrStr *path) {
|
|
|
2384
2376
|
}
|
|
2385
2377
|
ScrScandir *s = malloc(sizeof *s);
|
|
2386
2378
|
if (!s) {
|
|
2387
|
-
|
|
2388
|
-
abort();
|
|
2379
|
+
scr_trap("scriptc: out of memory\n");
|
|
2389
2380
|
}
|
|
2390
2381
|
s->len = 0;
|
|
2391
2382
|
s->cap = 8;
|
|
2392
2383
|
s->names = malloc(s->cap * sizeof *s->names);
|
|
2393
2384
|
s->kinds = malloc(s->cap);
|
|
2394
2385
|
if (!s->names || !s->kinds) {
|
|
2395
|
-
|
|
2396
|
-
abort();
|
|
2386
|
+
scr_trap("scriptc: out of memory\n");
|
|
2397
2387
|
}
|
|
2398
2388
|
const struct dirent *ent;
|
|
2399
2389
|
while ((ent = readdir(d)) != NULL) {
|
|
@@ -2434,8 +2424,7 @@ ScrScandir *scr_fs_scandir(ScrStr *path) {
|
|
|
2434
2424
|
s->names = realloc(s->names, s->cap * sizeof *s->names);
|
|
2435
2425
|
s->kinds = realloc(s->kinds, s->cap);
|
|
2436
2426
|
if (!s->names || !s->kinds) {
|
|
2437
|
-
|
|
2438
|
-
abort();
|
|
2427
|
+
scr_trap("scriptc: out of memory\n");
|
|
2439
2428
|
}
|
|
2440
2429
|
}
|
|
2441
2430
|
s->names[s->len] = scr_str_new(ent->d_name, strlen(ent->d_name));
|
|
@@ -2545,8 +2534,7 @@ ScrStr *scr_crypto_random_string(double n, ScrStr *enc) {
|
|
|
2545
2534
|
size_t size = (size_t)n;
|
|
2546
2535
|
unsigned char *bytes = malloc(size ? size : 1);
|
|
2547
2536
|
if (!bytes) {
|
|
2548
|
-
|
|
2549
|
-
abort();
|
|
2537
|
+
scr_trap("scriptc: out of memory\n");
|
|
2550
2538
|
}
|
|
2551
2539
|
arc4random_buf(bytes, size);
|
|
2552
2540
|
ScrStr *out;
|
|
@@ -2554,8 +2542,7 @@ ScrStr *scr_crypto_random_string(double n, ScrStr *enc) {
|
|
|
2554
2542
|
static const char hex[] = "0123456789abcdef";
|
|
2555
2543
|
char *buf = malloc(size * 2 + 1);
|
|
2556
2544
|
if (!buf) {
|
|
2557
|
-
|
|
2558
|
-
abort();
|
|
2545
|
+
scr_trap("scriptc: out of memory\n");
|
|
2559
2546
|
}
|
|
2560
2547
|
for (size_t i = 0; i < size; i++) {
|
|
2561
2548
|
buf[i * 2] = hex[bytes[i] >> 4];
|
|
@@ -2569,8 +2556,7 @@ ScrStr *scr_crypto_random_string(double n, ScrStr *enc) {
|
|
|
2569
2556
|
size_t outlen = (size + 2) / 3 * 4;
|
|
2570
2557
|
char *buf = malloc(outlen + 1);
|
|
2571
2558
|
if (!buf) {
|
|
2572
|
-
|
|
2573
|
-
abort();
|
|
2559
|
+
scr_trap("scriptc: out of memory\n");
|
|
2574
2560
|
}
|
|
2575
2561
|
size_t o = 0;
|
|
2576
2562
|
for (size_t i = 0; i < size; i += 3) {
|
|
@@ -2909,8 +2895,7 @@ static bool scr_x509_der(const uint8_t *in, size_t n, const uint8_t **der, size_
|
|
|
2909
2895
|
}
|
|
2910
2896
|
uint8_t *out = malloc(((size_t)(stop - b) / 4 + 1) * 3 + 3);
|
|
2911
2897
|
if (!out) {
|
|
2912
|
-
|
|
2913
|
-
abort();
|
|
2898
|
+
scr_trap("scriptc: out of memory\n");
|
|
2914
2899
|
}
|
|
2915
2900
|
size_t o = 0;
|
|
2916
2901
|
unsigned acc = 0;
|
|
@@ -3126,8 +3111,7 @@ static uint32_t scr_to_uint32(double d);
|
|
|
3126
3111
|
static ScrStr *scr_str_from_units(size_t n, uint32_t (*unit)(void *, size_t), void *src) {
|
|
3127
3112
|
char *out = malloc(n * 3 + 1); /* worst case: 3 bytes per UTF-16 unit */
|
|
3128
3113
|
if (!out) {
|
|
3129
|
-
|
|
3130
|
-
abort();
|
|
3114
|
+
scr_trap("scriptc: out of memory\n");
|
|
3131
3115
|
}
|
|
3132
3116
|
size_t o = 0;
|
|
3133
3117
|
for (size_t i = 0; i < n; i++) {
|