xref: /csrg-svn/sys/kern/makesyscalls.sh (revision 68295)
137326Skarels#! /bin/sh -
2*68295Scgd#
3*68295Scgd#	@(#)makesyscalls.sh	8.2 (Berkeley) 02/14/95
437326Skarels
543399Skarelsset -e
643399Skarels
7*68295Scgdcase $# in
8*68295Scgd    2)	;;
9*68295Scgd    *)	echo "Usage: $0 config-file input-file" 1>&2
10*68295Scgd	exit 1
11*68295Scgd	;;
12*68295Scgdesac
1337326Skarels
14*68295Scgd# source the config file.
15*68295Scgd. $1
1637326Skarels
17*68295Scgd# the config file sets the following variables:
18*68295Scgd#	sysnames	the syscall names file
19*68295Scgd#	sysnumhdr	the syscall numbers file
20*68295Scgd#	syssw		the syscall switch file
21*68295Scgd#	sysarghdr	the syscall argument struct definitions
22*68295Scgd#	compatopts	those syscall types that are for 'compat' syscalls
23*68295Scgd#	switchname	the name for the 'struct sysent' we define
24*68295Scgd#	namesname	the name for the 'char *[]' we define
25*68295Scgd#	constprefix	the prefix for the system call constants
26*68295Scgd#
27*68295Scgd# NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'.
28*68295Scgd
2937326Skarels# tmp files:
3037326Skarelssysdcl="sysent.dcl"
31*68295Scgdsyscompat_pref="sysent."
3237326Skarelssysent="sysent.switch"
3337326Skarels
34*68295Scgdsyscompat_files=""
35*68295Scgdfor file in $compatopts; do
36*68295Scgd	syscompat_files="$syscompat_files $syscompat_pref$file"
37*68295Scgddone
3843399Skarels
39*68295Scgdtrap "rm $sysdcl $syscompat_files $sysent" 0
4037326Skarels
41*68295Scgd# Awk program (must support nawk extensions)
42*68295Scgd# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
43*68295Scgdawk=${AWK:-awk}
4437326Skarels
45*68295Scgd# Does this awk have a "toupper" function? (i.e. is it GNU awk)
46*68295Scgdisgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
4737326Skarels
48*68295Scgd# If this awk does not define "toupper" then define our own.
49*68295Scgdif [ "$isgawk" = TRUE ] ; then
50*68295Scgd	# GNU awk provides it.
51*68295Scgd	toupper=
52*68295Scgdelse
53*68295Scgd	# Provide our own toupper()
54*68295Scgd	toupper='
55*68295Scgdfunction toupper(str) {
56*68295Scgd	_toupper_cmd = "echo "str" |tr a-z A-Z"
57*68295Scgd	_toupper_cmd | getline _toupper_str;
58*68295Scgd	close(_toupper_cmd);
59*68295Scgd	return _toupper_str;
60*68295Scgd}'
61*68295Scgdfi
6237326Skarels
63*68295Scgd# before handing it off to awk, make a few adjustments:
64*68295Scgd#	(1) insert spaces around {, }, (, ), *, and commas.
65*68295Scgd#	(2) get rid of any and all dollar signs (so that rcs id use safe)
66*68295Scgd#
67*68295Scgd# The awk script will deal with blank lines and lines that
68*68295Scgd# start with the comment character (';').
6937326Skarels
70*68295Scgdsed -e '
71*68295Scgds/\$//g
72*68295Scgd:join
73*68295Scgd	/\\$/{a\
74*68295Scgd
75*68295Scgd	N
76*68295Scgd	s/\\\n//
77*68295Scgd	b join
7838668Skarels	}
79*68295Scgd2,${
80*68295Scgd	/^#/!s/\([{}()*,]\)/ \1 /g
81*68295Scgd}
82*68295Scgd' < $2 | $awk "
83*68295Scgd$toupper
84*68295ScgdBEGIN {
85*68295Scgd	sysnames = \"$sysnames\"
86*68295Scgd	sysnumhdr = \"$sysnumhdr\"
87*68295Scgd	sysarghdr = \"$sysarghdr\"
88*68295Scgd	switchname = \"$switchname\"
89*68295Scgd	namesname = \"$namesname\"
90*68295Scgd	constprefix = \"$constprefix\"
9137326Skarels
92*68295Scgd	sysdcl = \"$sysdcl\"
93*68295Scgd	syscompat_pref = \"$syscompat_pref\"
94*68295Scgd	sysent = \"$sysent\"
95*68295Scgd	infile = \"$2\"
9637326Skarels
97*68295Scgd	compatopts = \"$compatopts\"
98*68295Scgd	"'
9937326Skarels
100*68295Scgd	printf "/*\n * System call switch table.\n *\n" > sysdcl
101*68295Scgd	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
102*68295Scgd
103*68295Scgd	ncompat = split(compatopts,compat)
104*68295Scgd	for (i = 1; i <= ncompat; i++) {
105*68295Scgd		compat_upper[i] = toupper(compat[i])
106*68295Scgd		compat_file[i] = sprintf("%s%s", syscompat_pref, compat[i])
107*68295Scgd
108*68295Scgd		printf "\n#ifdef %s\n", compat_upper[i] > compat_file[i]
109*68295Scgd		printf "#define %s(func) __CONCAT(%s_,func)\n\n", \
110*68295Scgd		    compat[i], compat[i] > compat_file[i]
11137326Skarels	}
112*68295Scgd
113*68295Scgd	printf "/*\n * System call names.\n *\n" > sysnames
114*68295Scgd	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
115*68295Scgd
116*68295Scgd	printf "/*\n * System call numbers.\n *\n" > sysnumhdr
117*68295Scgd	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr
118*68295Scgd
119*68295Scgd	printf "/*\n * System call argument lists.\n *\n" > sysarghdr
120*68295Scgd	printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr
121*68295Scgd}
122*68295ScgdNR == 1 {
123*68295Scgd	printf " * created from%s\n */\n\n", $0 > sysdcl
124*68295Scgd
125*68295Scgd	printf "#define\ts(type)\tsizeof(type)\n\n" > sysent
126*68295Scgd	printf "struct sysent %s[] = {\n",switchname > sysent
127*68295Scgd
128*68295Scgd	printf " * created from%s\n */\n\n", $0 > sysnames
129*68295Scgd	printf "char *%s[] = {\n",namesname > sysnames
130*68295Scgd
131*68295Scgd	printf " * created from%s\n */\n\n", $0 > sysnumhdr
132*68295Scgd
133*68295Scgd	printf " * created from%s\n */\n\n", $0 > sysarghdr
134*68295Scgd	printf "#define\tsyscallarg(x)\tunion { x datum; register_t pad; }\n" \
135*68295Scgd		> sysarghdr
136*68295Scgd	next
137*68295Scgd}
138*68295ScgdNF == 0 || $1 ~ /^;/ {
139*68295Scgd	next
140*68295Scgd}
141*68295Scgd$1 ~ /^#[ 	]*include/ {
142*68295Scgd	print > sysdcl
143*68295Scgd	next
144*68295Scgd}
145*68295Scgd$1 ~ /^#[ 	]*if/ {
146*68295Scgd	print > sysent
147*68295Scgd	print > sysdcl
148*68295Scgd	for (i = 1; i <= ncompat; i++)
149*68295Scgd		print > compat_file[i]
150*68295Scgd	print > sysnames
151*68295Scgd	savesyscall = syscall
152*68295Scgd	next
153*68295Scgd}
154*68295Scgd$1 ~ /^#[ 	]*else/ {
155*68295Scgd	print > sysent
156*68295Scgd	print > sysdcl
157*68295Scgd	for (i = 1; i <= ncompat; i++)
158*68295Scgd		print > compat_file[i]
159*68295Scgd	print > sysnames
160*68295Scgd	syscall = savesyscall
161*68295Scgd	next
162*68295Scgd}
163*68295Scgd$1 ~ /^#/ {
164*68295Scgd	print > sysent
165*68295Scgd	print > sysdcl
166*68295Scgd	for (i = 1; i <= ncompat; i++)
167*68295Scgd		print > compat_file[i]
168*68295Scgd	print > sysnames
169*68295Scgd	next
170*68295Scgd}
171*68295Scgdsyscall != $1 {
172*68295Scgd	printf "%s: line %d: syscall number out of sync at %d\n", \
173*68295Scgd	   infile, NR, syscall
174*68295Scgd	printf "line is:\n"
175*68295Scgd	print
176*68295Scgd	exit 1
177*68295Scgd}
178*68295Scgdfunction parserr(was, wanted) {
179*68295Scgd	printf "%s: line %d: unexpected %s (expected %s)\n", \
180*68295Scgd	    infile, NR, was, wanted
181*68295Scgd	exit 1
182*68295Scgd}
183*68295Scgdfunction parseline() {
184*68295Scgd	f=3			# toss number and type
185*68295Scgd	if ($NF != "}") {
186*68295Scgd		funcalias=$NF
187*68295Scgd		end=NF-1
188*68295Scgd	} else {
189*68295Scgd		funcalias=""
190*68295Scgd		end=NF
19137326Skarels	}
192*68295Scgd	if ($f != "{")
193*68295Scgd		parserr($f, "{")
194*68295Scgd	f++
195*68295Scgd	if ($end != "}")
196*68295Scgd		parserr($end, "}")
197*68295Scgd	end--
198*68295Scgd	if ($end != ";")
199*68295Scgd		parserr($end, ";")
200*68295Scgd	end--
201*68295Scgd	if ($end != ")")
202*68295Scgd		parserr($end, ")")
203*68295Scgd	end--
204*68295Scgd
205*68295Scgd	f++			# toss return type
206*68295Scgd
207*68295Scgd	funcname=$f
208*68295Scgd	if (funcalias == "")
209*68295Scgd		funcalias=funcname
210*68295Scgd	f++
211*68295Scgd
212*68295Scgd	if ($f != "(")
213*68295Scgd		parserr($f, ")")
214*68295Scgd	f++
215*68295Scgd
216*68295Scgd	argc= 0;
217*68295Scgd	if (f == end) {
218*68295Scgd		if ($f != "void")
219*68295Scgd			parserr($f, "argument definition")
220*68295Scgd		return
22138668Skarels	}
222*68295Scgd
223*68295Scgd	while (f <= end) {
224*68295Scgd		argc++
225*68295Scgd		argtype[argc]=""
226*68295Scgd		oldf=""
227*68295Scgd		while (f < end && $(f+1) != ",") {
228*68295Scgd			if (argtype[argc] != "" && oldf != "*")
229*68295Scgd				argtype[argc] = argtype[argc]" ";
230*68295Scgd			argtype[argc] = argtype[argc]$f;
231*68295Scgd			oldf = $f;
232*68295Scgd			f++
233*68295Scgd		}
234*68295Scgd		if (argtype[argc] == "")
235*68295Scgd			parserr($f, "argument definition")
236*68295Scgd		argname[argc]=$f;
237*68295Scgd		f += 2;			# skip name, and any comma
23838668Skarels	}
239*68295Scgd}
240*68295Scgdfunction putent(nodefs, declfile, compatwrap) {
241*68295Scgd	# output syscall declaration for switch table
242*68295Scgd	if (compatwrap == "")
243*68295Scgd		printf("int\t%s();\n", funcname) > declfile
244*68295Scgd	else
245*68295Scgd		printf("int\t%s(%s)();\n", compatwrap, funcname) > declfile
246*68295Scgd
247*68295Scgd	# output syscall switch entry
248*68295Scgd#	printf("\t{ { %d", argc) > sysent
249*68295Scgd#	for (i = 1; i <= argc; i++) {
250*68295Scgd#		if (i == 5) 		# wrap the line
251*68295Scgd#			printf(",\n\t    ") > sysent
252*68295Scgd#		else
253*68295Scgd#			printf(", ") > sysent
254*68295Scgd#		printf("s(%s)", argtypenospc[i]) > sysent
255*68295Scgd#	}
256*68295Scgd	printf("\t{ %d, ", argc) > sysent
257*68295Scgd	if (argc == 0)
258*68295Scgd		printf("0") > sysent
259*68295Scgd	else if (compatwrap == "")
260*68295Scgd		printf("s(struct %s_args)", funcname) > sysent
261*68295Scgd	else
262*68295Scgd		printf("s(struct %s_%s_args)", compatwrap, funcname) > sysent
263*68295Scgd	if (compatwrap == "")
264*68295Scgd		wfn = sprintf("%s", funcname);
265*68295Scgd	else
266*68295Scgd		wfn = sprintf("%s(%s)", compatwrap, funcname);
267*68295Scgd	printf(",\n\t    %s },", wfn) > sysent
268*68295Scgd	for (i = 0; i < (33 - length(wfn)) / 8; i++)
269*68295Scgd		printf("\t") > sysent
270*68295Scgd	if (compatwrap == "")
271*68295Scgd		printf("/* %d = %s */\n", syscall, funcalias) > sysent
272*68295Scgd	else
273*68295Scgd		printf("/* %d = %s %s */\n", syscall, compatwrap,
274*68295Scgd		    funcalias) > sysent
275*68295Scgd
276*68295Scgd	# output syscall name for names table
277*68295Scgd	if (compatwrap == "")
278*68295Scgd		printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall,
279*68295Scgd		    funcalias) > sysnames
280*68295Scgd	else
281*68295Scgd		printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap,
282*68295Scgd		    funcalias, syscall, compatwrap, funcalias) > sysnames
283*68295Scgd
284*68295Scgd	# output syscall number of header, if appropriate
285*68295Scgd	if (nodefs == "" || nodefs == "NOARGS")
286*68295Scgd		printf("#define\t%s%s\t%d\n", constprefix, funcalias,
287*68295Scgd		    syscall) > sysnumhdr
288*68295Scgd	else if (nodefs != "NODEF")
289*68295Scgd		printf("\t\t\t\t/* %d is %s %s */\n", syscall,
290*68295Scgd		    compatwrap, funcalias) > sysnumhdr
291*68295Scgd
292*68295Scgd	# output syscall argument structure, if it has arguments
293*68295Scgd	if (argc != 0 && nodefs != "NOARGS") {
294*68295Scgd		if (compatwrap == "")
295*68295Scgd			printf("\nstruct %s_args {\n", funcname) > sysarghdr
296*68295Scgd		else
297*68295Scgd			printf("\nstruct %s_%s_args {\n", compatwrap,
298*68295Scgd			    funcname) > sysarghdr
299*68295Scgd		for (i = 1; i <= argc; i++)
300*68295Scgd			printf("\tsyscallarg(%s) %s;\n", argtype[i],
301*68295Scgd			    argname[i]) > sysarghdr
302*68295Scgd		printf("};\n") > sysarghdr
30338668Skarels	}
304*68295Scgd}
305*68295Scgd$2 == "STD" {
306*68295Scgd	parseline()
307*68295Scgd	putent("", sysdcl, "")
308*68295Scgd	syscall++
309*68295Scgd	next
310*68295Scgd}
311*68295Scgd$2 == "NODEF" || $2 == "NOARGS" {
312*68295Scgd	parseline()
313*68295Scgd	putent($2, sysdcl, "")
314*68295Scgd	syscall++
315*68295Scgd	next
316*68295Scgd}
317*68295Scgd$2 == "OBSOL" || $2 == "UNIMPL" {
318*68295Scgd	if ($2 == "OBSOL")
319*68295Scgd		comment="obsolete"
320*68295Scgd	else
321*68295Scgd		comment="unimplemented"
322*68295Scgd	for (i = 3; i <= NF; i++)
323*68295Scgd		comment=comment " " $i
324*68295Scgd
325*68295Scgd	printf("\t{ 0, 0,\n\t    nosys },\t\t\t\t/* %d = %s */\n", \
326*68295Scgd	    syscall, comment) > sysent
327*68295Scgd	printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \
328*68295Scgd	    syscall, comment, syscall, comment) > sysnames
329*68295Scgd	if ($2 != "UNIMPL")
330*68295Scgd		printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr
331*68295Scgd	syscall++
332*68295Scgd	next
333*68295Scgd}
334*68295Scgd{
335*68295Scgd	for (i = 1; i <= ncompat; i++) {
336*68295Scgd		if ($2 == compat_upper[i]) {
337*68295Scgd			parseline();
338*68295Scgd			putent("COMMENT", compat_file[i], compat[i])
339*68295Scgd			syscall++
340*68295Scgd			next
341*68295Scgd		}
34238668Skarels	}
343*68295Scgd	printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
344*68295Scgd	exit 1
345*68295Scgd}
346*68295ScgdEND {
347*68295Scgd	printf "\n#undef\tsyscallarg\n" > sysarghdr
34837326Skarels
349*68295Scgd        for (i = 1; i <= ncompat; i++) {
350*68295Scgd		printf("\n#else /* %s */\n", compat_upper[i]) > compat_file[i]
351*68295Scgd		printf("#define %s(func) nosys\n", compat[i]) > \
352*68295Scgd		    compat_file[i]
353*68295Scgd		printf("#endif /* %s */\n\n", compat_upper[i]) > compat_file[i]
354*68295Scgd        }
35537326Skarels
356*68295Scgd	printf("};\n\n") > sysent
357*68295Scgd	printf("int\tn%s= sizeof(%s) / sizeof(%s[0]);\n", switchname,
358*68295Scgd	    switchname, switchname) > sysent
35937326Skarels
360*68295Scgd	printf("};\n") > sysnames
361*68295Scgd} '
36238668Skarels
363*68295Scgdcat $sysdcl $syscompat_files $sysent > $syssw
364*68295Scgd
365*68295Scgd#chmod 444 $sysnames $syshdr $syssw
366