summaryrefslogtreecommitdiff
path: root/util.myr
blob: c4265762ae55f17dde3e51bb909abc79603a9640 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std

use "opts.use"

pkg bld =
	const run	: (cmd : byte[:][:] -> void)
	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 run = {cmd
	var pid

	printcmd(cmd)
	pid = std.fork()
	if pid == -1
		std.fatal(1, "could not fork command\n")
	elif pid == 0
		if std.execvp(cmd[0], cmd) < 0
			std.fatal(1, "failed to exec %s\n", cmd[0])
		;;
	else
		match std.wait(pid)
		| `std.Wsuccess:	/* nothing */
		| `std.Wfailure:	std.fatal(1, "FAIL: \"%s\"\n", std.strjoin(cmd, " "))
		| `std.Wsignalled:	std.fatal(1, "CRASH: \"%s\"\n", std.strjoin(cmd, " "))
		| `std.Waiterror:	std.fatal(1, "WAT: \"%s\"\n", std.strjoin(cmd, " "))
		;;
	;;
}

const printcmd = {lst
	if lst.len > 0
		std.put("\t")
		std.put("%s\t", lst[0])
		for l in lst[1:]
			std.put("%s ", l)
		;;
	;;
	std.put("\n")
}

const srcsplit = {src
	var platf, suff

	platf = ""
	suff = ""
	match std.strrfind(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("%s%s", f, newsuff)
}

const srcswapsuffix = {src, new
	var base, platf, suff

	(base, platf, suff) = srcsplit(src)
	if std.sleq(suff, ".myr")
		-> std.strcat(base, new)
	elif std.sleq(suff, ".s")
		-> std.strcat(base, new)
	else
		std.fatal(1, "unrecognized source %s\n", src)
	;;
}

const strlistfree = {sl
	for s in sl
		std.slfree(s)
	;;
	std.slfree(sl)
}