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