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