1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * UNIX shell 32 */ 33 34 #include "defs.h" 35 36 static void free_arg(struct argnod *); 37 static void freeio(struct ionod *); 38 static void freereg(struct regnod *); 39 static void prarg(struct argnod *argp); 40 static void prio(struct ionod *iop); 41 42 void 43 freefunc(struct namnod *n) 44 { 45 freetree((struct trenod *)(n->namenv)); 46 } 47 48 void 49 freetree(struct trenod *t) 50 { 51 if (t) 52 { 53 int type; 54 55 type = t->tretyp & COMMSK; 56 57 switch (type) 58 { 59 case TFND: { 60 struct fndnod *f = fndptr(t); 61 62 if (f->fndref > 0) { 63 f->fndref--; 64 return; 65 } 66 free(f->fndnam); 67 freetree(f->fndval); 68 break; 69 } 70 71 case TCOM: 72 freeio(comptr(t)->comio); 73 free_arg(comptr(t)->comarg); 74 free_arg(comptr(t)->comset); 75 break; 76 77 case TFORK: 78 freeio(forkptr(t)->forkio); 79 freetree(forkptr(t)->forktre); 80 break; 81 82 case TPAR: 83 freetree(parptr(t)->partre); 84 break; 85 86 case TFIL: 87 case TLST: 88 case TAND: 89 case TORF: 90 freetree(lstptr(t)->lstlef); 91 freetree(lstptr(t)->lstrit); 92 break; 93 94 case TFOR: 95 { 96 struct fornod *f = (struct fornod *)t; 97 98 free(f->fornam); 99 freetree(f->fortre); 100 if (f->forlst) 101 { 102 freeio(f->forlst->comio); 103 free_arg(f->forlst->comarg); 104 free_arg(f->forlst->comset); 105 free(f->forlst); 106 } 107 } 108 break; 109 110 case TWH: 111 case TUN: 112 freetree(whptr(t)->whtre); 113 freetree(whptr(t)->dotre); 114 break; 115 116 case TIF: 117 freetree(ifptr(t)->iftre); 118 freetree(ifptr(t)->thtre); 119 freetree(ifptr(t)->eltre); 120 break; 121 122 case TSW: 123 free(swptr(t)->swarg); 124 freereg(swptr(t)->swlst); 125 break; 126 } 127 free(t); 128 } 129 } 130 131 static void 132 free_arg(struct argnod *argp) 133 { 134 struct argnod *sav; 135 136 while (argp) 137 { 138 sav = argp->argnxt; 139 free(argp); 140 argp = sav; 141 } 142 } 143 144 void 145 freeio(struct ionod *iop) 146 { 147 struct ionod *sav; 148 149 while (iop) 150 { 151 if (iop->iofile & IODOC) 152 { 153 154 #ifdef DEBUG 155 prs("unlinking "); 156 prs(iop->ioname); 157 newline(); 158 #endif 159 160 unlink(iop->ioname); 161 162 if (fiotemp == iop) 163 fiotemp = iop->iolst; 164 else 165 { 166 struct ionod *fiop = fiotemp; 167 168 while (fiop->iolst != iop) 169 fiop = fiop->iolst; 170 171 fiop->iolst = iop->iolst; 172 } 173 } 174 free(iop->ioname); 175 free(iop->iolink); 176 sav = iop->ionxt; 177 free(iop); 178 iop = sav; 179 } 180 } 181 182 static void 183 freereg(struct regnod *regp) 184 { 185 struct regnod *sav; 186 187 while (regp) 188 { 189 free_arg(regp->regptr); 190 freetree(regp->regcom); 191 sav = regp->regnxt; 192 free(regp); 193 regp = sav; 194 } 195 } 196 197 198 static int nonl = 0; 199 200 void 201 prbgnlst(void) 202 { 203 if (nonl) 204 prc_buff(SPACE); 205 else 206 prc_buff(NL); 207 } 208 209 void 210 prendlst(void) 211 { 212 if (nonl) { 213 prc_buff(';'); 214 prc_buff(SPACE); 215 } 216 else 217 prc_buff(NL); 218 } 219 220 void 221 prcmd(struct trenod *t) 222 { 223 nonl++; 224 prf(t); 225 nonl = 0; 226 } 227 228 void 229 prf(struct trenod *t) 230 { 231 sigchk(); 232 233 if (t) 234 { 235 int type; 236 237 type = t->tretyp & COMMSK; 238 239 switch(type) 240 { 241 case TFND: 242 { 243 struct fndnod *f = (struct fndnod *)t; 244 245 prs_buff(f->fndnam); 246 prs_buff("(){"); 247 prbgnlst(); 248 prf(f->fndval); 249 prbgnlst(); 250 prs_buff("}"); 251 break; 252 } 253 254 case TCOM: 255 if (comptr(t)->comset) { 256 prarg(comptr(t)->comset); 257 prc_buff(SPACE); 258 } 259 prarg(comptr(t)->comarg); 260 prio(comptr(t)->comio); 261 break; 262 263 case TFORK: 264 prf(forkptr(t)->forktre); 265 prio(forkptr(t)->forkio); 266 if (forkptr(t)->forktyp & FAMP) 267 prs_buff(" &"); 268 break; 269 270 case TPAR: 271 prs_buff("("); 272 prf(parptr(t)->partre); 273 prs_buff(")"); 274 break; 275 276 case TFIL: 277 prf(lstptr(t)->lstlef); 278 prs_buff(" | "); 279 prf(lstptr(t)->lstrit); 280 break; 281 282 case TLST: 283 prf(lstptr(t)->lstlef); 284 prendlst(); 285 prf(lstptr(t)->lstrit); 286 break; 287 288 case TAND: 289 prf(lstptr(t)->lstlef); 290 prs_buff(" && "); 291 prf(lstptr(t)->lstrit); 292 break; 293 294 case TORF: 295 prf(lstptr(t)->lstlef); 296 prs_buff(" || "); 297 prf(lstptr(t)->lstrit); 298 break; 299 300 case TFOR: 301 { 302 struct argnod *arg; 303 struct fornod *f = (struct fornod *)t; 304 305 prs_buff("for "); 306 prs_buff(f->fornam); 307 308 if (f->forlst) 309 { 310 arg = f->forlst->comarg; 311 prs_buff(" in"); 312 313 while(arg != ENDARGS) 314 { 315 prc_buff(SPACE); 316 prs_buff(arg->argval); 317 arg = arg->argnxt; 318 } 319 } 320 321 prendlst(); 322 prs_buff("do"); 323 prbgnlst(); 324 prf(f->fortre); 325 prendlst(); 326 prs_buff("done"); 327 } 328 break; 329 330 case TWH: 331 case TUN: 332 if (type == TWH) 333 prs_buff("while "); 334 else 335 prs_buff("until "); 336 prf(whptr(t)->whtre); 337 prendlst(); 338 prs_buff("do"); 339 prbgnlst(); 340 prf(whptr(t)->dotre); 341 prendlst(); 342 prs_buff("done"); 343 break; 344 345 case TIF: 346 { 347 struct ifnod *f = (struct ifnod *)t; 348 349 prs_buff("if "); 350 prf(f->iftre); 351 prendlst(); 352 prs_buff("then"); 353 prendlst(); 354 prf(f->thtre); 355 356 if (f->eltre) 357 { 358 prendlst(); 359 prs_buff("else"); 360 prendlst(); 361 prf(f->eltre); 362 } 363 364 prendlst(); 365 prs_buff("fi"); 366 break; 367 } 368 369 case TSW: 370 { 371 struct regnod *swl; 372 373 prs_buff("case "); 374 prs_buff(swptr(t)->swarg); 375 376 swl = swptr(t)->swlst; 377 while(swl) 378 { 379 struct argnod *arg = swl->regptr; 380 381 if (arg) 382 { 383 prs_buff(arg->argval); 384 arg = arg->argnxt; 385 } 386 387 while(arg) 388 { 389 prs_buff(" | "); 390 prs_buff(arg->argval); 391 arg = arg->argnxt; 392 } 393 394 prs_buff(")"); 395 prf(swl->regcom); 396 prs_buff(";;"); 397 swl = swl->regnxt; 398 } 399 } 400 break; 401 } 402 } 403 404 sigchk(); 405 } 406 407 static void 408 prarg(struct argnod *argp) 409 { 410 while (argp) 411 { 412 prs_buff(argp->argval); 413 argp=argp->argnxt; 414 if (argp) 415 prc_buff(SPACE); 416 } 417 } 418 419 static void 420 prio(struct ionod *iop) 421 { 422 int iof; 423 unsigned char *ion; 424 425 while (iop) 426 { 427 iof = iop->iofile; 428 ion = (unsigned char *) iop->ioname; 429 430 if (*ion) 431 { 432 prc_buff(SPACE); 433 434 prn_buff(iof & IOUFD); 435 436 if (iof & IODOC) 437 prs_buff("<<"); 438 else if (iof & IOMOV) 439 { 440 if (iof & IOPUT) 441 prs_buff(">&"); 442 else 443 prs_buff("<&"); 444 445 } 446 else if ((iof & IOPUT) == 0) 447 prc_buff('<'); 448 else if (iof & IOAPP) 449 prs_buff(">>"); 450 else 451 prc_buff('>'); 452 453 prs_buff(ion); 454 } 455 iop = iop->ionxt; 456 } 457 } 458