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