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