lib/io: port mode/whence/error + reader/writer/closer fn-aliases (#94 fold-d)
New lib/io/types.ww mirrors ref/hare/io/types.ha — the surrounding
port that lives alongside the existing lib/io/io.ww (pre-vtable
stream + eof + underread). Hare splits the same way (stream.ha +
types.ha share `module io`); ww does the equivalent via dir-enum.
Each type cites Hare per CLAUDE.md rule 9:
- mode (enum u8) — ref/hare/io/types.ha:29-34. RDWR=3 (not
Hare's `READ | WRITE`) because ww enum-value
positions don't fold expressions; bitfield
value SSoT preserved, divergence inline.
- whence (enum i32) — ref/hare/io/types.ha:37-41. Hare leaves the
underlying implicit; ww requires one. i32
matches the `off` type fold-e wires in.
- error — ref/hare/io/types.ha:11. Hare spreads
`errors::error`; lib/errors not ported, so
the union carries the two tags observable
in this fold: underread (from io.ww) and
the predeclared `nomem` (#29, type.c:72 /
check.ww:78). NOT redefined here.
- reader/writer/closer — ref/hare/io/types.ha:46/51/55. EOF=eof
(not Hare's `done` singleton) per #93
and the io.ww:8 rationale. `*stream`
forward-refs the existing pre-vtable
struct in io.ww; same cross-file pattern
Hare uses.
Drew signoff (this fold only): seeker, copier, strerror, and the
EOF=done singleton DEFERRED to fold-e — they need the `handle` sum
and #93's done landing. Hare's `_unsafe` carve-out unaffected.
eof / underread / stream re-used from io.ww (NOT redefined); io.ww
keeps the pre-vtable struct unchanged, ditto its WHY-comments.
Combined.ww regen (#110): selfhost/cmd/{w6c,wwdump}/main.combined.ww
auto-pulled the new types.ww via dir-enum (+52 lines each, same
package io). Makefile dep lines for wwdump_ww + w6c_ww add the new
source so editing it triggers rebuild.
Probe: test/wcc/768_io_types_run.c — 5 rows × 2 stages = 10
invocations. Pins enum value/underlying + the three fn-type aliases
at the param slot. Both siblings filed inline in the probe header:
- #189 wwstage `let r: io.reader = fn_name;` bails "let: not
assignable". cstage accepts. Param + struct-field paths work
in both stages, so io vtable port is unblocked. Probe uses
the alias only at the param slot.
- #190 wwstage match-arm on cross-module variant tag bails
"case: not a variant of scrutinee (io.eof | io.error)". Likely
same family as #178. cstage accepts. Probe uses `is` instead
of `match` for the variant gate.
make test: 201/201 (was 200; +1 from 768). 990-997 byte-id +
combined_ww_fresh + sizelint all green.
This commit is contained in:
11
Makefile
11
Makefile
@@ -113,7 +113,7 @@ $(BIN)/wwdump_ww: selfhost/cmd/wwdump/main.ww \
|
||||
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
||||
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
||||
selfhost/cmd/wcc/cgendecl.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/io/io.ww lib/memio/memio.ww lib/fmt/fmt.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/io/io.ww lib/io/types.ww lib/memio/memio.ww lib/fmt/fmt.ww \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@mkdir -p $(BIN)/wwdump_ww.d
|
||||
@@ -135,7 +135,7 @@ $(BIN)/w6c_ww: selfhost/cmd/w6c/main.ww \
|
||||
selfhost/cmd/wcc/cgen.ww selfhost/cmd/wcc/cgenexpr.ww \
|
||||
selfhost/cmd/wcc/cgenstmt.ww selfhost/cmd/wcc/cgenutil.ww \
|
||||
selfhost/cmd/wcc/cgendecl.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/io/io.ww lib/memio/memio.ww lib/fmt/fmt.ww \
|
||||
lib/os/os.ww lib/rt/malloc.ww lib/time/time.ww lib/strconv/strconv.ww lib/strconv/stof_data.ww lib/strconv/decimal.ww lib/strconv/stof.ww lib/strconv/ftos_data.ww lib/strconv/ftos.ww lib/strings/strings.ww lib/bytes/bytes.ww lib/encoding/utf8/utf8.ww lib/ascii/ascii.ww lib/io/io.ww lib/io/types.ww lib/memio/memio.ww lib/fmt/fmt.ww \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@mkdir -p $(BIN)/w6c_ww.d
|
||||
@@ -318,6 +318,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_star_fn_deref \
|
||||
$(BIN)/test_star_fn_deref_call \
|
||||
$(BIN)/test_match_variant_dispatch \
|
||||
$(BIN)/test_io_types_run \
|
||||
$(BIN)/test_use_promote_alias \
|
||||
$(BIN)/test_field_signed $(BIN)/test_frame_argcount \
|
||||
$(BIN)/test_selfhost $(BIN)/test_w6a_ww $(BIN)/test_w6l_ww \
|
||||
@@ -632,6 +633,12 @@ $(BIN)/test_match_variant_dispatch: test/wcc/767_match_variant_dispatch.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_io_types_run: test/wcc/768_io_types_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_arrlit_str_full: test/wcc/711_arrlit_str_full.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
|
||||
51
lib/io/types.ww
Normal file
51
lib/io/types.ww
Normal file
@@ -0,0 +1,51 @@
|
||||
// types — error union, mode/whence enums, reader/writer/closer
|
||||
// fn-type aliases. Project #94 fold-1 step (d) (drew Fold D).
|
||||
//
|
||||
// Hare splits the io module across stream.ha + types.ha and ww does
|
||||
// the same: lib/io/io.ww owns the (pre-vtable) `stream`, `eof`, and
|
||||
// `underread` shapes; this file owns the surrounding port. Both
|
||||
// files share `package io;` so forward refs (e.g. reader → stream)
|
||||
// resolve via the dir-enum concat order.
|
||||
//
|
||||
// Deferrals (drew-signed): `handle`, `seeker`, `copier`, `strerror`
|
||||
// land with fold-e (need the `handle` sum). Hare's `EOF = done`
|
||||
// stays as `io.eof` until the `done` singleton ships (#93).
|
||||
|
||||
package io;
|
||||
|
||||
// ref/hare/io/types.ha:29-34. RDWR is spelled `3` rather than Hare's
|
||||
// `READ | WRITE` because the ww parser doesn't fold expressions in
|
||||
// enum value positions; the value SSoT stays the same bitfield.
|
||||
export type mode = enum u8 {
|
||||
NONE = 0,
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
RDWR = 3,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:37-41. Hare leaves the underlying implicit;
|
||||
// ww requires one. i32 matches the off type that fold-e will plug
|
||||
// into the seeker signature.
|
||||
export type whence = enum i32 {
|
||||
SET = 0,
|
||||
CUR = 1,
|
||||
END = 2,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:11 spreads `errors::error` into the union;
|
||||
// lib/errors isn't ported yet, so the union carries only the tags
|
||||
// observable in this fold — `underread` (from io.ww) and the
|
||||
// predeclared `nomem` (#29, type.c:72 / check.ww:78).
|
||||
export type error = !(underread | nomem);
|
||||
|
||||
// ref/hare/io/types.ha:46. `eof` (not Hare's `done`) per the io.ww:8
|
||||
// rationale; lifts to `done` with #93. `*stream` forward-refs the
|
||||
// pre-vtable struct in io.ww — same cross-file pattern Hare uses.
|
||||
export type reader = fn(s: *stream, buf: []u8) (size | eof | error);
|
||||
|
||||
// ref/hare/io/types.ha:51. No `const` qualifier — ww has none, and
|
||||
// lib/io/io.ww:30 + lib/sort/sort.ww:18 drop it the same way.
|
||||
export type writer = fn(s: *stream, buf: []u8) (size | error);
|
||||
|
||||
// ref/hare/io/types.ha:55.
|
||||
export type closer = fn(s: *stream) (void | error);
|
||||
@@ -13879,6 +13879,58 @@ export fn close(s: *stream) (void | closed) = {
|
||||
return s.close(s);
|
||||
};
|
||||
|
||||
// types — error union, mode/whence enums, reader/writer/closer
|
||||
// fn-type aliases. Project #94 fold-1 step (d) (drew Fold D).
|
||||
//
|
||||
// Hare splits the io module across stream.ha + types.ha and ww does
|
||||
// the same: lib/io/io.ww owns the (pre-vtable) `stream`, `eof`, and
|
||||
// `underread` shapes; this file owns the surrounding port. Both
|
||||
// files share `package io;` so forward refs (e.g. reader → stream)
|
||||
// resolve via the dir-enum concat order.
|
||||
//
|
||||
// Deferrals (drew-signed): `handle`, `seeker`, `copier`, `strerror`
|
||||
// land with fold-e (need the `handle` sum). Hare's `EOF = done`
|
||||
// stays as `io.eof` until the `done` singleton ships (#93).
|
||||
|
||||
package io;
|
||||
|
||||
// ref/hare/io/types.ha:29-34. RDWR is spelled `3` rather than Hare's
|
||||
// `READ | WRITE` because the ww parser doesn't fold expressions in
|
||||
// enum value positions; the value SSoT stays the same bitfield.
|
||||
export type mode = enum u8 {
|
||||
NONE = 0,
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
RDWR = 3,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:37-41. Hare leaves the underlying implicit;
|
||||
// ww requires one. i32 matches the off type that fold-e will plug
|
||||
// into the seeker signature.
|
||||
export type whence = enum i32 {
|
||||
SET = 0,
|
||||
CUR = 1,
|
||||
END = 2,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:11 spreads `errors::error` into the union;
|
||||
// lib/errors isn't ported yet, so the union carries only the tags
|
||||
// observable in this fold — `underread` (from io.ww) and the
|
||||
// predeclared `nomem` (#29, type.c:72 / check.ww:78).
|
||||
export type error = !(underread | nomem);
|
||||
|
||||
// ref/hare/io/types.ha:46. `eof` (not Hare's `done`) per the io.ww:8
|
||||
// rationale; lifts to `done` with #93. `*stream` forward-refs the
|
||||
// pre-vtable struct in io.ww — same cross-file pattern Hare uses.
|
||||
export type reader = fn(s: *stream, buf: []u8) (size | eof | error);
|
||||
|
||||
// ref/hare/io/types.ha:51. No `const` qualifier — ww has none, and
|
||||
// lib/io/io.ww:30 + lib/sort/sort.ww:18 drop it the same way.
|
||||
export type writer = fn(s: *stream, buf: []u8) (size | error);
|
||||
|
||||
// ref/hare/io/types.ha:55.
|
||||
export type closer = fn(s: *stream) (void | error);
|
||||
|
||||
// memio — in-memory io stream.
|
||||
//
|
||||
// Hare's memio:: surface, drop underscores. Two flavours behind a
|
||||
|
||||
@@ -13879,6 +13879,58 @@ export fn close(s: *stream) (void | closed) = {
|
||||
return s.close(s);
|
||||
};
|
||||
|
||||
// types — error union, mode/whence enums, reader/writer/closer
|
||||
// fn-type aliases. Project #94 fold-1 step (d) (drew Fold D).
|
||||
//
|
||||
// Hare splits the io module across stream.ha + types.ha and ww does
|
||||
// the same: lib/io/io.ww owns the (pre-vtable) `stream`, `eof`, and
|
||||
// `underread` shapes; this file owns the surrounding port. Both
|
||||
// files share `package io;` so forward refs (e.g. reader → stream)
|
||||
// resolve via the dir-enum concat order.
|
||||
//
|
||||
// Deferrals (drew-signed): `handle`, `seeker`, `copier`, `strerror`
|
||||
// land with fold-e (need the `handle` sum). Hare's `EOF = done`
|
||||
// stays as `io.eof` until the `done` singleton ships (#93).
|
||||
|
||||
package io;
|
||||
|
||||
// ref/hare/io/types.ha:29-34. RDWR is spelled `3` rather than Hare's
|
||||
// `READ | WRITE` because the ww parser doesn't fold expressions in
|
||||
// enum value positions; the value SSoT stays the same bitfield.
|
||||
export type mode = enum u8 {
|
||||
NONE = 0,
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
RDWR = 3,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:37-41. Hare leaves the underlying implicit;
|
||||
// ww requires one. i32 matches the off type that fold-e will plug
|
||||
// into the seeker signature.
|
||||
export type whence = enum i32 {
|
||||
SET = 0,
|
||||
CUR = 1,
|
||||
END = 2,
|
||||
};
|
||||
|
||||
// ref/hare/io/types.ha:11 spreads `errors::error` into the union;
|
||||
// lib/errors isn't ported yet, so the union carries only the tags
|
||||
// observable in this fold — `underread` (from io.ww) and the
|
||||
// predeclared `nomem` (#29, type.c:72 / check.ww:78).
|
||||
export type error = !(underread | nomem);
|
||||
|
||||
// ref/hare/io/types.ha:46. `eof` (not Hare's `done`) per the io.ww:8
|
||||
// rationale; lifts to `done` with #93. `*stream` forward-refs the
|
||||
// pre-vtable struct in io.ww — same cross-file pattern Hare uses.
|
||||
export type reader = fn(s: *stream, buf: []u8) (size | eof | error);
|
||||
|
||||
// ref/hare/io/types.ha:51. No `const` qualifier — ww has none, and
|
||||
// lib/io/io.ww:30 + lib/sort/sort.ww:18 drop it the same way.
|
||||
export type writer = fn(s: *stream, buf: []u8) (size | error);
|
||||
|
||||
// ref/hare/io/types.ha:55.
|
||||
export type closer = fn(s: *stream) (void | error);
|
||||
|
||||
// memio — in-memory io stream.
|
||||
//
|
||||
// Hare's memio:: surface, drop underscores. Two flavours behind a
|
||||
|
||||
262
test/wcc/768_io_types_run.c
Normal file
262
test/wcc/768_io_types_run.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* 768_io_types_run — project #94 fold-1 step (d) (drew Fold D) sentinel.
|
||||
* Pins the new lib/io/types.ww port (ref/hare/io/types.ha) — `mode` /
|
||||
* `whence` enums, `error = !(underread | nomem)` union, and the
|
||||
* `reader` / `writer` / `closer` fn-type aliases. The aliases forward-
|
||||
* ref `*stream` from lib/io/io.ww (Hare splits the same way:
|
||||
* stream.ha + types.ha share the `io` module).
|
||||
*
|
||||
* Each row is a self-contained `import io;` program: cstage `ww build`
|
||||
* compiles it, we run the binary and assert the exit. Rows that hit a
|
||||
* known wwstage checker gap (see SIBLINGS below) are cstage-only via
|
||||
* stage_mask — the bulk run both stages so the dir-enum concat through
|
||||
* types.ww + io.ww is exercised by ww_ww too.
|
||||
*
|
||||
* row | what it pins
|
||||
* --------------------------+--------------------------------------
|
||||
* enum_mode_value | io.mode (enum u8) member access +
|
||||
* | underlying numeric promotion. RDWR=3
|
||||
* | matches Hare's READ|WRITE bitfield
|
||||
* | (1 SSoT; see types.ww header note on
|
||||
* | the value spelling).
|
||||
* enum_whence_value | io.whence (enum i32) member access.
|
||||
* | END=2 matches ref/hare/io/types.ha:40.
|
||||
* reader_alias_param | `io.reader` usable as a fn-VALUE param
|
||||
* | type — the immediate use case the
|
||||
* | upcoming vtable port needs. dummy_read
|
||||
* | passed by-name, called through the
|
||||
* | alias, `is size` gate confirms the
|
||||
* | (size | io.eof | io.error) return
|
||||
* | shape parses + dispatches.
|
||||
* writer_alias_param | `io.writer` same shape; (size |
|
||||
* | io.error) return.
|
||||
* closer_alias_param | `io.closer` (void | io.error). Most
|
||||
* | minimal of the three — pins the alias
|
||||
* | resolves without depending on the
|
||||
* | tagged-return discriminant path.
|
||||
*
|
||||
* SIBLINGS (out of scope for #94 fold-1(d), filed inline):
|
||||
*
|
||||
* - #189: wwstage checker bails "let: not assignable" on
|
||||
* `let r: io.reader = some_fn_name;`
|
||||
* i.e. binding a fn-name to a fn-VALUE-typed let. cstage accepts.
|
||||
* Param + struct-field assignment work in both stages, so the io
|
||||
* vtable port is not blocked. PROBE ROUTES AROUND by using the
|
||||
* alias only at the param slot.
|
||||
*
|
||||
* - #190: wwstage match-arm on cross-module variant tag bails
|
||||
* "case: not a variant of scrutinee (io.eof)" / "(io.error)"
|
||||
* on `match (r(s,buf)) { case io.eof => ...; case let e: io.error
|
||||
* => ...; }`. Likely the same family as #178 (typeeqast layer
|
||||
* asymmetry). cstage accepts. PROBE ROUTES AROUND by using `is`
|
||||
* instead of `match` for the variant gate. The Hare-faithful
|
||||
* match form lands once that family is closed.
|
||||
*
|
||||
* GATE POLARITY: must stay GREEN. A red here means either types.ww
|
||||
* stopped parsing/checking, an enum-value underlying narrowed, or the
|
||||
* fn-type alias resolution regressed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
{
|
||||
int rc = system(cmd);
|
||||
if (rc == -1) return -1;
|
||||
if (WIFEXITED(rc)) return WEXITSTATUS(rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define STAGE_CS 1
|
||||
#define STAGE_WW 2
|
||||
|
||||
struct row {
|
||||
const char *label;
|
||||
const char *src;
|
||||
int want_exit;
|
||||
int stage_mask;
|
||||
};
|
||||
|
||||
static const struct row rows[] = {
|
||||
{ "enum_mode_value",
|
||||
"package main;\n"
|
||||
"import io;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let m: io.mode = io.mode.RDWR;\n"
|
||||
" return m: i32;\n"
|
||||
"};\n",
|
||||
3,
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "enum_whence_value",
|
||||
"package main;\n"
|
||||
"import io;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let w: io.whence = io.whence.END;\n"
|
||||
" return w: i32;\n"
|
||||
"};\n",
|
||||
2,
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "reader_alias_param",
|
||||
"package main;\n"
|
||||
"import io;\n"
|
||||
"fn dummy_read(s: *io.stream, buf: []u8) (size | io.eof | io.error) = {\n"
|
||||
" return 0: size;\n"
|
||||
"};\n"
|
||||
"fn use_reader(r: io.reader, s: *io.stream, buf: []u8) i32 = {\n"
|
||||
" let v = r(s, buf);\n"
|
||||
" if (v is size) { return 11; };\n"
|
||||
" return -1;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let st: io.stream;\n"
|
||||
" let buf: [4]u8;\n"
|
||||
" let bs: []u8 = buf[0:4];\n"
|
||||
" return use_reader(dummy_read, &st, bs);\n"
|
||||
"};\n",
|
||||
11,
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "writer_alias_param",
|
||||
"package main;\n"
|
||||
"import io;\n"
|
||||
"fn dummy_write(s: *io.stream, buf: []u8) (size | io.error) = {\n"
|
||||
" return buf.len: size;\n"
|
||||
"};\n"
|
||||
"fn use_writer(w: io.writer, s: *io.stream, buf: []u8) i32 = {\n"
|
||||
" let v = w(s, buf);\n"
|
||||
" if (v is size) { return 22; };\n"
|
||||
" return -1;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let st: io.stream;\n"
|
||||
" let buf: [7]u8;\n"
|
||||
" let bs: []u8 = buf[0:7];\n"
|
||||
" return use_writer(dummy_write, &st, bs);\n"
|
||||
"};\n",
|
||||
22,
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "closer_alias_param",
|
||||
"package main;\n"
|
||||
"import io;\n"
|
||||
"fn dummy_close(s: *io.stream) (void | io.error) = {\n"
|
||||
" return void;\n"
|
||||
"};\n"
|
||||
"fn use_closer(c: io.closer, s: *io.stream) i32 = {\n"
|
||||
" let _v = c(s);\n"
|
||||
" return 33;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let st: io.stream;\n"
|
||||
" return use_closer(dummy_close, &st);\n"
|
||||
"};\n",
|
||||
33,
|
||||
STAGE_CS | STAGE_WW },
|
||||
};
|
||||
|
||||
static int
|
||||
build_with(const char *driver, const char *src_path, const char *tmpdir,
|
||||
const char *cwd)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src_path);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const char *bin = getenv("BIN");
|
||||
if (!bin) bin = "out/bin";
|
||||
char cwd[256];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
||||
char absbin[512];
|
||||
if (bin[0] != '/') {
|
||||
snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin);
|
||||
bin = absbin;
|
||||
}
|
||||
|
||||
char cdrv[640], wdrv[640];
|
||||
snprintf(cdrv, sizeof cdrv, "%s/ww", bin);
|
||||
snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin);
|
||||
int have_ww = (access(wdrv, X_OK) == 0);
|
||||
|
||||
int n = (int)(sizeof rows / sizeof rows[0]);
|
||||
int total = 0, fail = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
const struct row *r = &rows[i];
|
||||
|
||||
char src[64], tmpdir[64];
|
||||
snprintf(src, sizeof src, "/tmp/iotyp_%d_%d.ww",
|
||||
getpid(), i);
|
||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/iotyp_%d_d_%d",
|
||||
getpid(), i);
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { fail++; total++; continue; }
|
||||
fputs(r->src, f);
|
||||
fclose(f);
|
||||
mkdir(tmpdir, 0755);
|
||||
|
||||
const char *base = strrchr(src, '/');
|
||||
base = base ? base + 1 : src;
|
||||
char outbin[128];
|
||||
snprintf(outbin, sizeof outbin, "%s/%s", tmpdir, base);
|
||||
char *dot = strrchr(outbin, '.');
|
||||
if (dot && strcmp(dot, ".ww") == 0) *dot = '\0';
|
||||
|
||||
if (r->stage_mask & STAGE_CS) {
|
||||
total++;
|
||||
if (build_with(cdrv, src, tmpdir, cwd) != 0) {
|
||||
fprintf(stderr,
|
||||
"io_types_run[cs][%s]: build failed\n",
|
||||
r->label);
|
||||
fail++;
|
||||
} else {
|
||||
int got = runwait(outbin);
|
||||
if (got != r->want_exit) {
|
||||
fprintf(stderr,
|
||||
"io_types_run[cs][%s]: rc=%d want=%d\n",
|
||||
r->label, got, r->want_exit);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
unlink(outbin);
|
||||
}
|
||||
|
||||
if (have_ww && (r->stage_mask & STAGE_WW)) {
|
||||
total++;
|
||||
if (build_with(wdrv, src, tmpdir, cwd) != 0) {
|
||||
fprintf(stderr,
|
||||
"io_types_run[ww][%s]: build failed\n",
|
||||
r->label);
|
||||
fail++;
|
||||
} else {
|
||||
int got = runwait(outbin);
|
||||
if (got != r->want_exit) {
|
||||
fprintf(stderr,
|
||||
"io_types_run[ww][%s]: rc=%d want=%d\n",
|
||||
r->label, got, r->want_exit);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
unlink(outbin);
|
||||
}
|
||||
|
||||
unlink(src);
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
fprintf(stderr,
|
||||
"io_types_run: %d/%d rows failed\n", fail, total);
|
||||
return 1;
|
||||
}
|
||||
printf("io_types_run: %d/%d ok\n", total, total);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user