pcmd.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
pcmd.c (2681B) | |
--- | |
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… | |
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 } |