xref: /csrg-svn/bin/sh/show.c (revision 69272)
147144Sbostic /*-
260712Sbostic  * Copyright (c) 1991, 1993
360712Sbostic  *	The Regents of the University of California.  All rights reserved.
447144Sbostic  *
547144Sbostic  * This code is derived from software contributed to Berkeley by
647144Sbostic  * Kenneth Almquist.
747144Sbostic  *
860711Sbostic  * %sccs.include.redist.c%
947144Sbostic  */
1047144Sbostic 
1147144Sbostic #ifndef lint
12*69272Schristos static char sccsid[] = "@(#)show.c	8.3 (Berkeley) 05/04/95";
1347144Sbostic #endif /* not lint */
1447144Sbostic 
1547144Sbostic #include <stdio.h>
16*69272Schristos #if __STDC__
17*69272Schristos #include <stdarg.h>
18*69272Schristos #else
19*69272Schristos #include <varargs.h>
20*69272Schristos #endif
21*69272Schristos 
2247144Sbostic #include "shell.h"
2347144Sbostic #include "parser.h"
2447144Sbostic #include "nodes.h"
2547144Sbostic #include "mystring.h"
26*69272Schristos #include "show.h"
2747144Sbostic 
2847144Sbostic 
2947144Sbostic #ifdef DEBUG
30*69272Schristos static void shtree __P((union node *, int, char *, FILE*));
31*69272Schristos static void shcmd __P((union node *, FILE *));
32*69272Schristos static void sharg __P((union node *, FILE *));
33*69272Schristos static void indent __P((int, char *, FILE *));
34*69272Schristos static void trstring __P((char *));
3547144Sbostic 
3647144Sbostic 
37*69272Schristos void
showtree(n)3847144Sbostic showtree(n)
3947144Sbostic 	union node *n;
40*69272Schristos {
4147144Sbostic 	trputs("showtree called\n");
4247144Sbostic 	shtree(n, 1, NULL, stdout);
4347144Sbostic }
4447144Sbostic 
4547144Sbostic 
46*69272Schristos static void
shtree(n,ind,pfx,fp)4747144Sbostic shtree(n, ind, pfx, fp)
4847144Sbostic 	union node *n;
49*69272Schristos 	int ind;
5047144Sbostic 	char *pfx;
5147144Sbostic 	FILE *fp;
52*69272Schristos {
5347144Sbostic 	struct nodelist *lp;
5447144Sbostic 	char *s;
5547144Sbostic 
5669090Sbostic 	if (n == NULL)
5769090Sbostic 		return;
5869090Sbostic 
5947144Sbostic 	indent(ind, pfx, fp);
6047144Sbostic 	switch(n->type) {
6147144Sbostic 	case NSEMI:
6247144Sbostic 		s = "; ";
6347144Sbostic 		goto binop;
6447144Sbostic 	case NAND:
6547144Sbostic 		s = " && ";
6647144Sbostic 		goto binop;
6747144Sbostic 	case NOR:
6847144Sbostic 		s = " || ";
6947144Sbostic binop:
7047144Sbostic 		shtree(n->nbinary.ch1, ind, NULL, fp);
7147144Sbostic 	   /*    if (ind < 0) */
7247144Sbostic 			fputs(s, fp);
7347144Sbostic 		shtree(n->nbinary.ch2, ind, NULL, fp);
7447144Sbostic 		break;
7547144Sbostic 	case NCMD:
7647144Sbostic 		shcmd(n, fp);
7747144Sbostic 		if (ind >= 0)
7847144Sbostic 			putc('\n', fp);
7947144Sbostic 		break;
8047144Sbostic 	case NPIPE:
8147144Sbostic 		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
8247144Sbostic 			shcmd(lp->n, fp);
8347144Sbostic 			if (lp->next)
8447144Sbostic 				fputs(" | ", fp);
8547144Sbostic 		}
8647144Sbostic 		if (n->npipe.backgnd)
8747144Sbostic 			fputs(" &", fp);
8847144Sbostic 		if (ind >= 0)
8947144Sbostic 			putc('\n', fp);
9047144Sbostic 		break;
9147144Sbostic 	default:
9247144Sbostic 		fprintf(fp, "<node type %d>", n->type);
9347144Sbostic 		if (ind >= 0)
9447144Sbostic 			putc('\n', fp);
9547144Sbostic 		break;
9647144Sbostic 	}
9747144Sbostic }
9847144Sbostic 
9947144Sbostic 
10047144Sbostic 
101*69272Schristos static void
shcmd(cmd,fp)10247144Sbostic shcmd(cmd, fp)
10347144Sbostic 	union node *cmd;
10447144Sbostic 	FILE *fp;
105*69272Schristos {
10647144Sbostic 	union node *np;
10747144Sbostic 	int first;
10847144Sbostic 	char *s;
10947144Sbostic 	int dftfd;
11047144Sbostic 
11147144Sbostic 	first = 1;
11247144Sbostic 	for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
11347144Sbostic 		if (! first)
11447144Sbostic 			putchar(' ');
11547144Sbostic 		sharg(np, fp);
11647144Sbostic 		first = 0;
11747144Sbostic 	}
11847144Sbostic 	for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
11947144Sbostic 		if (! first)
12047144Sbostic 			putchar(' ');
12147144Sbostic 		switch (np->nfile.type) {
12247144Sbostic 			case NTO:	s = ">";  dftfd = 1; break;
12347144Sbostic 			case NAPPEND:	s = ">>"; dftfd = 1; break;
12447144Sbostic 			case NTOFD:	s = ">&"; dftfd = 1; break;
12547144Sbostic 			case NFROM:	s = "<";  dftfd = 0; break;
12647144Sbostic 			case NFROMFD:	s = "<&"; dftfd = 0; break;
127*69272Schristos 			default:  	s = "*error*"; dftfd = 0; break;
12847144Sbostic 		}
12947144Sbostic 		if (np->nfile.fd != dftfd)
13047144Sbostic 			fprintf(fp, "%d", np->nfile.fd);
13147144Sbostic 		fputs(s, fp);
13247144Sbostic 		if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
13347144Sbostic 			fprintf(fp, "%d", np->ndup.dupfd);
13447144Sbostic 		} else {
13547144Sbostic 			sharg(np->nfile.fname, fp);
13647144Sbostic 		}
13747144Sbostic 		first = 0;
13847144Sbostic 	}
13947144Sbostic }
14047144Sbostic 
14147144Sbostic 
14247144Sbostic 
143*69272Schristos static void
sharg(arg,fp)14447144Sbostic sharg(arg, fp)
14547144Sbostic 	union node *arg;
14647144Sbostic 	FILE *fp;
14747144Sbostic 	{
14847144Sbostic 	char *p;
14947144Sbostic 	struct nodelist *bqlist;
15047144Sbostic 	int subtype;
15147144Sbostic 
15247144Sbostic 	if (arg->type != NARG) {
15347144Sbostic 		printf("<node type %d>\n", arg->type);
15447144Sbostic 		fflush(stdout);
15547144Sbostic 		abort();
15647144Sbostic 	}
15747144Sbostic 	bqlist = arg->narg.backquote;
15847144Sbostic 	for (p = arg->narg.text ; *p ; p++) {
15947144Sbostic 		switch (*p) {
16047144Sbostic 		case CTLESC:
16147144Sbostic 			putc(*++p, fp);
16247144Sbostic 			break;
16347144Sbostic 		case CTLVAR:
16447144Sbostic 			putc('$', fp);
16547144Sbostic 			putc('{', fp);
16647144Sbostic 			subtype = *++p;
16769090Sbostic 			if (subtype == VSLENGTH)
16869090Sbostic 				putc('#', fp);
16969090Sbostic 
17047144Sbostic 			while (*p != '=')
17147144Sbostic 				putc(*p++, fp);
17269090Sbostic 
17347144Sbostic 			if (subtype & VSNUL)
17447144Sbostic 				putc(':', fp);
17569090Sbostic 
17647144Sbostic 			switch (subtype & VSTYPE) {
17747144Sbostic 			case VSNORMAL:
17847144Sbostic 				putc('}', fp);
17947144Sbostic 				break;
18047144Sbostic 			case VSMINUS:
18147144Sbostic 				putc('-', fp);
18247144Sbostic 				break;
18347144Sbostic 			case VSPLUS:
18447144Sbostic 				putc('+', fp);
18547144Sbostic 				break;
18647144Sbostic 			case VSQUESTION:
18747144Sbostic 				putc('?', fp);
18847144Sbostic 				break;
18947144Sbostic 			case VSASSIGN:
19047144Sbostic 				putc('=', fp);
19147144Sbostic 				break;
19269090Sbostic 			case VSTRIMLEFT:
19369090Sbostic 				putc('#', fp);
19469090Sbostic 				break;
19569090Sbostic 			case VSTRIMLEFTMAX:
19669090Sbostic 				putc('#', fp);
19769090Sbostic 				putc('#', fp);
19869090Sbostic 				break;
19969090Sbostic 			case VSTRIMRIGHT:
20069090Sbostic 				putc('%', fp);
20169090Sbostic 				break;
20269090Sbostic 			case VSTRIMRIGHTMAX:
20369090Sbostic 				putc('%', fp);
20469090Sbostic 				putc('%', fp);
20569090Sbostic 				break;
20669090Sbostic 			case VSLENGTH:
20769090Sbostic 				break;
20847144Sbostic 			default:
20947144Sbostic 				printf("<subtype %d>", subtype);
21047144Sbostic 			}
21147144Sbostic 			break;
21247144Sbostic 		case CTLENDVAR:
21347144Sbostic 		     putc('}', fp);
21447144Sbostic 		     break;
21547144Sbostic 		case CTLBACKQ:
21647144Sbostic 		case CTLBACKQ|CTLQUOTE:
21747144Sbostic 			putc('$', fp);
21847144Sbostic 			putc('(', fp);
21947144Sbostic 			shtree(bqlist->n, -1, NULL, fp);
22047144Sbostic 			putc(')', fp);
22147144Sbostic 			break;
22247144Sbostic 		default:
22347144Sbostic 			putc(*p, fp);
22447144Sbostic 			break;
22547144Sbostic 		}
22647144Sbostic 	}
22747144Sbostic }
22847144Sbostic 
22947144Sbostic 
230*69272Schristos static void
indent(amount,pfx,fp)23147144Sbostic indent(amount, pfx, fp)
232*69272Schristos 	int amount;
23347144Sbostic 	char *pfx;
23447144Sbostic 	FILE *fp;
235*69272Schristos {
23647144Sbostic 	int i;
23747144Sbostic 
23847144Sbostic 	for (i = 0 ; i < amount ; i++) {
23947144Sbostic 		if (pfx && i == amount - 1)
24047144Sbostic 			fputs(pfx, fp);
24147144Sbostic 		putc('\t', fp);
24247144Sbostic 	}
24347144Sbostic }
24447144Sbostic #endif
24547144Sbostic 
24647144Sbostic 
24747144Sbostic 
24847144Sbostic /*
24947144Sbostic  * Debugging stuff.
25047144Sbostic  */
25147144Sbostic 
25247144Sbostic 
25347144Sbostic FILE *tracefile;
25447144Sbostic 
25547983Smarc #if DEBUG == 2
25647983Smarc int debug = 1;
25747983Smarc #else
25847983Smarc int debug = 0;
25947983Smarc #endif
26047144Sbostic 
26147144Sbostic 
262*69272Schristos void
trputc(c)263*69272Schristos trputc(c)
264*69272Schristos 	int c;
265*69272Schristos {
26647144Sbostic #ifdef DEBUG
26747144Sbostic 	if (tracefile == NULL)
26847144Sbostic 		return;
26947144Sbostic 	putc(c, tracefile);
27047144Sbostic 	if (c == '\n')
27147144Sbostic 		fflush(tracefile);
27247144Sbostic #endif
27347144Sbostic }
27447144Sbostic 
275*69272Schristos void
276*69272Schristos #if __STDC__
trace(const char * fmt,...)277*69272Schristos trace(const char *fmt, ...)
278*69272Schristos #else
279*69272Schristos trace(va_alist)
280*69272Schristos 	va_dcl
281*69272Schristos #endif
282*69272Schristos {
283*69272Schristos #ifdef DEBUG
284*69272Schristos 	va_list va;
285*69272Schristos #if __STDC__
286*69272Schristos 	va_start(va, fmt);
287*69272Schristos #else
28847144Sbostic 	char *fmt;
289*69272Schristos 	va_start(va);
290*69272Schristos 	fmt = va_arg(va, char *);
29147144Sbostic #endif
292*69272Schristos 	if (tracefile != NULL) {
293*69272Schristos 		(void) vfprintf(tracefile, fmt, va);
294*69272Schristos 		if (strchr(fmt, '\n'))
295*69272Schristos 			(void) fflush(tracefile);
296*69272Schristos 	}
297*69272Schristos 	va_end(va);
298*69272Schristos #endif
29947144Sbostic }
30047144Sbostic 
30147144Sbostic 
302*69272Schristos void
trputs(s)30347144Sbostic trputs(s)
30447144Sbostic 	char *s;
305*69272Schristos {
30647144Sbostic #ifdef DEBUG
30747144Sbostic 	if (tracefile == NULL)
30847144Sbostic 		return;
30947144Sbostic 	fputs(s, tracefile);
31047144Sbostic 	if (strchr(s, '\n'))
31147144Sbostic 		fflush(tracefile);
31247144Sbostic #endif
31347144Sbostic }
31447144Sbostic 
31547144Sbostic 
316*69272Schristos static void
trstring(s)31747144Sbostic trstring(s)
31847144Sbostic 	char *s;
319*69272Schristos {
32047144Sbostic 	register char *p;
32147144Sbostic 	char c;
32247144Sbostic 
32347144Sbostic #ifdef DEBUG
32447144Sbostic 	if (tracefile == NULL)
32547144Sbostic 		return;
32647144Sbostic 	putc('"', tracefile);
32747144Sbostic 	for (p = s ; *p ; p++) {
32847144Sbostic 		switch (*p) {
32947144Sbostic 		case '\n':  c = 'n';  goto backslash;
33047144Sbostic 		case '\t':  c = 't';  goto backslash;
33147144Sbostic 		case '\r':  c = 'r';  goto backslash;
33247144Sbostic 		case '"':  c = '"';  goto backslash;
33347144Sbostic 		case '\\':  c = '\\';  goto backslash;
33447144Sbostic 		case CTLESC:  c = 'e';  goto backslash;
33547144Sbostic 		case CTLVAR:  c = 'v';  goto backslash;
33647144Sbostic 		case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
33747144Sbostic 		case CTLBACKQ:  c = 'q';  goto backslash;
33847144Sbostic 		case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
33947144Sbostic backslash:	  putc('\\', tracefile);
34047144Sbostic 			putc(c, tracefile);
34147144Sbostic 			break;
34247144Sbostic 		default:
34347144Sbostic 			if (*p >= ' ' && *p <= '~')
34447144Sbostic 				putc(*p, tracefile);
34547144Sbostic 			else {
34647144Sbostic 				putc('\\', tracefile);
34747144Sbostic 				putc(*p >> 6 & 03, tracefile);
34847144Sbostic 				putc(*p >> 3 & 07, tracefile);
34947144Sbostic 				putc(*p & 07, tracefile);
35047144Sbostic 			}
35147144Sbostic 			break;
35247144Sbostic 		}
35347144Sbostic 	}
35447144Sbostic 	putc('"', tracefile);
35547144Sbostic #endif
35647144Sbostic }
35747144Sbostic 
35847144Sbostic 
359*69272Schristos void
trargs(ap)36047144Sbostic trargs(ap)
36147144Sbostic 	char **ap;
362*69272Schristos {
36347144Sbostic #ifdef DEBUG
36447144Sbostic 	if (tracefile == NULL)
36547144Sbostic 		return;
36647144Sbostic 	while (*ap) {
36747144Sbostic 		trstring(*ap++);
36847144Sbostic 		if (*ap)
36947144Sbostic 			putc(' ', tracefile);
37047144Sbostic 		else
37147144Sbostic 			putc('\n', tracefile);
37247144Sbostic 	}
37347144Sbostic 	fflush(tracefile);
37447144Sbostic #endif
37547144Sbostic }
37647144Sbostic 
37747144Sbostic 
378*69272Schristos void
opentrace()37947144Sbostic opentrace() {
38047144Sbostic 	char s[100];
38147144Sbostic 	char *getenv();
382*69272Schristos #ifdef O_APPEND
38347144Sbostic 	int flags;
384*69272Schristos #endif
38547144Sbostic 
38647144Sbostic #ifdef DEBUG
38747983Smarc 	if (!debug)
38847983Smarc 		return;
38955226Smarc #ifdef not_this_way
390*69272Schristos 	{
391*69272Schristos 		char *p;
392*69272Schristos 		if ((p = getenv("HOME")) == NULL) {
393*69272Schristos 			if (geteuid() == 0)
394*69272Schristos 				p = "/";
395*69272Schristos 			else
396*69272Schristos 				p = "/tmp";
397*69272Schristos 		}
398*69272Schristos 		scopy(p, s);
399*69272Schristos 		strcat(s, "/trace");
40047983Smarc 	}
40155226Smarc #else
40255226Smarc 	scopy("./trace", s);
40355226Smarc #endif /* not_this_way */
40447144Sbostic 	if ((tracefile = fopen(s, "a")) == NULL) {
40547144Sbostic 		fprintf(stderr, "Can't open %s\n", s);
40647983Smarc 		return;
40747144Sbostic 	}
40847144Sbostic #ifdef O_APPEND
40947144Sbostic 	if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
41047144Sbostic 		fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
41147144Sbostic #endif
41247144Sbostic 	fputs("\nTracing started.\n", tracefile);
41347144Sbostic 	fflush(tracefile);
41455226Smarc #endif /* DEBUG */
41547144Sbostic }
416