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