Files
ww/test/wcc/wwtestpkg.h
Hojun-Cho 7b9488706b 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".
2026-06-29 03:55:26 +09:00

62 lines
1.7 KiB
C

/*
* 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