xref: /plan9-contrib/sys/src/cmd/rc/pcmd.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "rc.h"
2 #include "io.h"
3 #include "fns.h"
4 char nl='\n';		/* change to semicolon for bourne-proofing */
5 #define	c0	t->child[0]
6 #define	c1	t->child[1]
7 #define	c2	t->child[2]
8 void pdeglob(io *f, char *s)
9 {
10 	while(*s){
11 		if(*s==GLOB) s++;
12 		pchr(f, *s++);
13 	}
14 }
15 void pcmd(io *f, tree *t)
16 {
17 	if(t==0) return;
18 	switch(t->type){
19 	default:	pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); break;
20 	case '$':	pfmt(f, "$%t", c0); break;
21 	case '"':	pfmt(f, "$\"%t", c0); break;
22 	case '&':	pfmt(f, "%t&", c0); break;
23 	case '^':	pfmt(f, "%t^%t", c0, c1); break;
24 	case '`':	pfmt(f, "`%t", c0); break;
25 	case ANDAND:	pfmt(f, "%t && %t", c0, c1); break;
26 	case ARGLIST:	pfmt(f, "%t %t", c0, c1); break;
27 	case BANG:	pfmt(f, "! %t", c0); break;
28 	case BRACE:	pfmt(f, "{%t}", c0); break;
29 	case COUNT:	pfmt(f, "$#%t", c0); break;
30 	case FN:	pfmt(f, "fn %t %t", c0, c1); break;
31 	case IF:	pfmt(f, "if%t%t", c0, c1); break;
32 	case NOT:	pfmt(f, "if not %t", c0); break;
33 	case OROR:	pfmt(f, "%t || %t", c0, c1); break;
34 	case PCMD:
35 	case PAREN:	pfmt(f, "(%t)", c0); break;
36 	case SUB:	pfmt(f, "$%t(%t)", c0, c1); break;
37 	case SIMPLE:	pfmt(f, "%t", c0); break;
38 	case SUBSHELL:	pfmt(f, "@ %t", c0); break;
39 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1); break;
40 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1); break;
41 	case WHILE:	pfmt(f, "while %t%t", c0, c1); break;
42 	case ';':
43 		if(c0){
44 			if(c1) pfmt(f, "%t%c%t", c0, nl, c1);
45 			else pfmt(f, "%t", c0);
46 		}
47 		else pfmt(f, "%t", c1);
48 		break;
49 	case WORDS:
50 		if(c0) pfmt(f, "%t ", c0);
51 		pfmt(f, "%t", c1);
52 		break;
53 	case FOR:
54 		pfmt(f, "for(%t", c0);
55 		if(c1) pfmt(f, " in %t", c1);
56 		pfmt(f, ")%t", c2);
57 		break;
58 	case WORD:
59 		if(t->quoted) pfmt(f, "%Q", t->str);
60 		else pdeglob(f, t->str);
61 		break;
62 	case DUP:
63 		pfmt(f, ">[%d=", t->fd0);
64 		if(t->rtype==DUPFD) pfmt(f, "%d", t->fd1);
65 		pchr(f, ']');
66 		break;
67 	case PIPEFD:
68 	case REDIR:
69 		switch(t->rtype){
70 		case HERE:
71 			pchr(f, '<');
72 		case READ:
73 			pchr(f, '<');
74 			if(t->fd0!=0) pfmt(f, "[%d]", t->fd0);
75 			break;
76 		case APPEND:
77 			pchr(f, '>');
78 		case WRITE:
79 			pchr(f, '>');
80 			if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
81 			break;
82 		}
83 		pfmt(f, "%t", c0);
84 		if(c1) pfmt(f, " %t", c1);
85 		break;
86 	case '=':
87 		pfmt(f, "%t=%t", c0, c1);
88 		if(c2) pfmt(f, " %t", c2);
89 		break;
90 	case PIPE:
91 		pfmt(f, "%t|", c0);
92 		if(t->fd1==0){
93 			if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
94 		}
95 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
96 		pfmt(f, "%t", c1);
97 		break;
98 	}
99 }
100