summaryrefslogtreecommitdiff
path: root/src/user/lib/syscall.c.awk
blob: 192df6ac51b7abbb5b53a66bc2987edbeb758024 (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
BEGIN {
	print "\
/* generated by syscall.c.awk\n\
 * don't modify manually, instead run:\n\
 *     make src/user/lib/syscall.c\n\
 */\n\
#include <camellia/syscalls.h>\n\
\n";
}

/_syscall\(/ { next; } # skipping _syscall(), it's implemented elsewhere

/\);/ {
	sub(/;/, " {");
	print $0;

	name = substr($0, match($0, /_syscall_[^(]+/), RLENGTH);
	rets = substr($0, 0, RSTART - 1);
	sub(/ *$/, "", rets)

	params = substr($0, match($0, /\(.+\)/) + 1, RLENGTH - 2);
	gsub(/\[[^\]]\]/, "", params);
	if (params == "void") params = ""

	split(params, p, /,/);
	for (i = 0; i < 6; i += 1) {
		if (p[i]) {
			# p[i] is a parameter, convert it into an expression to pass to _syscall()
			sub(/^ */, "", p[i]); # strip
			split(p[i], words, / /);
			if (length(words) != 1) {
				var = words[length(words)];
				sub(/\*/, "", var);
				if (words[1] != "long") var = "(long)" var;
			}
			p[i] = var;
		} else {
			p[i] = 0;
		}
	}

	printf "\t";
	if (!index($0, "_Noreturn")) {
		printf "return ";
		if (rets != "long") printf "(%s)", rets;
	}
	printf "_syscall(%s, %s, %s, %s, %s, %s);\n", toupper(name), p[1], p[2], p[3], p[4], p[5];
	if (index($0, "_Noreturn")) print "\t__builtin_unreachable();";

	print "}\n";
}