xref: /csrg-svn/bin/sh/show.c (revision 60712)
147144Sbostic /*-
2*60712Sbostic  * Copyright (c) 1991, 1993
3*60712Sbostic  *	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*60712Sbostic static char sccsid[] = "@(#)show.c	8.1 (Berkeley) 05/31/93";
1347144Sbostic #endif /* not lint */
1447144Sbostic 
1547144Sbostic #include <stdio.h>
1647144Sbostic #include "shell.h"
1747144Sbostic #include "parser.h"
1847144Sbostic #include "nodes.h"
1947144Sbostic #include "mystring.h"
2047144Sbostic 
2147144Sbostic 
2247144Sbostic #ifdef DEBUG
2347144Sbostic static shtree(), shcmd(), sharg(), indent();
2447144Sbostic 
2547144Sbostic 
2647144Sbostic showtree(n)
2747144Sbostic 	union node *n;
2847144Sbostic 	{
2947144Sbostic 	trputs("showtree called\n");
3047144Sbostic 	shtree(n, 1, NULL, stdout);
3147144Sbostic }
3247144Sbostic 
3347144Sbostic 
3447144Sbostic static
3547144Sbostic shtree(n, ind, pfx, fp)
3647144Sbostic 	union node *n;
3747144Sbostic 	char *pfx;
3847144Sbostic 	FILE *fp;
3947144Sbostic 	{
4047144Sbostic 	struct nodelist *lp;
4147144Sbostic 	char *s;
4247144Sbostic 
4347144Sbostic 	indent(ind, pfx, fp);
4447144Sbostic 	switch(n->type) {
4547144Sbostic 	case NSEMI:
4647144Sbostic 		s = "; ";
4747144Sbostic 		goto binop;
4847144Sbostic 	case NAND:
4947144Sbostic 		s = " && ";
5047144Sbostic 		goto binop;
5147144Sbostic 	case NOR:
5247144Sbostic 		s = " || ";
5347144Sbostic binop:
5447144Sbostic 		shtree(n->nbinary.ch1, ind, NULL, fp);
5547144Sbostic 	   /*    if (ind < 0) */
5647144Sbostic 			fputs(s, fp);
5747144Sbostic 		shtree(n->nbinary.ch2, ind, NULL, fp);
5847144Sbostic 		break;
5947144Sbostic 	case NCMD:
6047144Sbostic 		shcmd(n, fp);
6147144Sbostic 		if (ind >= 0)
6247144Sbostic 			putc('\n', fp);
6347144Sbostic 		break;
6447144Sbostic 	case NPIPE:
6547144Sbostic 		for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
6647144Sbostic 			shcmd(lp->n, fp);
6747144Sbostic 			if (lp->next)
6847144Sbostic 				fputs(" | ", fp);
6947144Sbostic 		}
7047144Sbostic 		if (n->npipe.backgnd)
7147144Sbostic 			fputs(" &", fp);
7247144Sbostic 		if (ind >= 0)
7347144Sbostic 			putc('\n', fp);
7447144Sbostic 		break;
7547144Sbostic 	default:
7647144Sbostic 		fprintf(fp, "<node type %d>", n->type);
7747144Sbostic 		if (ind >= 0)
7847144Sbostic 			putc('\n', fp);
7947144Sbostic 		break;
8047144Sbostic 	}
8147144Sbostic }
8247144Sbostic 
8347144Sbostic 
8447144Sbostic 
8547144Sbostic static
8647144Sbostic shcmd(cmd, fp)
8747144Sbostic 	union node *cmd;
8847144Sbostic 	FILE *fp;
8947144Sbostic 	{
9047144Sbostic 	union node *np;
9147144Sbostic 	int first;
9247144Sbostic 	char *s;
9347144Sbostic 	int dftfd;
9447144Sbostic 
9547144Sbostic 	first = 1;
9647144Sbostic 	for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
9747144Sbostic 		if (! first)
9847144Sbostic 			putchar(' ');
9947144Sbostic 		sharg(np, fp);
10047144Sbostic 		first = 0;
10147144Sbostic 	}
10247144Sbostic 	for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
10347144Sbostic 		if (! first)
10447144Sbostic 			putchar(' ');
10547144Sbostic 		switch (np->nfile.type) {
10647144Sbostic 			case NTO:	s = ">";  dftfd = 1; break;
10747144Sbostic 			case NAPPEND:	s = ">>"; dftfd = 1; break;
10847144Sbostic 			case NTOFD:	s = ">&"; dftfd = 1; break;
10947144Sbostic 			case NFROM:	s = "<";  dftfd = 0; break;
11047144Sbostic 			case NFROMFD:	s = "<&"; dftfd = 0; break;
11147144Sbostic 		}
11247144Sbostic 		if (np->nfile.fd != dftfd)
11347144Sbostic 			fprintf(fp, "%d", np->nfile.fd);
11447144Sbostic 		fputs(s, fp);
11547144Sbostic 		if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
11647144Sbostic 			fprintf(fp, "%d", np->ndup.dupfd);
11747144Sbostic 		} else {
11847144Sbostic 			sharg(np->nfile.fname, fp);
11947144Sbostic 		}
12047144Sbostic 		first = 0;
12147144Sbostic 	}
12247144Sbostic }
12347144Sbostic 
12447144Sbostic 
12547144Sbostic 
12647144Sbostic static
12747144Sbostic sharg(arg, fp)
12847144Sbostic 	union node *arg;
12947144Sbostic 	FILE *fp;
13047144Sbostic 	{
13147144Sbostic 	char *p;
13247144Sbostic 	struct nodelist *bqlist;
13347144Sbostic 	int subtype;
13447144Sbostic 
13547144Sbostic 	if (arg->type != NARG) {
13647144Sbostic 		printf("<node type %d>\n", arg->type);
13747144Sbostic 		fflush(stdout);
13847144Sbostic 		abort();
13947144Sbostic 	}
14047144Sbostic 	bqlist = arg->narg.backquote;
14147144Sbostic 	for (p = arg->narg.text ; *p ; p++) {
14247144Sbostic 		switch (*p) {
14347144Sbostic 		case CTLESC:
14447144Sbostic 			putc(*++p, fp);
14547144Sbostic 			break;
14647144Sbostic 		case CTLVAR:
14747144Sbostic 			putc('$', fp);
14847144Sbostic 			putc('{', fp);
14947144Sbostic 			subtype = *++p;
15047144Sbostic 			while (*p != '=')
15147144Sbostic 				putc(*p++, fp);
15247144Sbostic 			if (subtype & VSNUL)
15347144Sbostic 				putc(':', fp);
15447144Sbostic 			switch (subtype & VSTYPE) {
15547144Sbostic 			case VSNORMAL:
15647144Sbostic 				putc('}', fp);
15747144Sbostic 				break;
15847144Sbostic 			case VSMINUS:
15947144Sbostic 				putc('-', fp);
16047144Sbostic 				break;
16147144Sbostic 			case VSPLUS:
16247144Sbostic 				putc('+', fp);
16347144Sbostic 				break;
16447144Sbostic 			case VSQUESTION:
16547144Sbostic 				putc('?', fp);
16647144Sbostic 				break;
16747144Sbostic 			case VSASSIGN:
16847144Sbostic 				putc('=', fp);
16947144Sbostic 				break;
17047144Sbostic 			default:
17147144Sbostic 				printf("<subtype %d>", subtype);
17247144Sbostic 			}
17347144Sbostic 			break;
17447144Sbostic 		case CTLENDVAR:
17547144Sbostic 		     putc('}', fp);
17647144Sbostic 		     break;
17747144Sbostic 		case CTLBACKQ:
17847144Sbostic 		case CTLBACKQ|CTLQUOTE:
17947144Sbostic 			putc('$', fp);
18047144Sbostic 			putc('(', fp);
18147144Sbostic 			shtree(bqlist->n, -1, NULL, fp);
18247144Sbostic 			putc(')', fp);
18347144Sbostic 			break;
18447144Sbostic 		default:
18547144Sbostic 			putc(*p, fp);
18647144Sbostic 			break;
18747144Sbostic 		}
18847144Sbostic 	}
18947144Sbostic }
19047144Sbostic 
19147144Sbostic 
19247144Sbostic static
19347144Sbostic indent(amount, pfx, fp)
19447144Sbostic 	char *pfx;
19547144Sbostic 	FILE *fp;
19647144Sbostic 	{
19747144Sbostic 	int i;
19847144Sbostic 
19947144Sbostic 	for (i = 0 ; i < amount ; i++) {
20047144Sbostic 		if (pfx && i == amount - 1)
20147144Sbostic 			fputs(pfx, fp);
20247144Sbostic 		putc('\t', fp);
20347144Sbostic 	}
20447144Sbostic }
20547144Sbostic #endif
20647144Sbostic 
20747144Sbostic 
20847144Sbostic 
20947144Sbostic /*
21047144Sbostic  * Debugging stuff.
21147144Sbostic  */
21247144Sbostic 
21347144Sbostic 
21447144Sbostic FILE *tracefile;
21547144Sbostic 
21647983Smarc #if DEBUG == 2
21747983Smarc int debug = 1;
21847983Smarc #else
21947983Smarc int debug = 0;
22047983Smarc #endif
22147144Sbostic 
22247144Sbostic 
22347144Sbostic trputc(c) {
22447144Sbostic #ifdef DEBUG
22547144Sbostic 	if (tracefile == NULL)
22647144Sbostic 		return;
22747144Sbostic 	putc(c, tracefile);
22847144Sbostic 	if (c == '\n')
22947144Sbostic 		fflush(tracefile);
23047144Sbostic #endif
23147144Sbostic }
23247144Sbostic 
23347144Sbostic 
23447144Sbostic trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
23547144Sbostic 	char *fmt;
23647144Sbostic 	{
23747144Sbostic #ifdef DEBUG
23847144Sbostic 	if (tracefile == NULL)
23947144Sbostic 		return;
24047144Sbostic 	fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
24147144Sbostic 	if (strchr(fmt, '\n'))
24247144Sbostic 		fflush(tracefile);
24347144Sbostic #endif
24447144Sbostic }
24547144Sbostic 
24647144Sbostic 
24747144Sbostic trputs(s)
24847144Sbostic 	char *s;
24947144Sbostic 	{
25047144Sbostic #ifdef DEBUG
25147144Sbostic 	if (tracefile == NULL)
25247144Sbostic 		return;
25347144Sbostic 	fputs(s, tracefile);
25447144Sbostic 	if (strchr(s, '\n'))
25547144Sbostic 		fflush(tracefile);
25647144Sbostic #endif
25747144Sbostic }
25847144Sbostic 
25947144Sbostic 
26047144Sbostic trstring(s)
26147144Sbostic 	char *s;
26247144Sbostic 	{
26347144Sbostic 	register char *p;
26447144Sbostic 	char c;
26547144Sbostic 
26647144Sbostic #ifdef DEBUG
26747144Sbostic 	if (tracefile == NULL)
26847144Sbostic 		return;
26947144Sbostic 	putc('"', tracefile);
27047144Sbostic 	for (p = s ; *p ; p++) {
27147144Sbostic 		switch (*p) {
27247144Sbostic 		case '\n':  c = 'n';  goto backslash;
27347144Sbostic 		case '\t':  c = 't';  goto backslash;
27447144Sbostic 		case '\r':  c = 'r';  goto backslash;
27547144Sbostic 		case '"':  c = '"';  goto backslash;
27647144Sbostic 		case '\\':  c = '\\';  goto backslash;
27747144Sbostic 		case CTLESC:  c = 'e';  goto backslash;
27847144Sbostic 		case CTLVAR:  c = 'v';  goto backslash;
27947144Sbostic 		case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
28047144Sbostic 		case CTLBACKQ:  c = 'q';  goto backslash;
28147144Sbostic 		case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
28247144Sbostic backslash:	  putc('\\', tracefile);
28347144Sbostic 			putc(c, tracefile);
28447144Sbostic 			break;
28547144Sbostic 		default:
28647144Sbostic 			if (*p >= ' ' && *p <= '~')
28747144Sbostic 				putc(*p, tracefile);
28847144Sbostic 			else {
28947144Sbostic 				putc('\\', tracefile);
29047144Sbostic 				putc(*p >> 6 & 03, tracefile);
29147144Sbostic 				putc(*p >> 3 & 07, tracefile);
29247144Sbostic 				putc(*p & 07, tracefile);
29347144Sbostic 			}
29447144Sbostic 			break;
29547144Sbostic 		}
29647144Sbostic 	}
29747144Sbostic 	putc('"', tracefile);
29847144Sbostic #endif
29947144Sbostic }
30047144Sbostic 
30147144Sbostic 
30247144Sbostic trargs(ap)
30347144Sbostic 	char **ap;
30447144Sbostic 	{
30547144Sbostic #ifdef DEBUG
30647144Sbostic 	if (tracefile == NULL)
30747144Sbostic 		return;
30847144Sbostic 	while (*ap) {
30947144Sbostic 		trstring(*ap++);
31047144Sbostic 		if (*ap)
31147144Sbostic 			putc(' ', tracefile);
31247144Sbostic 		else
31347144Sbostic 			putc('\n', tracefile);
31447144Sbostic 	}
31547144Sbostic 	fflush(tracefile);
31647144Sbostic #endif
31747144Sbostic }
31847144Sbostic 
31947144Sbostic 
32047144Sbostic opentrace() {
32147144Sbostic 	char s[100];
32247144Sbostic 	char *p;
32347144Sbostic 	char *getenv();
32447144Sbostic 	int flags;
32547144Sbostic 
32647144Sbostic #ifdef DEBUG
32747983Smarc 	if (!debug)
32847983Smarc 		return;
32955226Smarc #ifdef not_this_way
33047983Smarc 	if ((p = getenv("HOME")) == NULL) {
33155226Smarc 		if (geteuid() == 0)
33247983Smarc 			p = "/";
33347983Smarc 		else
33447983Smarc 			p = "/tmp";
33547983Smarc 	}
33647144Sbostic 	scopy(p, s);
33747144Sbostic 	strcat(s, "/trace");
33855226Smarc #else
33955226Smarc 	scopy("./trace", s);
34055226Smarc #endif /* not_this_way */
34147144Sbostic 	if ((tracefile = fopen(s, "a")) == NULL) {
34247144Sbostic 		fprintf(stderr, "Can't open %s\n", s);
34347983Smarc 		return;
34447144Sbostic 	}
34547144Sbostic #ifdef O_APPEND
34647144Sbostic 	if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
34747144Sbostic 		fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
34847144Sbostic #endif
34947144Sbostic 	fputs("\nTracing started.\n", tracefile);
35047144Sbostic 	fflush(tracefile);
35155226Smarc #endif /* DEBUG */
35247144Sbostic }
353