parse: enforce strict-package — reject package-less files (#24a)
Flip the soft-default to a hard "missing package clause" error symmetrically in both stages (cmd/wcc/parse.c + lib/ww/syntax/parse.ww): the first real decl of a primary section with empty pathmod/resetmod and no seen clause is now rejected. Closes the documented soft-default divergence (the 63-wrapper carve-out). The gate flip can't be split from the migration it breaks, so this is one atomic commit: ~80 test/wcc wrappers gain `package main;` via a shared wwtestpkg.h helper, 6 data fixtures plus 17 asm-grep assertions update for the bare->main.<leaf> root-helper mangle shift, and rt/ declares `package rt;` with @symbol pinning the bare rt_ensure/rt_malloc linker names. Root mangling narrows: the executable entry `main` stays bare (existing carve-out), but root helper symbols become main.X. The #84 cluster is rewritten to assert main.run distinct from aa.run/test.run; its cgen fix and bare machinery are retained — still load-bearing for package-less module-reset deps. New table-driven test 782_strict_package.c (6 rows, both stages). Retiring //ww:module-reset is deferred to #24b: it is load-bearing (clears the .wwi pathmod so the body's package clause asserts), not a vestige; fusing its removal here would be a silent mismatch. All byte-id gates green; full make test reports "all 335 tests passed".
This commit is contained in:
61
test/wcc/wwtestpkg.h
Normal file
61
test/wcc/wwtestpkg.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* wwtestpkg.h — strict-package (#24a) test support.
|
||||
*
|
||||
* Inline ww test fixtures historically omitted the `package main;` clause
|
||||
* that the parser now requires (a missing clause is a hard error). These
|
||||
* helpers inject it transparently so the fixtures stay terse, WITHOUT
|
||||
* disturbing fixtures that already declare their own module identity.
|
||||
*
|
||||
* wwtest_fputs is a drop-in for fputs(src, f): it prepends `package main;`
|
||||
* only when writing at the START of a fresh file (ftell == 0) AND the
|
||||
* fixture does not already open with its own `package`/`//ww:module`
|
||||
* directive. The ftell guard keeps multi-part writes and writes to
|
||||
* non-seekable streams (stderr) behaving exactly like plain fputs.
|
||||
*/
|
||||
#ifndef WWTESTPKG_H
|
||||
#define WWTESTPKG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline int
|
||||
wwtest_has_module(const char *s)
|
||||
{
|
||||
const char *p = s;
|
||||
while (p != NULL) {
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (strncmp(p, "package ", 8) == 0
|
||||
|| strncmp(p, "package\t", 8) == 0
|
||||
|| strncmp(p, "//ww:module", 11) == 0)
|
||||
return 1;
|
||||
p = strchr(p, '\n');
|
||||
if (p != NULL)
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wwtest_fputs(const char *src, FILE *f)
|
||||
{
|
||||
if (ftell(f) == 0 && !wwtest_has_module(src))
|
||||
fputs("package main;\n", f);
|
||||
fputs(src, f);
|
||||
}
|
||||
|
||||
/* In-process variant: a malloc'd copy of src with the clause prefixed
|
||||
* (unless src declares its own module). Caller frees. */
|
||||
static inline char *
|
||||
wwtest_wrap(const char *src)
|
||||
{
|
||||
const char *pfx = wwtest_has_module(src) ? "" : "package main;\n";
|
||||
size_t np = strlen(pfx), ns = strlen(src);
|
||||
char *b = malloc(np + ns + 1);
|
||||
memcpy(b, pfx, np);
|
||||
memcpy(b + np, src, ns + 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user