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