build: omit named test source operands
This commit is contained in:
@@ -991,6 +991,102 @@ fn slurp(pathcs: *u8) (*u8, u64) = {
|
||||
return buf.ptr, nu;
|
||||
};
|
||||
|
||||
// Named source recognition accepts every existing non-directory Stat result.
|
||||
// Read to EOF without seeking so a finite FIFO follows the same package-header
|
||||
// loading path as a regular file.
|
||||
fn sourceheaderslurp(pathcs: *u8) (*u8, u64, u64) = {
|
||||
let fd: i32 = os.open(pathstr(pathcs), os.flag.RDONLY, 0i32);
|
||||
if (fd < 0) { return nil, 0u64, 0u64; };
|
||||
let cap: i32 = 4096;
|
||||
let allocation: ([]u8 | nomem) = sepallocbytes(cap);
|
||||
let buf: []u8;
|
||||
match (allocation) {
|
||||
case let value: []u8 => buf = value;
|
||||
case nomem => {
|
||||
sepfailnomem();
|
||||
os.close(fd);
|
||||
return nil, 0u64, 0u64;
|
||||
};
|
||||
};
|
||||
let used: u64 = 0u64;
|
||||
for (true) {
|
||||
if (used == cap: u64) {
|
||||
if (cap == SEP_COUNT_MAX) {
|
||||
sepfailsize();
|
||||
os.close(fd);
|
||||
os.free(buf.ptr: *void, cap: u64);
|
||||
return nil, 0u64, 0u64;
|
||||
};
|
||||
let nextcap: i32 = cap;
|
||||
if (cap > SEP_COUNT_MAX / 2) { nextcap = SEP_COUNT_MAX; }
|
||||
else { nextcap = cap * 2; };
|
||||
let nextallocation: ([]u8 | nomem) = sepallocbytes(nextcap);
|
||||
let next: []u8;
|
||||
match (nextallocation) {
|
||||
case let value: []u8 => next = value;
|
||||
case nomem => {
|
||||
sepfailnomem();
|
||||
os.close(fd);
|
||||
os.free(buf.ptr: *void, cap: u64);
|
||||
return nil, 0u64, 0u64;
|
||||
};
|
||||
};
|
||||
bytecpy(next.ptr, buf.ptr, used);
|
||||
os.free(buf.ptr: *void, cap: u64);
|
||||
buf = next;
|
||||
cap = nextcap;
|
||||
};
|
||||
let got: i64 = os.read(fd, buf.ptr + used,
|
||||
(cap: u64) - used);
|
||||
if (got == -(os.EINTR: i32): i64) { continue; };
|
||||
if (got < 0i64) {
|
||||
os.close(fd);
|
||||
os.free(buf.ptr: *void, cap: u64);
|
||||
return nil, 0u64, 0u64;
|
||||
};
|
||||
if (got == 0i64) { break; };
|
||||
used += got: u64;
|
||||
};
|
||||
if (os.close(fd) != 0) {
|
||||
os.free(buf.ptr: *void, cap: u64);
|
||||
return nil, 0u64, 0u64;
|
||||
};
|
||||
buf[used] = 0u8;
|
||||
return buf.ptr, used, cap: u64;
|
||||
};
|
||||
|
||||
// Validate only the package/import header. The returned syntax is deliberately
|
||||
// discarded: an ordinary build creates no package or import graph for this
|
||||
// test-only named source.
|
||||
fn sourcebuildheader(path: *u8) bool = {
|
||||
let view: str = pathstr(path);
|
||||
let bufp: *u8;
|
||||
let blen: u64;
|
||||
let bcap: u64;
|
||||
bufp, blen, bcap = sourceheaderslurp(path);
|
||||
if (bufp == nil) {
|
||||
cerrpath("ww: cannot read ", path, "\n");
|
||||
return false;
|
||||
};
|
||||
let l: syntax.lex;
|
||||
syntax.lexinit(&l, view, bufp, blen);
|
||||
let ps: syntax.parser;
|
||||
syntax.parserinit(&ps, &l);
|
||||
let header: *syntax.node = syntax.parsepackageheader(&ps);
|
||||
if (l.errs > 0 || ps.errs > 0) {
|
||||
os.free(bufp: *void, bcap);
|
||||
return false;
|
||||
};
|
||||
if (header.nmod.len == 0) {
|
||||
cerrpos(view, 1, 1);
|
||||
cerr(": error: invalid or missing package clause\n");
|
||||
os.free(bufp: *void, bcap);
|
||||
return false;
|
||||
};
|
||||
os.free(bufp: *void, bcap);
|
||||
return true;
|
||||
};
|
||||
|
||||
fn makestem(stem: *u8, src: *u8) void = {
|
||||
let n: u64 = cstrlen(src);
|
||||
let stop: u64 = n;
|
||||
@@ -8943,15 +9039,35 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
|
||||
nil, nil, false, true);
|
||||
};
|
||||
let requestedliteral: bool = false;
|
||||
let requestednondirectory: bool = false;
|
||||
let requestedstat: os.filestat;
|
||||
match (os.stat(&requestedstat, pathstr(src))) {
|
||||
case void => requestedliteral = true;
|
||||
case void => {
|
||||
requestedliteral = true;
|
||||
let typ: u32 = (requestedstat.mode: u32) & 61440u32;
|
||||
requestednondirectory = typ != os.mode.DIR: u32;
|
||||
};
|
||||
case let e: os.oserror => void;
|
||||
};
|
||||
if (sourceoperandignored(src)) {
|
||||
sourceoperandnosources(src);
|
||||
return 1;
|
||||
};
|
||||
let requestedlen: u64 = cstrlen(src);
|
||||
let requestedbase: u64 = basenameoff(src, requestedlen);
|
||||
if (requestednondirectory && requestedlen - requestedbase >= 8u64
|
||||
&& cstrendswithlit(src, "_test.ww")) {
|
||||
if (!sourcebuildheader(src)) { return 1; };
|
||||
if (outflag == nil || cstreqlit(outflag, "/dev/null")) {
|
||||
return 0;
|
||||
};
|
||||
if (buildoutputdir(outflag)) {
|
||||
cerr("ww: no main packages to build\n");
|
||||
} else {
|
||||
cerr("ww: no packages to build\n");
|
||||
};
|
||||
return 1;
|
||||
};
|
||||
let isdir: i32 = 0;
|
||||
let resolved: *u8 = resolvemodule(selfdir, src, incs.ptr, &isdir);
|
||||
if (resolved == nil) {
|
||||
|
||||
Reference in New Issue
Block a user