xref: /freebsd/sys/tools/vnode_if.awk (revision 7f3dea244c40159a41ab22da77a434d7c5b5e85a)
1#!/bin/sh -
2#
3# Copyright (c) 1992, 1993
4#	The Regents of the University of California.  All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14# 3. All advertising materials mentioning features or use of this software
15#    must display the following acknowledgement:
16#	This product includes software developed by the University of
17#	California, Berkeley and its contributors.
18# 4. Neither the name of the University nor the names of its contributors
19#    may be used to endorse or promote products derived from this software
20#    without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32# SUCH DAMAGE.
33#
34#	@(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
35# $Id: vnode_if.sh,v 1.17 1999/02/28 11:30:00 bde Exp $
36#
37
38# Script to produce VFS front-end sugar.
39#
40# usage: vnode_if.sh srcfile
41#	(where srcfile is currently /sys/kern/vnode_if.src)
42#
43# These awk scripts are not particularly well written, specifically they
44# don't use arrays well and figure out the same information repeatedly.
45# Please rewrite them if you actually understand how to use awk.  Note,
46# they use nawk extensions and gawk's toupper.
47
48if [ $# -ne 1 ] ; then
49	echo 'usage: vnode_if.sh srcfile'
50	exit 1
51fi
52
53# Name of the source file.
54SRC=$1
55
56# Names of the created files.
57CFILE=vnode_if.c
58HEADER=vnode_if.h
59
60# Awk program (must support nawk extensions and gawk's "toupper")
61# Use "awk" at Berkeley, "gawk" elsewhere.
62AWK=awk
63
64# Print out header information for vnode_if.h.
65cat << END_OF_LEADING_COMMENT > $HEADER
66/*
67 * This file is produced automatically.
68 * Do not modify anything in here by hand.
69 *
70 * Created from @(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
71 */
72
73extern struct vnodeop_desc vop_default_desc;
74END_OF_LEADING_COMMENT
75
76# Awk script to take vnode_if.src and turn it into vnode_if.h.
77$AWK '
78	NF == 0 || $0 ~ "^#" {
79		next;
80	}
81	{
82		# Get the function name.
83		name = $1;
84		uname = toupper(name);
85
86		# Get the function arguments.
87		for (c1 = 0;; ++c1) {
88			if (getline <= 0)
89				exit
90			if ($0 ~ "^};")
91				break;
92			a[c1] = $0;
93		}
94
95		# Print out the vop_F_args structure.
96		printf("struct %s_args {\n\tstruct vnodeop_desc *a_desc;\n",
97		    name);
98		for (c2 = 0; c2 < c1; ++c2) {
99			c3 = split(a[c2], t);
100			printf("\t");
101			if (t[2] ~ "WILLRELE")
102				c4 = 3;
103			else
104				c4 = 2;
105			for (; c4 < c3; ++c4)
106				printf("%s ", t[c4]);
107			beg = match(t[c3], "[^*]");
108			printf("%sa_%s\n",
109			    substr(t[c4], 0, beg - 1), substr(t[c4], beg));
110		}
111		printf("};\n");
112
113		# Print out extern declaration.
114		printf("extern struct vnodeop_desc %s_desc;\n", name);
115
116		# Print out prototype.
117		printf("static __inline int %s __P((\n", uname);
118		sep = ",\n";
119		for (c2 = 0; c2 < c1; ++c2) {
120			if (c2 == c1 - 1)
121				sep = "));\n";
122			c3 = split(a[c2], t);
123			printf("\t");
124			if (t[2] ~ "WILLRELE")
125				c4 = 3;
126			else
127				c4 = 2;
128			for (; c4 < c3; ++c4)
129				printf("%s ", t[c4]);
130			beg = match(t[c3], "[^*]");
131			end = match(t[c3], ";");
132			printf("%s%s%s",
133			    substr(t[c4], 0, beg - 1),
134			    substr(t[c4], beg, end - beg), sep);
135		}
136
137		# Print out function.
138		printf("static __inline int %s(", uname);
139		sep = ", ";
140		for (c2 = 0; c2 < c1; ++c2) {
141			if (c2 == c1 - 1)
142				sep = ")\n";
143			c3 = split(a[c2], t);
144			beg = match(t[c3], "[^*]");
145			end = match(t[c3], ";");
146			printf("%s%s", substr(t[c3], beg, end - beg), sep);
147		}
148		for (c2 = 0; c2 < c1; ++c2) {
149			c3 = split(a[c2], t);
150			printf("\t");
151			if (t[2] ~ "WILLRELE")
152				c4 = 3;
153			else
154				c4 = 2;
155			for (; c4 < c3; ++c4)
156				printf("%s ", t[c4]);
157			beg = match(t[c3], "[^*]");
158			printf("%s%s\n",
159			    substr(t[c4], 0, beg - 1), substr(t[c4], beg));
160		}
161		printf("{\n\tstruct %s_args a;\n\n", name);
162		printf("\ta.a_desc = VDESC(%s);\n", name);
163		for (c2 = 0; c2 < c1; ++c2) {
164			c3 = split(a[c2], t);
165			printf("\t");
166			beg = match(t[c3], "[^*]");
167			end = match(t[c3], ";");
168			printf("a.a_%s = %s\n",
169			    substr(t[c3], beg, end - beg), substr(t[c3], beg));
170		}
171		c1 = split(a[0], t);
172		beg = match(t[c1], "[^*]");
173		end = match(t[c1], ";");
174		printf("\treturn (VCALL(%s, VOFFSET(%s), &a));\n}\n",
175		    substr(t[c1], beg, end - beg), name);
176	}' < $SRC >> $HEADER
177
178# Print out header information for vnode_if.c.
179cat << END_OF_LEADING_COMMENT > $CFILE
180/*
181 * This file is produced automatically.
182 * Do not modify anything in here by hand.
183 *
184 * Created from @(#)vnode_if.sh	8.1 (Berkeley) 6/10/93
185 */
186
187#include <sys/param.h>
188#include <sys/vnode.h>
189
190struct vnodeop_desc vop_default_desc = {
191	1,			/* special case, vop_default => 1 */
192	"default",
193	0,
194	NULL,
195	VDESC_NO_OFFSET,
196	VDESC_NO_OFFSET,
197	VDESC_NO_OFFSET,
198	VDESC_NO_OFFSET,
199	NULL,
200};
201
202END_OF_LEADING_COMMENT
203
204# Awk script to take vnode_if.src and turn it into vnode_if.c.
205$AWK 'function kill_surrounding_ws (s) {
206		sub (/^[ \t]*/, "", s);
207		sub (/[ \t]*$/, "", s);
208		return s;
209	}
210
211	function read_args() {
212		numargs = 0;
213		while (getline ln) {
214			if (ln ~ /}/) {
215				break;
216			};
217
218			# Delete comments, if any.
219			gsub (/\/\*.*\*\//, "", ln);
220
221			# Delete leading/trailing space.
222			ln = kill_surrounding_ws(ln);
223
224			# Pick off direction.
225			if (1 == sub(/^INOUT[ \t]+/, "", ln))
226				dir = "INOUT";
227			else if (1 == sub(/^IN[ \t]+/, "", ln))
228				dir = "IN";
229			else if (1 == sub(/^OUT[ \t]+/, "", ln))
230				dir = "OUT";
231			else
232				bail("No IN/OUT direction for \"" ln "\".");
233
234			# check for "WILLRELE"
235			if (1 == sub(/^WILLRELE[ \t]+/, "", ln)) {
236				rele = "WILLRELE";
237			} else {
238				rele = "WONTRELE";
239			};
240
241			# kill trailing ;
242			if (1 != sub (/;$/, "", ln)) {
243				bail("Missing end-of-line ; in \"" ln "\".");
244			};
245
246			# pick off variable name
247			if (!(i = match(ln, /[A-Za-z0-9_]+$/))) {
248				bail("Missing var name \"a_foo\" in \"" ln "\".");
249			};
250			arg = substr (ln, i);
251			# Want to <<substr(ln, i) = "";>>, but nawk cannot.
252			# Hack around this.
253			ln = substr(ln, 1, i-1);
254
255			# what is left must be type
256			# (put clean it up some)
257			type = ln;
258			gsub (/[ \t]+/, " ", type);   # condense whitespace
259			type = kill_surrounding_ws(type);
260
261			# (boy this was easier in Perl)
262
263			numargs++;
264			dirs[numargs] = dir;
265			reles[numargs] = rele;
266			types[numargs] = type;
267			args[numargs] = arg;
268		};
269	}
270
271	function generate_operation_vp_offsets() {
272		printf ("static int %s_vp_offsets[] = {\n", name);
273		# as a side effect, figure out the releflags
274		releflags = "";
275		vpnum = 0;
276		for (i=1; i<=numargs; i++) {
277			if (types[i] == "struct vnode *") {
278				printf ("\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n",
279					name, args[i]);
280				if (reles[i] == "WILLRELE") {
281					releflags = releflags "|VDESC_VP" vpnum "_WILLRELE";
282				};
283				vpnum++;
284			};
285		};
286		sub (/^\|/, "", releflags);
287		print "\tVDESC_NO_OFFSET";
288		print "};";
289	}
290
291	function find_arg_with_type (type) {
292		for (i=1; i<=numargs; i++) {
293			if (types[i] == type) {
294				return "VOPARG_OFFSETOF(struct " name "_args,a_" args[i] ")";
295			};
296		};
297		return "VDESC_NO_OFFSET";
298	}
299
300	function generate_operation_desc() {
301		printf ("struct vnodeop_desc %s_desc = {\n", name);
302		# offset
303		printf ("\t0,\n");
304		# printable name
305		printf ("\t\"%s\",\n", name);
306		# flags
307		vppwillrele = "";
308		for (i=1; i<=numargs; i++) {
309			if (types[i] == "struct vnode **" &&
310				(reles[i] == "WILLRELE")) {
311				vppwillrele = "|VDESC_VPP_WILLRELE";
312			};
313		};
314		if (releflags == "") {
315			printf ("\t0%s,\n", vppwillrele);
316		} else {
317			printf ("\t%s%s,\n", releflags, vppwillrele);
318		};
319		# vp offsets
320		printf ("\t%s_vp_offsets,\n", name);
321		# vpp (if any)
322		printf ("\t%s,\n", find_arg_with_type("struct vnode **"));
323		# cred (if any)
324		printf ("\t%s,\n", find_arg_with_type("struct ucred *"));
325		# proc (if any)
326		printf ("\t%s,\n", find_arg_with_type("struct proc *"));
327		# componentname
328		printf ("\t%s,\n", find_arg_with_type("struct componentname *"));
329		# transport layer information
330		printf ("\tNULL,\n};\n");
331	}
332
333	NF == 0 || $0 ~ "^#" {
334		next;
335	}
336	{
337		# get the function name
338		name = $1;
339
340		# get the function arguments
341		read_args();
342
343		# Print out the vop_F_vp_offsets structure.  This all depends
344		# on naming conventions and nothing else.
345		generate_operation_vp_offsets();
346
347		# Print out the vnodeop_desc structure.
348		generate_operation_desc();
349
350		printf "\n";
351
352	}' < $SRC >> $CFILE
353