ref: a229550437b42fcddd9b79bf059a28130b2e74b1
dir: /mbld/util.myr/
use std use "opts" use "types" pkg bld = const run : (cmd : byte[:][:] -> bool) const printcmd : (cmd : byte[:][:] -> void) const mbldput : (fmt : byte[:], args : ... -> void) const srcsplit : (src : byte[:] -> (byte[:], byte[:], byte[:])) const swapsuffix : (f : byte[:], suff : byte[:], newsuff : byte[:] -> byte[:]) const srcswapsuffix : (f : byte[:], newsuff : byte[:] -> byte[:]) const strlistfree : (sl : byte[:][:] -> void) const gettarg : (tab : std.htab(byte[:], targ)#, n : byte[:] -> targ) const setdir : (b : build#, dir : byte[:] -> void) ;; const run = {cmd var pid printcmd(cmd) pid = std.fork() if pid == -1 std.fatal("could not fork command\n") -> false elif pid == 0 if std.execvp(cmd[0], cmd) < 0 std.fatal("failed to exec {}\n", cmd[0]) ;; -> false else match std.wait(pid) | `std.Wsuccess: -> true | `std.Wfailure: std.fatal("FAIL: \"{}\"\n", std.strjoin(cmd, " ")) | `std.Wsignalled: std.fatal("CRASH: \"{}\"\n", std.strjoin(cmd, " ")) | `std.Waiterror: std.fatal("WAT: \"{}\"\n", std.strjoin(cmd, " ")) ;; ;; } const mbldput = {fmt, args var ap if !opt_silent ap = std.vastart(&args) std.putv(fmt, &ap) ;; } const printcmd = {lst if lst.len > 0 mbldput("\t") mbldput("{}\t", lst[0]) for l in lst[1:] mbldput("{} ", l) ;; ;; mbldput("\n") } const srcsplit = {src var platf, suff platf = "" suff = "" match std.strfind(src, ".") | `std.Some i: suff = src[i:] src = src[:i] | `std.None: /* no suffix to trim */ ;; match std.strrfind(src, "+") | `std.Some i: platf = src[i:] src = src[:i] | `std.None: /* no platform to trim */ ;; -> (src, platf, suff) } const swapsuffix = {f, suff, newsuff if std.hassuffix(f, suff) f = f[:f.len - suff.len] ;; -> std.fmt("{}{}", f, newsuff) } const srcswapsuffix = {src, new var base, platf, suff (base, platf, suff) = srcsplit(src) if std.hassuffix(suff, ".myr") -> std.strcat(base, new) elif std.hassuffix(suff, ".s") -> std.strcat(base, new) elif std.hassuffix(suff, ".glue.c") -> std.strjoin([base, ".glue", new][:], "") else std.fatal("unrecognized source {}\n", src) ;; } const strlistfree = {sl for s in sl std.slfree(s) ;; std.slfree(sl) } const gettarg = {tab, n match std.htget(tab, n) | `std.None: std.fatal("unknown target '{}'\n", n) | `std.Some t: -> t ;; } const setdir = {b, dir var p if !std.sleq(b.curdir, dir) p = std.pathcat(b.basedir, dir) if !std.chdir(p) std.fatal("could not cd into {}\n", p) ;; b.curdir = dir std.slfree(p) ;; }