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