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