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