summaryrefslogtreecommitdiff
path: root/mbld/util.myr
blob: bef6321f15e3932138badf64129bb2d7e1332a55 (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
use std

use "opts"
use "types"

pkg bld =
	const run	: (cmd : byte[:][:], dir : byte[:] -> std.pid)
	const mbldput	: (fmt : byte[:], args : ... -> void)
	const srcsplit	: (src : byte[:] -> (byte[:], byte[:], byte[:]))
	const changesuffix	: (f : byte[:], newsuff : byte[:] -> byte[:])
	const gettarg	: (tab : std.htab(byte[:], targ)#, n : byte[:] -> targ)
;;

const run = {cmd, dir
	var pid

	std.assert(cmd.len != 0, "empty command\n")
	mbldput("\t{j= }\n", cmd);
	pid = std.fork()
	if pid == -1
		std.fatal("could not fork command\n")
	elif pid == 0
		if dir.len != 0
			std.chdir(dir)
		;;
		if std.execvp(cmd[0], cmd) < 0
			std.fatal("failed to exec {}\n", cmd[0])
		;;
	;;
	-> pid
}

const mbldput = {fmt, args
	var ap

	if !opt_silent
		ap = std.vastart(&args)
		std.putv(fmt, &ap)
	;;
}

const srcsplit = {src
	var platf, fbase, suff

	platf = ""
	suff = ""

	match std.strrfind(src, "/")
	| `std.Some i:	fbase = i
	| `std.None:	fbase = 0
	;;
	match std.strfind(src[fbase:], ".")
	| `std.None: /* no suffix to trim */
	| `std.Some i:
		suff = src[fbase+i:]
		src = src[:fbase+i]
	;;

	match std.strrfind(src[fbase:], "+")
	| `std.None: /* no platform to trim */
	| `std.Some i:
		platf = src[fbase+i:]
		src = src[:fbase+i]
	;;
	-> (src, platf, suff)
}

const changesuffix = {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][:], "")
	elif std.hassuffix(src, ".o") || std.hassuffix(src, ".6")
		-> std.sldup(src)
	else
		std.fatal("unrecognized source {}\n", src)
	;;
}

const gettarg = {tab, n
	match std.htget(tab, n)
	| `std.None:	std.fatal("unknown target '{}'\n", n)
	| `std.Some t:	-> t
	;;
}