@scriptc/cli-darwin-x64 0.2.3 → 0.2.4
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/dist/THIRD_PARTY_NOTICES +1 -1
- package/dist/bin/scriptc +0 -0
- package/dist/bin/scriptc.json +1 -1
- package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
- package/dist/lib/llvm/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/runtime-pack.json +129 -129
- package/dist/lib/runtime-sources/package.json +1 -1
- package/dist/lib/runtime-sources/src/scr_array.c +50 -34
- package/dist/lib/runtime-sources/src/scr_bigint.c +15 -0
- package/dist/lib/runtime-sources/src/scr_cycle.c +84 -60
- package/dist/lib/runtime-sources/src/scr_json.c +15 -11
- package/dist/lib/runtime-sources/src/scr_lib.c +45 -16
- package/dist/lib/runtime-sources/src/scr_map.c +228 -40
- package/dist/lib/runtime-sources/src/scr_regex.c +47 -8
- package/dist/lib/runtime-sources/src/scr_runtime.h +39 -13
- package/dist/lib/runtime-sources/src/scr_string.c +29 -0
- package/package.json +1 -1
|
@@ -297,7 +297,7 @@ void scr_library_bytes_out(ScrBytes *b, const uint8_t **out, size_t *out_len);
|
|
|
297
297
|
* The collector is synchronous Bacon–Rajan trial deletion: a release that
|
|
298
298
|
* leaves a candidate's rc above zero buffers it as a possible cycle root;
|
|
299
299
|
* collection walks the buffer (markGray: trial-decrement internal edges;
|
|
300
|
-
* scan: restore externally-referenced subgraphs;
|
|
300
|
+
* scan: restore externally-referenced subgraphs; gather: free the
|
|
301
301
|
* dead cycle members, releasing only edges that LEAVE the white set).
|
|
302
302
|
* It is GENERATIONAL: each header carries a generation, a pass names the
|
|
303
303
|
* oldest one it will walk, and objects that survive a pass are promoted out
|
|
@@ -322,9 +322,9 @@ typedef void (*ScrTraceVisit)(void *child, void *ctx);
|
|
|
322
322
|
typedef void (*ScrTraceFn)(void *obj, ScrTraceVisit visit, void *ctx);
|
|
323
323
|
typedef void (*ScrCycFreeFn)(void *obj);
|
|
324
324
|
|
|
325
|
-
/* DOOMED
|
|
326
|
-
*
|
|
327
|
-
*
|
|
325
|
+
/* DOOMED identifies the gathered dead set during re-buffering and weak
|
|
326
|
+
* observer teardown. WHITE candidates may still become black when a later
|
|
327
|
+
* outside root restores them; only the settled white set becomes DOOMED. */
|
|
328
328
|
enum {
|
|
329
329
|
SCR_CYC_BLACK = 0, SCR_CYC_PURPLE = 1, SCR_CYC_GRAY = 2, SCR_CYC_WHITE = 3,
|
|
330
330
|
SCR_CYC_DOOMED = 4
|
|
@@ -437,7 +437,7 @@ typedef struct ScrVt {
|
|
|
437
437
|
*
|
|
438
438
|
* cap is the usable byte capacity of data[] excluding the NUL (allocation
|
|
439
439
|
* is sizeof(ScrStr) + cap + 1); cap == len for interned literals and plain
|
|
440
|
-
* allocations.
|
|
440
|
+
* allocations. Builders and concat results may have spare capacity so
|
|
441
441
|
* scr_str_concat can append in place when the left operand is uniquely
|
|
442
442
|
* owned (rc == 1) — observable immutability is preserved: a string with
|
|
443
443
|
* rc > 1 or rc == SIZE_MAX is never mutated.
|
|
@@ -454,7 +454,7 @@ ScrStr *scr_str_new(const char *bytes, size_t len); /* returns +1 */
|
|
|
454
454
|
* malformed subsequences with U+FFFD. NULL with len == 0 is an empty span. */
|
|
455
455
|
ScrStr *scr_str_from_utf8_lossy(const uint8_t *bytes, size_t len); /* +1 */
|
|
456
456
|
|
|
457
|
-
/* Internal allocators for buffer builders
|
|
457
|
+
/* Internal allocators for buffer builders: a +1 string with
|
|
458
458
|
* UNINITIALIZED data (the builder fills bytes, then len and the NUL), and
|
|
459
459
|
* an rc==1-only realloc that grows capacity in place. Both keep the RC
|
|
460
460
|
* audit's live count exact. */
|
|
@@ -470,6 +470,8 @@ void scr_str_release(ScrStr *s); /* NULL-tolerant (uninitialized locals) */
|
|
|
470
470
|
|
|
471
471
|
/* Borrow both args, return +1. */
|
|
472
472
|
ScrStr *scr_str_concat(ScrStr *a, ScrStr *b);
|
|
473
|
+
/* Borrow each part without mutation; return one independently owned result. */
|
|
474
|
+
ScrStr *scr_str_concat_parts(ScrStr *const *parts, size_t count);
|
|
473
475
|
|
|
474
476
|
bool scr_str_eq(ScrStr *a, ScrStr *b);
|
|
475
477
|
|
|
@@ -1321,10 +1323,10 @@ ScrArr *scr_regex_match_all_into(ScrStr *s, ScrRegex *re, ScrArr *indices);
|
|
|
1321
1323
|
* are visited (they append), deleted entries are skipped (tombstones), and
|
|
1322
1324
|
* a delete + re-add moves the key to the end (Node-verified).
|
|
1323
1325
|
*
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
* the
|
|
1326
|
+
* Primitive keys compare by value and reference keys by identity. Numbers
|
|
1327
|
+
* use SameValueZero: NaN equals NaN and -0 is stored as +0. Union wrappers
|
|
1328
|
+
* are representations, never identities; their arm descriptors select
|
|
1329
|
+
* the primitive or reference comparison, including null and undefined.
|
|
1328
1330
|
*
|
|
1329
1331
|
* Values are one uniform kind per map (like ScrArr elements): f64, bool, or
|
|
1330
1332
|
* a refcounted pointer whose RC entry points arrive as function pointers at
|
|
@@ -1351,13 +1353,17 @@ ScrArr *scr_regex_match_all_into(ScrStr *s, ScrRegex *re, ScrArr *indices);
|
|
|
1351
1353
|
* DYN owns a checked-value box and compares its JavaScript value using
|
|
1352
1354
|
* SameValueZero, including reference identity for object payloads.
|
|
1353
1355
|
* These key kinds serve both Maps and Sets. */
|
|
1354
|
-
typedef enum {
|
|
1356
|
+
typedef enum {
|
|
1357
|
+
SCR_MAP_KEY_F64, SCR_MAP_KEY_STR, SCR_MAP_KEY_REF, SCR_MAP_KEY_UNION_REF, SCR_MAP_KEY_DYN,
|
|
1358
|
+
SCR_MAP_KEY_BIGINT, SCR_MAP_KEY_BOOL, SCR_MAP_KEY_UNION_VALUE,
|
|
1359
|
+
SCR_MAP_KEY_NULL, SCR_MAP_KEY_UNDEFINED /* tag-only union arms */
|
|
1360
|
+
} ScrMapKeyKind;
|
|
1355
1361
|
typedef enum { SCR_MAP_VAL_F64, SCR_MAP_VAL_BOOL, SCR_MAP_VAL_REF } ScrMapValKind;
|
|
1356
1362
|
|
|
1357
1363
|
typedef struct {
|
|
1358
1364
|
uint64_t key; /* double bits (normalized), ScrStr* (owned), or ref ptr (owned) */
|
|
1359
1365
|
uint64_t val; /* double bits, bool, or owned pointer */
|
|
1360
|
-
|
|
1366
|
+
uint64_t hash; /* nonzero cached hash; zero = tombstone (key/val released) */
|
|
1361
1367
|
} ScrMapEntry;
|
|
1362
1368
|
|
|
1363
1369
|
/* Checked views use the original storage. Slot converters borrow on reads
|
|
@@ -1380,7 +1386,7 @@ typedef struct ScrMap {
|
|
|
1380
1386
|
void *(*val_retain)(void *);
|
|
1381
1387
|
void (*val_release)(void *);
|
|
1382
1388
|
ScrTraceFn val_trace;
|
|
1383
|
-
/*
|
|
1389
|
+
/* Reference-represented keys, including bigint and union values. */
|
|
1384
1390
|
void *(*key_retain)(void *);
|
|
1385
1391
|
void (*key_release)(void *);
|
|
1386
1392
|
ScrTraceFn key_trace;
|
|
@@ -1392,8 +1398,17 @@ typedef struct ScrMap {
|
|
|
1392
1398
|
size_t *buckets; /* entry indices; SIZE_MAX = empty */
|
|
1393
1399
|
size_t iter_depth; /* > 0: an iteration is active — no compaction */
|
|
1394
1400
|
const ScrMapDynOps *dyn_ops;
|
|
1401
|
+
const uint8_t *union_keys; /* immutable key-kind table indexed by union tag */
|
|
1395
1402
|
} ScrMap;
|
|
1396
1403
|
|
|
1404
|
+
/* Called once on a fresh UNION_VALUE collection, before its first insert. */
|
|
1405
|
+
void scr_map_union_keys(ScrMap *map, const uint8_t *kinds);
|
|
1406
|
+
/* Fresh shallow copies with compact storage and independent mutation.
|
|
1407
|
+
* keys_only selects a Set; checked views materialize their boxed values. */
|
|
1408
|
+
ScrMap *scr_map_clone(const ScrMap *source, bool keys_only);
|
|
1409
|
+
ScrMap *scr_map_clone_dyn(const ScrMap *source, bool keys_only);
|
|
1410
|
+
void scr_map_values_into(ScrMap *set, const ScrMap *source, bool checked);
|
|
1411
|
+
|
|
1397
1412
|
void scr_map_dyn_attach(ScrMap *map, const ScrMapDynOps *ops);
|
|
1398
1413
|
struct ScrDyn *scr_map_dyn_key(const ScrMap *map, double index);
|
|
1399
1414
|
struct ScrDyn *scr_map_dyn_value(const ScrMap *map, double index);
|
|
@@ -1426,9 +1441,11 @@ double scr_map_size(const ScrMap *m); /* live entries (Map.size) */
|
|
|
1426
1441
|
void scr_map_clear(ScrMap *m);
|
|
1427
1442
|
|
|
1428
1443
|
bool scr_map_has_f64(const ScrMap *m, double key);
|
|
1444
|
+
bool scr_map_has_bool(const ScrMap *m, bool key);
|
|
1429
1445
|
bool scr_map_has_str(const ScrMap *m, const ScrStr *key);
|
|
1430
1446
|
bool scr_map_has_ref(const ScrMap *m, const void *key);
|
|
1431
1447
|
bool scr_map_delete_f64(ScrMap *m, double key);
|
|
1448
|
+
bool scr_map_delete_bool(ScrMap *m, bool key);
|
|
1432
1449
|
bool scr_map_delete_str(ScrMap *m, const ScrStr *key);
|
|
1433
1450
|
bool scr_map_delete_ref(ScrMap *m, const void *key);
|
|
1434
1451
|
|
|
@@ -1438,6 +1455,9 @@ bool scr_map_delete_ref(ScrMap *m, const void *key);
|
|
|
1438
1455
|
void scr_map_set_f64_f64(ScrMap *m, double key, double v);
|
|
1439
1456
|
void scr_map_set_f64_bool(ScrMap *m, double key, bool v);
|
|
1440
1457
|
void scr_map_set_f64_ref(ScrMap *m, double key, void *v);
|
|
1458
|
+
void scr_map_set_bool_f64(ScrMap *m, bool key, double v);
|
|
1459
|
+
void scr_map_set_bool_bool(ScrMap *m, bool key, bool v);
|
|
1460
|
+
void scr_map_set_bool_ref(ScrMap *m, bool key, void *v);
|
|
1441
1461
|
void scr_map_set_str_f64(ScrMap *m, ScrStr *key, double v);
|
|
1442
1462
|
void scr_map_set_str_bool(ScrMap *m, ScrStr *key, bool v);
|
|
1443
1463
|
void scr_map_set_str_ref(ScrMap *m, ScrStr *key, void *v);
|
|
@@ -1452,6 +1472,9 @@ void scr_map_set_ref_ref(ScrMap *m, void *key, void *v);
|
|
|
1452
1472
|
bool scr_map_get_f64_f64(const ScrMap *m, double key, double *out);
|
|
1453
1473
|
bool scr_map_get_f64_bool(const ScrMap *m, double key, bool *out);
|
|
1454
1474
|
void *scr_map_get_f64_ref(const ScrMap *m, double key);
|
|
1475
|
+
bool scr_map_get_bool_f64(const ScrMap *m, bool key, double *out);
|
|
1476
|
+
bool scr_map_get_bool_bool(const ScrMap *m, bool key, bool *out);
|
|
1477
|
+
void *scr_map_get_bool_ref(const ScrMap *m, bool key);
|
|
1455
1478
|
bool scr_map_get_str_f64(const ScrMap *m, const ScrStr *key, double *out);
|
|
1456
1479
|
bool scr_map_get_str_bool(const ScrMap *m, const ScrStr *key, bool *out);
|
|
1457
1480
|
void *scr_map_get_str_ref(const ScrMap *m, const ScrStr *key);
|
|
@@ -1467,6 +1490,7 @@ void *scr_map_get_ref_ref(const ScrMap *m, const void *key);
|
|
|
1467
1490
|
double scr_map_iter_count(const ScrMap *m); /* entries incl. tombstones */
|
|
1468
1491
|
bool scr_map_iter_live(const ScrMap *m, double i);
|
|
1469
1492
|
double scr_map_iter_key_f64(const ScrMap *m, double i);
|
|
1493
|
+
bool scr_map_iter_key_bool(const ScrMap *m, double i);
|
|
1470
1494
|
ScrStr *scr_map_iter_key_str(const ScrMap *m, double i); /* +1 */
|
|
1471
1495
|
void *scr_map_iter_key_ref(const ScrMap *m, double i); /* +1 */
|
|
1472
1496
|
double scr_map_iter_val_f64(const ScrMap *m, double i);
|
|
@@ -1484,6 +1508,7 @@ void scr_set_add_all(ScrMap *set, ScrArr *values);
|
|
|
1484
1508
|
/* `[...set]` (scr_lib.c): the live entries drained into a fresh +1 elem[]
|
|
1485
1509
|
* in insertion order. Borrows the set; string elements retained in. */
|
|
1486
1510
|
ScrArr *scr_set_to_arr_f64(const ScrMap *s);
|
|
1511
|
+
ScrArr *scr_set_to_arr_bool(const ScrMap *s);
|
|
1487
1512
|
ScrArr *scr_set_to_arr_str(const ScrMap *s);
|
|
1488
1513
|
ScrArr *scr_set_to_arr_ref(const ScrMap *s);
|
|
1489
1514
|
ScrArr *scr_set_to_arr_dyn(const ScrMap *s);
|
|
@@ -3397,6 +3422,7 @@ ScrBigInt *scr_bigint_xor(ScrBigInt *a, ScrBigInt *b);
|
|
|
3397
3422
|
ScrBigInt *scr_bigint_shl(ScrBigInt *a, ScrBigInt *count);
|
|
3398
3423
|
ScrBigInt *scr_bigint_shr(ScrBigInt *a, ScrBigInt *count);
|
|
3399
3424
|
bool scr_bigint_eq(ScrBigInt *a, ScrBigInt *b);
|
|
3425
|
+
uint64_t scr_bigint_hash(const ScrBigInt *value); /* normalized value, no allocation */
|
|
3400
3426
|
bool scr_bigint_eq_string(ScrBigInt *a, ScrStr *b); /* StringToBigInt failure is false */
|
|
3401
3427
|
double scr_bigint_cmp_string(ScrBigInt *a, ScrStr *b); /* 2 = invalid StringToBigInt */
|
|
3402
3428
|
double scr_bigint_cmp_f64(ScrBigInt *a, ScrBigInt *b); /* -1, 0, 1 */
|
|
@@ -271,6 +271,7 @@ ScrStr *scr_str_alloc_raw(size_t len, size_t cap) {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
ScrStr *scr_str_regrow(ScrStr *s, size_t newcap) {
|
|
274
|
+
if (newcap < s->len || newcap > SIZE_MAX - sizeof(ScrStr) - 1) scr_oom();
|
|
274
275
|
scr_short_forget(s);
|
|
275
276
|
scr_sidx_purge(s); /* realloc may move; the old address may be recycled */
|
|
276
277
|
ScrStr *r = realloc(s, sizeof(ScrStr) + newcap + 1);
|
|
@@ -300,6 +301,8 @@ void scr_str_release(ScrStr *s) {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
ScrStr *scr_str_concat(ScrStr *a, ScrStr *b) {
|
|
304
|
+
if (a->len == 0) return scr_str_retain(b);
|
|
305
|
+
if (b->len == 0) return scr_str_retain(a);
|
|
303
306
|
if (a->len > SIZE_MAX - b->len - sizeof(ScrStr) - 1) scr_oom();
|
|
304
307
|
size_t newlen = a->len + b->len;
|
|
305
308
|
/* In-place append: a is uniquely owned by the caller's borrow (rc == 1 —
|
|
@@ -343,6 +346,32 @@ ScrStr *scr_str_concat(ScrStr *a, ScrStr *b) {
|
|
|
343
346
|
return s;
|
|
344
347
|
}
|
|
345
348
|
|
|
349
|
+
ScrStr *scr_str_concat_parts(ScrStr *const *parts, size_t count) {
|
|
350
|
+
const size_t limit = SIZE_MAX - sizeof(ScrStr) - 1;
|
|
351
|
+
size_t len = 0;
|
|
352
|
+
ScrStr *only = NULL;
|
|
353
|
+
size_t nonempty = 0;
|
|
354
|
+
for (size_t i = 0; i < count; i++) {
|
|
355
|
+
const size_t n = parts[i]->len;
|
|
356
|
+
if (n > limit - len) scr_oom();
|
|
357
|
+
len += n;
|
|
358
|
+
if (n != 0) {
|
|
359
|
+
only = parts[i];
|
|
360
|
+
nonempty++;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (nonempty == 1) return scr_str_retain(only);
|
|
364
|
+
ScrStr *out = scr_str_alloc_raw(len, len);
|
|
365
|
+
size_t offset = 0;
|
|
366
|
+
for (size_t i = 0; i < count; i++) {
|
|
367
|
+
const ScrStr *part = parts[i];
|
|
368
|
+
memcpy(out->data + offset, part->data, part->len);
|
|
369
|
+
offset += part->len;
|
|
370
|
+
}
|
|
371
|
+
out->data[len] = '\0';
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
|
|
346
375
|
bool scr_str_eq(ScrStr *a, ScrStr *b) {
|
|
347
376
|
return a == b || (a->len == b->len && memcmp(a->data, b->data, a->len) == 0);
|
|
348
377
|
}
|