xref: /f-stack/freebsd/tools/makeobjops.awk (revision 22ce4aff)
1a9643ea8Slogwang#!/usr/bin/awk -f
2a9643ea8Slogwang
3a9643ea8Slogwang#-
4*22ce4affSfengbojiang# SPDX-License-Identifier: BSD-3-Clause
5*22ce4affSfengbojiang#
6a9643ea8Slogwang# Copyright (c) 1992, 1993
7a9643ea8Slogwang#        The Regents of the University of California.  All rights reserved.
8a9643ea8Slogwang#
9a9643ea8Slogwang# Redistribution and use in source and binary forms, with or without
10a9643ea8Slogwang# modification, are permitted provided that the following conditions
11a9643ea8Slogwang# are met:
12a9643ea8Slogwang# 1. Redistributions of source code must retain the above copyright
13a9643ea8Slogwang#    notice, this list of conditions and the following disclaimer.
14a9643ea8Slogwang# 2. Redistributions in binary form must reproduce the above copyright
15a9643ea8Slogwang#    notice, this list of conditions and the following disclaimer in the
16a9643ea8Slogwang#    documentation and/or other materials provided with the distribution.
17*22ce4affSfengbojiang# 3. Neither the name of the University nor the names of its contributors
18a9643ea8Slogwang#    may be used to endorse or promote products derived from this software
19a9643ea8Slogwang#    without specific prior written permission.
20a9643ea8Slogwang#
21a9643ea8Slogwang# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22a9643ea8Slogwang# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23a9643ea8Slogwang# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24a9643ea8Slogwang# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25a9643ea8Slogwang# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26a9643ea8Slogwang# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27a9643ea8Slogwang# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28a9643ea8Slogwang# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29a9643ea8Slogwang# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30a9643ea8Slogwang# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31a9643ea8Slogwang# SUCH DAMAGE.
32a9643ea8Slogwang#
33a9643ea8Slogwang# From @(#)vnode_if.sh        8.1 (Berkeley) 6/10/93
34a9643ea8Slogwang# From @(#)makedevops.sh 1.1 1998/06/14 13:53:12 dfr Exp $
35a9643ea8Slogwang# From @(#)makedevops.sh ?.? 1998/10/05
36a9643ea8Slogwang# From src/sys/kern/makedevops.pl,v 1.12 1999/11/22 14:40:04 n_hibma Exp
37a9643ea8Slogwang# From src/sys/kern/makeobjops.pl,v 1.8 2001/11/16 02:02:42 joe Exp
38a9643ea8Slogwang#
39a9643ea8Slogwang# $FreeBSD$
40a9643ea8Slogwang
41a9643ea8Slogwang#
42a9643ea8Slogwang#   Script to produce kobj front-end sugar.
43a9643ea8Slogwang#
44a9643ea8Slogwang
45a9643ea8Slogwangfunction usage ()
46a9643ea8Slogwang{
47a9643ea8Slogwang	print "usage: makeobjops.awk <srcfile.m> [-d] [-p] [-l <nr>] [-c|-h]";
48a9643ea8Slogwang	print "where -c   produce only .c files";
49a9643ea8Slogwang	print "      -h   produce only .h files";
50a9643ea8Slogwang	print "      -p   use the path component in the source file for destination dir";
51a9643ea8Slogwang	print "      -l   set line width for output files [80]";
52a9643ea8Slogwang	print "      -d   switch on debugging";
53a9643ea8Slogwang	exit 1;
54a9643ea8Slogwang}
55a9643ea8Slogwang
56a9643ea8Slogwangfunction warn (msg)
57a9643ea8Slogwang{
58a9643ea8Slogwang	print "makeobjops.awk:", msg > "/dev/stderr";
59a9643ea8Slogwang}
60a9643ea8Slogwang
61a9643ea8Slogwangfunction warnsrc (msg)
62a9643ea8Slogwang{
63a9643ea8Slogwang	warn(src ":" lineno ": " msg);
64a9643ea8Slogwang}
65a9643ea8Slogwang
66a9643ea8Slogwangfunction debug (msg)
67a9643ea8Slogwang{
68a9643ea8Slogwang	if (opt_d)
69a9643ea8Slogwang		warn(msg);
70a9643ea8Slogwang}
71a9643ea8Slogwang
72a9643ea8Slogwangfunction die (msg)
73a9643ea8Slogwang{
74a9643ea8Slogwang	warn(msg);
75a9643ea8Slogwang	exit 1;
76a9643ea8Slogwang}
77a9643ea8Slogwang
78a9643ea8Slogwang#   These are just for convenience ...
79a9643ea8Slogwangfunction printc(s) {if (opt_c) print s > ctmpfilename;}
80a9643ea8Slogwangfunction printh(s) {if (opt_h) print s > htmpfilename;}
81a9643ea8Slogwang
82a9643ea8Slogwang#
83a9643ea8Slogwang#   If a line exceeds maxlength, split it into multiple
84a9643ea8Slogwang#   lines at commas.  Subsequent lines are indented by
85a9643ea8Slogwang#   the specified number of spaces.
86a9643ea8Slogwang#
87a9643ea8Slogwang#   In other words:  Lines are split by replacing ", "
88a9643ea8Slogwang#   by ",\n" plus indent spaces.
89a9643ea8Slogwang#
90a9643ea8Slogwang
91a9643ea8Slogwangfunction format_line (line, maxlength, indent)
92a9643ea8Slogwang{
93a9643ea8Slogwang	rline = "";
94a9643ea8Slogwang
95a9643ea8Slogwang	while (length(line) > maxlength) {
96a9643ea8Slogwang		#
97a9643ea8Slogwang		#   Find the rightmost ", " so that the part
98a9643ea8Slogwang		#   to the left of it is just within maxlength.
99a9643ea8Slogwang		#   If there is none, give up and leave it as-is.
100a9643ea8Slogwang		#
101a9643ea8Slogwang		if (!match(substr(line, 1, maxlength + 1), /^.*, /))
102a9643ea8Slogwang			break;
103a9643ea8Slogwang		rline = rline substr(line, 1, RLENGTH - 1) "\n";
104a9643ea8Slogwang		line = sprintf("%*s", indent, "") substr(line, RLENGTH + 1);
105a9643ea8Slogwang	}
106a9643ea8Slogwang	return rline line;
107a9643ea8Slogwang}
108a9643ea8Slogwang
109a9643ea8Slogwang#
110a9643ea8Slogwang#   Join an array into a string.
111a9643ea8Slogwang#
112a9643ea8Slogwang
113a9643ea8Slogwangfunction join (separator, array, num)
114a9643ea8Slogwang{
115a9643ea8Slogwang	_result = ""
116a9643ea8Slogwang	if (num) {
117a9643ea8Slogwang		while (num > 1)
118a9643ea8Slogwang			_result = separator array[num--] _result;
119a9643ea8Slogwang		_result = array[1] _result;
120a9643ea8Slogwang	}
121a9643ea8Slogwang	return _result;
122a9643ea8Slogwang}
123a9643ea8Slogwang
124a9643ea8Slogwang#
125a9643ea8Slogwang#   Execute a system command and report if it failed.
126a9643ea8Slogwang#
127a9643ea8Slogwang
128a9643ea8Slogwangfunction system_check (cmd)
129a9643ea8Slogwang{
130a9643ea8Slogwang	if ((rc = system(cmd)))
131a9643ea8Slogwang		warn(cmd " failed (" rc ")");
132a9643ea8Slogwang}
133a9643ea8Slogwang
134a9643ea8Slogwang#
135a9643ea8Slogwang#   Handle "INTERFACE" line.
136a9643ea8Slogwang#
137a9643ea8Slogwang
138a9643ea8Slogwangfunction handle_interface ()
139a9643ea8Slogwang{
140a9643ea8Slogwang	intname = $2;
141a9643ea8Slogwang	sub(/;$/, "", intname);
142a9643ea8Slogwang	if (intname !~ /^[a-z_][a-z0-9_]*$/) {
143a9643ea8Slogwang		debug($0);
144a9643ea8Slogwang		warnsrc("Invalid interface name '" intname "', use [a-z_][a-z0-9_]*");
145a9643ea8Slogwang		error = 1;
146a9643ea8Slogwang		return;
147a9643ea8Slogwang	}
148a9643ea8Slogwang	if (!/;[ 	]*$/)
149a9643ea8Slogwang		warnsrc("Semicolon missing at end of line, no problem");
150a9643ea8Slogwang
151a9643ea8Slogwang	debug("Interface " intname);
152a9643ea8Slogwang
153a9643ea8Slogwang	printh("#ifndef _" intname "_if_h_");
154a9643ea8Slogwang	printh("#define _" intname "_if_h_\n");
155a9643ea8Slogwang	printc("#include \"" intname "_if.h\"\n");
156a9643ea8Slogwang}
157a9643ea8Slogwang
158a9643ea8Slogwang#
159a9643ea8Slogwang# Pass doc comments through to the C file
160a9643ea8Slogwang#
161a9643ea8Slogwangfunction handle_doc ()
162a9643ea8Slogwang{
163a9643ea8Slogwang	doc = ""
164a9643ea8Slogwang	while (!/\*\//) {
165a9643ea8Slogwang		doc = doc $0 "\n";
166a9643ea8Slogwang		getline < src;
167a9643ea8Slogwang		lineno++;
168a9643ea8Slogwang	}
169a9643ea8Slogwang	doc = doc $0 "\n";
170a9643ea8Slogwang	return doc;
171a9643ea8Slogwang}
172a9643ea8Slogwang
173a9643ea8Slogwang#
174a9643ea8Slogwang#   Handle "CODE" and "HEADER" sections.
175a9643ea8Slogwang#   Returns the code as-is.
176a9643ea8Slogwang#
177a9643ea8Slogwang
178a9643ea8Slogwangfunction handle_code ()
179a9643ea8Slogwang{
180a9643ea8Slogwang	code = "\n";
181a9643ea8Slogwang	getline < src;
182a9643ea8Slogwang	indent = $0;
183a9643ea8Slogwang	sub(/[^	 ].*$/, "", indent);	# find the indent used
184a9643ea8Slogwang	while (!/^}/) {
185a9643ea8Slogwang		sub("^" indent, "");	# remove the indent
186a9643ea8Slogwang		code = code $0 "\n";
187a9643ea8Slogwang		getline < src;
188a9643ea8Slogwang		lineno++;;
189a9643ea8Slogwang	}
190a9643ea8Slogwang	return code;
191a9643ea8Slogwang}
192a9643ea8Slogwang
193a9643ea8Slogwang#
194a9643ea8Slogwang#   Handle "METHOD" and "STATICMETHOD" sections.
195a9643ea8Slogwang#
196a9643ea8Slogwang
197a9643ea8Slogwangfunction handle_method (static, doc)
198a9643ea8Slogwang{
199a9643ea8Slogwang	#
200a9643ea8Slogwang	#   Get the return type and function name and delete that from
201a9643ea8Slogwang	#   the line. What is left is the possibly first function argument
202a9643ea8Slogwang	#   if it is on the same line.
203a9643ea8Slogwang	#
204a9643ea8Slogwang	if (!intname) {
205a9643ea8Slogwang		warnsrc("No interface name defined");
206a9643ea8Slogwang		error = 1;
207a9643ea8Slogwang		return;
208a9643ea8Slogwang	}
209a9643ea8Slogwang	sub(/^[^ 	]+[ 	]+/, "");
210a9643ea8Slogwang	ret = $0;
211a9643ea8Slogwang	sub(/[ 	]*\{.*$/, "", ret);
212a9643ea8Slogwang	name = ret;
213a9643ea8Slogwang	sub(/^.*[ 	]/, "", name);	# last element is name of method
214a9643ea8Slogwang	sub(/[ 	]+[^ 	]+$/, "", ret);	# return type
215a9643ea8Slogwang	debug("Method: name=" name " return type=" ret);
216a9643ea8Slogwang
217a9643ea8Slogwang	sub(/^[^\{]*\{[	 ]*/, "");
218a9643ea8Slogwang
219a9643ea8Slogwang	if (!name || !ret) {
220a9643ea8Slogwang		debug($0);
221a9643ea8Slogwang		warnsrc("Invalid method specification");
222a9643ea8Slogwang		error = 1;
223a9643ea8Slogwang		return;
224a9643ea8Slogwang	}
225a9643ea8Slogwang
226a9643ea8Slogwang	if (name !~ /^[a-z_][a-z_0-9]*$/) {
227a9643ea8Slogwang		warnsrc("Invalid method name '" name "', use [a-z_][a-z0-9_]*");
228a9643ea8Slogwang		error = 1;
229a9643ea8Slogwang		return;
230a9643ea8Slogwang	}
231a9643ea8Slogwang
232a9643ea8Slogwang	if (methods[name]) {
233a9643ea8Slogwang		warnsrc("Duplicate method name");
234a9643ea8Slogwang		error = 1;
235a9643ea8Slogwang		return;
236a9643ea8Slogwang	}
237a9643ea8Slogwang	methods[name] = name;
238a9643ea8Slogwang
239a9643ea8Slogwang	line = $0;
240a9643ea8Slogwang	while (line !~ /\}/ && (getline < src) > 0) {
241a9643ea8Slogwang		line = line " " $0;
242a9643ea8Slogwang		lineno++
243a9643ea8Slogwang	}
244a9643ea8Slogwang
245a9643ea8Slogwang	default_function = "";
246a9643ea8Slogwang	if (!match(line, /\};?/)) {
247a9643ea8Slogwang		warnsrc("Premature end of file");
248a9643ea8Slogwang		error = 1;
249a9643ea8Slogwang		return;
250a9643ea8Slogwang	}
251a9643ea8Slogwang	extra = substr(line, RSTART + RLENGTH);
252a9643ea8Slogwang	if (extra ~ /[	 ]*DEFAULT[ 	]*[a-zA-Z_][a-zA-Z_0-9]*[ 	]*;/) {
253a9643ea8Slogwang		default_function = extra;
254a9643ea8Slogwang		sub(/.*DEFAULT[	 ]*/, "", default_function);
255a9643ea8Slogwang		sub(/[; 	]+.*$/, "", default_function);
256a9643ea8Slogwang	}
257a9643ea8Slogwang	else if (extra && opt_d) {
258a9643ea8Slogwang		#   Warn about garbage at end of line.
259a9643ea8Slogwang		warnsrc("Ignored '" extra "'");
260a9643ea8Slogwang	}
261a9643ea8Slogwang	sub(/\};?.*$/, "", line);
262a9643ea8Slogwang
263a9643ea8Slogwang	#
264a9643ea8Slogwang	#   Create a list of variables without the types prepended.
265a9643ea8Slogwang	#
266a9643ea8Slogwang	sub(/^[	 ]+/, "", line);	# remove leading ...
267a9643ea8Slogwang	sub(/[ 	]+$/, "", line);	# ... and trailing whitespace
268a9643ea8Slogwang	gsub(/[	 ]+/, " ", line);	# remove double spaces
269a9643ea8Slogwang
270a9643ea8Slogwang	num_arguments = split(line, arguments, / *; */) - 1;
271a9643ea8Slogwang	delete varnames;		# list of varnames
272a9643ea8Slogwang	num_varnames = 0;
273a9643ea8Slogwang	for (i = 1; i <= num_arguments; i++) {
274a9643ea8Slogwang		if (!arguments[i])
275a9643ea8Slogwang			continue;	# skip argument if argument is empty
276a9643ea8Slogwang		num_ar = split(arguments[i], ar, /[* 	]+/);
277a9643ea8Slogwang		if (num_ar < 2) {	# only 1 word in argument?
278a9643ea8Slogwang			warnsrc("no type for '" arguments[i] "'");
279a9643ea8Slogwang			error = 1;
280a9643ea8Slogwang			return;
281a9643ea8Slogwang		}
282a9643ea8Slogwang		#   Last element is name of variable.
283a9643ea8Slogwang		varnames[++num_varnames] = ar[num_ar];
284a9643ea8Slogwang	}
285a9643ea8Slogwang
286a9643ea8Slogwang	argument_list = join(", ", arguments, num_arguments);
287a9643ea8Slogwang	varname_list = join(", ", varnames, num_varnames);
288a9643ea8Slogwang
289a9643ea8Slogwang	if (opt_d) {
290a9643ea8Slogwang		warn("Arguments: " argument_list);
291a9643ea8Slogwang		warn("Varnames: " varname_list);
292a9643ea8Slogwang	}
293a9643ea8Slogwang
294a9643ea8Slogwang	mname = intname "_" name;	# method name
295a9643ea8Slogwang	umname = toupper(mname);	# uppercase method name
296a9643ea8Slogwang
297a9643ea8Slogwang	firstvar = varnames[1];
298a9643ea8Slogwang
299a9643ea8Slogwang	if (default_function == "")
300a9643ea8Slogwang		default_function = "kobj_error_method";
301a9643ea8Slogwang
302a9643ea8Slogwang	# the method description
303a9643ea8Slogwang	printh("/** @brief Unique descriptor for the " umname "() method */");
304a9643ea8Slogwang	printh("extern struct kobjop_desc " mname "_desc;");
305a9643ea8Slogwang	# the method typedef
306a9643ea8Slogwang	printh("/** @brief A function implementing the " umname "() method */");
307a9643ea8Slogwang	prototype = "typedef " ret " " mname "_t(";
308a9643ea8Slogwang	printh(format_line(prototype argument_list ");",
309a9643ea8Slogwang	    line_width, length(prototype)));
310a9643ea8Slogwang
311a9643ea8Slogwang	# Print out the method desc
312a9643ea8Slogwang	printc("struct kobjop_desc " mname "_desc = {");
313a9643ea8Slogwang	printc("\t0, { &" mname "_desc, (kobjop_t)" default_function " }");
314a9643ea8Slogwang	printc("};\n");
315a9643ea8Slogwang
316a9643ea8Slogwang	# Print out the method itself
317a9643ea8Slogwang	printh(doc);
318a9643ea8Slogwang	if (0) {		# haven't chosen the format yet
319a9643ea8Slogwang		printh("static __inline " ret " " umname "(" varname_list ")");
320a9643ea8Slogwang		printh("\t" join(";\n\t", arguments, num_arguments) ";");
321a9643ea8Slogwang	}
322a9643ea8Slogwang	else {
323a9643ea8Slogwang		prototype = "static __inline " ret " " umname "(";
324a9643ea8Slogwang		printh(format_line(prototype argument_list ")",
325a9643ea8Slogwang		    line_width, length(prototype)));
326a9643ea8Slogwang	}
327a9643ea8Slogwang	printh("{");
328*22ce4affSfengbojiang	if (singleton)
329*22ce4affSfengbojiang		printh("\tstatic kobjop_t _m;");
330*22ce4affSfengbojiang	else
331a9643ea8Slogwang		printh("\tkobjop_t _m;");
332*22ce4affSfengbojiang	if (ret != "void")
333*22ce4affSfengbojiang		printh("\t" ret " rc;");
334a9643ea8Slogwang	if (!static)
335a9643ea8Slogwang		firstvar = "((kobj_t)" firstvar ")";
336*22ce4affSfengbojiang	if (prolog != "")
337*22ce4affSfengbojiang		printh(prolog);
338*22ce4affSfengbojiang	if (singleton)
339*22ce4affSfengbojiang		printh("\tif (_m == NULL)");
340a9643ea8Slogwang	printh("\tKOBJOPLOOKUP(" firstvar "->ops," mname ");");
341*22ce4affSfengbojiang	rceq = (ret != "void") ? "rc = " : "";
342*22ce4affSfengbojiang	printh("\t" rceq "((" mname "_t *) _m)(" varname_list ");");
343*22ce4affSfengbojiang	if (epilog != "")
344*22ce4affSfengbojiang		printh(epilog);
345*22ce4affSfengbojiang	if (ret != "void")
346*22ce4affSfengbojiang		printh("\treturn (rc);");
347a9643ea8Slogwang	printh("}\n");
348a9643ea8Slogwang}
349a9643ea8Slogwang
350a9643ea8Slogwang#
351a9643ea8Slogwang#   Begin of the main program.
352a9643ea8Slogwang#
353a9643ea8Slogwang
354a9643ea8SlogwangBEGIN {
355a9643ea8Slogwang
356a9643ea8Slogwangline_width = 80;
357a9643ea8Slogwanggerror = 0;
358a9643ea8Slogwang
359a9643ea8Slogwang#
360a9643ea8Slogwang#   Process the command line.
361a9643ea8Slogwang#
362a9643ea8Slogwang
363a9643ea8Slogwangnum_files = 0;
364a9643ea8Slogwang
365a9643ea8Slogwangfor (i = 1; i < ARGC; i++) {
366a9643ea8Slogwang	if (ARGV[i] ~ /^-/) {
367a9643ea8Slogwang		#
368a9643ea8Slogwang		#   awk doesn't have getopt(), so we have to do it ourselves.
369a9643ea8Slogwang		#   This is a bit clumsy, but it works.
370a9643ea8Slogwang		#
371a9643ea8Slogwang		for (j = 2; j <= length(ARGV[i]); j++) {
372a9643ea8Slogwang			o = substr(ARGV[i], j, 1);
373a9643ea8Slogwang			if	(o == "c")	opt_c = 1;
374a9643ea8Slogwang			else if	(o == "h")	opt_h = 1;
375a9643ea8Slogwang			else if	(o == "p")	opt_p = 1;
376a9643ea8Slogwang			else if	(o == "d")	opt_d = 1;
377a9643ea8Slogwang			else if	(o == "l") {
378a9643ea8Slogwang				if (length(ARGV[i]) > j) {
379a9643ea8Slogwang					opt_l = substr(ARGV[i], j + 1);
380a9643ea8Slogwang					break;
381a9643ea8Slogwang				}
382a9643ea8Slogwang				else {
383a9643ea8Slogwang					if (++i < ARGC)
384a9643ea8Slogwang						opt_l = ARGV[i];
385a9643ea8Slogwang					else
386a9643ea8Slogwang						usage();
387a9643ea8Slogwang				}
388a9643ea8Slogwang			}
389a9643ea8Slogwang			else
390a9643ea8Slogwang				usage();
391a9643ea8Slogwang		}
392a9643ea8Slogwang	}
393a9643ea8Slogwang	else if (ARGV[i] ~ /\.m$/)
394a9643ea8Slogwang		filenames[num_files++] = ARGV[i];
395a9643ea8Slogwang	else
396a9643ea8Slogwang		usage();
397a9643ea8Slogwang}
398a9643ea8Slogwang
399a9643ea8Slogwangif (!num_files || !(opt_c || opt_h))
400a9643ea8Slogwang	usage();
401a9643ea8Slogwang
402a9643ea8Slogwangif (opt_p)
403a9643ea8Slogwang	debug("Will produce files in original not in current directory");
404a9643ea8Slogwang
405a9643ea8Slogwangif (opt_l) {
406a9643ea8Slogwang	if (opt_l !~ /^[0-9]+$/ || opt_l < 1)
407a9643ea8Slogwang		die("Invalid line width '" opt_l "'");
408a9643ea8Slogwang	line_width = opt_l;
409a9643ea8Slogwang	debug("Line width set to " line_width);
410a9643ea8Slogwang}
411a9643ea8Slogwang
412a9643ea8Slogwangfor (i = 0; i < num_files; i++)
413a9643ea8Slogwang	debug("Filename: " filenames[i]);
414a9643ea8Slogwang
415a9643ea8Slogwangfor (file_i = 0; file_i < num_files; file_i++) {
416a9643ea8Slogwang	src = filenames[file_i];
417a9643ea8Slogwang	cfilename = hfilename = src;
418a9643ea8Slogwang	sub(/\.m$/, ".c", cfilename);
419a9643ea8Slogwang	sub(/\.m$/, ".h", hfilename);
420a9643ea8Slogwang	if (!opt_p) {
421a9643ea8Slogwang		sub(/^.*\//, "", cfilename);
422a9643ea8Slogwang		sub(/^.*\//, "", hfilename);
423a9643ea8Slogwang	}
424a9643ea8Slogwang
425a9643ea8Slogwang	debug("Processing from " src " to " cfilename " / " hfilename);
426a9643ea8Slogwang
427a9643ea8Slogwang	ctmpfilename = cfilename ".tmp";
428a9643ea8Slogwang	htmpfilename = hfilename ".tmp";
429a9643ea8Slogwang
430*22ce4affSfengbojiang	# Avoid a literal generated file tag here.
431*22ce4affSfengbojiang	generated = "@" "generated";
432*22ce4affSfengbojiang
433a9643ea8Slogwang	common_head = \
434a9643ea8Slogwang	    "/*\n" \
435*22ce4affSfengbojiang	    " * This file is " generated " automatically.\n" \
436a9643ea8Slogwang	    " * Do not modify anything in here by hand.\n" \
437a9643ea8Slogwang	    " *\n" \
438a9643ea8Slogwang	    " * Created from source file\n" \
439a9643ea8Slogwang	    " *   " src "\n" \
440a9643ea8Slogwang	    " * with\n" \
441a9643ea8Slogwang	    " *   makeobjops.awk\n" \
442a9643ea8Slogwang	    " *\n" \
443a9643ea8Slogwang	    " * See the source file for legal information\n" \
444a9643ea8Slogwang	    " */\n";
445a9643ea8Slogwang
446a9643ea8Slogwang	printc(common_head "\n" \
447a9643ea8Slogwang	    "#include <sys/param.h>\n" \
448a9643ea8Slogwang	    "#include <sys/queue.h>\n" \
449a9643ea8Slogwang	    "#include <sys/kernel.h>\n" \
450a9643ea8Slogwang	    "#include <sys/kobj.h>");
451a9643ea8Slogwang
452a9643ea8Slogwang	printh(common_head);
453a9643ea8Slogwang
454a9643ea8Slogwang	delete methods;		# clear list of methods
455a9643ea8Slogwang	intname = "";
456a9643ea8Slogwang	lineno = 0;
457a9643ea8Slogwang	error = 0;		# to signal clean up and gerror setting
458a9643ea8Slogwang	lastdoc = "";
459*22ce4affSfengbojiang	prolog = "";
460*22ce4affSfengbojiang	epilog = "";
461*22ce4affSfengbojiang	singleton = 0;
462a9643ea8Slogwang
463a9643ea8Slogwang	while (!error && (getline < src) > 0) {
464a9643ea8Slogwang		lineno++;
465a9643ea8Slogwang
466a9643ea8Slogwang		#
467a9643ea8Slogwang		#   Take special notice of include directives.
468a9643ea8Slogwang		#
469a9643ea8Slogwang		if (/^#[ 	]*include[ 	]+["<][^">]+[">]/) {
470a9643ea8Slogwang			incld = $0;
471a9643ea8Slogwang			sub(/^#[ 	]*include[ 	]+/, "", incld);
472a9643ea8Slogwang			debug("Included file: " incld);
473a9643ea8Slogwang			printc("#include " incld);
474a9643ea8Slogwang		}
475a9643ea8Slogwang
476a9643ea8Slogwang		sub(/#.*/, "");		# remove comments
477a9643ea8Slogwang		sub(/^[	 ]+/, "");	# remove leading ...
478a9643ea8Slogwang		sub(/[ 	]+$/, "");	# ... and trailing whitespace
479a9643ea8Slogwang
480a9643ea8Slogwang		if (/^$/) {		# skip empty lines
481a9643ea8Slogwang		}
482a9643ea8Slogwang		else if (/^\/\*\*/)
483a9643ea8Slogwang			lastdoc = handle_doc();
484a9643ea8Slogwang		else if (/^INTERFACE[ 	]+[^ 	;]*[ 	]*;?[ 	]*$/) {
485a9643ea8Slogwang			printh(lastdoc);
486a9643ea8Slogwang			lastdoc = "";
487a9643ea8Slogwang			handle_interface();
488a9643ea8Slogwang		} else if (/^CODE[ 	]*{$/)
489a9643ea8Slogwang			printc(handle_code());
490a9643ea8Slogwang		else if (/^HEADER[	 ]*{$/)
491a9643ea8Slogwang			printh(handle_code());
492a9643ea8Slogwang		else if (/^METHOD/) {
493a9643ea8Slogwang			handle_method(0, lastdoc);
494a9643ea8Slogwang			lastdoc = "";
495*22ce4affSfengbojiang			prolog = "";
496*22ce4affSfengbojiang			epilog = "";
497a9643ea8Slogwang		} else if (/^STATICMETHOD/) {
498a9643ea8Slogwang			handle_method(1, lastdoc);
499a9643ea8Slogwang			lastdoc = "";
500*22ce4affSfengbojiang			prolog = "";
501*22ce4affSfengbojiang			epilog = "";
502*22ce4affSfengbojiang		} else if (/^PROLOG[ 	]*{$/)
503*22ce4affSfengbojiang			prolog = handle_code();
504*22ce4affSfengbojiang		else if (/^EPILOG[ 	]*{$/)
505*22ce4affSfengbojiang			epilog = handle_code();
506*22ce4affSfengbojiang		else if (/^SINGLETON/)
507*22ce4affSfengbojiang			singleton = 1;
508*22ce4affSfengbojiang		else {
509a9643ea8Slogwang			debug($0);
510a9643ea8Slogwang			warnsrc("Invalid line encountered");
511a9643ea8Slogwang			error = 1;
512a9643ea8Slogwang		}
513a9643ea8Slogwang	}
514a9643ea8Slogwang
515a9643ea8Slogwang	#
516a9643ea8Slogwang	#   Print the final '#endif' in the header file.
517a9643ea8Slogwang	#
518a9643ea8Slogwang	printh("#endif /* _" intname "_if_h_ */");
519a9643ea8Slogwang
520a9643ea8Slogwang	close (ctmpfilename);
521a9643ea8Slogwang	close (htmpfilename);
522a9643ea8Slogwang
523a9643ea8Slogwang	if (error) {
524a9643ea8Slogwang		warn("Output skipped");
525a9643ea8Slogwang		system_check("rm -f " ctmpfilename " " htmpfilename);
526a9643ea8Slogwang		gerror = 1;
527a9643ea8Slogwang	}
528a9643ea8Slogwang	else {
529a9643ea8Slogwang		if (opt_c)
530a9643ea8Slogwang			system_check("mv -f " ctmpfilename " " cfilename);
531a9643ea8Slogwang		if (opt_h)
532a9643ea8Slogwang			system_check("mv -f " htmpfilename " " hfilename);
533a9643ea8Slogwang	}
534a9643ea8Slogwang}
535a9643ea8Slogwang
536a9643ea8Slogwangexit gerror;
537a9643ea8Slogwang
538a9643ea8Slogwang}
539