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