xref: /openbsd/sys/kern/genassym.sh (revision 09467b48)
1#	$OpenBSD: genassym.sh,v 1.13 2017/08/15 01:53:06 tedu Exp $
2#	$NetBSD: genassym.sh,v 1.9 1998/04/25 19:48:27 matthias Exp $
3
4#
5# Copyright (c) 1997 Matthias Pfaller.
6# All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29# If first argument is -c, create a temporary C file,
30# compile it and execute the result.
31
32awk=${AWK:-awk}
33
34if [ "x$1" = "x-c" ] ; then
35	shift
36	ccode=1
37else
38	ccode=0
39fi
40
41WRKDIR=`mktemp -d /tmp/genassym_XXXXXXXXXX` || exit 1
42
43TMPC=${WRKDIR}/genassym.c
44TMP=${WRKDIR}/genassym
45
46trap "rm -rf $WRKDIR" 0 1 2 3 15
47
48$awk '
49BEGIN {
50	printf("#ifndef _KERNEL\n#define _KERNEL\n#endif\n");
51	printf("#define	offsetof(type, member) ((size_t)(&((type *)0)->member))\n");
52	defining = 0;
53	type = "long";
54	asmtype = "n";
55	asmprint = "";
56}
57
58$0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ {
59	# Just ignore comments and empty lines
60	next;
61}
62
63$0 ~ /^config[ \t]/ {
64	type = $2;
65	asmtype = $3;
66	asmprint = $4;
67	next;
68}
69
70/^include[ \t]/ {
71	if (defining != 0) {
72		defining = 0;
73		printf("}\n");
74	}
75	if (includes[$2] == 0) {
76		printf("#%s\n", $0);
77		includes[$2] = 1;
78	}
79	next;
80}
81
82$0 ~ /^if[ \t]/ ||
83$0 ~ /^ifdef[ \t]/ ||
84$0 ~ /^ifndef[ \t]/ ||
85$0 ~ /^else/ ||
86$0 ~ /^elif[ \t]/ ||
87$0 ~ /^endif/ {
88	printf("#%s\n", $0);
89	next;
90}
91
92/^union[ \t]/ {
93	structname = $2;
94	prefixname = toupper($3);
95	structtype = "union"
96	if (union[structname] == 1)
97		next;
98	else {
99		union[structname] = 1;
100		$0 = "define " toupper(structname) "_SIZEOF sizeof(union " structname ")";
101	}
102	# fall through
103}
104
105/^struct[ \t]/ {
106	structname = $2;
107	prefixname = toupper($3);
108	structtype = "struct"
109	if (struct[structname] == 1)
110		next;
111	else {
112		struct[structname] = 1;
113		$0 = "define " toupper(structname) "_SIZEOF sizeof(struct " structname ")";
114	}
115	# fall through
116}
117
118/^member[ \t]/ {
119	if (NF > 2)
120		$0 = "define " prefixname toupper($2) " offsetof(" structtype " " structname ", " $3 ")";
121	else
122		$0 = "define " prefixname toupper($2) " offsetof(" structtype " " structname ", " $2 ")";
123	# fall through
124}
125
126/^export[ \t]/ {
127	$0 = "define " $2 " " $2;
128	# fall through
129}
130
131/^define[ \t]/ {
132	if (defining == 0) {
133		defining = 1;
134		printf("void f" FNR "(void);\n");
135		printf("void f" FNR "() {\n");
136		if (ccode)
137			call[FNR] = "f" FNR;
138		defining = 1;
139	}
140	value = $0
141	gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value)
142	if (ccode)
143		printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type);
144	else
145		printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value);
146	next;
147}
148
149/^quote[ \t]/ {
150	gsub("^quote[ \t]+", "");
151	print;
152	next;
153}
154
155{
156	printf("syntax error in line %d\n", FNR) >"/dev/stderr";
157	exit(1);
158}
159
160END {
161	if (defining != 0) {
162		defining = 0;
163		printf("}\n");
164	}
165	if (ccode) {
166		printf("int main(int argc, char **argv) {");
167		for (i in call)
168			printf(call[i] "();");
169		printf("return(0); }\n");
170	}
171}
172' ccode=$ccode > $TMPC || exit 1
173
174if [ $ccode = 1 ] ; then
175	"$@" -x c $TMPC -o $TMP && $TMP
176else
177	# Kill all of the "#" and "$" modifiers; locore.s already
178	# prepends the correct "constant" modifier.
179	"$@" -x c -S ${TMPC} -o ${TMP} || exit 1
180	sed -e 's/#//g' -e 's/\$//g' ${TMP} | sed -n 's/.*XYZZY/#define/gp'
181fi
182