ww: select sources by Go platform suffixes
This commit is contained in:
121
cmd/ww/main.c
121
cmd/ww/main.c
@@ -372,6 +372,79 @@ strs_cmp(const void *a, const void *b)
|
||||
return strcmp(sa, sb);
|
||||
}
|
||||
|
||||
static int
|
||||
sep_name_is(const char *s, size_t n, const char *word)
|
||||
{
|
||||
return strlen(word) == n && memcmp(s, word, n) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sep_known_os(const char *s, size_t n)
|
||||
{
|
||||
static const char *known[] = {
|
||||
"aix", "android", "darwin", "dragonfly", "freebsd", "hurd",
|
||||
"illumos", "ios", "js", "linux", "nacl", "netbsd", "openbsd",
|
||||
"plan9", "solaris", "wasip1", "windows", "zos",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof known / sizeof known[0]; i++)
|
||||
if (sep_name_is(s, n, known[i])) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sep_known_arch(const char *s, size_t n)
|
||||
{
|
||||
static const char *known[] = {
|
||||
"386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be",
|
||||
"loong64", "mips", "mipsle", "mips64", "mips64le", "mips64p32",
|
||||
"mips64p32le", "ppc", "ppc64", "ppc64le", "riscv", "riscv64",
|
||||
"s390", "s390x", "sparc", "sparc64", "wasm",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof known / sizeof known[0]; i++)
|
||||
if (sep_name_is(s, n, known[i])) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sep_target_tag(const char *s, size_t n)
|
||||
{
|
||||
return sep_name_is(s, n, "linux") || sep_name_is(s, n, "amd64");
|
||||
}
|
||||
|
||||
/* Go 1.26.5 build.go:1980-2027 filters known platform suffixes before
|
||||
* opening a source. WW currently has one honest target, linux/amd64. */
|
||||
static int
|
||||
sep_source_matches_target(const char *name)
|
||||
{
|
||||
size_t stem = strcspn(name, ".");
|
||||
if (memchr(name, '_', stem) == NULL) return 1;
|
||||
|
||||
size_t end = stem;
|
||||
size_t last = end;
|
||||
while (last > 0 && name[last - 1] != '_') last--;
|
||||
if (sep_name_is(name + last, end - last, "test")) {
|
||||
if (last == 0) return 1;
|
||||
end = last - 1;
|
||||
last = end;
|
||||
while (last > 0 && name[last - 1] != '_') last--;
|
||||
}
|
||||
if (last == 0) return 1;
|
||||
|
||||
const char *final = name + last;
|
||||
size_t nfinal = end - last;
|
||||
size_t prevend = last - 1;
|
||||
size_t prev = prevend;
|
||||
while (prev > 0 && name[prev - 1] != '_') prev--;
|
||||
if (prev < prevend
|
||||
&& sep_known_os(name + prev, prevend - prev)
|
||||
&& sep_known_arch(final, nfinal))
|
||||
return sep_target_tag(final, nfinal)
|
||||
&& sep_target_tag(name + prev, prevend - prev);
|
||||
if (sep_known_os(final, nfinal) || sep_known_arch(final, nfinal))
|
||||
return sep_target_tag(final, nfinal);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sep_slurp(const char*, char**, u64*);
|
||||
|
||||
/* Go's contract: only *_test.ww is a test source. Ask the compiler parser,
|
||||
@@ -564,15 +637,39 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
{
|
||||
DIR *d = opendir(dirpath);
|
||||
if (d == NULL) { *out_files = NULL; return -1; }
|
||||
char **names = NULL;
|
||||
int nnames = 0, capnames = 0;
|
||||
char **prod = NULL, **tests = NULL;
|
||||
int nprod = 0, capprod = 0, ntests = 0, captests = 0;
|
||||
struct dirent *ent;
|
||||
while ((ent = readdir(d)) != NULL) {
|
||||
struct dirent *ent = NULL;
|
||||
for (;;) {
|
||||
errno = 0;
|
||||
ent = readdir(d);
|
||||
if (ent == NULL) break;
|
||||
const char *nm = ent->d_name;
|
||||
size_t nl = strlen(nm);
|
||||
if (nl <= 3) continue;
|
||||
if (nm[0] == '.' || nm[0] == '_') continue;
|
||||
if (strcmp(nm + nl - 3, ".ww") != 0) continue;
|
||||
if (source_list_add(&names, &nnames, &capnames, nm) < 0) {
|
||||
source_list_free(names, nnames);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
int direrr = errno;
|
||||
closedir(d);
|
||||
if (direrr != 0) {
|
||||
source_list_free(names, nnames);
|
||||
*out_files = NULL;
|
||||
return -1;
|
||||
}
|
||||
if (nnames > 1) qsort(names, (size_t)nnames, sizeof *names, strs_cmp);
|
||||
for (int ni = 0; ni < nnames; ni++) {
|
||||
const char *nm = names[ni];
|
||||
size_t nl = strlen(nm);
|
||||
if (!sep_source_matches_target(nm)) continue;
|
||||
int is_test = nl >= 8 && strcmp(nm + nl - 8, "_test.ww") == 0;
|
||||
if (variant == SEP_VARIANT_PRODUCTION && is_test) continue;
|
||||
if (variant == SEP_VARIANT_EXTERNAL && !is_test) continue;
|
||||
@@ -580,9 +677,9 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
int pn = snprintf(path, sizeof path, "%s/%s", dirpath, nm);
|
||||
if (pn < 0 || (size_t)pn >= sizeof path) {
|
||||
fprintf(stderr, "ww: package source path is too long\n");
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
@@ -590,9 +687,9 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
if (lstat(path, &st) != 0) {
|
||||
fprintf(stderr,
|
||||
"ww: %s: package source is not a regular file\n", path);
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
@@ -601,9 +698,9 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
fprintf(stderr,
|
||||
"ww: %s: package source is not a regular file\n",
|
||||
path);
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
@@ -613,17 +710,17 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
fprintf(stderr,
|
||||
"ww: %s: package source is not a regular file\n", path);
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
int has_test = !is_test ? source_has_test_decl(path) : 0;
|
||||
if (has_test < 0) {
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
@@ -631,18 +728,18 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
fprintf(stderr,
|
||||
"ww: %s: @test declaration outside *_test.ww\n",
|
||||
path);
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
if (is_test) {
|
||||
char *package = NULL;
|
||||
if (source_package_name(path, &package) < 0) {
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
@@ -656,14 +753,14 @@ enumerate_dir_ww(const char *dirpath, int variant, const char *test_package,
|
||||
int *n = is_test ? &ntests : &nprod;
|
||||
int *cap = is_test ? &captests : &capprod;
|
||||
if (source_list_add(list, n, cap, path) < 0) {
|
||||
source_list_free(names, nnames);
|
||||
source_list_free(prod, nprod);
|
||||
source_list_free(tests, ntests);
|
||||
closedir(d);
|
||||
*out_files = NULL;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
source_list_free(names, nnames);
|
||||
if (nprod > 1) qsort(prod, (size_t)nprod, sizeof *prod, strs_cmp);
|
||||
if (ntests > 1) qsort(tests, (size_t)ntests, sizeof *tests, strs_cmp);
|
||||
if (nprod > INT_MAX - ntests) {
|
||||
@@ -4161,7 +4258,7 @@ static void
|
||||
workdir_stamp_text(char *buf, size_t bufsz, int is_test, int emit_asm)
|
||||
{
|
||||
snprintf(buf, bufsz, "ww workdir fmt %d mode %s asm %d\n",
|
||||
is_test ? 16 : 17, is_test ? "test" : "build", emit_asm);
|
||||
is_test ? 17 : 18, is_test ? "test" : "build", emit_asm);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user