xref: /plan9/sys/src/cmd/rc/pcmd.c (revision 0b459c2cb92b7c9d88818e9a2f72e678e5bc4553)
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 BANG:	pfmt(f, "! %t", c0); break;
27 	case BRACE:	pfmt(f, "{%t}", c0); break;
28 	case COUNT:	pfmt(f, "$#%t", c0); break;
29 	case FN:	pfmt(f, "fn %t %t", c0, c1); break;
30 	case IF:	pfmt(f, "if%t%t", c0, c1); break;
31 	case NOT:	pfmt(f, "if not %t", c0); break;
32 	case OROR:	pfmt(f, "%t || %t", c0, c1); break;
33 	case PCMD:
34 	case PAREN:	pfmt(f, "(%t)", c0); break;
35 	case SUB:	pfmt(f, "$%t(%t)", c0, c1); break;
36 	case SIMPLE:	pfmt(f, "%t", c0); break;
37 	case SUBSHELL:	pfmt(f, "@ %t", c0); break;
38 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1); break;
39 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1); break;
40 	case WHILE:	pfmt(f, "while %t%t", c0, c1); break;
41 	case ARGLIST:
42 		if(c0==0)
43 			pfmt(f, "%t", c1);
44 		else if(c1==0)
45 			pfmt(f, "%t", c0);
46 		else
47 			pfmt(f, "%t %t", c0, c1);
48 		break;
49 	case ';':
50 		if(c0){
51 			if(c1) pfmt(f, "%t%c%t", c0, nl, c1);
52 			else pfmt(f, "%t", c0);
53 		}
54 		else pfmt(f, "%t", c1);
55 		break;
56 	case WORDS:
57 		if(c0) pfmt(f, "%t ", c0);
58 		pfmt(f, "%t", c1);
59 		break;
60 	case FOR:
61 		pfmt(f, "for(%t", c0);
62 		if(c1) pfmt(f, " in %t", c1);
63 		pfmt(f, ")%t", c2);
64 		break;
65 	case WORD:
66 		if(t->quoted) pfmt(f, "%Q", t->str);
67 		else pdeglob(f, t->str);
68 		break;
69 	case DUP:
70 		if(t->rtype==DUPFD)
71 			pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */
72 		else
73 			pfmt(f, ">[%d=]", t->fd0);
74 		pfmt(f, "%t", c1);
75 		break;
76 	case PIPEFD:
77 	case REDIR:
78 		switch(t->rtype){
79 		case HERE:
80 			pchr(f, '<');
81 		case READ:
82 			pchr(f, '<');
83 			if(t->fd0!=0) pfmt(f, "[%d]", t->fd0);
84 			break;
85 		case APPEND:
86 			pchr(f, '>');
87 		case WRITE:
88 			pchr(f, '>');
89 			if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
90 			break;
91 		}
92 		pfmt(f, "%t", c0);
93 		if(c1) pfmt(f, " %t", c1);
94 		break;
95 	case '=':
96 		pfmt(f, "%t=%t", c0, c1);
97 		if(c2) pfmt(f, " %t", c2);
98 		break;
99 	case PIPE:
100 		pfmt(f, "%t|", c0);
101 		if(t->fd1==0){
102 			if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
103 		}
104 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
105 		pfmt(f, "%t", c1);
106 		break;
107 	}
108 }
109