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