From 6f9a964a79402b8547ddbb6948638ca693667be8 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 2 Jun 2026 23:10:47 +0900 Subject: [PATCH] w6c,w6l: write diagnostics via str .len (fix off-by-one hand-counts) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The argv-error diagnostics in w6c/main.ww (7 sites) and w6l/main.ww (13 literal sites) passed hand-counted byte lengths to os.write that were systematically short by one — every length dropped the final byte (usually '\n'; "w6l: cannot find -l" dropped the 'l'), so the diagnostics printed truncated. Replace each magic length with the string's own .len, which both fixes the off-by-one and closes the hand-count class by construction. Uses the local-binding idiom (let m: str = "..."; os.write(2, m.ptr, m.len: u64);) — the established wcc/err.ww pattern — rather than "literal".len directly: string-literal .len is miscompiled on cstage (returns the pointer, not the length; cstage != wwstage), filed as #14. str-variable .len is correct on both stages, so this is byte- identical cs==ww and independent of #14. The w6l runtime cstr write (os.write(2, nm, cstrlen(nm))) is unchanged. --- selfhost/cmd/w6c/main.combined.ww | 21 ++++++++++------ selfhost/cmd/w6c/main.ww | 21 ++++++++++------ selfhost/cmd/w6l/main.combined.ww | 42 ++++++++++++++++++++----------- selfhost/cmd/w6l/main.ww | 42 ++++++++++++++++++++----------- 4 files changed, 84 insertions(+), 42 deletions(-) diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 4abe90d7..d8b00378 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -34615,16 +34615,19 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreq(a, "-o")) { i += 1; if (i >= argc) { - os.write(2, "w6c: -o requires arg\n".ptr, 20u64); + let m: str = "w6c: -o requires arg\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; out = argv[i]; } else { if (a[0u64] == 45u8) { - os.write(2, "w6c: unknown flag\n".ptr, 17u64); + let m: str = "w6c: unknown flag\n"; + os.write(2, m.ptr, m.len: u64); return 2; } else { if (src != nil) { - os.write(2, "w6c: only one input\n".ptr, 19u64); + let m: str = "w6c: only one input\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; src = a; @@ -34633,7 +34636,8 @@ export fn main(argc: i32, argv: **u8) i32 = { }; if (src == nil) { - os.write(2, "usage: w6c_ww [-o out.s] file.ww\n".ptr, 32u64); + let m: str = "usage: w6c_ww [-o out.s] file.ww\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; @@ -34641,7 +34645,8 @@ export fn main(argc: i32, argv: **u8) i32 = { let blen: u64; buf, blen = slurp(src); if (buf == nil) { - os.write(2, "w6c: cannot read input\n".ptr, 22u64); + let m: str = "w6c: cannot read input\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; @@ -34652,11 +34657,13 @@ export fn main(argc: i32, argv: **u8) i32 = { let ofd: i32 = os.open(pathstr(out), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (ofd < 0) { - os.write(2, "w6c: cannot open output\n".ptr, 23u64); + let m: str = "w6c: cannot open output\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; if (os.dup2(ofd, 1i32) < 0) { - os.write(2, "w6c: dup2 failed\n".ptr, 16u64); + let m: str = "w6c: dup2 failed\n"; + os.write(2, m.ptr, m.len: u64); os.close(ofd); return 1; }; diff --git a/selfhost/cmd/w6c/main.ww b/selfhost/cmd/w6c/main.ww index 6788b83c..9cecefef 100644 --- a/selfhost/cmd/w6c/main.ww +++ b/selfhost/cmd/w6c/main.ww @@ -86,16 +86,19 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreq(a, "-o")) { i += 1; if (i >= argc) { - os.write(2, "w6c: -o requires arg\n".ptr, 20u64); + let m: str = "w6c: -o requires arg\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; out = argv[i]; } else { if (a[0u64] == 45u8) { - os.write(2, "w6c: unknown flag\n".ptr, 17u64); + let m: str = "w6c: unknown flag\n"; + os.write(2, m.ptr, m.len: u64); return 2; } else { if (src != nil) { - os.write(2, "w6c: only one input\n".ptr, 19u64); + let m: str = "w6c: only one input\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; src = a; @@ -104,7 +107,8 @@ export fn main(argc: i32, argv: **u8) i32 = { }; if (src == nil) { - os.write(2, "usage: w6c_ww [-o out.s] file.ww\n".ptr, 32u64); + let m: str = "usage: w6c_ww [-o out.s] file.ww\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; @@ -112,7 +116,8 @@ export fn main(argc: i32, argv: **u8) i32 = { let blen: u64; buf, blen = slurp(src); if (buf == nil) { - os.write(2, "w6c: cannot read input\n".ptr, 22u64); + let m: str = "w6c: cannot read input\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; @@ -123,11 +128,13 @@ export fn main(argc: i32, argv: **u8) i32 = { let ofd: i32 = os.open(pathstr(out), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (ofd < 0) { - os.write(2, "w6c: cannot open output\n".ptr, 23u64); + let m: str = "w6c: cannot open output\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; if (os.dup2(ofd, 1i32) < 0) { - os.write(2, "w6c: dup2 failed\n".ptr, 16u64); + let m: str = "w6c: dup2 failed\n"; + os.write(2, m.ptr, m.len: u64); os.close(ofd); return 1; }; diff --git a/selfhost/cmd/w6l/main.combined.ww b/selfhost/cmd/w6l/main.combined.ww index 5734d695..57bde81a 100644 --- a/selfhost/cmd/w6l/main.combined.ww +++ b/selfhost/cmd/w6l/main.combined.ww @@ -5240,14 +5240,16 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreq(a, "-o")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -o requires argument\n".ptr, 25u64); + let m: str = "w6l: -o requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; outpath = argv[i]; } else { if (cstreq(a, "-L")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -L requires argument\n".ptr, 25u64); + let m: str = "w6l: -L requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; libdirs[nlibdirs] = argv[i]; @@ -5255,7 +5257,8 @@ export fn main(argc: i32, argv: **u8) i32 = { } else { if (cstreq(a, "-l")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -l requires argument\n".ptr, 25u64); + let m: str = "w6l: -l requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; lflags[nlflags] = argv[i]; @@ -5267,7 +5270,8 @@ export fn main(argc: i32, argv: **u8) i32 = { libdirs[nlibdirs] = a + 2u64; nlibdirs += 1; } else { - os.write(2, "w6l: bare -L\n".ptr, 12u64); + let m: str = "w6l: bare -L\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; } else { if (a[1u64] == 'l') { @@ -5275,16 +5279,19 @@ export fn main(argc: i32, argv: **u8) i32 = { lflags[nlflags] = a + 2u64; nlflags += 1; } else { - os.write(2, "w6l: bare -l\n".ptr, 12u64); + let m: str = "w6l: bare -l\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; } else { - os.write(2, "w6l: unknown flag\n".ptr, 17u64); + let m: str = "w6l: unknown flag\n"; + os.write(2, m.ptr, m.len: u64); return 2; };}; } else { if (ninputs >= maxinputs) { - os.write(2, "w6l: too many inputs\n".ptr, 20u64); + let m: str = "w6l: too many inputs\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; inputs[ninputs] = a; @@ -5294,11 +5301,13 @@ export fn main(argc: i32, argv: **u8) i32 = { }; if (outpath == nil) { - os.write(2, "usage: w6l_ww -o exe [-L...] [-l...] file1.o [file2.o...]\n".ptr, 68u64); + let m: str = "usage: w6l_ww -o exe [-L...] [-l...] file1.o [file2.o...]\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; if (ninputs == 0) { - os.write(2, "w6l: no inputs\n".ptr, 14u64); + let m: str = "w6l: no inputs\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; @@ -5322,10 +5331,12 @@ export fn main(argc: i32, argv: **u8) i32 = { for (lf < nlflags) { let p: *u8 = resolvelib(lflags[lf], libdirs.ptr, nlibdirs); if (p == nil) { - os.write(2, "w6l: cannot find -l".ptr, 18u64); + let m: str = "w6l: cannot find -l"; + os.write(2, m.ptr, m.len: u64); let nm: *u8 = lflags[lf]; os.write(2, nm, cstrlen(nm)); - os.write(2, "\n".ptr, 1u64); + let nl: str = "\n"; + os.write(2, nl.ptr, nl.len: u64); return 1; }; if (isso(p) != 0) { @@ -5345,18 +5356,21 @@ export fn main(argc: i32, argv: **u8) i32 = { if (entrysym == nil) { entrysym = lookup(l, "main"); } else { if (entrysym.defined == 0) { entrysym = lookup(l, "main"); }; }; if (entrysym == nil) { - os.write(2, "w6l: no _start or main symbol\n".ptr, 29u64); + let m: str = "w6l: no _start or main symbol\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; if (entrysym.defined == 0) { - os.write(2, "w6l: no _start or main symbol\n".ptr, 29u64); + let m: str = "w6l: no _start or main symbol\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; let flags: os.flag = os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC; let fd: i32 = os.open(pathstr(outpath), flags, 493i32); // 0o755 if (fd < 0) { - os.write(2, "w6l: cannot open output\n".ptr, 23u64); + let m: str = "w6l: cannot open output\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; diff --git a/selfhost/cmd/w6l/main.ww b/selfhost/cmd/w6l/main.ww index 8bc7d0d3..f74d021a 100644 --- a/selfhost/cmd/w6l/main.ww +++ b/selfhost/cmd/w6l/main.ww @@ -205,14 +205,16 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreq(a, "-o")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -o requires argument\n".ptr, 25u64); + let m: str = "w6l: -o requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; outpath = argv[i]; } else { if (cstreq(a, "-L")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -L requires argument\n".ptr, 25u64); + let m: str = "w6l: -L requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; libdirs[nlibdirs] = argv[i]; @@ -220,7 +222,8 @@ export fn main(argc: i32, argv: **u8) i32 = { } else { if (cstreq(a, "-l")) { i += 1; if (i >= argc) { - os.write(2, "w6l: -l requires argument\n".ptr, 25u64); + let m: str = "w6l: -l requires argument\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; lflags[nlflags] = argv[i]; @@ -232,7 +235,8 @@ export fn main(argc: i32, argv: **u8) i32 = { libdirs[nlibdirs] = a + 2u64; nlibdirs += 1; } else { - os.write(2, "w6l: bare -L\n".ptr, 12u64); + let m: str = "w6l: bare -L\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; } else { if (a[1u64] == 'l') { @@ -240,16 +244,19 @@ export fn main(argc: i32, argv: **u8) i32 = { lflags[nlflags] = a + 2u64; nlflags += 1; } else { - os.write(2, "w6l: bare -l\n".ptr, 12u64); + let m: str = "w6l: bare -l\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; } else { - os.write(2, "w6l: unknown flag\n".ptr, 17u64); + let m: str = "w6l: unknown flag\n"; + os.write(2, m.ptr, m.len: u64); return 2; };}; } else { if (ninputs >= maxinputs) { - os.write(2, "w6l: too many inputs\n".ptr, 20u64); + let m: str = "w6l: too many inputs\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; inputs[ninputs] = a; @@ -259,11 +266,13 @@ export fn main(argc: i32, argv: **u8) i32 = { }; if (outpath == nil) { - os.write(2, "usage: w6l_ww -o exe [-L...] [-l...] file1.o [file2.o...]\n".ptr, 68u64); + let m: str = "usage: w6l_ww -o exe [-L...] [-l...] file1.o [file2.o...]\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; if (ninputs == 0) { - os.write(2, "w6l: no inputs\n".ptr, 14u64); + let m: str = "w6l: no inputs\n"; + os.write(2, m.ptr, m.len: u64); return 2; }; @@ -287,10 +296,12 @@ export fn main(argc: i32, argv: **u8) i32 = { for (lf < nlflags) { let p: *u8 = resolvelib(lflags[lf], libdirs.ptr, nlibdirs); if (p == nil) { - os.write(2, "w6l: cannot find -l".ptr, 18u64); + let m: str = "w6l: cannot find -l"; + os.write(2, m.ptr, m.len: u64); let nm: *u8 = lflags[lf]; os.write(2, nm, cstrlen(nm)); - os.write(2, "\n".ptr, 1u64); + let nl: str = "\n"; + os.write(2, nl.ptr, nl.len: u64); return 1; }; if (isso(p) != 0) { @@ -310,18 +321,21 @@ export fn main(argc: i32, argv: **u8) i32 = { if (entrysym == nil) { entrysym = lookup(l, "main"); } else { if (entrysym.defined == 0) { entrysym = lookup(l, "main"); }; }; if (entrysym == nil) { - os.write(2, "w6l: no _start or main symbol\n".ptr, 29u64); + let m: str = "w6l: no _start or main symbol\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; if (entrysym.defined == 0) { - os.write(2, "w6l: no _start or main symbol\n".ptr, 29u64); + let m: str = "w6l: no _start or main symbol\n"; + os.write(2, m.ptr, m.len: u64); return 1; }; let flags: os.flag = os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC; let fd: i32 = os.open(pathstr(outpath), flags, 493i32); // 0o755 if (fd < 0) { - os.write(2, "w6l: cannot open output\n".ptr, 23u64); + let m: str = "w6l: cannot open output\n"; + os.write(2, m.ptr, m.len: u64); return 1; };