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 #include "shinstance.h"
52
53
54 size_t funcblocksize; /* size of structures in function */
55 size_t funcstringsize; /* size of strings in node */
56 pointer funcblock; /* block to allocate function from */
57 char *funcstring; /* block to allocate strings from */
58
59 static const short nodesize[26] = {
60 SHELL_ALIGN(sizeof (struct nbinary)),
61 SHELL_ALIGN(sizeof (struct ncmd)),
62 SHELL_ALIGN(sizeof (struct npipe)),
63 SHELL_ALIGN(sizeof (struct nredir)),
64 SHELL_ALIGN(sizeof (struct nredir)),
65 SHELL_ALIGN(sizeof (struct nredir)),
66 SHELL_ALIGN(sizeof (struct nbinary)),
67 SHELL_ALIGN(sizeof (struct nbinary)),
68 SHELL_ALIGN(sizeof (struct nif)),
69 SHELL_ALIGN(sizeof (struct nbinary)),
70 SHELL_ALIGN(sizeof (struct nbinary)),
71 SHELL_ALIGN(sizeof (struct nfor)),
72 SHELL_ALIGN(sizeof (struct ncase)),
73 SHELL_ALIGN(sizeof (struct nclist)),
74 SHELL_ALIGN(sizeof (struct narg)),
75 SHELL_ALIGN(sizeof (struct narg)),
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 nfile)),
81 SHELL_ALIGN(sizeof (struct ndup)),
82 SHELL_ALIGN(sizeof (struct ndup)),
83 SHELL_ALIGN(sizeof (struct nhere)),
84 SHELL_ALIGN(sizeof (struct nhere)),
85 SHELL_ALIGN(sizeof (struct nnot)),
86 };
87
88
89 STATIC void calcsize(union node *);
90 STATIC void sizenodelist(struct nodelist *);
91 STATIC union node *copynode(union node *);
92 STATIC struct nodelist *copynodelist(struct nodelist *);
93 STATIC char *nodesavestr(char *);
94
95
96
97 /*
98 * Make a copy of a parse tree.
99 */
100
101 union node *
copyfunc(psh,n)102 copyfunc(psh, n)
103 struct shinstance *psh;
104 union node *n;
105 {
106 if (n == NULL)
107 return NULL;
108 funcblocksize = 0;
109 funcstringsize = 0;
110 calcsize(n);
111 funcblock = ckmalloc(psh, funcblocksize + funcstringsize);
112 funcstring = (char *) funcblock + funcblocksize;
113 return copynode(n);
114 }
115
116
117
118 STATIC void
calcsize(n)119 calcsize(n)
120 union node *n;
121 {
122 if (n == NULL)
123 return;
124 funcblocksize += nodesize[n->type];
125 switch (n->type) {
126 case NSEMI:
127 case NAND:
128 case NOR:
129 case NWHILE:
130 case NUNTIL:
131 calcsize(n->nbinary.ch2);
132 calcsize(n->nbinary.ch1);
133 break;
134 case NCMD:
135 calcsize(n->ncmd.redirect);
136 calcsize(n->ncmd.args);
137 break;
138 case NPIPE:
139 sizenodelist(n->npipe.cmdlist);
140 break;
141 case NREDIR:
142 case NBACKGND:
143 case NSUBSHELL:
144 calcsize(n->nredir.redirect);
145 calcsize(n->nredir.n);
146 break;
147 case NIF:
148 calcsize(n->nif.elsepart);
149 calcsize(n->nif.ifpart);
150 calcsize(n->nif.test);
151 break;
152 case NFOR:
153 funcstringsize += strlen(n->nfor.var) + 1;
154 calcsize(n->nfor.body);
155 calcsize(n->nfor.args);
156 break;
157 case NCASE:
158 calcsize(n->ncase.cases);
159 calcsize(n->ncase.expr);
160 break;
161 case NCLIST:
162 calcsize(n->nclist.body);
163 calcsize(n->nclist.pattern);
164 calcsize(n->nclist.next);
165 break;
166 case NDEFUN:
167 case NARG:
168 sizenodelist(n->narg.backquote);
169 funcstringsize += strlen(n->narg.text) + 1;
170 calcsize(n->narg.next);
171 break;
172 case NTO:
173 case NCLOBBER:
174 case NFROM:
175 case NFROMTO:
176 case NAPPEND:
177 calcsize(n->nfile.fname);
178 calcsize(n->nfile.next);
179 break;
180 case NTOFD:
181 case NFROMFD:
182 calcsize(n->ndup.vname);
183 calcsize(n->ndup.next);
184 break;
185 case NHERE:
186 case NXHERE:
187 calcsize(n->nhere.doc);
188 calcsize(n->nhere.next);
189 break;
190 case NNOT:
191 calcsize(n->nnot.com);
192 break;
193 };
194 }
195
196
197
198 STATIC void
sizenodelist(lp)199 sizenodelist(lp)
200 struct nodelist *lp;
201 {
202 while (lp) {
203 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
204 calcsize(lp->n);
205 lp = lp->next;
206 }
207 }
208
209
210
211 STATIC union node *
copynode(n)212 copynode(n)
213 union node *n;
214 {
215 union node *new;
216
217 if (n == NULL)
218 return NULL;
219 new = funcblock;
220 funcblock = (char *) funcblock + nodesize[n->type];
221 switch (n->type) {
222 case NSEMI:
223 case NAND:
224 case NOR:
225 case NWHILE:
226 case NUNTIL:
227 new->nbinary.ch2 = copynode(n->nbinary.ch2);
228 new->nbinary.ch1 = copynode(n->nbinary.ch1);
229 break;
230 case NCMD:
231 new->ncmd.redirect = copynode(n->ncmd.redirect);
232 new->ncmd.args = copynode(n->ncmd.args);
233 new->ncmd.backgnd = n->ncmd.backgnd;
234 break;
235 case NPIPE:
236 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
237 new->npipe.backgnd = n->npipe.backgnd;
238 break;
239 case NREDIR:
240 case NBACKGND:
241 case NSUBSHELL:
242 new->nredir.redirect = copynode(n->nredir.redirect);
243 new->nredir.n = copynode(n->nredir.n);
244 break;
245 case NIF:
246 new->nif.elsepart = copynode(n->nif.elsepart);
247 new->nif.ifpart = copynode(n->nif.ifpart);
248 new->nif.test = copynode(n->nif.test);
249 break;
250 case NFOR:
251 new->nfor.var = nodesavestr(n->nfor.var);
252 new->nfor.body = copynode(n->nfor.body);
253 new->nfor.args = copynode(n->nfor.args);
254 break;
255 case NCASE:
256 new->ncase.cases = copynode(n->ncase.cases);
257 new->ncase.expr = copynode(n->ncase.expr);
258 break;
259 case NCLIST:
260 new->nclist.body = copynode(n->nclist.body);
261 new->nclist.pattern = copynode(n->nclist.pattern);
262 new->nclist.next = copynode(n->nclist.next);
263 break;
264 case NDEFUN:
265 case NARG:
266 new->narg.backquote = copynodelist(n->narg.backquote);
267 new->narg.text = nodesavestr(n->narg.text);
268 new->narg.next = copynode(n->narg.next);
269 break;
270 case NTO:
271 case NCLOBBER:
272 case NFROM:
273 case NFROMTO:
274 case NAPPEND:
275 new->nfile.fname = copynode(n->nfile.fname);
276 new->nfile.fd = n->nfile.fd;
277 new->nfile.next = copynode(n->nfile.next);
278 break;
279 case NTOFD:
280 case NFROMFD:
281 new->ndup.vname = copynode(n->ndup.vname);
282 new->ndup.dupfd = n->ndup.dupfd;
283 new->ndup.fd = n->ndup.fd;
284 new->ndup.next = copynode(n->ndup.next);
285 break;
286 case NHERE:
287 case NXHERE:
288 new->nhere.doc = copynode(n->nhere.doc);
289 new->nhere.fd = n->nhere.fd;
290 new->nhere.next = copynode(n->nhere.next);
291 break;
292 case NNOT:
293 new->nnot.com = copynode(n->nnot.com);
294 break;
295 };
296 new->type = n->type;
297 return new;
298 }
299
300
301 STATIC struct nodelist *
copynodelist(lp)302 copynodelist(lp)
303 struct nodelist *lp;
304 {
305 struct nodelist *start;
306 struct nodelist **lpp;
307
308 lpp = &start;
309 while (lp) {
310 *lpp = funcblock;
311 funcblock = (char *) funcblock +
312 SHELL_ALIGN(sizeof(struct nodelist));
313 (*lpp)->n = copynode(lp->n);
314 lp = lp->next;
315 lpp = &(*lpp)->next;
316 }
317 *lpp = NULL;
318 return start;
319 }
320
321
322
323 STATIC char *
nodesavestr(s)324 nodesavestr(s)
325 char *s;
326 {
327 register char *p = s;
328 register char *q = funcstring;
329 char *rtn = funcstring;
330
331 while ((*q++ = *p++) != 0)
332 continue;
333 funcstring = q;
334 return rtn;
335 }
336
337
338
339 /*
340 * Free a parse tree.
341 */
342
343 void
freefunc(psh,n)344 freefunc(psh, n)
345 shinstance *psh;
346 union node *n;
347 {
348 if (n)
349 ckfree(psh, n);
350 }
351