1#! /bin/sh
2#	$NetBSD: mknodes.sh,v 1.1 2004/01/16 23:24:38 dsl Exp $
3
4# Copyright (c) 2003 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# This code is derived from software contributed to The NetBSD Foundation
8# by David Laight.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18# 3. Neither the name of The NetBSD Foundation nor the names of its
19#    contributors may be used to endorse or promote products derived
20#    from this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32# POSSIBILITY OF SUCH DAMAGE.
33
34nodetypes=$1
35nodes_pat=$2
36objdir="$3"
37
38exec <$nodetypes
39exec >$objdir/nodes.h.tmp
40
41echo "/*"
42echo " * This file was generated by mknodes.sh"
43echo " */"
44echo
45
46tagno=0
47while IFS=; read -r line; do
48	line="${line%%#*}"
49	IFS=' 	'
50	set -- $line
51	IFS=
52	[ -z "$2" ] && continue
53	case "$line" in
54	[" 	"]* )
55		IFS=' '
56		[ $field = 0 ] && struct_list="$struct_list $struct"
57		eval field_${struct}_$field=\"\$*\"
58		eval numfld_$struct=\$field
59		field=$(($field + 1))
60		;;
61	* )
62		define=$1
63		struct=$2
64		echo "#define $define $tagno"
65		tagno=$(($tagno + 1))
66		eval define_$struct=\"\$define_$struct \$define\"
67		struct_define="$struct_define $struct"
68		field=0
69		;;
70	esac
71done
72
73echo
74
75IFS=' '
76for struct in $struct_list; do
77	echo
78	echo
79	echo "struct $struct {"
80	field=0
81	while
82		eval line=\"\$field_${struct}_$field\"
83		field=$(($field + 1))
84		[ -n "$line" ]
85	do
86		IFS=' '
87		set -- $line
88		name=$1
89		case $2 in
90		nodeptr ) type="union node *";;
91		nodelist ) type="struct nodelist *";;
92		string ) type="char *";;
93		int ) type="int ";;
94		* ) name=; shift 2; type="$*";;
95		esac
96		echo "      $type$name;"
97	done
98	echo "};"
99done
100
101echo
102echo
103echo "union node {"
104echo "      int type;"
105for struct in $struct_list; do
106	echo "      struct $struct $struct;"
107done
108echo "};"
109echo
110echo
111echo "struct nodelist {"
112echo "	struct nodelist *next;"
113echo "	union node *n;"
114echo "};"
115echo
116echo
117echo "union node *copyfunc(union node *);"
118echo "void freefunc(union node *);"
119
120mv $objdir/nodes.h.tmp $objdir/nodes.h || exit 1
121
122exec <$nodes_pat
123exec >$objdir/nodes.c.tmp
124
125echo "/*"
126echo " * This file was generated by mknodes.sh"
127echo " */"
128echo
129
130while IFS=; read -r line; do
131	IFS=' 	'
132	set -- $line
133	IFS=
134	case "$1" in
135	'%SIZES' )
136		echo "static const short nodesize[$tagno] = {"
137		IFS=' '
138		for struct in $struct_define; do
139			echo "      SHELL_ALIGN(sizeof (struct $struct)),"
140		done
141		echo "};"
142		;;
143	'%CALCSIZE' )
144		echo "      if (n == NULL)"
145		echo "	    return;"
146		echo "      funcblocksize += nodesize[n->type];"
147		echo "      switch (n->type) {"
148		IFS=' '
149		for struct in $struct_list; do
150			eval defines=\"\$define_$struct\"
151			for define in $defines; do
152				echo "      case $define:"
153			done
154			eval field=\$numfld_$struct
155			while
156				[ $field != 0 ]
157			do
158				eval line=\"\$field_${struct}_$field\"
159				field=$(($field - 1))
160				IFS=' '
161				set -- $line
162				name=$1
163				cl=")"
164				case $2 in
165				nodeptr ) fn=calcsize;;
166				nodelist ) fn=sizenodelist;;
167				string ) fn="funcstringsize += strlen"
168					cl=") + 1";;
169				* ) continue;;
170				esac
171				echo "	    ${fn}(n->$struct.$name${cl};"
172			done
173			echo "	    break;"
174		done
175		echo "      };"
176		;;
177	'%COPY' )
178		echo "      if (n == NULL)"
179		echo "	    return NULL;"
180		echo "      new = funcblock;"
181		echo "      funcblock = (char *) funcblock + nodesize[n->type];"
182		echo "      switch (n->type) {"
183		IFS=' '
184		for struct in $struct_list; do
185			eval defines=\"\$define_$struct\"
186			for define in $defines; do
187				echo "      case $define:"
188			done
189			eval field=\$numfld_$struct
190			while
191				[ $field != 0 ]
192			do
193				eval line=\"\$field_${struct}_$field\"
194				field=$(($field - 1))
195				IFS=' '
196				set -- $line
197				name=$1
198				case $2 in
199				nodeptr ) fn="copynode(";;
200				nodelist ) fn="copynodelist(";;
201				string ) fn="nodesavestr(";;
202				int ) fn=;;
203				* ) continue;;
204				esac
205				f="$struct.$name"
206				echo "	    new->$f = ${fn}n->$f${fn:+)};"
207			done
208			echo "	    break;"
209		done
210		echo "      };"
211		echo "      new->type = n->type;"
212		;;
213	* ) echo "$line";;
214	esac
215done
216
217mv $objdir/nodes.c.tmp $objdir/nodes.c || exit 1
218