Blob


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]
9 void
10 pdeglob(io *f, char *s)
11 {
12 while(*s){
13 if(*s==GLOB)
14 s++;
15 pchr(f, *s++);
16 }
17 }
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;
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);
143 else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
144 pfmt(f, "%t", c1);
145 break;
149 void
150 pcmdu(io *f, tree *t) /* unambiguous */
152 if(t==0) {
153 pfmt(f, "<nil>");
154 return;
157 switch(t->type){
158 default: pfmt(f, "(bad %d %p %p %p)", t->type, c0, c1, c2);
159 break;
160 case '$': pfmt(f, "($ %u)", c0);
161 break;
162 case '"': pfmt(f, "($\" %u)", c0);
163 break;
164 case '&': pfmt(f, "(& %u)", c0);
165 break;
166 case '^': pfmt(f, "(^ %u %u)", c0, c1);
167 break;
168 case '`': pfmt(f, "(` %u)", c0);
169 break;
170 case ANDAND: pfmt(f, "(&& %u %u)", c0, c1);
171 break;
172 case BANG: pfmt(f, "(! %u)", c0);
173 break;
174 case BRACE: pfmt(f, "(brace %u)", c0);
175 break;
176 case COUNT: pfmt(f, "($# %u)", c0);
177 break;
178 case FN: pfmt(f, "(fn %u %u)", c0, c1);
179 break;
180 case IF: pfmt(f, "(if %u %u)", c0, c1);
181 break;
182 case NOT: pfmt(f, "(if not %u)", c0);
183 break;
184 case OROR: pfmt(f, "(|| %u %u)", c0, c1);
185 break;
186 case PCMD:
187 case PAREN: pfmt(f, "(paren %u)", c0);
188 break;
189 case SUB: pfmt(f, "($sub %u %u)", c0, c1);
190 break;
191 case SIMPLE: pfmt(f, "(simple %u)", c0);
192 break;
193 case SUBSHELL: pfmt(f, "(@ %u)", c0);
194 break;
195 case SWITCH: pfmt(f, "(switch %u %u)", c0, c1);
196 break;
197 case TWIDDLE: pfmt(f, "(~ %u %u)", c0, c1);
198 break;
199 case WHILE: pfmt(f, "(while %u %u)", c0, c1);
200 break;
201 case ARGLIST:
202 pfmt(f, "(arglist %u %u)", c0, c1);
203 break;
204 case ';':
205 pfmt(f, "(; %u %u)", c0, c1);
206 break;
207 case WORDS:
208 pfmt(f, "(words %u %u)", c0, c1);
209 break;
210 case FOR:
211 pfmt(f, "(for %u %u %u)", c0, c1, c2);
212 break;
213 case WORD:
214 if(t->quoted)
215 pfmt(f, "%Q", t->str);
216 else pdeglob(f, t->str);
217 break;
218 case DUP:
219 if(t->rtype==DUPFD)
220 pfmt(f, "(>[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */
221 else
222 pfmt(f, "(>[%d=]", t->fd0); /*)*/
223 pfmt(f, " %u)", c1);
224 break;
225 case PIPEFD:
226 case REDIR:
227 pfmt(f, "(");
228 switch(t->rtype){
229 case HERE:
230 pchr(f, '<');
231 case READ:
232 case RDWR:
233 pchr(f, '<');
234 if(t->rtype==RDWR)
235 pchr(f, '>');
236 if(t->fd0!=0)
237 pfmt(f, "[%d]", t->fd0);
238 break;
239 case APPEND:
240 pchr(f, '>');
241 case WRITE:
242 pchr(f, '>');
243 if(t->fd0!=1)
244 pfmt(f, "[%d]", t->fd0);
245 break;
247 if(t->rtype == HERE)
248 pfmt(f, "HERE %u)", c1);
249 else
250 pfmt(f, "%u %u)", c0, c1);
251 break;
252 case '=':
253 pfmt(f, "(%u=%u %u)", c0, c1, c2);
254 break;
255 case PIPE:
256 pfmt(f, "(|");
257 if(t->fd1==0){
258 if(t->fd0!=1)
259 pfmt(f, "[%d]", t->fd0);
261 else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
262 pfmt(f, " %u %u", c0, c1);
263 break;