xref: /csrg-svn/bin/sh/show.c (revision 47144)
1*47144Sbostic /*-
2*47144Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*47144Sbostic  * All rights reserved.
4*47144Sbostic  *
5*47144Sbostic  * This code is derived from software contributed to Berkeley by
6*47144Sbostic  * Kenneth Almquist.
7*47144Sbostic  *
8*47144Sbostic  * %sccs.include.redist.c%
9*47144Sbostic  */
10*47144Sbostic 
11*47144Sbostic #ifndef lint
12*47144Sbostic static char sccsid[] = "@(#)show.c	5.1 (Berkeley) 03/07/91";
13*47144Sbostic #endif /* not lint */
14*47144Sbostic 
15*47144Sbostic #include <stdio.h>
16*47144Sbostic #include "shell.h"
17*47144Sbostic #include "parser.h"
18*47144Sbostic #include "nodes.h"
19*47144Sbostic #include "mystring.h"
20*47144Sbostic 
21*47144Sbostic 
22*47144Sbostic #ifdef DEBUG
23*47144Sbostic static shtree(), shcmd(), sharg(), indent();
24*47144Sbostic 
25*47144Sbostic 
26*47144Sbostic showtree(n)
27*47144Sbostic 	union node *n;
28*47144Sbostic 	{
29*47144Sbostic 	trputs("showtree called\n");
30*47144Sbostic 	shtree(n, 1, NULL, stdout);
31*47144Sbostic }
32*47144Sbostic 
33*47144Sbostic 
34*47144Sbostic static
35*47144Sbostic shtree(n, ind, pfx, fp)
36*47144Sbostic 	union node *n;
37*47144Sbostic 	char *pfx;
38*47144Sbostic 	FILE *fp;
39*47144Sbostic 	{
40*47144Sbostic 	struct nodelist *lp;
41*47144Sbostic 	char *s;
42*47144Sbostic 
43*47144Sbostic 	indent(ind, pfx, fp);
44*47144Sbostic 	switch(n->type) {
45*47144Sbostic 	case NSEMI:
46*47144Sbostic 		s = "; ";
47*47144Sbostic 		goto binop;
48*47144Sbostic 	case NAND:
49*47144Sbostic 		s = " && ";
50*47144Sbostic 		goto binop;
51*47144Sbostic 	case NOR:
52*47144Sbostic 		s = " || ";
53*47144Sbostic binop:
54*47144Sbostic 		shtree(n->nbinary.ch1, ind, NULL, fp);
55*47144Sbostic 	   /*    if (ind < 0) */
56*47144Sbostic 			fputs(s, fp);
57*47144Sbostic 		shtree(n->nbinary.ch2, ind, NULL, fp);
58*47144Sbostic 		break;
59*47144Sbostic 	case NCMD:
60*47144Sbostic 		shcmd(n, fp);
61*47144Sbostic 		if (ind >= 0)
62*47144Sbostic 			putc('\n', fp);
63*47144Sbostic 		break;
64*47144Sbostic 	case NPIPE:
65*47144Sbostic 		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
66*47144Sbostic 			shcmd(lp->n, fp);
67*47144Sbostic 			if (lp->next)
68*47144Sbostic 				fputs(" | ", fp);
69*47144Sbostic 		}
70*47144Sbostic 		if (n->npipe.backgnd)
71*47144Sbostic 			fputs(" &", fp);
72*47144Sbostic 		if (ind >= 0)
73*47144Sbostic 			putc('\n', fp);
74*47144Sbostic 		break;
75*47144Sbostic 	default:
76*47144Sbostic 		fprintf(fp, "<node type %d>", n->type);
77*47144Sbostic 		if (ind >= 0)
78*47144Sbostic 			putc('\n', fp);
79*47144Sbostic 		break;
80*47144Sbostic 	}
81*47144Sbostic }
82*47144Sbostic 
83*47144Sbostic 
84*47144Sbostic 
85*47144Sbostic static
86*47144Sbostic shcmd(cmd, fp)
87*47144Sbostic 	union node *cmd;
88*47144Sbostic 	FILE *fp;
89*47144Sbostic 	{
90*47144Sbostic 	union node *np;
91*47144Sbostic 	int first;
92*47144Sbostic 	char *s;
93*47144Sbostic 	int dftfd;
94*47144Sbostic 
95*47144Sbostic 	first = 1;
96*47144Sbostic 	for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
97*47144Sbostic 		if (! first)
98*47144Sbostic 			putchar(' ');
99*47144Sbostic 		sharg(np, fp);
100*47144Sbostic 		first = 0;
101*47144Sbostic 	}
102*47144Sbostic 	for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
103*47144Sbostic 		if (! first)
104*47144Sbostic 			putchar(' ');
105*47144Sbostic 		switch (np->nfile.type) {
106*47144Sbostic 			case NTO:	s = ">";  dftfd = 1; break;
107*47144Sbostic 			case NAPPEND:	s = ">>"; dftfd = 1; break;
108*47144Sbostic 			case NTOFD:	s = ">&"; dftfd = 1; break;
109*47144Sbostic 			case NFROM:	s = "<";  dftfd = 0; break;
110*47144Sbostic 			case NFROMFD:	s = "<&"; dftfd = 0; break;
111*47144Sbostic 		}
112*47144Sbostic 		if (np->nfile.fd != dftfd)
113*47144Sbostic 			fprintf(fp, "%d", np->nfile.fd);
114*47144Sbostic 		fputs(s, fp);
115*47144Sbostic 		if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
116*47144Sbostic 			fprintf(fp, "%d", np->ndup.dupfd);
117*47144Sbostic 		} else {
118*47144Sbostic 			sharg(np->nfile.fname, fp);
119*47144Sbostic 		}
120*47144Sbostic 		first = 0;
121*47144Sbostic 	}
122*47144Sbostic }
123*47144Sbostic 
124*47144Sbostic 
125*47144Sbostic 
126*47144Sbostic static
127*47144Sbostic sharg(arg, fp)
128*47144Sbostic 	union node *arg;
129*47144Sbostic 	FILE *fp;
130*47144Sbostic 	{
131*47144Sbostic 	char *p;
132*47144Sbostic 	struct nodelist *bqlist;
133*47144Sbostic 	int subtype;
134*47144Sbostic 
135*47144Sbostic 	if (arg->type != NARG) {
136*47144Sbostic 		printf("<node type %d>\n", arg->type);
137*47144Sbostic 		fflush(stdout);
138*47144Sbostic 		abort();
139*47144Sbostic 	}
140*47144Sbostic 	bqlist = arg->narg.backquote;
141*47144Sbostic 	for (p = arg->narg.text ; *p ; p++) {
142*47144Sbostic 		switch (*p) {
143*47144Sbostic 		case CTLESC:
144*47144Sbostic 			putc(*++p, fp);
145*47144Sbostic 			break;
146*47144Sbostic 		case CTLVAR:
147*47144Sbostic 			putc('$', fp);
148*47144Sbostic 			putc('{', fp);
149*47144Sbostic 			subtype = *++p;
150*47144Sbostic 			while (*p != '=')
151*47144Sbostic 				putc(*p++, fp);
152*47144Sbostic 			if (subtype & VSNUL)
153*47144Sbostic 				putc(':', fp);
154*47144Sbostic 			switch (subtype & VSTYPE) {
155*47144Sbostic 			case VSNORMAL:
156*47144Sbostic 				putc('}', fp);
157*47144Sbostic 				break;
158*47144Sbostic 			case VSMINUS:
159*47144Sbostic 				putc('-', fp);
160*47144Sbostic 				break;
161*47144Sbostic 			case VSPLUS:
162*47144Sbostic 				putc('+', fp);
163*47144Sbostic 				break;
164*47144Sbostic 			case VSQUESTION:
165*47144Sbostic 				putc('?', fp);
166*47144Sbostic 				break;
167*47144Sbostic 			case VSASSIGN:
168*47144Sbostic 				putc('=', fp);
169*47144Sbostic 				break;
170*47144Sbostic 			default:
171*47144Sbostic 				printf("<subtype %d>", subtype);
172*47144Sbostic 			}
173*47144Sbostic 			break;
174*47144Sbostic 		case CTLENDVAR:
175*47144Sbostic 		     putc('}', fp);
176*47144Sbostic 		     break;
177*47144Sbostic 		case CTLBACKQ:
178*47144Sbostic 		case CTLBACKQ|CTLQUOTE:
179*47144Sbostic 			putc('$', fp);
180*47144Sbostic 			putc('(', fp);
181*47144Sbostic 			shtree(bqlist->n, -1, NULL, fp);
182*47144Sbostic 			putc(')', fp);
183*47144Sbostic 			break;
184*47144Sbostic 		default:
185*47144Sbostic 			putc(*p, fp);
186*47144Sbostic 			break;
187*47144Sbostic 		}
188*47144Sbostic 	}
189*47144Sbostic }
190*47144Sbostic 
191*47144Sbostic 
192*47144Sbostic static
193*47144Sbostic indent(amount, pfx, fp)
194*47144Sbostic 	char *pfx;
195*47144Sbostic 	FILE *fp;
196*47144Sbostic 	{
197*47144Sbostic 	int i;
198*47144Sbostic 
199*47144Sbostic 	for (i = 0 ; i < amount ; i++) {
200*47144Sbostic 		if (pfx && i == amount - 1)
201*47144Sbostic 			fputs(pfx, fp);
202*47144Sbostic 		putc('\t', fp);
203*47144Sbostic 	}
204*47144Sbostic }
205*47144Sbostic #endif
206*47144Sbostic 
207*47144Sbostic 
208*47144Sbostic 
209*47144Sbostic /*
210*47144Sbostic  * Debugging stuff.
211*47144Sbostic  */
212*47144Sbostic 
213*47144Sbostic 
214*47144Sbostic FILE *tracefile;
215*47144Sbostic 
216*47144Sbostic 
217*47144Sbostic 
218*47144Sbostic trputc(c) {
219*47144Sbostic #ifdef DEBUG
220*47144Sbostic 	if (tracefile == NULL)
221*47144Sbostic 		return;
222*47144Sbostic 	putc(c, tracefile);
223*47144Sbostic 	if (c == '\n')
224*47144Sbostic 		fflush(tracefile);
225*47144Sbostic #endif
226*47144Sbostic }
227*47144Sbostic 
228*47144Sbostic 
229*47144Sbostic trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
230*47144Sbostic 	char *fmt;
231*47144Sbostic 	{
232*47144Sbostic #ifdef DEBUG
233*47144Sbostic 	if (tracefile == NULL)
234*47144Sbostic 		return;
235*47144Sbostic 	fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
236*47144Sbostic 	if (strchr(fmt, '\n'))
237*47144Sbostic 		fflush(tracefile);
238*47144Sbostic #endif
239*47144Sbostic }
240*47144Sbostic 
241*47144Sbostic 
242*47144Sbostic trputs(s)
243*47144Sbostic 	char *s;
244*47144Sbostic 	{
245*47144Sbostic #ifdef DEBUG
246*47144Sbostic 	if (tracefile == NULL)
247*47144Sbostic 		return;
248*47144Sbostic 	fputs(s, tracefile);
249*47144Sbostic 	if (strchr(s, '\n'))
250*47144Sbostic 		fflush(tracefile);
251*47144Sbostic #endif
252*47144Sbostic }
253*47144Sbostic 
254*47144Sbostic 
255*47144Sbostic trstring(s)
256*47144Sbostic 	char *s;
257*47144Sbostic 	{
258*47144Sbostic 	register char *p;
259*47144Sbostic 	char c;
260*47144Sbostic 
261*47144Sbostic #ifdef DEBUG
262*47144Sbostic 	if (tracefile == NULL)
263*47144Sbostic 		return;
264*47144Sbostic 	putc('"', tracefile);
265*47144Sbostic 	for (p = s ; *p ; p++) {
266*47144Sbostic 		switch (*p) {
267*47144Sbostic 		case '\n':  c = 'n';  goto backslash;
268*47144Sbostic 		case '\t':  c = 't';  goto backslash;
269*47144Sbostic 		case '\r':  c = 'r';  goto backslash;
270*47144Sbostic 		case '"':  c = '"';  goto backslash;
271*47144Sbostic 		case '\\':  c = '\\';  goto backslash;
272*47144Sbostic 		case CTLESC:  c = 'e';  goto backslash;
273*47144Sbostic 		case CTLVAR:  c = 'v';  goto backslash;
274*47144Sbostic 		case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
275*47144Sbostic 		case CTLBACKQ:  c = 'q';  goto backslash;
276*47144Sbostic 		case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
277*47144Sbostic backslash:	  putc('\\', tracefile);
278*47144Sbostic 			putc(c, tracefile);
279*47144Sbostic 			break;
280*47144Sbostic 		default:
281*47144Sbostic 			if (*p >= ' ' && *p <= '~')
282*47144Sbostic 				putc(*p, tracefile);
283*47144Sbostic 			else {
284*47144Sbostic 				putc('\\', tracefile);
285*47144Sbostic 				putc(*p >> 6 & 03, tracefile);
286*47144Sbostic 				putc(*p >> 3 & 07, tracefile);
287*47144Sbostic 				putc(*p & 07, tracefile);
288*47144Sbostic 			}
289*47144Sbostic 			break;
290*47144Sbostic 		}
291*47144Sbostic 	}
292*47144Sbostic 	putc('"', tracefile);
293*47144Sbostic #endif
294*47144Sbostic }
295*47144Sbostic 
296*47144Sbostic 
297*47144Sbostic trargs(ap)
298*47144Sbostic 	char **ap;
299*47144Sbostic 	{
300*47144Sbostic #ifdef DEBUG
301*47144Sbostic 	if (tracefile == NULL)
302*47144Sbostic 		return;
303*47144Sbostic 	while (*ap) {
304*47144Sbostic 		trstring(*ap++);
305*47144Sbostic 		if (*ap)
306*47144Sbostic 			putc(' ', tracefile);
307*47144Sbostic 		else
308*47144Sbostic 			putc('\n', tracefile);
309*47144Sbostic 	}
310*47144Sbostic 	fflush(tracefile);
311*47144Sbostic #endif
312*47144Sbostic }
313*47144Sbostic 
314*47144Sbostic 
315*47144Sbostic opentrace() {
316*47144Sbostic 	char s[100];
317*47144Sbostic 	char *p;
318*47144Sbostic 	char *getenv();
319*47144Sbostic 	int flags;
320*47144Sbostic 
321*47144Sbostic #ifdef DEBUG
322*47144Sbostic 	if ((p = getenv("HOME")) == NULL)
323*47144Sbostic 		p = "/tmp";
324*47144Sbostic 	scopy(p, s);
325*47144Sbostic 	strcat(s, "/trace");
326*47144Sbostic 	if ((tracefile = fopen(s, "a")) == NULL) {
327*47144Sbostic 		fprintf(stderr, "Can't open %s\n", s);
328*47144Sbostic 		exit(2);
329*47144Sbostic 	}
330*47144Sbostic #ifdef O_APPEND
331*47144Sbostic 	if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
332*47144Sbostic 		fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
333*47144Sbostic #endif
334*47144Sbostic 	fputs("\nTracing started.\n", tracefile);
335*47144Sbostic 	fflush(tracefile);
336*47144Sbostic #endif
337*47144Sbostic }
338