/* * 110_uniesc_run — .wwi round-trip carrier for \u / \U Unicode escapes. * * The value-row half (rune/string \u \U \x decode asserts) migrated to the * in-language row-table test/lang/uniesc_test.ww (fold-6, task #4); this * file retains ONLY the .wwi round-trip case, which is a two-package * sep-build observer with no in-language @test home (it asserts the * PRODUCER re-serializes a wide-rune `def` byte-exact, observed across a * package boundary — not expressible as a single-compile @test). * * An exported wide-rune `def` re-serialized by the producer must re-parse * into the same codepoint (the write-twin of the lexer read-fix — * cmd/w6c/wwi.c wwi_rune / selfhost/cmd/wcc/wwi.ww wwirune emit \u/\U above * 0xFF). Runs through both the cstage `ww` and wwstage `ww_ww` drivers * (task #50); the wwstage arm is skipped when ww_ww is absent (a * cstage-only build), mirroring 640_int_cast_signed. */ #include #include #include #include #include static int runwait(const char *cmd) { int rc = system(cmd); if (rc == -1) return -1; if (WIFEXITED(rc)) return WEXITSTATUS(rc); return -1; } /* run_roundtrip — sep-build a two-package program where the imported * package exports wide-rune defs; the producer must serialize them as * \u/\U so the importer re-parses the same codepoint. Returns the built * program's exit code (42 on a correct round-trip). */ static int run_roundtrip(const char *driver, int id) { char dir[80], wrdir[112], wrp[176], mainp[160], cmd[1024], outbin[160]; snprintf(dir, sizeof dir, "/tmp/wwue_rt_%d_%d", getpid(), id); snprintf(wrdir, sizeof wrdir, "%s/wr", dir); mkdir(dir, 0755); mkdir(wrdir, 0755); snprintf(wrp, sizeof wrp, "%s/wr.ww", wrdir); snprintf(mainp, sizeof mainp, "%s/main.ww", dir); FILE *f = fopen(wrp, "wb"); if (!f) { snprintf(cmd, sizeof cmd, "rm -rf %s", dir); (void)system(cmd); return -1; } /* one def per serializer branch: \x (<=0xFF), \u (<=0xFFFF), \U. */ fputs("package wr;\n" "export def EACUTE: rune = '\\u00e9';\n" "export def EURO: rune = '\\u20ac';\n" "export def SMILEY: rune = '\\U0001F600';\n", f); fclose(f); f = fopen(mainp, "wb"); if (!f) { snprintf(cmd, sizeof cmd, "rm -rf %s", dir); (void)system(cmd); return -1; } fputs("package main;\n" "import wr;\n" "fn main() i32 = {\n" " let a: rune = wr.EACUTE;\n" " let b: rune = wr.EURO;\n" " let c: rune = wr.SMILEY;\n" " if ((a: u32) != 233u32) { return 1; };\n" " if ((b: u32) != 8364u32) { return 2; };\n" " if ((c: u32) != 128512u32) { return 3; };\n" " return 42;\n" "};\n", f); fclose(f); snprintf(cmd, sizeof cmd, "cd %s && %s build main.ww", dir, driver); if (runwait(cmd) != 0) { fprintf(stderr, "roundtrip: build via %s failed\n", driver); snprintf(cmd, sizeof cmd, "rm -rf %s", dir); (void)system(cmd); return -1; } snprintf(outbin, sizeof outbin, "%s/main", dir); int got = runwait(outbin); snprintf(cmd, sizeof cmd, "rm -rf %s", dir); (void)system(cmd); return got; } int main(void) { const char *bin = getenv("BIN"); if (!bin) bin = "out/bin"; char absbin[1024]; if (bin[0] != '/') { char cwd[1024]; if (getcwd(cwd, sizeof cwd) == NULL) return 1; snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin); bin = absbin; } char cdrv[1024]; snprintf(cdrv, sizeof cdrv, "%s/ww", bin); char wdrv[1024]; snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); struct { const char *name; const char *path; int gated_on_existence; } drivers[] = { { "cstage", cdrv, 0 }, { "wwstage", wdrv, 1 }, { NULL, NULL, 0 }, }; int total = 0, fail = 0; for (int d = 0; drivers[d].name; d++) { if (drivers[d].gated_on_existence && access(drivers[d].path, X_OK) != 0) { fprintf(stderr, "uniesc_run: skip %s (no %s)\n", drivers[d].name, drivers[d].path); continue; } int rt = run_roundtrip(drivers[d].path, d); total++; if (rt != 42) { fprintf(stderr, "uniesc_run[%s][wwi_roundtrip]: exit=%d want=42\n", drivers[d].name, rt); fail++; } } if (fail) { fprintf(stderr, "uniesc_run: %d/%d fixtures failed\n", fail, total); return 1; } printf("uniesc_run: %d/%d ok\n", total, total); return 0; }