Home | History | Annotate | Download | only in sh
      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