ww: lib tests run via -T test mode; bare mains retired (closes @test conversion)

'ww test' gains the istest build path (-T injection in build_one/
buildone) and do_test/dotest accept -I, mirroring do_run - both twins.
The 35 converted lib tests drop their interim bare mains (-T
synthesizes the entry from @test fns and rejects a user main); their
35 C run-drivers flip 'ww run' -> 'ww test'; 989_lib_byteid compiles
lib tests under -T (8 user-main probe fixtures stay non-T, gated on
the fixture field). Abort-on-first-failure stands until the deferred
record-and-continue harness lands with the multi-package arc.
This commit is contained in:
2026-06-10 20:45:46 +09:00
parent 5b212e51cf
commit 2338ea5d59
74 changed files with 178 additions and 670 deletions

View File

@@ -3614,7 +3614,7 @@ type lflags = struct {
// touches no C-built code at runtime. The C `ww` driver in cmd/ww/
// still drives the C-built w6c/w6a/w6l. Test 993 pins the two
// pipelines to byte-identical output on a corpus.
fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, incs: *u8, lf: *lflags) i32 = {
fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, incs: *u8, lf: *lflags, istest: i32) i32 = {
let c6: *u8 = joinpathlit(selfdir, "w6c_ww");
let a6: *u8 = joinpathlit(selfdir, "w6a_ww");
let l6: *u8 = joinpathlit(selfdir, "w6l_ww");
@@ -3729,15 +3729,17 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, inc
};
os.close(cf);
// Step 2: w6c -o <stem>.s <stem>.combined.ww
// Step 2: w6c [-T] -o <stem>.s <stem>.combined.ww
{
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6c\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = asmf;
argv[3] = combined;
argv[4] = nil;
let argv: []*u8 = alloc([], 6u64)!;
let p: i32 = 0;
argv[p] = "w6c\0".ptr; p += 1;
if (istest != 0) { argv[p] = "-T\0".ptr; p += 1; };
argv[p] = "-o\0".ptr; p += 1;
argv[p] = asmf; p += 1;
argv[p] = combined; p += 1;
argv[p] = nil; p += 1;
argv.len = p;
if (procrun(c6, argv.ptr) != 0) {
cerr("ww: w6c failed\n");
return 1;
@@ -4079,7 +4081,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
lf.nlibdirs = nlibdirs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
return buildone(selfdir, resolved, isdir, out, objstem, incs.ptr, &lf);
return buildone(selfdir, resolved, isdir, out, objstem, incs.ptr, &lf, 0i32);
};
// Format the scratch path /tmp/ww_run_<pid> into buf. Returns NUL-
@@ -4235,7 +4237,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
lf.nlibs = nlibs;
// objstem = tmp → intermediates at /tmp/ww_run_<pid>.{s,o,combined.ww},
// never next to the source (T3).
if (buildone(selfdir, resolved, isdir, tmp.ptr, tmp.ptr, incs.ptr, &lf) != 0) {
if (buildone(selfdir, resolved, isdir, tmp.ptr, tmp.ptr, incs.ptr, &lf, 0i32) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -4265,11 +4267,11 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
// directory: open the dir, getdents64, build+run each *_test.ww,
// report ok/FAIL per file, return 0 iff all pass.
fn runsingletest(selfdir: *u8, src: *u8) i32 = {
fn runsingletest(selfdir: *u8, src: *u8, incs: *u8) i32 = {
let tmp: []u8 = alloc([], (os.PATH_MAX: u64))!;
tmp.len = os.PATH_MAX;
makeruntmp(tmp.ptr);
if (buildone(selfdir, src, 0, tmp.ptr, nil, "\0".ptr, nil) != 0) {
if (buildone(selfdir, src, 0, tmp.ptr, nil, incs, nil, 1i32) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -4324,7 +4326,7 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let tmp: []u8 = alloc([], (os.PATH_MAX: u64))!;
tmp.len = os.PATH_MAX;
makeruntmp(tmp.ptr);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, nil, tincs.ptr, nil);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, nil, tincs.ptr, nil, 1i32);
if (bres != 0) {
fail += 1;
cerr("FAIL ");
@@ -4360,18 +4362,55 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
};
fn dotest(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let target: *u8;
if (start >= argc) {
// -I parsing mirrors dobuild/dorun so a single-file test can resolve
// transitive imports (e.g. 905_nkname asttest → tok); coupled to the
// -T flip (task #5/#10).
let target: *u8 = nil;
let incs: []u8 = alloc([], (os.PATH_MAX: u64) * 2u64)!;
incs.len = ((os.PATH_MAX: u64) * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs.ptr, 0u64);
let i: i32 = start;
for (i < argc) {
let p: *u8 = argv[i];
if (p[0u64] == 45u8) { // '-'
if (p[1u64] == 73u8) { // '-I'
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
dir = p + 2u64;
} else {
if (i + 1 >= argc) {
cerr("ww test: -I needs an argument\n");
return 2;
};
i += 1;
dir = argv[i];
};
if (incoff > 0u64) {
incs[incoff] = 58u8; // ':'
incoff += 1u64;
};
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else {
cerr("ww test: unknown flag\n");
return 2;
};
} else {
if (target == nil) { target = p; };
};
i += 1;
};
if (target == nil) {
let dot: [2]u8 = ['.': u8, 0u8];
target = &dot[0];
} else {
target = argv[start];
};
// single-file mode: literal *.ww that exists
if (cstrendswithlit(target, ".ww")) {
if (os.access(pathstr(target), 0i32) == 0) {
return runsingletest(selfdir, target);
return runsingletest(selfdir, target, incs.ptr);
};
};

View File

@@ -828,7 +828,7 @@ type lflags = struct {
// touches no C-built code at runtime. The C `ww` driver in cmd/ww/
// still drives the C-built w6c/w6a/w6l. Test 993 pins the two
// pipelines to byte-identical output on a corpus.
fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, incs: *u8, lf: *lflags) i32 = {
fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, incs: *u8, lf: *lflags, istest: i32) i32 = {
let c6: *u8 = joinpathlit(selfdir, "w6c_ww");
let a6: *u8 = joinpathlit(selfdir, "w6a_ww");
let l6: *u8 = joinpathlit(selfdir, "w6l_ww");
@@ -943,15 +943,17 @@ fn buildone(selfdir: *u8, src: *u8, entryisdir: i32, out: *u8, objstem: *u8, inc
};
os.close(cf);
// Step 2: w6c -o <stem>.s <stem>.combined.ww
// Step 2: w6c [-T] -o <stem>.s <stem>.combined.ww
{
let argv: []*u8 = alloc([], 5u64)!;
argv.len = 5;
argv[0] = "w6c\0".ptr;
argv[1] = "-o\0".ptr;
argv[2] = asmf;
argv[3] = combined;
argv[4] = nil;
let argv: []*u8 = alloc([], 6u64)!;
let p: i32 = 0;
argv[p] = "w6c\0".ptr; p += 1;
if (istest != 0) { argv[p] = "-T\0".ptr; p += 1; };
argv[p] = "-o\0".ptr; p += 1;
argv[p] = asmf; p += 1;
argv[p] = combined; p += 1;
argv[p] = nil; p += 1;
argv.len = p;
if (procrun(c6, argv.ptr) != 0) {
cerr("ww: w6c failed\n");
return 1;
@@ -1293,7 +1295,7 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
lf.nlibdirs = nlibdirs;
lf.libs = libs.ptr;
lf.nlibs = nlibs;
return buildone(selfdir, resolved, isdir, out, objstem, incs.ptr, &lf);
return buildone(selfdir, resolved, isdir, out, objstem, incs.ptr, &lf, 0i32);
};
// Format the scratch path /tmp/ww_run_<pid> into buf. Returns NUL-
@@ -1449,7 +1451,7 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
lf.nlibs = nlibs;
// objstem = tmp → intermediates at /tmp/ww_run_<pid>.{s,o,combined.ww},
// never next to the source (T3).
if (buildone(selfdir, resolved, isdir, tmp.ptr, tmp.ptr, incs.ptr, &lf) != 0) {
if (buildone(selfdir, resolved, isdir, tmp.ptr, tmp.ptr, incs.ptr, &lf, 0i32) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -1479,11 +1481,11 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
// directory: open the dir, getdents64, build+run each *_test.ww,
// report ok/FAIL per file, return 0 iff all pass.
fn runsingletest(selfdir: *u8, src: *u8) i32 = {
fn runsingletest(selfdir: *u8, src: *u8, incs: *u8) i32 = {
let tmp: []u8 = alloc([], (os.PATH_MAX: u64))!;
tmp.len = os.PATH_MAX;
makeruntmp(tmp.ptr);
if (buildone(selfdir, src, 0, tmp.ptr, nil, "\0".ptr, nil) != 0) {
if (buildone(selfdir, src, 0, tmp.ptr, nil, incs, nil, 1i32) != 0) {
os.remove(pathstr(tmp.ptr));
return 1;
};
@@ -1538,7 +1540,7 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
let tmp: []u8 = alloc([], (os.PATH_MAX: u64))!;
tmp.len = os.PATH_MAX;
makeruntmp(tmp.ptr);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, nil, tincs.ptr, nil);
let bres: i32 = buildone(selfdir, path.ptr, 0, tmp.ptr, nil, tincs.ptr, nil, 1i32);
if (bres != 0) {
fail += 1;
cerr("FAIL ");
@@ -1574,18 +1576,55 @@ fn rundirtests(selfdir: *u8, dir: *u8) i32 = {
};
fn dotest(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
let target: *u8;
if (start >= argc) {
// -I parsing mirrors dobuild/dorun so a single-file test can resolve
// transitive imports (e.g. 905_nkname asttest → tok); coupled to the
// -T flip (task #5/#10).
let target: *u8 = nil;
let incs: []u8 = alloc([], (os.PATH_MAX: u64) * 2u64)!;
incs.len = ((os.PATH_MAX: u64) * 2u64): i32;
let incoff: u64 = 0u64;
cstrseal(incs.ptr, 0u64);
let i: i32 = start;
for (i < argc) {
let p: *u8 = argv[i];
if (p[0u64] == 45u8) { // '-'
if (p[1u64] == 73u8) { // '-I'
let dir: *u8 = nil;
if (p[2u64] != 0u8) {
dir = p + 2u64;
} else {
if (i + 1 >= argc) {
cerr("ww test: -I needs an argument\n");
return 2;
};
i += 1;
dir = argv[i];
};
if (incoff > 0u64) {
incs[incoff] = 58u8; // ':'
incoff += 1u64;
};
incoff = cstrinto(incs.ptr, incoff, dir);
cstrseal(incs.ptr, incoff);
} else {
cerr("ww test: unknown flag\n");
return 2;
};
} else {
if (target == nil) { target = p; };
};
i += 1;
};
if (target == nil) {
let dot: [2]u8 = ['.': u8, 0u8];
target = &dot[0];
} else {
target = argv[start];
};
// single-file mode: literal *.ww that exists
if (cstrendswithlit(target, ".ww")) {
if (os.access(pathstr(target), 0i32) == 0) {
return runsingletest(selfdir, target);
return runsingletest(selfdir, target, incs.ptr);
};
};