commit 12ee201

shrub  ·  2026-11-02 19:53:14 +0000 UTC
parent ff5b08e
add -f flag and flag parsing
2 files changed,  +50, -3
+48, -2
 1@@ -2,13 +2,59 @@
 2 staload "libats/libc/SATS/stdio.sats"
 3 staload "libats/SATS/stringbuf.sats"
 4 staload "libats/DATS/stringbuf.dats"
 5+
 6 staload "scan.sats"
 7 staload "parse.sats"
 8 staload "graph.sats"
 9 
10-implement main0 () = 
11+%{^
12+#define ARGBEGIN \
13+	for (;;) { \
14+		if (argc > 0) \
15+			++argv, --argc; \
16+		if (argc == 0 || (*argv)[0] != '-') \
17+			break; \
18+		if ((*argv)[1] == '-' && !(*argv)[2]) { \
19+			++argv, --argc; \
20+			break; \
21+		} \
22+		for (char *opt_ = &(*argv)[1], done_ = 0; !done_ && *opt_; ++opt_) { \
23+			switch (*opt_)
24+
25+#define ARGEND \
26+		} \
27+	}
28+
29+#define EARGF(x) \
30+	(done_ = 1, opt_[1] ? ++opt_ : argv[1] ? --argc, *++argv : ((x), abort(), (char *)0))
31+
32+static void usage(const char *program) {
33+    fprintf(stderr, "usage: %s [-f file]\n", program);
34+    exit(1);
35+}
36+
37+static char * argz(int argc, char **argv) {
38+    const char *program = argc > 0 ? argv[0] : "monk";
39+    char *file = "build.ninja";
40+
41+    ARGBEGIN {
42+    case 'f':
43+        file = EARGF(usage(program));
44+        break;
45+    default:
46+        usage(program);
47+    } ARGEND
48+
49+    return file;
50+}
51+%}
52+
53+extern fun argz{n:int} (argc: int(n), argv: !argv(n)): string = "mac#argz"
54+
55+implement main0 (argc, argv) = 
56 let
57-    val manifest = fileref_open_exn("build.ninja", file_mode_r)
58+    val filename = argz(argc, argv)
59+    val manifest = fileref_open_exn(filename, file_mode_r)
60     (* initialize the scanner *)
61     var s: scanner = @{
62         file = manifest,
+2, -1
 1@@ -23,7 +23,7 @@ fun parts_free(p: List0_vt(stringpart)): void =
 2 
 3 fun binding_destroy(b: binding): void = 
 4     let
 5-        val @{key = k, value = v} = entry
 6+        val @{key = k, value = v} = b
 7     in
 8         strptr_free(k);
 9         parts_free (v)
10@@ -54,6 +54,7 @@ fun edge_destroy (e: edge): void =
11         strptr_free(r);
12         paths_free(i);
13         bindings_free(b)
14+    end
15 
16 fun edge_free(e: List0_vt(edge)): void = 
17      list_destroy<edge>(e, edge_destroy)