@scriptc/runtime 0.0.23 → 0.0.24
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 +65 -0
- package/src/scr_async.c +286 -5
- package/src/scr_bytes.c +634 -4
- package/src/scr_bytes_io.c +4 -2
- package/src/scr_file_handle.c +491 -0
- package/src/scr_island.c +10 -0
- package/src/scr_json.c +51 -19
- package/src/scr_lib.c +680 -30
- package/src/scr_number.c +9 -0
- package/src/scr_regex.c +12 -1
- package/src/scr_runtime.h +101 -8
- package/src/scr_string.c +13 -2
- package/src/scr_text_decoder_data.h +7389 -0
- package/src/scr_util.c +984 -0
- package/src/scr_win_stats.h +23 -0
package/src/scr_number.c
CHANGED
|
@@ -24,6 +24,15 @@
|
|
|
24
24
|
* unchanged. Provides d2d(), d2d_small_int(), decimalLength17(), div10(). */
|
|
25
25
|
#include "../vendor/ryu/d2s.c"
|
|
26
26
|
|
|
27
|
+
/* ECMA ToUint32, shared by bitwise operators and split's limit: non-finite
|
|
28
|
+
* values become zero, finite values truncate toward zero and wrap mod 2^32. */
|
|
29
|
+
uint32_t scr_to_uint32(double d) {
|
|
30
|
+
if (!isfinite(d)) return 0;
|
|
31
|
+
double t = fmod(trunc(d), 4294967296.0);
|
|
32
|
+
if (t < 0) t += 4294967296.0;
|
|
33
|
+
return (uint32_t)t;
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
/* The Ryū digit core, shared by the ECMA placement below and the Intl
|
|
28
37
|
* en-US number formatter (scr_lib.c): the shortest round-tripping digit
|
|
29
38
|
* string for a positive finite double — value = 0.digits × 10^n with no
|
package/src/scr_regex.c
CHANGED
|
@@ -624,8 +624,10 @@ ScrStr *scr_regex_replace_all(ScrStr *s, ScrRegex *re, ScrStr *rep) {
|
|
|
624
624
|
|
|
625
625
|
/* ── split ────────────────────────────────────────────────────────────── */
|
|
626
626
|
|
|
627
|
-
ScrArr *
|
|
627
|
+
ScrArr *scr_regex_split_limit(ScrStr *s, ScrRegex *re, double limit_num) {
|
|
628
628
|
uint8_t *bc = scr_regex_bc(re);
|
|
629
|
+
uint32_t limit = scr_to_uint32(limit_num);
|
|
630
|
+
if (limit == 0) return scr_arr_new(SCR_ELEM_STR, 0);
|
|
629
631
|
if (lre_get_capture_count(bc) > 1) {
|
|
630
632
|
/* JS splices every capture group's value into the result between the
|
|
631
633
|
* pieces, changing the array's SHAPE per match — not modeled this
|
|
@@ -675,6 +677,11 @@ ScrArr *scr_regex_split(ScrStr *s, ScrRegex *re) {
|
|
|
675
677
|
q = scr_advance(u, len, start, unicode);
|
|
676
678
|
} else {
|
|
677
679
|
scr_arr_push_ref(out, scr_str_from_utf16(u, p, start));
|
|
680
|
+
if (out->len == limit) {
|
|
681
|
+
free(capture);
|
|
682
|
+
free(u);
|
|
683
|
+
return out;
|
|
684
|
+
}
|
|
678
685
|
p = end;
|
|
679
686
|
q = p;
|
|
680
687
|
}
|
|
@@ -685,6 +692,10 @@ ScrArr *scr_regex_split(ScrStr *s, ScrRegex *re) {
|
|
|
685
692
|
return out;
|
|
686
693
|
}
|
|
687
694
|
|
|
695
|
+
ScrArr *scr_regex_split(ScrStr *s, ScrRegex *re) {
|
|
696
|
+
return scr_regex_split_limit(s, re, 4294967295.0);
|
|
697
|
+
}
|
|
698
|
+
|
|
688
699
|
/* ── String.prototype.toLowerCase / toUpperCase (the static path) ──────
|
|
689
700
|
* ECMA-262 Default Case Conversion via the vendored libunicode's
|
|
690
701
|
* lre_case_conv — the exact tables and algorithm the engine's own
|
package/src/scr_runtime.h
CHANGED
|
@@ -612,12 +612,14 @@ ScrStr *scr_str_cp_at(ScrStr *s, double i);
|
|
|
612
612
|
ScrStr *scr_str_trim_start(ScrStr *s);
|
|
613
613
|
ScrStr *scr_str_trim_end(ScrStr *s);
|
|
614
614
|
|
|
615
|
-
/* split(separator) with a STRING separator
|
|
615
|
+
/* split(separator[, limit]) with a STRING separator: limit uses ToUint32;
|
|
616
|
+
* the no-limit wrapper supplies 2^32-1. Empty separator
|
|
616
617
|
* splits into single UTF-16 code units (each half of an astral char is
|
|
617
618
|
* U+FFFD — divergence, see above); otherwise splits on every occurrence,
|
|
618
619
|
* empty pieces kept. Borrows both; returns a +1 string[] (SCR_ELEM_STR). */
|
|
619
620
|
struct ScrArr;
|
|
620
621
|
struct ScrArr *scr_str_split(ScrStr *s, ScrStr *sep);
|
|
622
|
+
struct ScrArr *scr_str_split_limit(ScrStr *s, ScrStr *sep, double limit);
|
|
621
623
|
|
|
622
624
|
/* padStart(maxLength, fill)/padEnd — ECMA StringPad, UTF-16 unit counts.
|
|
623
625
|
* Target at or below the length (or empty fill) returns the receiver
|
|
@@ -720,6 +722,12 @@ void scr_qs_parse_into(ScrMap *out, const ScrStr *qs, const ScrStr *sep,
|
|
|
720
722
|
const ScrStr *eq, double max_keys, uint32_t str_tag,
|
|
721
723
|
uint32_t arr_tag);
|
|
722
724
|
|
|
725
|
+
/* node:util.parseArgs — the static checked-dynamic boundary. `config` is
|
|
726
|
+
* the documented JSON-safe configuration object; the returned dyn tree is
|
|
727
|
+
* a fresh ParsedResults object whose `values` child has null prototype.
|
|
728
|
+
* Borrows config; returns +1, or NULL with a Node-coded TypeError pending. */
|
|
729
|
+
struct ScrDyn *scr_util_parse_args(const struct ScrDyn *config);
|
|
730
|
+
|
|
723
731
|
/* querystring.stringify — Node's stringify over a borrowed dyn value (the
|
|
724
732
|
* frontend dynFroms the typed record; JS-world dyn values pass straight
|
|
725
733
|
* through). Non-object dyn values answer "" like Node; object keys iterate in
|
|
@@ -880,6 +888,15 @@ double scr_arr_push_f64(ScrArr *a, double v);
|
|
|
880
888
|
double scr_arr_push_bool(ScrArr *a, bool v);
|
|
881
889
|
double scr_arr_push_ref(ScrArr *a, void *v);
|
|
882
890
|
|
|
891
|
+
/* unshift returns the new length and _ref takes ownership. The spread form
|
|
892
|
+
* borrows a same-element-kind source, retains copied refs, and snapshots
|
|
893
|
+
* self-spread. reverse mutates in place and returns the receiver at +1. */
|
|
894
|
+
double scr_arr_unshift_f64(ScrArr *a, double v);
|
|
895
|
+
double scr_arr_unshift_bool(ScrArr *a, bool v);
|
|
896
|
+
double scr_arr_unshift_ref(ScrArr *a, void *v);
|
|
897
|
+
double scr_arr_unshift_spread(ScrArr *a, const ScrArr *src);
|
|
898
|
+
ScrArr *scr_arr_reverse(ScrArr *a);
|
|
899
|
+
|
|
883
900
|
/* pop traps on an empty array; _ref transfers ownership out (+1 to the
|
|
884
901
|
* caller, no release). */
|
|
885
902
|
double scr_arr_pop_f64(ScrArr *a);
|
|
@@ -983,8 +1000,10 @@ ScrStr *scr_regex_flags(ScrRegex *re); /* +1 */
|
|
|
983
1000
|
ScrStr *scr_regex_replace(ScrStr *s, ScrRegex *re, ScrStr *rep);
|
|
984
1001
|
/* replaceAll: throws Node's TypeError when /g is missing (may-throw). */
|
|
985
1002
|
ScrStr *scr_regex_replace_all(ScrStr *s, ScrRegex *re, ScrStr *rep);
|
|
986
|
-
/* split: capture-free patterns only — capture groups throw (may-throw).
|
|
1003
|
+
/* split: capture-free patterns only — capture groups throw (may-throw).
|
|
1004
|
+
* limit uses ToUint32; the no-limit wrapper supplies 2^32-1. */
|
|
987
1005
|
ScrArr *scr_regex_split(ScrStr *s, ScrRegex *re);
|
|
1006
|
+
ScrArr *scr_regex_split_limit(ScrStr *s, ScrRegex *re, double limit);
|
|
988
1007
|
/* matchAll drained eagerly: +1 string[][] of honest match slices; throws
|
|
989
1008
|
* Node's TypeError on a non-global regex (catchable). */
|
|
990
1009
|
ScrArr *scr_regex_match_all(ScrStr *s, ScrRegex *re);
|
|
@@ -2047,6 +2066,11 @@ void scr_fs_chmod(ScrStr *path, double mode);
|
|
|
2047
2066
|
void scr_fs_chown(ScrStr *path, double uid, double gid);
|
|
2048
2067
|
void scr_fs_copyfile(ScrStr *src, ScrStr *dest);
|
|
2049
2068
|
void scr_fs_rename(ScrStr *oldpath, ScrStr *newpath);
|
|
2069
|
+
/* The callback rename worker uses the non-throwing syscall seam off the
|
|
2070
|
+
* runtime thread, then materializes any Node-shaped Error back on the main
|
|
2071
|
+
* thread. raw returns 0 on success or a positive errno value on failure. */
|
|
2072
|
+
int scr_fs_rename_raw(const ScrStr *oldpath, const ScrStr *newpath);
|
|
2073
|
+
void scr_fs_rename_error(int error, const ScrStr *oldpath, const ScrStr *newpath);
|
|
2050
2074
|
void scr_fs_write_file_mode(ScrStr *path, ScrStr *data, double mode);
|
|
2051
2075
|
void scr_fs_mkdir_mode(ScrStr *path, double mode);
|
|
2052
2076
|
void scr_fs_mkdir_recursive_mode(ScrStr *path, double mode);
|
|
@@ -2079,6 +2103,7 @@ double scr_process_columns(double fd);
|
|
|
2079
2103
|
* stat(2) — follows symlinks, like Node's stat family. scr_fs_stat
|
|
2080
2104
|
* THROWS like the other sync calls. */
|
|
2081
2105
|
typedef struct ScrStats ScrStats;
|
|
2106
|
+
typedef struct ScrFileHandle ScrFileHandle;
|
|
2082
2107
|
typedef struct ScrPromise ScrPromise; /* full section further down */
|
|
2083
2108
|
|
|
2084
2109
|
ScrStats *scr_fs_stat(ScrStr *path); /* +1, or throws */
|
|
@@ -2091,6 +2116,9 @@ bool scr_stats_is_file(ScrStats *s);
|
|
|
2091
2116
|
bool scr_stats_is_dir(ScrStats *s);
|
|
2092
2117
|
bool scr_stats_is_symlink(ScrStats *s); /* lstat snapshots only */
|
|
2093
2118
|
double scr_stats_size(ScrStats *s);
|
|
2119
|
+
double scr_stats_blocks(ScrStats *s); /* allocated size in 512-byte units */
|
|
2120
|
+
double scr_stats_nlink(ScrStats *s);
|
|
2121
|
+
double scr_stats_atime_ms(ScrStats *s); /* ms with the sub-second fraction */
|
|
2094
2122
|
double scr_stats_mtime_ms(ScrStats *s); /* ms with the ns fraction */
|
|
2095
2123
|
|
|
2096
2124
|
/* fs/promises: the SAME sync operations, minting an already-settled
|
|
@@ -2101,6 +2129,7 @@ double scr_stats_mtime_ms(ScrStats *s); /* ms with the ns fraction */
|
|
|
2101
2129
|
* scr_lib.c without the fiber slice). */
|
|
2102
2130
|
ScrPromise *scr_fsp_read_file(ScrStr *path);
|
|
2103
2131
|
ScrPromise *scr_fsp_write_file(ScrStr *path, ScrStr *data);
|
|
2132
|
+
ScrPromise *scr_fsp_write_file_mode(ScrStr *path, ScrStr *data, double mode);
|
|
2104
2133
|
ScrPromise *scr_fsp_mkdir(ScrStr *path);
|
|
2105
2134
|
ScrPromise *scr_fsp_mkdir_mode(ScrStr *path, double mode);
|
|
2106
2135
|
ScrPromise *scr_fsp_mkdir_recursive(ScrStr *path);
|
|
@@ -2110,6 +2139,24 @@ ScrPromise *scr_fsp_chmod(ScrStr *path, double mode);
|
|
|
2110
2139
|
ScrPromise *scr_fsp_readdir(ScrStr *path);
|
|
2111
2140
|
ScrPromise *scr_fsp_rm(ScrStr *path);
|
|
2112
2141
|
ScrPromise *scr_fsp_stat(ScrStr *path);
|
|
2142
|
+
ScrPromise *scr_fsp_rename(ScrStr *oldpath, ScrStr *newpath);
|
|
2143
|
+
ScrPromise *scr_fsp_open(ScrStr *path, ScrStr *flags, double mode);
|
|
2144
|
+
ScrPromise *scr_file_handle_close_promise(ScrFileHandle *h);
|
|
2145
|
+
ScrPromise *scr_file_handle_read_file_promise(ScrFileHandle *h, ScrStr *encoding);
|
|
2146
|
+
ScrPromise *scr_file_handle_read_file_bytes_promise(ScrFileHandle *h, ScrStr *encoding);
|
|
2147
|
+
ScrPromise *scr_file_handle_write_file_promise(ScrFileHandle *h, ScrStr *data, ScrStr *encoding);
|
|
2148
|
+
ScrPromise *scr_file_handle_write_file_bytes_promise(ScrFileHandle *h, ScrBytes *data, ScrStr *encoding);
|
|
2149
|
+
ScrPromise *scr_file_handle_stat_promise(ScrFileHandle *h);
|
|
2150
|
+
|
|
2151
|
+
/* fs.rename: the syscall is submitted to a native worker immediately and
|
|
2152
|
+
* its error-first callback fires on a later event-loop turn through an
|
|
2153
|
+
* emitted, program-shaped adapter. Both paths and the callback are borrowed
|
|
2154
|
+
* at entry; the callback MOVES into the operation. err is borrowed and NULL
|
|
2155
|
+
* on success. */
|
|
2156
|
+
typedef void (*ScrFsRenameFn)(ScrClosure *cb, ScrError *err);
|
|
2157
|
+
void scr_fs_rename_async(ScrStr *oldpath, ScrStr *newpath,
|
|
2158
|
+
ScrClosure *cb /*moves*/, ScrFsRenameFn fn);
|
|
2159
|
+
void scr_fs_rename_thunk0(ScrClosure *cb, ScrError *err);
|
|
2113
2160
|
|
|
2114
2161
|
/* ── node:timers/promises (scr_async.c) ──────────────────────────────
|
|
2115
2162
|
* The promisified pair: a PENDING void promise a one-shot heap timer /
|
|
@@ -2459,10 +2506,36 @@ ScrStr *scr_path_win32_to_namespaced_path(ScrStr *path);
|
|
|
2459
2506
|
* (failure throws the path-less "EBADF: bad file descriptor, close").
|
|
2460
2507
|
* The pair behind spawn's fd-stdio form. */
|
|
2461
2508
|
double scr_fs_open(ScrStr *path, ScrStr *flags);
|
|
2509
|
+
ScrFileHandle *scr_file_handle_open(ScrStr *path, ScrStr *flags, double mode);
|
|
2510
|
+
ScrFileHandle *scr_file_handle_retain(ScrFileHandle *h);
|
|
2511
|
+
void scr_file_handle_release(ScrFileHandle *h);
|
|
2512
|
+
void *scr_file_handle_retain_v(void *p);
|
|
2513
|
+
void scr_file_handle_release_v(void *p);
|
|
2514
|
+
double scr_file_handle_fd(ScrFileHandle *h);
|
|
2515
|
+
void scr_file_handle_close(ScrFileHandle *h);
|
|
2516
|
+
double scr_file_handle_read(ScrFileHandle *h, ScrBytes *buf, double offset,
|
|
2517
|
+
double length, double position, bool length_default);
|
|
2518
|
+
double scr_file_handle_write_bytes(ScrFileHandle *h, ScrBytes *buf,
|
|
2519
|
+
double offset, double length,
|
|
2520
|
+
double position, bool length_default);
|
|
2521
|
+
double scr_file_handle_write_str(ScrFileHandle *h, ScrStr *data,
|
|
2522
|
+
double position, ScrStr *encoding);
|
|
2523
|
+
ScrStr *scr_file_handle_read_file(ScrFileHandle *h);
|
|
2524
|
+
ScrBytes *scr_file_handle_read_file_bytes(ScrFileHandle *h);
|
|
2525
|
+
void scr_file_handle_write_file(ScrFileHandle *h, ScrStr *data);
|
|
2526
|
+
void scr_file_handle_write_file_bytes(ScrFileHandle *h, ScrBytes *data);
|
|
2527
|
+
ScrStats *scr_file_handle_stat(ScrFileHandle *h);
|
|
2462
2528
|
/* position == -1 reads from and advances the descriptor's current offset;
|
|
2463
2529
|
* nonnegative positions leave that offset unchanged (pread/ReadFile seam). */
|
|
2464
2530
|
double scr_fs_read_sync(double fd, ScrBytes *buf, double offset, double length,
|
|
2465
2531
|
double position);
|
|
2532
|
+
/* writeSync's classic Buffer window and utf8 string forms. position -1 (or
|
|
2533
|
+
* any other non-safe/nonnegative-integer value) writes at and advances the
|
|
2534
|
+
* current descriptor offset; safe nonnegative positions leave it unchanged. */
|
|
2535
|
+
double scr_fs_write_sync(double fd, ScrBytes *buf, double offset, double length,
|
|
2536
|
+
double position);
|
|
2537
|
+
double scr_fs_write_str_sync(double fd, ScrStr *data, double position,
|
|
2538
|
+
ScrStr *encoding);
|
|
2466
2539
|
void scr_fs_close(double fd);
|
|
2467
2540
|
|
|
2468
2541
|
/* ── WHATWG URL (scr_url.c) ──────────────────────────────────────────
|
|
@@ -3397,6 +3470,8 @@ typedef struct {
|
|
|
3397
3470
|
} ScrJsonBuf;
|
|
3398
3471
|
|
|
3399
3472
|
void scr_jb_init(ScrJsonBuf *b);
|
|
3473
|
+
/* Append one borrowed runtime string verbatim (no JSON quoting). */
|
|
3474
|
+
void scr_jb_put_str(ScrJsonBuf *b, const ScrStr *s);
|
|
3400
3475
|
/* Push a container onto the circular-detection stack before serializing
|
|
3401
3476
|
* its members. If `v` is already ON the stack, throws V8's exact
|
|
3402
3477
|
* "Converting circular structure to JSON" TypeError (the --> starting at /
|
|
@@ -3712,6 +3787,10 @@ bool scr_immediate_has_ref(double handle);
|
|
|
3712
3787
|
* teardown (they must never run yet must not leak). cb ownership moves
|
|
3713
3788
|
* in. */
|
|
3714
3789
|
void scr_next_tick(ScrClosure *cb);
|
|
3790
|
+
/* A successful process.stdout/stderr.write completion on that same queue.
|
|
3791
|
+
* The callback and its program-shaped Error | null adapter both MOVE into
|
|
3792
|
+
* the entry; the adapter is invoked with NULL (Node's success argument). */
|
|
3793
|
+
void scr_process_write_callback(ScrClosure *cb, ScrFsRenameFn fn);
|
|
3715
3794
|
/* A raw C-hook entry on the SAME queue: the stream unit enqueues one
|
|
3716
3795
|
* marker per deferred stream emission, so stream ticks and user
|
|
3717
3796
|
* nextTicks run in true FIFO order (in Node they are the same queue).
|
|
@@ -4493,12 +4572,14 @@ double scr_date_get_minutes_utc(double ms);
|
|
|
4493
4572
|
double scr_date_get_seconds_local(double ms);
|
|
4494
4573
|
double scr_date_get_seconds_utc(double ms);
|
|
4495
4574
|
|
|
4496
|
-
/* ── bitwise operators
|
|
4575
|
+
/* ── numeric coercion + bitwise operators ─────────────────────────────
|
|
4497
4576
|
* JS-exact ToInt32/ToUint32 semantics: NaN/±Infinity → 0, truncation
|
|
4498
4577
|
* toward zero, modular wrap into 32 bits; the operation runs in 32-bit
|
|
4499
4578
|
* space (shift counts mask to 5 bits, `>>` is an arithmetic shift spelled
|
|
4500
4579
|
* portably — no C UB/implementation-defined shifts) and the result
|
|
4501
|
-
* returns to f64: `>>>` as Uint32, everything else as Int32.
|
|
4580
|
+
* returns to f64: `>>>` as Uint32, everything else as Int32.
|
|
4581
|
+
* scr_to_uint32 lives in scr_number.c; the bitwise operations in scr_lib.c. */
|
|
4582
|
+
uint32_t scr_to_uint32(double d);
|
|
4502
4583
|
double scr_bit_and(double a, double b);
|
|
4503
4584
|
double scr_bit_or(double a, double b);
|
|
4504
4585
|
double scr_bit_xor(double a, double b);
|
|
@@ -4695,12 +4776,22 @@ void scr_bytes_set_from(ScrBytes *dst, const ScrBytes *src, double offset);
|
|
|
4695
4776
|
* compiler fences other encodings). */
|
|
4696
4777
|
ScrStr *scr_bytes_to_str(const ScrBytes *b, const ScrStr *enc);
|
|
4697
4778
|
ScrStr *scr_bytes_to_str_range(const ScrBytes *b, const ScrStr *enc, double start, double end);
|
|
4779
|
+
/* Runtime-valued Buffer.toString encoding: aliases/case canonicalize;
|
|
4780
|
+
* unknown names throw ERR_UNKNOWN_ENCODING. +1, or NULL when throwing. */
|
|
4781
|
+
ScrStr *scr_bytes_to_str_checked(const ScrBytes *b, const ScrStr *enc);
|
|
4782
|
+
ScrStr *scr_bytes_to_str_checked_range(const ScrBytes *b, const ScrStr *enc, double start, double end);
|
|
4698
4783
|
|
|
4699
4784
|
/* WHATWG TextDecoder.decode over u8 bytes (utf-8, default options): the
|
|
4700
4785
|
* same replacement decode as toString("utf8") with the leading BOM
|
|
4701
4786
|
* stripped. Borrows; +1; never throws. */
|
|
4702
4787
|
ScrStr *scr_text_decode(const ScrBytes *b);
|
|
4703
4788
|
|
|
4789
|
+
/* TextDecoder with a compile-time WHATWG legacy-encoding id. The frontend
|
|
4790
|
+
* owns label canonicalization and emits only the ids understood by
|
|
4791
|
+
* scr_bytes.c; keeping this separate from scr_text_decode means default
|
|
4792
|
+
* UTF-8 users do not retain the legacy mapping tables. Borrows; +1. */
|
|
4793
|
+
ScrStr *scr_text_decode_legacy(const ScrBytes *b, double encoding);
|
|
4794
|
+
|
|
4704
4795
|
/* Buffer.from(string, enc): "utf8" copies the bytes; "hex" parses pairs
|
|
4705
4796
|
* and stops at the first invalid/odd tail (Node-lenient); "base64" and
|
|
4706
4797
|
* "base64url" decode the standard AND url-safe alphabets, skipping
|
|
@@ -4895,10 +4986,12 @@ ScrPromise *scr_fsp_read_file_bytes(ScrStr *path); /* +1 */
|
|
|
4895
4986
|
* RangeError catchably (same check as scr_crypto_random_string). */
|
|
4896
4987
|
ScrBytes *scr_crypto_random_bytes(double n); /* +1 */
|
|
4897
4988
|
|
|
4898
|
-
/* process.stdout/stderr.write(buf): the raw byte writes' Buffer
|
|
4899
|
-
* (same streams and buffering as the string forms).
|
|
4900
|
-
|
|
4901
|
-
|
|
4989
|
+
/* process.stdout/stderr.write(buf[, encoding]): the raw byte writes' Buffer
|
|
4990
|
+
* overloads (same streams and buffering as the string forms). The encoding
|
|
4991
|
+
* is evaluated by the caller and ignored here, as Node does for bytes.
|
|
4992
|
+
* Constantly true. */
|
|
4993
|
+
bool scr_process_stdout_write_bytes(const ScrBytes *b, const ScrStr *encoding);
|
|
4994
|
+
bool scr_process_stderr_write_bytes(const ScrBytes *b, const ScrStr *encoding);
|
|
4902
4995
|
|
|
4903
4996
|
/* The Node-shaped fs error thrower (scr_lib.c): formats "ENOENT: no such
|
|
4904
4997
|
* file or directory, open 'x'" and throws it catchably. Shared with
|
package/src/scr_string.c
CHANGED
|
@@ -678,7 +678,9 @@ ScrStr *scr_str_trim_end(ScrStr *s) {
|
|
|
678
678
|
static const struct { size_t rc; size_t len; size_t cap; char data[4]; }
|
|
679
679
|
scr_lit_fffd = {SIZE_MAX, 3, 3, "\xEF\xBF\xBD"};
|
|
680
680
|
|
|
681
|
-
/* split(separator) with a STRING separator
|
|
681
|
+
/* split(separator, limit) with a STRING separator (ECMA-262 22.1.3.23):
|
|
682
|
+
* limit is ToUint32'd; zero returns [] and reaching the limit stops before
|
|
683
|
+
* any later separator probes. The no-limit wrapper supplies 2^32-1.
|
|
682
684
|
* an empty separator splits into single UTF-16 code units ("".split("") is
|
|
683
685
|
* [] — no probe matches nothing); a non-empty separator splits on every
|
|
684
686
|
* byte-level occurrence (well-formed UTF-8 is self-synchronizing, so byte
|
|
@@ -688,8 +690,10 @@ static const struct { size_t rc; size_t len; size_t cap; char data[4]; }
|
|
|
688
690
|
* yield the two lone surrogate halves, each half is U+FFFD here
|
|
689
691
|
* (divergence 2 — the same substitution the island's boundary marshal
|
|
690
692
|
* applied). Borrows both; returns a +1 string[]. */
|
|
691
|
-
ScrArr *
|
|
693
|
+
ScrArr *scr_str_split_limit(ScrStr *s, ScrStr *sep, double limit_num) {
|
|
692
694
|
ScrArr *out = scr_arr_new(SCR_ELEM_STR, 0);
|
|
695
|
+
uint32_t limit = scr_to_uint32(limit_num);
|
|
696
|
+
if (limit == 0) return out;
|
|
693
697
|
if (sep->len == 0) {
|
|
694
698
|
size_t i = 0;
|
|
695
699
|
while (i < s->len) {
|
|
@@ -697,10 +701,12 @@ ScrArr *scr_str_split(ScrStr *s, ScrStr *sep) {
|
|
|
697
701
|
uint32_t cp = scr_utf8_decode(s->data + i, &adv);
|
|
698
702
|
if (cp >= 0x10000) { /* two units in JS: both halves become U+FFFD */
|
|
699
703
|
scr_arr_push_ref(out, scr_str_retain((ScrStr *)&scr_lit_fffd));
|
|
704
|
+
if (out->len == limit) return out;
|
|
700
705
|
scr_arr_push_ref(out, scr_str_retain((ScrStr *)&scr_lit_fffd));
|
|
701
706
|
} else {
|
|
702
707
|
scr_arr_push_ref(out, scr_str_from_span(s->data + i, adv));
|
|
703
708
|
}
|
|
709
|
+
if (out->len == limit) return out;
|
|
704
710
|
i += adv;
|
|
705
711
|
}
|
|
706
712
|
return out;
|
|
@@ -712,12 +718,17 @@ ScrArr *scr_str_split(ScrStr *s, ScrStr *sep) {
|
|
|
712
718
|
if (!found) break;
|
|
713
719
|
size_t at = (size_t)(found - s->data);
|
|
714
720
|
scr_arr_push_ref(out, scr_str_from_span(s->data + start, at - start));
|
|
721
|
+
if (out->len == limit) return out;
|
|
715
722
|
start = at + sep->len;
|
|
716
723
|
}
|
|
717
724
|
scr_arr_push_ref(out, scr_str_from_span(s->data + start, s->len - start));
|
|
718
725
|
return out;
|
|
719
726
|
}
|
|
720
727
|
|
|
728
|
+
ScrArr *scr_str_split(ScrStr *s, ScrStr *sep) {
|
|
729
|
+
return scr_str_split_limit(s, sep, 4294967295.0);
|
|
730
|
+
}
|
|
731
|
+
|
|
721
732
|
/* StringPad (ECMA-262 22.1.3.16/17): target length in UTF-16 units, the
|
|
722
733
|
* filler built from whole repetitions of `fill` plus a truncated prefix.
|
|
723
734
|
* A target at or below the length (or an empty fill) returns the receiver
|