Home | History | Annotate | Download | only in sh
      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 
     53 int     funcblocksize;		/* size of structures in function */
     54 int     funcstringsize;		/* size of strings in node */
     55 pointer funcblock;		/* block to allocate function from */
     56 char   *funcstring;		/* block to allocate strings from */
     57 
     58 static 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 
     88 STATIC void calcsize(union node *);
     89 STATIC void sizenodelist(struct nodelist *);
     90 STATIC union node *copynode(union node *);
     91 STATIC struct nodelist *copynodelist(struct nodelist *);
     92 STATIC char *nodesavestr(char *);
     93 
     94 
     95 
     96 /*
     97  * Make a copy of a parse tree.
     98  */
     99 
    100 union node *
    101 copyfunc(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 
    116 STATIC void
    117 calcsize(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 
    196 STATIC void
    197 sizenodelist(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 
    209 STATIC union node *
    210 copynode(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 
    299 STATIC struct nodelist *
    300 copynodelist(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 
    321 STATIC char *
    322 nodesavestr(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 
    341 void
    342 freefunc(n)
    343 	union node *n;
    344 {
    345 	if (n)
    346 		ckfree(n);
    347 }
    348