xref: /plan9-contrib/sys/src/cmd/rc/pcmd.c (revision 4d44ba9b9ee4246ddbd96c7fcaf0918ab92ab35a)
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 
9 void
10 pdeglob(io *f, char *s)
11 {
12 	while(*s){
13 		if(*s==GLOB)
14 			s++;
15 		pchr(f, *s++);
16 	}
17 }
18 
19 void
20 pcmd(io *f, tree *t)
21 {
22 	if(t==0)
23 		return;
24 	switch(t->type){
25 	default:	pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2);
26 	break;
27 	case '$':	pfmt(f, "$%t", c0);
28 	break;
29 	case '"':	pfmt(f, "$\"%t", c0);
30 	break;
31 	case '&':	pfmt(f, "%t&", c0);
32 	break;
33 	case '^':	pfmt(f, "%t^%t", c0, c1);
34 	break;
35 	case '`':	pfmt(f, "`%t", c0);
36 	break;
37 	case ANDAND:	pfmt(f, "%t && %t", c0, c1);
38 	break;
39 	case BANG:	pfmt(f, "! %t", c0);
40 	break;
41 	case BRACE:	pfmt(f, "{%t}", c0);
42 	break;
43 	case COUNT:	pfmt(f, "$#%t", c0);
44 	break;
45 	case FN:	pfmt(f, "fn %t %t", c0, c1);
46 	break;
47 	case IF:	pfmt(f, "if%t%t", c0, c1);
48 	break;
49 	case NOT:	pfmt(f, "if not %t", c0);
50 	break;
51 	case OROR:	pfmt(f, "%t || %t", c0, c1);
52 	break;
53 	case PCMD:
54 	case PAREN:	pfmt(f, "(%t)", c0);
55 	break;
56 	case SUB:	pfmt(f, "$%t(%t)", c0, c1);
57 	break;
58 	case SIMPLE:	pfmt(f, "%t", c0);
59 	break;
60 	case SUBSHELL:	pfmt(f, "@ %t", c0);
61 	break;
62 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1);
63 	break;
64 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1);
65 	break;
66 	case WHILE:	pfmt(f, "while %t%t", c0, c1);
67 	break;
68 	case ARGLIST:
69 		if(c0==0)
70 			pfmt(f, "%t", c1);
71 		else if(c1==0)
72 			pfmt(f, "%t", c0);
73 		else
74 			pfmt(f, "%t %t", c0, c1);
75 		break;
76 	case ';':
77 		if(c0){
78 			if(c1)
79 				pfmt(f, "%t%c%t", c0, nl, c1);
80 			else pfmt(f, "%t", c0);
81 		}
82 		else pfmt(f, "%t", c1);
83 		break;
84 	case WORDS:
85 		if(c0)
86 			pfmt(f, "%t ", c0);
87 		pfmt(f, "%t", c1);
88 		break;
89 	case FOR:
90 		pfmt(f, "for(%t", c0);
91 		if(c1)
92 			pfmt(f, " in %t", c1);
93 		pfmt(f, ")%t", c2);
94 		break;
95 	case WORD:
96 		if(t->quoted)
97 			pfmt(f, "%Q", t->str);
98 		else pdeglob(f, t->str);
99 		break;
100 	case DUP:
101 		if(t->rtype==DUPFD)
102 			pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */
103 		else
104 			pfmt(f, ">[%d=]", t->fd0);
105 		pfmt(f, "%t", c1);
106 		break;
107 	case PIPEFD:
108 	case REDIR:
109 		switch(t->rtype){
110 		case HERE:
111 			pchr(f, '<');
112 		case READ:
113 		case RDWR:
114 			pchr(f, '<');
115 			if(t->rtype==RDWR)
116 				pchr(f, '>');
117 			if(t->fd0!=0)
118 				pfmt(f, "[%d]", t->fd0);
119 			break;
120 		case APPEND:
121 			pchr(f, '>');
122 		case WRITE:
123 			pchr(f, '>');
124 			if(t->fd0!=1)
125 				pfmt(f, "[%d]", t->fd0);
126 			break;
127 		}
128 		pfmt(f, "%t", c0);
129 		if(c1)
130 			pfmt(f, " %t", c1);
131 		break;
132 	case '=':
133 		pfmt(f, "%t=%t", c0, c1);
134 		if(c2)
135 			pfmt(f, " %t", c2);
136 		break;
137 	case PIPE:
138 		pfmt(f, "%t|", c0);
139 		if(t->fd1==0){
140 			if(t->fd0!=1)
141 				pfmt(f, "[%d]", t->fd0);
142 		}
143 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
144 		pfmt(f, "%t", c1);
145 		break;
146 	}
147 }
148