From 50fc976e1de7d619ffe531f29e5674a43c09241d Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Wed, 3 Jun 2026 02:59:29 +0900 Subject: [PATCH] =?UTF-8?q?cmd/ww:=20FOLD=202=20=E2=80=94=20str-lift=20sca?= =?UTF-8?q?nuse/peekpackage/dirfilekeep=20scanners=20(capstone)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three byte-id-critical import scanners in cmd/ww/main.ww drop their hand-rolled byte-pyramids for strings.has{prefix,suffix} over constructed str views, keeping every boundary guard that the lifted helpers do not subsume: - dirfilekeep: nlen<=3 guard kept (bare ".ww" len-3 stays rejected, which strings.hassuffix(".ww") alone would wrongly accept). - scanuse: i+7>len guard kept (hasprefix("import") covers 6 bytes; the separator read at src[i+6] still needs i+6 < len). - peekpackage: s+8<=q guard kept (hasprefix("package") covers 7 bytes; the separator read at buf[s+7] needs s+7 < q). bytecmp (the enumeratedir sort comparator) is left as-is: it is a magnitude-returning 3-way memcmp at a read boundary, not a spell-out. Regenerated ww/main.combined.ww. All 6 corpus .combined.ww remain byte-identical (cstage ww == wwstage ww_ww); 990-997 byte-id + 993 self-rebuild green. --- selfhost/cmd/ww/main.combined.ww | 86 ++++++++++---------------------- selfhost/cmd/ww/main.ww | 86 ++++++++++---------------------- 2 files changed, 54 insertions(+), 118 deletions(-) diff --git a/selfhost/cmd/ww/main.combined.ww b/selfhost/cmd/ww/main.combined.ww index 1f759d17..cdb8a180 100644 --- a/selfhost/cmd/ww/main.combined.ww +++ b/selfhost/cmd/ww/main.combined.ww @@ -3143,45 +3143,17 @@ fn locateimport(dirs: *u8, name: *u8, namelen: u64, // build leaves them in the source tree; they parse-error when // re-included). Returns true to keep. fn dirfilekeep(name: *u8, nlen: u64) bool = { + // nlen<=3 guard kept: a bare ".ww" (len 3) is rejected here but + // would pass strings.hassuffix(".ww"); preserves cstage parity. if (nlen <= 3u64) { return false; }; - if (name[nlen - 3u64] != 46u8) { return false; }; // '.' - if (name[nlen - 2u64] != 119u8) { return false; }; // 'w' - if (name[nlen - 1u64] != 119u8) { return false; }; // 'w' - if (nlen >= 7u64) { - if (name[nlen - 7u64] == 116u8) { // 't' - if (name[nlen - 6u64] == 101u8) { // 'e' - if (name[nlen - 5u64] == 115u8) { // 's' - if (name[nlen - 4u64] == 116u8) { // 't' - return false; - }; - }; - }; - }; - }; - if (nlen >= 12u64) { - // ".combined.ww" — full 12-char match mirrors cstage - // cmd/ww/main.c enumerate_dir_ww strcmp (rule 10); the - // trailing .ww is pre-guaranteed by the early-out above. - if (name[nlen - 12u64] == 46u8) { // '.' - if (name[nlen - 11u64] == 99u8) { // 'c' - if (name[nlen - 10u64] == 111u8) { // 'o' - if (name[nlen - 9u64] == 109u8) { // 'm' - if (name[nlen - 8u64] == 98u8) { // 'b' - if (name[nlen - 7u64] == 105u8) { // 'i' - if (name[nlen - 6u64] == 110u8) { // 'n' - if (name[nlen - 5u64] == 101u8) { // 'e' - if (name[nlen - 4u64] == 100u8) { // 'd' - return false; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; + let s: str; + s.ptr = name; + s.len = nlen: i32; + if (!strings.hassuffix(s, ".ww")) { return false; }; + if (strings.hassuffix(s, "test.ww")) { return false; }; + // ".combined.ww" — full 12-char match mirrors cstage + // cmd/ww/main.c enumerate_dir_ww strcmp (rule 10). + if (strings.hassuffix(s, ".combined.ww")) { return false; }; return true; }; @@ -3311,13 +3283,13 @@ fn scanuse(src: *u8, len: u64) (*u8, u64) = { if (src[i] != 32u8) { if (src[i] != 9u8) { break; }; }; i += 1u64; }; + // i+7>len guard kept: hasprefix("import") covers the 6 spell-out + // bytes, but the sep read at src[i+6] still needs i+6 < len. if (i + 7u64 > len) { return nil, 0u64; }; - if (src[i] != 105u8) { return nil, 0u64; }; // 'i' - if (src[i + 1u64] != 109u8) { return nil, 0u64; }; // 'm' - if (src[i + 2u64] != 112u8) { return nil, 0u64; }; // 'p' - if (src[i + 3u64] != 111u8) { return nil, 0u64; }; // 'o' - if (src[i + 4u64] != 114u8) { return nil, 0u64; }; // 'r' - if (src[i + 5u64] != 116u8) { return nil, 0u64; }; // 't' + let rest: str; + rest.ptr = src + i; + rest.len = (len - i): i32; + if (!strings.hasprefix(rest, "import")) { return nil, 0u64; }; let sep: u8 = src[i + 6u64]; if (sep != 32u8) { if (sep != 9u8) { return nil, 0u64; }; }; i += 7u64; @@ -3411,22 +3383,18 @@ fn peekpackage(pathcs: *u8) *u8 = { s += 1u64; }; if (s < q) { - if (s + 1u64 < q) { - if (buf[s] == 47u8) { - if (buf[s + 1u64] == 47u8) { - p = q + 1u64; - continue; - }; - }; + let line: str; + line.ptr = buf.ptr + s; + line.len = (q - s): i32; + // hasprefix("//") subsumes the old s+1= 7u64) { - if (name[nlen - 7u64] == 116u8) { // 't' - if (name[nlen - 6u64] == 101u8) { // 'e' - if (name[nlen - 5u64] == 115u8) { // 's' - if (name[nlen - 4u64] == 116u8) { // 't' - return false; - }; - }; - }; - }; - }; - if (nlen >= 12u64) { - // ".combined.ww" — full 12-char match mirrors cstage - // cmd/ww/main.c enumerate_dir_ww strcmp (rule 10); the - // trailing .ww is pre-guaranteed by the early-out above. - if (name[nlen - 12u64] == 46u8) { // '.' - if (name[nlen - 11u64] == 99u8) { // 'c' - if (name[nlen - 10u64] == 111u8) { // 'o' - if (name[nlen - 9u64] == 109u8) { // 'm' - if (name[nlen - 8u64] == 98u8) { // 'b' - if (name[nlen - 7u64] == 105u8) { // 'i' - if (name[nlen - 6u64] == 110u8) { // 'n' - if (name[nlen - 5u64] == 101u8) { // 'e' - if (name[nlen - 4u64] == 100u8) { // 'd' - return false; - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; + let s: str; + s.ptr = name; + s.len = nlen: i32; + if (!strings.hassuffix(s, ".ww")) { return false; }; + if (strings.hassuffix(s, "test.ww")) { return false; }; + // ".combined.ww" — full 12-char match mirrors cstage + // cmd/ww/main.c enumerate_dir_ww strcmp (rule 10). + if (strings.hassuffix(s, ".combined.ww")) { return false; }; return true; }; @@ -477,13 +449,13 @@ fn scanuse(src: *u8, len: u64) (*u8, u64) = { if (src[i] != 32u8) { if (src[i] != 9u8) { break; }; }; i += 1u64; }; + // i+7>len guard kept: hasprefix("import") covers the 6 spell-out + // bytes, but the sep read at src[i+6] still needs i+6 < len. if (i + 7u64 > len) { return nil, 0u64; }; - if (src[i] != 105u8) { return nil, 0u64; }; // 'i' - if (src[i + 1u64] != 109u8) { return nil, 0u64; }; // 'm' - if (src[i + 2u64] != 112u8) { return nil, 0u64; }; // 'p' - if (src[i + 3u64] != 111u8) { return nil, 0u64; }; // 'o' - if (src[i + 4u64] != 114u8) { return nil, 0u64; }; // 'r' - if (src[i + 5u64] != 116u8) { return nil, 0u64; }; // 't' + let rest: str; + rest.ptr = src + i; + rest.len = (len - i): i32; + if (!strings.hasprefix(rest, "import")) { return nil, 0u64; }; let sep: u8 = src[i + 6u64]; if (sep != 32u8) { if (sep != 9u8) { return nil, 0u64; }; }; i += 7u64; @@ -577,22 +549,18 @@ fn peekpackage(pathcs: *u8) *u8 = { s += 1u64; }; if (s < q) { - if (s + 1u64 < q) { - if (buf[s] == 47u8) { - if (buf[s + 1u64] == 47u8) { - p = q + 1u64; - continue; - }; - }; + let line: str; + line.ptr = buf.ptr + s; + line.len = (q - s): i32; + // hasprefix("//") subsumes the old s+1