/* * 815: residual separated-package cstage/wwstage assembly identity. * Runtime is owned by r815_*; -S stops both driver legs before assembly, * archive creation, and linking. The sorted package-assembly concatenation * remains the byte oracle. */ #include #include #include #include #include struct row { const char *label, *path; }; static const struct row rows[] = { { "bare_int", "test/wcc/data/r815_bare_int/case.ww" }, { "bare_int_neg", "test/wcc/data/r815_bare_int_neg/case.ww" }, { "bare_uint", "test/wcc/data/r815_bare_uint/case.ww" }, { "uint_highbit", "test/wcc/data/r815_uint_highbit/case.ww" }, { "int_printf", "test/wcc/data/r815_int_printf/case.ww" }, { "unaffected_i64", "test/wcc/data/r815_unaffected_i64/case.ww" }, { "unaffected_str", "test/wcc/data/r815_unaffected_str/case.ww" }, { "mixed", "test/wcc/data/r815_mixed/case.ww" }, }; static int runwait(const char *cmd) { int rc = system(cmd); return rc != -1 && WIFEXITED(rc) ? WEXITSTATUS(rc) : -1; } static int copyfile(const char *src, const char *dst) { char buf[8192]; size_t n; int rc = 0; FILE *in = fopen(src, "rb"), *out; if (!in) return -1; out = fopen(dst, "wb"); if (!out) { fclose(in); return -1; } while ((n = fread(buf, 1, sizeof buf, in)) != 0) if (fwrite(buf, 1, n, out) != n) { rc = -1; break; } if (ferror(in)) rc = -1; if (fclose(out) != 0) rc = -1; fclose(in); return rc; } static int samefile(const char *a, const char *b) { FILE *fa = fopen(a, "rb"), *fb = fopen(b, "rb"); int rc = 0; if (!fa || !fb) rc = -1; else for (;;) { int ca = fgetc(fa), cb = fgetc(fb); if (ca != cb) { rc = -1; break; } if (ca == EOF) break; } if (fa) fclose(fa); if (fb) fclose(fb); return rc; } static int byteid(const char *cdrv, const char *wdrv, const char *cwd, const struct row *r, int seq) { char tmp[256], src[512], cs[512], ws[512], cmd[2048]; int rc = -1; snprintf(tmp, sizeof tmp, "/tmp/fic_%d_b_%d", getpid(), seq); snprintf(src, sizeof src, "%s/main815b.ww", tmp); snprintf(cs, sizeof cs, "%s/all_cs.s", tmp); snprintf(ws, sizeof ws, "%s/all_ww.s", tmp); /* an unowned path (stale dir, full /tmp) must not be built in — or * rm -rf'd — below. */ if (mkdir(tmp, 0755) != 0) { perror(tmp); return -1; } if (copyfile(r->path, src) != 0) goto out; snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build -S -I %s/lib " "-o %s/main815b_c %s 2>/dev/null", tmp, cdrv, cwd, tmp, src); if (runwait(cmd) != 0) goto out; snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build -S -I %s/lib " "-o %s/main815b_w %s 2>/dev/null", tmp, wdrv, cwd, tmp, src); if (runwait(cmd) != 0) goto out; snprintf(cmd, sizeof cmd, "cat %s/main815b_c.sepwork/*.s > %s 2>/dev/null", tmp, cs); if (runwait(cmd) != 0) goto out; snprintf(cmd, sizeof cmd, "cat %s/main815b_w.sepwork/*.s > %s 2>/dev/null", tmp, ws); if (runwait(cmd) != 0) goto out; rc = samefile(cs, ws); out: if (rc != 0) fprintf(stderr, "fmt_int_run[%s]: byte mismatch/error\n", r->label); snprintf(cmd, sizeof cmd, "rm -rf %s", tmp); if (runwait(cmd) != 0) { fprintf(stderr, "fmt_int_run[%s]: cleanup %s failed\n", r->label, tmp); if (rc == 0) rc = -1; } return rc; } int main(void) { const char *bin = getenv("BIN"); char cwd[1024], absbin[1024]; char cdrv[1024], wdrv[1024]; if (!getcwd(cwd, sizeof cwd)) return 1; if (!bin) bin = "out/bin"; if (bin[0] != '/') { snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin); bin = absbin; } snprintf(cdrv, sizeof cdrv, "%s/ww", bin); snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); if (access(wdrv, X_OK) != 0) { fprintf(stderr, "fmt_int_run: skip wwstage\n"); return 0; } int n = (int)(sizeof rows / sizeof rows[0]), fail = 0; for (int i = 0; i < n; i++) if (byteid(cdrv, wdrv, cwd, &rows[i], i) != 0) fail++; if (fail) { fprintf(stderr, "fmt_int_run: %d/%d byte rows failed\n", fail, n); return 1; } printf("fmt_int_run: %d/%d byte rows ok\n", n, n); return 0; }