shithub: mc

ref: dc611e92af421149bc0277b199250966919fe7e7
dir: /mbld/util.myr/

View raw version
use std

use "opts"
use "types"

pkg bld =
	const run	: (cmd : byte[:][:] -> bool)
	const printcmd
	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 printcmd = {lst
	if lst.len > 0
		std.put("\t")
		std.put("{}\t", lst[0])
		for l in lst[1:]
			std.put("{} ", l)
		;;
	;;
	std.put("\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)
	;;
}