1/*
2 * This file was generated by mknodes.sh
3 */
4
5/*	$NetBSD: nodes.c.pat,v 1.12 2004/06/15 22:57:27 dsl Exp $	*/
6
7/*-
8 * Copyright (c) 1991, 1993
9 *	The Regents of the University of California.  All rights reserved.
10 *
11 * This code is derived from software contributed to Berkeley by
12 * Kenneth Almquist.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)nodes.c.pat	8.2 (Berkeley) 5/4/95
39 */
40
41#include <stdlib.h>
42/*
43 * Routine for dealing with parsed shell commands.
44 */
45
46#include "shell.h"
47#include "nodes.h"
48#include "memalloc.h"
49#include "machdep.h"
50#include "mystring.h"
51
52
53int     funcblocksize;		/* size of structures in function */
54int     funcstringsize;		/* size of strings in node */
55pointer funcblock;		/* block to allocate function from */
56char   *funcstring;		/* block to allocate strings from */
57
58static const short nodesize[26] = {
59      SHELL_ALIGN(sizeof (struct nbinary)),
60      SHELL_ALIGN(sizeof (struct ncmd)),
61      SHELL_ALIGN(sizeof (struct npipe)),
62      SHELL_ALIGN(sizeof (struct nredir)),
63      SHELL_ALIGN(sizeof (struct nredir)),
64      SHELL_ALIGN(sizeof (struct nredir)),
65      SHELL_ALIGN(sizeof (struct nbinary)),
66      SHELL_ALIGN(sizeof (struct nbinary)),
67      SHELL_ALIGN(sizeof (struct nif)),
68      SHELL_ALIGN(sizeof (struct nbinary)),
69      SHELL_ALIGN(sizeof (struct nbinary)),
70      SHELL_ALIGN(sizeof (struct nfor)),
71      SHELL_ALIGN(sizeof (struct ncase)),
72      SHELL_ALIGN(sizeof (struct nclist)),
73      SHELL_ALIGN(sizeof (struct narg)),
74      SHELL_ALIGN(sizeof (struct narg)),
75      SHELL_ALIGN(sizeof (struct nfile)),
76      SHELL_ALIGN(sizeof (struct nfile)),
77      SHELL_ALIGN(sizeof (struct nfile)),
78      SHELL_ALIGN(sizeof (struct nfile)),
79      SHELL_ALIGN(sizeof (struct nfile)),
80      SHELL_ALIGN(sizeof (struct ndup)),
81      SHELL_ALIGN(sizeof (struct ndup)),
82      SHELL_ALIGN(sizeof (struct nhere)),
83      SHELL_ALIGN(sizeof (struct nhere)),
84      SHELL_ALIGN(sizeof (struct nnot)),
85};
86
87
88STATIC void calcsize(union node *);
89STATIC void sizenodelist(struct nodelist *);
90STATIC union node *copynode(union node *);
91STATIC struct nodelist *copynodelist(struct nodelist *);
92STATIC char *nodesavestr(char *);
93
94
95
96/*
97 * Make a copy of a parse tree.
98 */
99
100union node *
101copyfunc(n)
102	union node *n;
103{
104	if (n == NULL)
105		return NULL;
106	funcblocksize = 0;
107	funcstringsize = 0;
108	calcsize(n);
109	funcblock = ckmalloc(funcblocksize + funcstringsize);
110	funcstring = (char *) funcblock + funcblocksize;
111	return copynode(n);
112}
113
114
115
116STATIC void
117calcsize(n)
118	union node *n;
119{
120      if (n == NULL)
121	    return;
122      funcblocksize += nodesize[n->type];
123      switch (n->type) {
124      case NSEMI:
125      case NAND:
126      case NOR:
127      case NWHILE:
128      case NUNTIL:
129	    calcsize(n->nbinary.ch2);
130	    calcsize(n->nbinary.ch1);
131	    break;
132      case NCMD:
133	    calcsize(n->ncmd.redirect);
134	    calcsize(n->ncmd.args);
135	    break;
136      case NPIPE:
137	    sizenodelist(n->npipe.cmdlist);
138	    break;
139      case NREDIR:
140      case NBACKGND:
141      case NSUBSHELL:
142	    calcsize(n->nredir.redirect);
143	    calcsize(n->nredir.n);
144	    break;
145      case NIF:
146	    calcsize(n->nif.elsepart);
147	    calcsize(n->nif.ifpart);
148	    calcsize(n->nif.test);
149	    break;
150      case NFOR:
151	    funcstringsize += strlen(n->nfor.var) + 1;
152	    calcsize(n->nfor.body);
153	    calcsize(n->nfor.args);
154	    break;
155      case NCASE:
156	    calcsize(n->ncase.cases);
157	    calcsize(n->ncase.expr);
158	    break;
159      case NCLIST:
160	    calcsize(n->nclist.body);
161	    calcsize(n->nclist.pattern);
162	    calcsize(n->nclist.next);
163	    break;
164      case NDEFUN:
165      case NARG:
166	    sizenodelist(n->narg.backquote);
167	    funcstringsize += strlen(n->narg.text) + 1;
168	    calcsize(n->narg.next);
169	    break;
170      case NTO:
171      case NCLOBBER:
172      case NFROM:
173      case NFROMTO:
174      case NAPPEND:
175	    calcsize(n->nfile.fname);
176	    calcsize(n->nfile.next);
177	    break;
178      case NTOFD:
179      case NFROMFD:
180	    calcsize(n->ndup.vname);
181	    calcsize(n->ndup.next);
182	    break;
183      case NHERE:
184      case NXHERE:
185	    calcsize(n->nhere.doc);
186	    calcsize(n->nhere.next);
187	    break;
188      case NNOT:
189	    calcsize(n->nnot.com);
190	    break;
191      };
192}
193
194
195
196STATIC void
197sizenodelist(lp)
198	struct nodelist *lp;
199{
200	while (lp) {
201		funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
202		calcsize(lp->n);
203		lp = lp->next;
204	}
205}
206
207
208
209STATIC union node *
210copynode(n)
211	union node *n;
212{
213	union node *new;
214
215      if (n == NULL)
216	    return NULL;
217      new = funcblock;
218      funcblock = (char *) funcblock + nodesize[n->type];
219      switch (n->type) {
220      case NSEMI:
221      case NAND:
222      case NOR:
223      case NWHILE:
224      case NUNTIL:
225	    new->nbinary.ch2 = copynode(n->nbinary.ch2);
226	    new->nbinary.ch1 = copynode(n->nbinary.ch1);
227	    break;
228      case NCMD:
229	    new->ncmd.redirect = copynode(n->ncmd.redirect);
230	    new->ncmd.args = copynode(n->ncmd.args);
231	    new->ncmd.backgnd = n->ncmd.backgnd;
232	    break;
233      case NPIPE:
234	    new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
235	    new->npipe.backgnd = n->npipe.backgnd;
236	    break;
237      case NREDIR:
238      case NBACKGND:
239      case NSUBSHELL:
240	    new->nredir.redirect = copynode(n->nredir.redirect);
241	    new->nredir.n = copynode(n->nredir.n);
242	    break;
243      case NIF:
244	    new->nif.elsepart = copynode(n->nif.elsepart);
245	    new->nif.ifpart = copynode(n->nif.ifpart);
246	    new->nif.test = copynode(n->nif.test);
247	    break;
248      case NFOR:
249	    new->nfor.var = nodesavestr(n->nfor.var);
250	    new->nfor.body = copynode(n->nfor.body);
251	    new->nfor.args = copynode(n->nfor.args);
252	    break;
253      case NCASE:
254	    new->ncase.cases = copynode(n->ncase.cases);
255	    new->ncase.expr = copynode(n->ncase.expr);
256	    break;
257      case NCLIST:
258	    new->nclist.body = copynode(n->nclist.body);
259	    new->nclist.pattern = copynode(n->nclist.pattern);
260	    new->nclist.next = copynode(n->nclist.next);
261	    break;
262      case NDEFUN:
263      case NARG:
264	    new->narg.backquote = copynodelist(n->narg.backquote);
265	    new->narg.text = nodesavestr(n->narg.text);
266	    new->narg.next = copynode(n->narg.next);
267	    break;
268      case NTO:
269      case NCLOBBER:
270      case NFROM:
271      case NFROMTO:
272      case NAPPEND:
273	    new->nfile.fname = copynode(n->nfile.fname);
274	    new->nfile.fd = n->nfile.fd;
275	    new->nfile.next = copynode(n->nfile.next);
276	    break;
277      case NTOFD:
278      case NFROMFD:
279	    new->ndup.vname = copynode(n->ndup.vname);
280	    new->ndup.dupfd = n->ndup.dupfd;
281	    new->ndup.fd = n->ndup.fd;
282	    new->ndup.next = copynode(n->ndup.next);
283	    break;
284      case NHERE:
285      case NXHERE:
286	    new->nhere.doc = copynode(n->nhere.doc);
287	    new->nhere.fd = n->nhere.fd;
288	    new->nhere.next = copynode(n->nhere.next);
289	    break;
290      case NNOT:
291	    new->nnot.com = copynode(n->nnot.com);
292	    break;
293      };
294      new->type = n->type;
295	return new;
296}
297
298
299STATIC struct nodelist *
300copynodelist(lp)
301	struct nodelist *lp;
302{
303	struct nodelist *start;
304	struct nodelist **lpp;
305
306	lpp = &start;
307	while (lp) {
308		*lpp = funcblock;
309		funcblock = (char *) funcblock +
310		    SHELL_ALIGN(sizeof(struct nodelist));
311		(*lpp)->n = copynode(lp->n);
312		lp = lp->next;
313		lpp = &(*lpp)->next;
314	}
315	*lpp = NULL;
316	return start;
317}
318
319
320
321STATIC char *
322nodesavestr(s)
323	char   *s;
324{
325	register char *p = s;
326	register char *q = funcstring;
327	char   *rtn = funcstring;
328
329	while ((*q++ = *p++) != 0)
330		continue;
331	funcstring = q;
332	return rtn;
333}
334
335
336
337/*
338 * Free a parse tree.
339 */
340
341void
342freefunc(n)
343	union node *n;
344{
345	if (n)
346		ckfree(n);
347}
348