1 #!/usr/bin/awk -f
2
3 #
4 # Copyright (c) 1992, 1993
5 # The Regents of the University of California. All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # 3. All advertising materials mentioning features or use of this software
16 # must display the following acknowledgement:
17 # This product includes software developed by the University of
18 # California, Berkeley and its contributors.
19 # 4. Neither the name of the University nor the names of its contributors
20 # may be used to endorse or promote products derived from this software
21 # without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 # SUCH DAMAGE.
34 #
35 # @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
36 # $FreeBSD: releng/5.2/sys/tools/vnode_if.awk 116694 2003-06-22 21:20:06Z truckman $
37 #
38 # Script to produce VFS front-end sugar.
39 #
40 # usage: vnode_if.awk <srcfile> [-c | -h]
41 # (where <srcfile> is currently /sys/kern/vnode_if.src)
42 #
43
44 function usage()
45 {
46 print "usage: vnode_if.awk <srcfile> [-c|-h]";
47 exit 1;
48 }
49
50 function die(msg, what)
51 {
52 printf msg "\n", what > "/dev/stderr";
53 exit 1;
54 }
55
56 function t_spc(type)
57 {
58 # Append a space if the type is not a pointer
59 return (type ~ /\*$/) ? type : type " ";
60 }
61
62 # These are just for convenience ...
63 function printc(s) {print s > cfile;}
64 function printh(s) {print s > hfile;}
65
66 function add_debug_code(name, arg, pos)
67 {
68 if (arg == "vpp")
69 arg = "*vpp";
70 if (lockdata[name, arg, pos] && (lockdata[name, arg, pos] != "-")) {
71 if (arg ~ /^\*/) {
72 printh("\tif ("substr(arg, 2)" != NULL) {");
73 }
74 printh("\tASSERT_VI_UNLOCKED("arg", \""uname"\");");
75 # Add assertions for locking
76 if (lockdata[name, arg, pos] == "L")
77 printh("\tASSERT_VOP_LOCKED("arg", \""uname"\");");
78 else if (lockdata[name, arg, pos] == "U")
79 printh("\tASSERT_VOP_UNLOCKED("arg", \""uname"\");");
80 else if (0) {
81 # XXX More checks!
82 }
83 if (arg ~ /^\*/) {
84 printh("\t}");
85 }
86 }
87 }
88
89 function add_debug_pre(name)
90 {
91 if (lockdata[name, "pre"]) {
92 printh("#ifdef DEBUG_VFS_LOCKS");
93 printh("\t"lockdata[name, "pre"]"(&a);");
94 printh("#endif");
95 }
96 }
97
98 function add_debug_post(name)
99 {
100 if (lockdata[name, "post"]) {
101 printh("#ifdef DEBUG_VFS_LOCKS");
102 printh("\t"lockdata[name, "post"]"(&a, rc);");
103 printh("#endif");
104 }
105 }
106
107 function find_arg_with_type (type)
108 {
109 for (jj = 0; jj < numargs; jj++) {
110 if (types[jj] == type) {
111 return "VOPARG_OFFSETOF(struct " \
112 name "_args,a_" args[jj] ")";
113 }
114 }
115
116 return "VDESC_NO_OFFSET";
117 }
118
119 BEGIN{
120
121 # Process the command line
122 for (i = 1; i < ARGC; i++) {
123 arg = ARGV[i];
124 if (arg !~ /^-[ch]+$/ && arg !~ /\.src$/)
125 usage();
126 if (arg ~ /^-.*c/)
127 cfile = "vnode_if.c";
128 if (arg ~ /^-.*h/)
129 hfile = "vnode_if.h";
130 if (arg ~ /\.src$/)
131 srcfile = arg;
132 }
133 ARGC = 1;
134
135 if (!cfile && !hfile)
136 exit 0;
137
138 if (!srcfile)
139 usage();
140
141 common_head = \
142 "/*\n" \
143 " * This file is produced automatically.\n" \
144 " * Do not modify anything in here by hand.\n" \
145 " *\n" \
146 " * Created from $FreeBSD: releng/5.2/sys/tools/vnode_if.awk 116694 2003-06-22 21:20:06Z truckman $\n" \
147 " */\n" \
148 "\n";
149
150 if (hfile)
151 printh(common_head "extern struct vnodeop_desc vop_default_desc;");
152
153 if (cfile) {
154 printc(common_head \
155 "#include <sys/param.h>\n" \
156 "#include <sys/systm.h>\n" \
157 "#include <sys/vnode.h>\n" \
158 "\n" \
159 "struct vnodeop_desc vop_default_desc = {\n" \
160 " 1,\t\t\t/* special case, vop_default => 1 */\n" \
161 " \"default\",\n" \
162 " 0,\n" \
163 " NULL,\n" \
164 " VDESC_NO_OFFSET,\n" \
165 " VDESC_NO_OFFSET,\n" \
166 " VDESC_NO_OFFSET,\n" \
167 " VDESC_NO_OFFSET,\n" \
168 " NULL,\n" \
169 "};\n");
170 }
171
172 while ((getline < srcfile) > 0) {
173 if (NF == 0)
174 continue;
175 if ($1 ~ /^#%/) {
176 if (NF != 6 || $1 != "#%" || \
177 $2 !~ /^[a-z]+$/ || $3 !~ /^[a-z]+$/ || \
178 $4 !~ /^.$/ || $5 !~ /^.$/ || $6 !~ /^.$/)
179 continue;
180 if ($3 == "vpp")
181 $3 = "*vpp";
182 lockdata["vop_" $2, $3, "Entry"] = $4;
183 lockdata["vop_" $2, $3, "OK"] = $5;
184 lockdata["vop_" $2, $3, "Error"] = $6;
185 continue;
186 }
187
188 if ($1 ~ /^#!/) {
189 if (NF != 4 || $1 != "#!")
190 continue;
191 if ($3 != "pre" && $3 != "post")
192 continue;
193 lockdata["vop_" $2, $3] = $4;
194 continue;
195 }
196 if ($1 ~ /^#/)
197 continue;
198
199 # Get the function name.
200 name = $1;
201 uname = toupper(name);
202
203 # Start constructing a ktrpoint string
204 ctrstr = "\"" uname;
205 # Get the function arguments.
206 for (numargs = 0; ; ++numargs) {
207 if ((getline < srcfile) <= 0) {
208 die("Unable to read through the arguments for \"%s\"",
209 name);
210 }
211 if ($1 ~ /^\};/)
212 break;
213
214 # Delete comments, if any.
215 gsub (/\/\*.*\*\//, "");
216
217 # Condense whitespace and delete leading/trailing space.
218 gsub(/[[:space:]]+/, " ");
219 sub(/^ /, "");
220 sub(/ $/, "");
221
222 # Pick off direction.
223 if ($1 != "INOUT" && $1 != "IN" && $1 != "OUT")
224 die("No IN/OUT direction for \"%s\".", $0);
225 dirs[numargs] = $1;
226 sub(/^[A-Z]* /, "");
227
228 if ((reles[numargs] = $1) == "WILLRELE")
229 sub(/^[A-Z]* /, "");
230 else
231 reles[numargs] = "WONTRELE";
232
233 # kill trailing ;
234 if (sub(/;$/, "") < 1)
235 die("Missing end-of-line ; in \"%s\".", $0);
236
237 # pick off variable name
238 if ((argp = match($0, /[A-Za-z0-9_]+$/)) < 1)
239 die("Missing var name \"a_foo\" in \"%s\".", $0);
240 args[numargs] = substr($0, argp);
241 $0 = substr($0, 1, argp - 1);
242
243 # what is left must be type
244 # remove trailing space (if any)
245 sub(/ $/, "");
246 types[numargs] = $0;
247
248 # We can do a maximum of 6 arguments to CTR*
249 if (numargs <= 6) {
250 if (numargs == 0)
251 ctrstr = ctrstr "(" args[numargs];
252 else
253 ctrstr = ctrstr ", " args[numargs];
254 if (types[numargs] ~ /\*/)
255 ctrstr = ctrstr " 0x%lX";
256 else
257 ctrstr = ctrstr " %ld";
258 }
259 }
260 if (numargs > 6)
261 ctrargs = 6;
262 else
263 ctrargs = numargs;
264 ctrstr = "\tCTR" ctrargs "(KTR_VOP, " ctrstr ")\"";
265 for (i = 0; i < ctrargs; ++i)
266 ctrstr = ctrstr ", " args[i];
267 ctrstr = ctrstr ");";
268
269 if (hfile) {
270 # Print out the vop_F_args structure.
271 printh("struct "name"_args {\n\tstruct vnodeop_desc *a_desc;");
272 for (i = 0; i < numargs; ++i)
273 printh("\t" t_spc(types[i]) "a_" args[i] ";");
274 printh("};");
275
276 # Print out extern declaration.
277 printh("extern struct vnodeop_desc " name "_desc;");
278
279 # Print out function.
280 printh("static __inline int " uname "(");
281 for (i = 0; i < numargs; ++i) {
282 printh("\t" t_spc(types[i]) args[i] \
283 (i < numargs - 1 ? "," : ")"));
284 }
285 printh("{\n\tstruct " name "_args a;");
286 printh("\tint rc;");
287 printh("\ta.a_desc = VDESC(" name ");");
288 for (i = 0; i < numargs; ++i)
289 printh("\ta.a_" args[i] " = " args[i] ";");
290 for (i = 0; i < numargs; ++i)
291 add_debug_code(name, args[i], "Entry");
292 add_debug_pre(name);
293 printh("\trc = VCALL(" args[0] ", VOFFSET(" name "), &a);");
294 printh(ctrstr);
295 printh("if (rc == 0) {");
296 for (i = 0; i < numargs; ++i)
297 add_debug_code(name, args[i], "OK");
298 printh("} else {");
299 for (i = 0; i < numargs; ++i)
300 add_debug_code(name, args[i], "Error");
301 printh("}");
302 add_debug_post(name);
303 printh("\treturn (rc);\n}");
304 }
305
306 if (cfile) {
307 # Print out the vop_F_vp_offsets structure. This all depends
308 # on naming conventions and nothing else.
309 printc("static int " name "_vp_offsets[] = {");
310 # as a side effect, figure out the releflags
311 releflags = "";
312 vpnum = 0;
313 for (i = 0; i < numargs; i++) {
314 if (types[i] == "struct vnode *") {
315 printc("\tVOPARG_OFFSETOF(struct " name \
316 "_args,a_" args[i] "),");
317 if (reles[i] == "WILLRELE") {
318 releflags = releflags \
319 "|VDESC_VP" vpnum "_WILLRELE";
320 }
321 vpnum++;
322 }
323 }
324
325 sub(/^\|/, "", releflags);
326 printc("\tVDESC_NO_OFFSET");
327 printc("};");
328
329 # Print out the vnodeop_desc structure.
330 printc("struct vnodeop_desc " name "_desc = {");
331 # offset
332 printc("\t0,");
333 # printable name
334 printc("\t\"" name "\",");
335 # flags
336 vppwillrele = "";
337 for (i = 0; i < numargs; i++) {
338 if (types[i] == "struct vnode **" && \
339 reles[i] == "WILLRELE") {
340 vppwillrele = "|VDESC_VPP_WILLRELE";
341 }
342 }
343
344 if (!releflags)
345 releflags = "0";
346 printc("\t" releflags vppwillrele ",");
347
348 # vp offsets
349 printc("\t" name "_vp_offsets,");
350 # vpp (if any)
351 printc("\t" find_arg_with_type("struct vnode **") ",");
352 # cred (if any)
353 printc("\t" find_arg_with_type("struct ucred *") ",");
354 # thread (if any)
355 printc("\t" find_arg_with_type("struct thread *") ",");
356 # componentname
357 printc("\t" find_arg_with_type("struct componentname *") ",");
358 # transport layer information
359 printc("\tNULL,\n};\n");
360 }
361 }
362
363 if (hfile)
364 close(hfile);
365 if (cfile)
366 close(cfile);
367 close(srcfile);
368
369 exit 0;
370
371 }
Cache object: e9dbe0fe36d5832d78a4f66fc0a0c7eb
|