xref: /dragonfly/bin/sh/pregenerated/nodes.c (revision 3e3895bf4584c1562faf4533cbd97026ee6a8dcf)
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 *
copyfunc(union node * n)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 *
getfuncnode(struct funcdef * fn)132 getfuncnode(struct funcdef *fn)
133 {
134           return fn == NULL ? NULL : &fn->n;
135 }
136 
137 
138 static void
calcsize(union node * n,struct nodesize * result)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
sizenodelist(struct nodelist * lp,struct nodesize * result)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 *
copynode(union node * n,struct nodecopystate * state)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 *
copynodelist(struct nodelist * lp,struct nodecopystate * state)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 *
nodesavestr(const char * s,struct nodecopystate * state)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
reffunc(struct funcdef * fn)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
unreffunc(struct funcdef * fn)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