diff --git a/selfhost/cmd/ww/main.combined.ww b/selfhost/cmd/ww/main.combined.ww index cdb8a180..32961e17 100644 --- a/selfhost/cmd/ww/main.combined.ww +++ b/selfhost/cmd/ww/main.combined.ww @@ -2857,6 +2857,16 @@ import strings; // the cgen #127 mod-mangle attribution bug consumer per rule-7. def CMD_MAX: u64 = 8192u64; +// cerr — bare stderr fragment writer for the driver's piecewise +// diagnostics. Tool-local (NOT a lib wrapper): messages are built from +// many fragments and we route through os.write to avoid libc stdio. +// .len replaces the error-prone hand-counted byte literals these sites +// carried. Lives here (the selfhost ww-driver build is a single main.ww; +// err.c's bare-message path is not ported into this tree). +fn cerr(m: str) void = { + os.write(2, m.ptr, m.len: u64); +}; + // ---- C-string helpers -------------------------------------------------- fn cstrlen(p: *u8) u64 = { @@ -2981,18 +2991,18 @@ fn joinpathlit(dir: *u8, name: str) *u8 = { fn procrun(path: *u8, argv: **u8) i32 = { let pid: i32 = os.fork(); if (pid < 0) { - os.write(2, "ww: fork failed\n".ptr, 16u64); + cerr("ww: fork failed\n"); return -1; }; if (pid == 0) { os.execve(pathstr(path), argv, nil: **u8); - os.write(2, "ww: execve failed\n".ptr, 18u64); + cerr("ww: execve failed\n"); os.exit(127); }; let status: i32 = 0; let r: i32 = os.wait4(pid, &status, 0i32, nil: *void); if (r < 0) { - os.write(2, "ww: wait4 failed\n".ptr, 17u64); + cerr("ww: wait4 failed\n"); return -1; }; // Linux wait status: low byte = signal (0 if exited cleanly), @@ -3324,7 +3334,7 @@ fn expand(c: *expctx, pathcs: *u8) void = { let blen: u64; bufp, blen = slurp(pathcs); if (bufp == nil) { - os.write(2, "ww: cannot read source\n".ptr, 23u64); + cerr("ww: cannot read source\n"); return; }; @@ -3435,15 +3445,15 @@ fn peekpackage(pathcs: *u8) *u8 = { // Strict-same-package error helper. Bundled here per task #22 // brief — failure mode is dir-enum's own. fn strictpkgmismatch(file: *u8, pkg: *u8, dirpkg: *u8, dirpath: *u8) void = { - os.write(2, "ww: ".ptr, 4u64); + cerr("ww: "); os.write(2, file, cstrlen(file)); - os.write(2, ": package ".ptr, 10u64); + cerr(": package "); os.write(2, pkg, cstrlen(pkg)); - os.write(2, " differs from ".ptr, 14u64); + cerr(" differs from "); os.write(2, dirpkg, cstrlen(dirpkg)); - os.write(2, " in same module dir ".ptr, 20u64); + cerr(" in same module dir "); os.write(2, dirpath, cstrlen(dirpath)); - os.write(2, "\n".ptr, 1u64); + cerr("\n"); os.exit(1); }; @@ -3637,7 +3647,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l // enumerate the module dir; file entry → start at the file. let cf: i32 = os.open(pathstr(combined), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (cf < 0) { - os.write(2, "ww: cannot open combined\n".ptr, 25u64); + cerr("ww: cannot open combined\n"); return 1; }; { @@ -3660,7 +3670,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l argv[3] = combined; argv[4] = nil; if (procrun(c6, argv.ptr) != 0) { - os.write(2, "ww: w6c failed\n".ptr, 15u64); + cerr("ww: w6c failed\n"); return 1; }; }; @@ -3675,7 +3685,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l argv[3] = asmf; argv[4] = nil; if (procrun(a6, argv.ptr) != 0) { - os.write(2, "ww: w6a failed\n".ptr, 15u64); + cerr("ww: w6a failed\n"); return 1; }; }; @@ -3721,7 +3731,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l }; argv[pos] = nil; if (procrun(l6, argv.ptr) != 0) { - os.write(2, "ww: w6l failed\n".ptr, 15u64); + cerr("ww: w6l failed\n"); return 1; }; }; @@ -3890,7 +3900,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -I needs an argument\n".ptr, 31u64); + cerr("ww build: -I needs an argument\n"); return 2; }; i += 1; @@ -3908,14 +3918,14 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -L needs an argument\n".ptr, 31u64); + cerr("ww build: -L needs an argument\n"); return 2; }; i += 1; dir = argv[i]; }; if (nlibdirs >= maxlflags) { - os.write(2, "ww build: too many -L\n".ptr, 22u64); + cerr("ww build: too many -L\n"); return 2; }; libdirs[nlibdirs] = dir; @@ -3926,20 +3936,20 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { nm = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -l needs an argument\n".ptr, 31u64); + cerr("ww build: -l needs an argument\n"); return 2; }; i += 1; nm = argv[i]; }; if (nlibs >= maxlflags) { - os.write(2, "ww build: too many -l\n".ptr, 22u64); + cerr("ww build: too many -l\n"); return 2; }; libs[nlibs] = nm; nlibs += 1; } else { - os.write(2, "ww build: unknown flag\n".ptr, 23u64); + cerr("ww build: unknown flag\n"); return 2; }; }; }; } else { @@ -3956,7 +3966,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { let isdir: i32 = 0; let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { - os.write(2, "ww build: cannot find module\n".ptr, 29u64); + cerr("ww build: cannot find module\n"); return 1; }; let out: *u8 = nil; @@ -4043,7 +4053,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -I needs an argument\n".ptr, 29u64); + cerr("ww run: -I needs an argument\n"); return 2; }; i += 1; @@ -4061,14 +4071,14 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -L needs an argument\n".ptr, 29u64); + cerr("ww run: -L needs an argument\n"); return 2; }; i += 1; dir = argv[i]; }; if (nlibdirs >= maxlflags) { - os.write(2, "ww run: too many -L\n".ptr, 20u64); + cerr("ww run: too many -L\n"); return 2; }; libdirs[nlibdirs] = dir; @@ -4079,20 +4089,20 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { nm = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -l needs an argument\n".ptr, 29u64); + cerr("ww run: -l needs an argument\n"); return 2; }; i += 1; nm = argv[i]; }; if (nlibs >= maxlflags) { - os.write(2, "ww run: too many -l\n".ptr, 20u64); + cerr("ww run: too many -l\n"); return 2; }; libs[nlibs] = nm; nlibs += 1; } else { - os.write(2, "ww run: unknown flag\n".ptr, 21u64); + cerr("ww run: unknown flag\n"); return 2; }; }; }; i += 1; @@ -4114,7 +4124,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { let isdir: i32 = 0; let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { - os.write(2, "ww run: cannot find module\n".ptr, 27u64); + cerr("ww run: cannot find module\n"); return 1; }; @@ -4176,7 +4186,7 @@ fn runsingletest(selfdir: *u8, src: *u8) i32 = { fn rundirtests(selfdir: *u8, dir: *u8) i32 = { let fd: i32 = os.open(pathstr(dir), os.flag.RDONLY, 0i32); if (fd < 0) { - os.write(2, "ww test: cannot open directory\n".ptr, 31u64); + cerr("ww test: cannot open directory\n"); return 1; }; @@ -4218,9 +4228,9 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, tincs.ptr, nil); if (bres != 0) { fail += 1; - os.write(2, "FAIL ".ptr, 5u64); + cerr("FAIL "); os.write(2, name, nlen); - os.write(2, " (build)\n".ptr, 9u64); + cerr(" (build)\n"); } else { let execargv: []*u8 = alloc([], 2u64)!; execargv.len = 2; @@ -4234,9 +4244,9 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { os.write(1, "\n".ptr, 1u64); } else { fail += 1; - os.write(2, "FAIL ".ptr, 5u64); + cerr("FAIL "); os.write(2, name, nlen); - os.write(2, "\n".ptr, 1u64); + cerr("\n"); }; }; os.remove(pathstr(tmp.ptr)); @@ -4307,7 +4317,7 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreqlit(cmd, "test")) { return dotest(selfdir.ptr, argv, argc, 2); }; - os.write(2, "ww: unknown subcommand\n".ptr, 23u64); + cerr("ww: unknown subcommand\n"); writeusage(2); return 2; }; diff --git a/selfhost/cmd/ww/main.ww b/selfhost/cmd/ww/main.ww index d7658e4e..344a5930 100644 --- a/selfhost/cmd/ww/main.ww +++ b/selfhost/cmd/ww/main.ww @@ -23,6 +23,16 @@ import strings; // the cgen #127 mod-mangle attribution bug consumer per rule-7. def CMD_MAX: u64 = 8192u64; +// cerr — bare stderr fragment writer for the driver's piecewise +// diagnostics. Tool-local (NOT a lib wrapper): messages are built from +// many fragments and we route through os.write to avoid libc stdio. +// .len replaces the error-prone hand-counted byte literals these sites +// carried. Lives here (the selfhost ww-driver build is a single main.ww; +// err.c's bare-message path is not ported into this tree). +fn cerr(m: str) void = { + os.write(2, m.ptr, m.len: u64); +}; + // ---- C-string helpers -------------------------------------------------- fn cstrlen(p: *u8) u64 = { @@ -147,18 +157,18 @@ fn joinpathlit(dir: *u8, name: str) *u8 = { fn procrun(path: *u8, argv: **u8) i32 = { let pid: i32 = os.fork(); if (pid < 0) { - os.write(2, "ww: fork failed\n".ptr, 16u64); + cerr("ww: fork failed\n"); return -1; }; if (pid == 0) { os.execve(pathstr(path), argv, nil: **u8); - os.write(2, "ww: execve failed\n".ptr, 18u64); + cerr("ww: execve failed\n"); os.exit(127); }; let status: i32 = 0; let r: i32 = os.wait4(pid, &status, 0i32, nil: *void); if (r < 0) { - os.write(2, "ww: wait4 failed\n".ptr, 17u64); + cerr("ww: wait4 failed\n"); return -1; }; // Linux wait status: low byte = signal (0 if exited cleanly), @@ -490,7 +500,7 @@ fn expand(c: *expctx, pathcs: *u8) void = { let blen: u64; bufp, blen = slurp(pathcs); if (bufp == nil) { - os.write(2, "ww: cannot read source\n".ptr, 23u64); + cerr("ww: cannot read source\n"); return; }; @@ -601,15 +611,15 @@ fn peekpackage(pathcs: *u8) *u8 = { // Strict-same-package error helper. Bundled here per task #22 // brief — failure mode is dir-enum's own. fn strictpkgmismatch(file: *u8, pkg: *u8, dirpkg: *u8, dirpath: *u8) void = { - os.write(2, "ww: ".ptr, 4u64); + cerr("ww: "); os.write(2, file, cstrlen(file)); - os.write(2, ": package ".ptr, 10u64); + cerr(": package "); os.write(2, pkg, cstrlen(pkg)); - os.write(2, " differs from ".ptr, 14u64); + cerr(" differs from "); os.write(2, dirpkg, cstrlen(dirpkg)); - os.write(2, " in same module dir ".ptr, 20u64); + cerr(" in same module dir "); os.write(2, dirpath, cstrlen(dirpath)); - os.write(2, "\n".ptr, 1u64); + cerr("\n"); os.exit(1); }; @@ -803,7 +813,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l // enumerate the module dir; file entry → start at the file. let cf: i32 = os.open(pathstr(combined), os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644 if (cf < 0) { - os.write(2, "ww: cannot open combined\n".ptr, 25u64); + cerr("ww: cannot open combined\n"); return 1; }; { @@ -826,7 +836,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l argv[3] = combined; argv[4] = nil; if (procrun(c6, argv.ptr) != 0) { - os.write(2, "ww: w6c failed\n".ptr, 15u64); + cerr("ww: w6c failed\n"); return 1; }; }; @@ -841,7 +851,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l argv[3] = asmf; argv[4] = nil; if (procrun(a6, argv.ptr) != 0) { - os.write(2, "ww: w6a failed\n".ptr, 15u64); + cerr("ww: w6a failed\n"); return 1; }; }; @@ -887,7 +897,7 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, incs: *u8, lf: *l }; argv[pos] = nil; if (procrun(l6, argv.ptr) != 0) { - os.write(2, "ww: w6l failed\n".ptr, 15u64); + cerr("ww: w6l failed\n"); return 1; }; }; @@ -1056,7 +1066,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -I needs an argument\n".ptr, 31u64); + cerr("ww build: -I needs an argument\n"); return 2; }; i += 1; @@ -1074,14 +1084,14 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -L needs an argument\n".ptr, 31u64); + cerr("ww build: -L needs an argument\n"); return 2; }; i += 1; dir = argv[i]; }; if (nlibdirs >= maxlflags) { - os.write(2, "ww build: too many -L\n".ptr, 22u64); + cerr("ww build: too many -L\n"); return 2; }; libdirs[nlibdirs] = dir; @@ -1092,20 +1102,20 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { nm = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww build: -l needs an argument\n".ptr, 31u64); + cerr("ww build: -l needs an argument\n"); return 2; }; i += 1; nm = argv[i]; }; if (nlibs >= maxlflags) { - os.write(2, "ww build: too many -l\n".ptr, 22u64); + cerr("ww build: too many -l\n"); return 2; }; libs[nlibs] = nm; nlibs += 1; } else { - os.write(2, "ww build: unknown flag\n".ptr, 23u64); + cerr("ww build: unknown flag\n"); return 2; }; }; }; } else { @@ -1122,7 +1132,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { let isdir: i32 = 0; let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { - os.write(2, "ww build: cannot find module\n".ptr, 29u64); + cerr("ww build: cannot find module\n"); return 1; }; let out: *u8 = nil; @@ -1209,7 +1219,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -I needs an argument\n".ptr, 29u64); + cerr("ww run: -I needs an argument\n"); return 2; }; i += 1; @@ -1227,14 +1237,14 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { dir = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -L needs an argument\n".ptr, 29u64); + cerr("ww run: -L needs an argument\n"); return 2; }; i += 1; dir = argv[i]; }; if (nlibdirs >= maxlflags) { - os.write(2, "ww run: too many -L\n".ptr, 20u64); + cerr("ww run: too many -L\n"); return 2; }; libdirs[nlibdirs] = dir; @@ -1245,20 +1255,20 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { nm = p + 2u64; } else { if (i + 1 >= argc) { - os.write(2, "ww run: -l needs an argument\n".ptr, 29u64); + cerr("ww run: -l needs an argument\n"); return 2; }; i += 1; nm = argv[i]; }; if (nlibs >= maxlflags) { - os.write(2, "ww run: too many -l\n".ptr, 20u64); + cerr("ww run: too many -l\n"); return 2; }; libs[nlibs] = nm; nlibs += 1; } else { - os.write(2, "ww run: unknown flag\n".ptr, 21u64); + cerr("ww run: unknown flag\n"); return 2; }; }; }; i += 1; @@ -1280,7 +1290,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = { let isdir: i32 = 0; let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir); if (resolved == nil) { - os.write(2, "ww run: cannot find module\n".ptr, 27u64); + cerr("ww run: cannot find module\n"); return 1; }; @@ -1342,7 +1352,7 @@ fn runsingletest(selfdir: *u8, src: *u8) i32 = { fn rundirtests(selfdir: *u8, dir: *u8) i32 = { let fd: i32 = os.open(pathstr(dir), os.flag.RDONLY, 0i32); if (fd < 0) { - os.write(2, "ww test: cannot open directory\n".ptr, 31u64); + cerr("ww test: cannot open directory\n"); return 1; }; @@ -1384,9 +1394,9 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, tincs.ptr, nil); if (bres != 0) { fail += 1; - os.write(2, "FAIL ".ptr, 5u64); + cerr("FAIL "); os.write(2, name, nlen); - os.write(2, " (build)\n".ptr, 9u64); + cerr(" (build)\n"); } else { let execargv: []*u8 = alloc([], 2u64)!; execargv.len = 2; @@ -1400,9 +1410,9 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = { os.write(1, "\n".ptr, 1u64); } else { fail += 1; - os.write(2, "FAIL ".ptr, 5u64); + cerr("FAIL "); os.write(2, name, nlen); - os.write(2, "\n".ptr, 1u64); + cerr("\n"); }; }; os.remove(pathstr(tmp.ptr)); @@ -1473,7 +1483,7 @@ export fn main(argc: i32, argv: **u8) i32 = { if (cstreqlit(cmd, "test")) { return dotest(selfdir.ptr, argv, argc, 2); }; - os.write(2, "ww: unknown subcommand\n".ptr, 23u64); + cerr("ww: unknown subcommand\n"); writeusage(2); return 2; };