Blame


1 f08fdedc 2003-11-23 devnull #include "rc.h"
2 f08fdedc 2003-11-23 devnull #include "io.h"
3 f08fdedc 2003-11-23 devnull #include "exec.h"
4 f08fdedc 2003-11-23 devnull #include "fns.h"
5 f08fdedc 2003-11-23 devnull #include "getflags.h"
6 f08fdedc 2003-11-23 devnull #define c0 t->child[0]
7 f08fdedc 2003-11-23 devnull #define c1 t->child[1]
8 f08fdedc 2003-11-23 devnull #define c2 t->child[2]
9 f08fdedc 2003-11-23 devnull int codep, ncode;
10 c8f53842 2007-03-26 devnull #define emitf(x) ((void)(codep!=ncode || morecode()), codebuf[codep].f = (x), codep++)
11 c8f53842 2007-03-26 devnull #define emiti(x) ((void)(codep!=ncode || morecode()), codebuf[codep].i = (x), codep++)
12 c8f53842 2007-03-26 devnull #define emits(x) ((void)(codep!=ncode || morecode()), codebuf[codep].s = (x), codep++)
13 f08fdedc 2003-11-23 devnull void stuffdot(int);
14 f08fdedc 2003-11-23 devnull char *fnstr(tree*);
15 f08fdedc 2003-11-23 devnull void outcode(tree*, int);
16 f08fdedc 2003-11-23 devnull void codeswitch(tree*, int);
17 f08fdedc 2003-11-23 devnull int iscase(tree*);
18 f08fdedc 2003-11-23 devnull code *codecopy(code*);
19 f08fdedc 2003-11-23 devnull void codefree(code*);
20 c8f53842 2007-03-26 devnull
21 c8f53842 2007-03-26 devnull int
22 c8f53842 2007-03-26 devnull morecode(void)
23 c8f53842 2007-03-26 devnull {
24 f08fdedc 2003-11-23 devnull ncode+=100;
25 c8f53842 2007-03-26 devnull codebuf = (code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
26 c8f53842 2007-03-26 devnull if(codebuf==0)
27 c8f53842 2007-03-26 devnull panic("Can't realloc %d bytes in morecode!",
28 f08fdedc 2003-11-23 devnull ncode*sizeof codebuf[0]);
29 40402738 2007-03-26 devnull memset(codebuf+ncode-100, 0, 100*sizeof codebuf[0]);
30 f08fdedc 2003-11-23 devnull return 0;
31 f08fdedc 2003-11-23 devnull }
32 c8f53842 2007-03-26 devnull
33 c8f53842 2007-03-26 devnull void
34 c8f53842 2007-03-26 devnull stuffdot(int a)
35 c8f53842 2007-03-26 devnull {
36 c8f53842 2007-03-26 devnull if(a<0 || codep<=a)
37 c8f53842 2007-03-26 devnull panic("Bad address %d in stuffdot", a);
38 c8f53842 2007-03-26 devnull codebuf[a].i = codep;
39 f08fdedc 2003-11-23 devnull }
40 c8f53842 2007-03-26 devnull
41 c8f53842 2007-03-26 devnull int
42 c8f53842 2007-03-26 devnull compile(tree *t)
43 f08fdedc 2003-11-23 devnull {
44 47d4646e 2020-05-05 rsc if(flag['D']) {
45 47d4646e 2020-05-05 rsc struct io *s;
46 47d4646e 2020-05-05 rsc s = openstr();
47 47d4646e 2020-05-05 rsc pfmt(s, "compile: %u\n", t);
48 47d4646e 2020-05-05 rsc write(2, s->strp, strlen(s->strp));
49 47d4646e 2020-05-05 rsc closeio(s);
50 47d4646e 2020-05-05 rsc if(eflagok) // made it out of rcmain - stop executing commands, just print them
51 47d4646e 2020-05-05 rsc t = nil;
52 47d4646e 2020-05-05 rsc }
53 47d4646e 2020-05-05 rsc
54 c8f53842 2007-03-26 devnull ncode = 100;
55 c8f53842 2007-03-26 devnull codebuf = (code *)emalloc(ncode*sizeof codebuf[0]);
56 c8f53842 2007-03-26 devnull codep = 0;
57 f08fdedc 2003-11-23 devnull emiti(0); /* reference count */
58 f08fdedc 2003-11-23 devnull outcode(t, flag['e']?1:0);
59 f08fdedc 2003-11-23 devnull if(nerror){
60 f08fdedc 2003-11-23 devnull efree((char *)codebuf);
61 f08fdedc 2003-11-23 devnull return 0;
62 f08fdedc 2003-11-23 devnull }
63 f08fdedc 2003-11-23 devnull readhere();
64 f08fdedc 2003-11-23 devnull emitf(Xreturn);
65 f08fdedc 2003-11-23 devnull emitf(0);
66 f08fdedc 2003-11-23 devnull return 1;
67 f08fdedc 2003-11-23 devnull }
68 c8f53842 2007-03-26 devnull
69 c8f53842 2007-03-26 devnull void
70 c8f53842 2007-03-26 devnull cleanhere(char *f)
71 f08fdedc 2003-11-23 devnull {
72 f08fdedc 2003-11-23 devnull emitf(Xdelhere);
73 f08fdedc 2003-11-23 devnull emits(strdup(f));
74 f08fdedc 2003-11-23 devnull }
75 c8f53842 2007-03-26 devnull
76 c8f53842 2007-03-26 devnull char*
77 c8f53842 2007-03-26 devnull fnstr(tree *t)
78 f08fdedc 2003-11-23 devnull {
79 c8f53842 2007-03-26 devnull io *f = openstr();
80 f08fdedc 2003-11-23 devnull char *v;
81 f08fdedc 2003-11-23 devnull extern char nl;
82 c8f53842 2007-03-26 devnull char svnl = nl;
83 f08fdedc 2003-11-23 devnull nl=';';
84 f08fdedc 2003-11-23 devnull pfmt(f, "%t", t);
85 c8f53842 2007-03-26 devnull nl = svnl;
86 c8f53842 2007-03-26 devnull v = f->strp;
87 c8f53842 2007-03-26 devnull f->strp = 0;
88 f08fdedc 2003-11-23 devnull closeio(f);
89 f08fdedc 2003-11-23 devnull return v;
90 f08fdedc 2003-11-23 devnull }
91 c8f53842 2007-03-26 devnull
92 c8f53842 2007-03-26 devnull void
93 c8f53842 2007-03-26 devnull outcode(tree *t, int eflag)
94 f08fdedc 2003-11-23 devnull {
95 f08fdedc 2003-11-23 devnull int p, q;
96 f08fdedc 2003-11-23 devnull tree *tt;
97 c8f53842 2007-03-26 devnull if(t==0)
98 c8f53842 2007-03-26 devnull return;
99 c8f53842 2007-03-26 devnull if(t->type!=NOT && t->type!=';')
100 c8f53842 2007-03-26 devnull runq->iflast = 0;
101 f08fdedc 2003-11-23 devnull switch(t->type){
102 f08fdedc 2003-11-23 devnull default:
103 f08fdedc 2003-11-23 devnull pfmt(err, "bad type %d in outcode\n", t->type);
104 f08fdedc 2003-11-23 devnull break;
105 f08fdedc 2003-11-23 devnull case '$':
106 f08fdedc 2003-11-23 devnull emitf(Xmark);
107 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
108 f08fdedc 2003-11-23 devnull emitf(Xdol);
109 f08fdedc 2003-11-23 devnull break;
110 f08fdedc 2003-11-23 devnull case '"':
111 f08fdedc 2003-11-23 devnull emitf(Xmark);
112 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
113 f08fdedc 2003-11-23 devnull emitf(Xqdol);
114 f08fdedc 2003-11-23 devnull break;
115 f08fdedc 2003-11-23 devnull case SUB:
116 f08fdedc 2003-11-23 devnull emitf(Xmark);
117 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
118 f08fdedc 2003-11-23 devnull emitf(Xmark);
119 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
120 f08fdedc 2003-11-23 devnull emitf(Xsub);
121 f08fdedc 2003-11-23 devnull break;
122 f08fdedc 2003-11-23 devnull case '&':
123 f08fdedc 2003-11-23 devnull emitf(Xasync);
124 c8f53842 2007-03-26 devnull if(havefork){
125 c8f53842 2007-03-26 devnull p = emiti(0);
126 c8f53842 2007-03-26 devnull outcode(c0, eflag);
127 c8f53842 2007-03-26 devnull emitf(Xexit);
128 c8f53842 2007-03-26 devnull stuffdot(p);
129 c8f53842 2007-03-26 devnull } else
130 c8f53842 2007-03-26 devnull emits(fnstr(c0));
131 f08fdedc 2003-11-23 devnull break;
132 f08fdedc 2003-11-23 devnull case ';':
133 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
134 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
135 f08fdedc 2003-11-23 devnull break;
136 f08fdedc 2003-11-23 devnull case '^':
137 f08fdedc 2003-11-23 devnull emitf(Xmark);
138 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
139 f08fdedc 2003-11-23 devnull emitf(Xmark);
140 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
141 f08fdedc 2003-11-23 devnull emitf(Xconc);
142 f08fdedc 2003-11-23 devnull break;
143 f08fdedc 2003-11-23 devnull case '`':
144 f08fdedc 2003-11-23 devnull emitf(Xbackq);
145 c8f53842 2007-03-26 devnull if(havefork){
146 c8f53842 2007-03-26 devnull p = emiti(0);
147 c8f53842 2007-03-26 devnull outcode(c0, 0);
148 c8f53842 2007-03-26 devnull emitf(Xexit);
149 c8f53842 2007-03-26 devnull stuffdot(p);
150 c8f53842 2007-03-26 devnull } else
151 c8f53842 2007-03-26 devnull emits(fnstr(c0));
152 f08fdedc 2003-11-23 devnull break;
153 f08fdedc 2003-11-23 devnull case ANDAND:
154 f08fdedc 2003-11-23 devnull outcode(c0, 0);
155 f08fdedc 2003-11-23 devnull emitf(Xtrue);
156 c8f53842 2007-03-26 devnull p = emiti(0);
157 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
158 f08fdedc 2003-11-23 devnull stuffdot(p);
159 f08fdedc 2003-11-23 devnull break;
160 f08fdedc 2003-11-23 devnull case ARGLIST:
161 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
162 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
163 f08fdedc 2003-11-23 devnull break;
164 f08fdedc 2003-11-23 devnull case BANG:
165 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
166 f08fdedc 2003-11-23 devnull emitf(Xbang);
167 f08fdedc 2003-11-23 devnull break;
168 f08fdedc 2003-11-23 devnull case PCMD:
169 f08fdedc 2003-11-23 devnull case BRACE:
170 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
171 f08fdedc 2003-11-23 devnull break;
172 f08fdedc 2003-11-23 devnull case COUNT:
173 f08fdedc 2003-11-23 devnull emitf(Xmark);
174 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
175 f08fdedc 2003-11-23 devnull emitf(Xcount);
176 f08fdedc 2003-11-23 devnull break;
177 f08fdedc 2003-11-23 devnull case FN:
178 f08fdedc 2003-11-23 devnull emitf(Xmark);
179 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
180 f08fdedc 2003-11-23 devnull if(c1){
181 f08fdedc 2003-11-23 devnull emitf(Xfn);
182 c8f53842 2007-03-26 devnull p = emiti(0);
183 f08fdedc 2003-11-23 devnull emits(fnstr(c1));
184 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
185 f08fdedc 2003-11-23 devnull emitf(Xunlocal); /* get rid of $* */
186 f08fdedc 2003-11-23 devnull emitf(Xreturn);
187 f08fdedc 2003-11-23 devnull stuffdot(p);
188 f08fdedc 2003-11-23 devnull }
189 f08fdedc 2003-11-23 devnull else
190 f08fdedc 2003-11-23 devnull emitf(Xdelfn);
191 f08fdedc 2003-11-23 devnull break;
192 f08fdedc 2003-11-23 devnull case IF:
193 f08fdedc 2003-11-23 devnull outcode(c0, 0);
194 f08fdedc 2003-11-23 devnull emitf(Xif);
195 c8f53842 2007-03-26 devnull p = emiti(0);
196 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
197 f08fdedc 2003-11-23 devnull emitf(Xwastrue);
198 f08fdedc 2003-11-23 devnull stuffdot(p);
199 f08fdedc 2003-11-23 devnull break;
200 f08fdedc 2003-11-23 devnull case NOT:
201 c8f53842 2007-03-26 devnull if(!runq->iflast)
202 c8f53842 2007-03-26 devnull yyerror("`if not' does not follow `if(...)'");
203 f08fdedc 2003-11-23 devnull emitf(Xifnot);
204 c8f53842 2007-03-26 devnull p = emiti(0);
205 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
206 f08fdedc 2003-11-23 devnull stuffdot(p);
207 f08fdedc 2003-11-23 devnull break;
208 f08fdedc 2003-11-23 devnull case OROR:
209 f08fdedc 2003-11-23 devnull outcode(c0, 0);
210 f08fdedc 2003-11-23 devnull emitf(Xfalse);
211 c8f53842 2007-03-26 devnull p = emiti(0);
212 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
213 f08fdedc 2003-11-23 devnull stuffdot(p);
214 f08fdedc 2003-11-23 devnull break;
215 f08fdedc 2003-11-23 devnull case PAREN:
216 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
217 f08fdedc 2003-11-23 devnull break;
218 f08fdedc 2003-11-23 devnull case SIMPLE:
219 f08fdedc 2003-11-23 devnull emitf(Xmark);
220 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
221 f08fdedc 2003-11-23 devnull emitf(Xsimple);
222 c8f53842 2007-03-26 devnull if(eflag)
223 c8f53842 2007-03-26 devnull emitf(Xeflag);
224 f08fdedc 2003-11-23 devnull break;
225 f08fdedc 2003-11-23 devnull case SUBSHELL:
226 f08fdedc 2003-11-23 devnull emitf(Xsubshell);
227 c8f53842 2007-03-26 devnull if(havefork){
228 c8f53842 2007-03-26 devnull p = emiti(0);
229 c8f53842 2007-03-26 devnull outcode(c0, eflag);
230 c8f53842 2007-03-26 devnull emitf(Xexit);
231 c8f53842 2007-03-26 devnull stuffdot(p);
232 c8f53842 2007-03-26 devnull } else
233 c8f53842 2007-03-26 devnull emits(fnstr(c0));
234 c8f53842 2007-03-26 devnull if(eflag)
235 c8f53842 2007-03-26 devnull emitf(Xeflag);
236 f08fdedc 2003-11-23 devnull break;
237 f08fdedc 2003-11-23 devnull case SWITCH:
238 f08fdedc 2003-11-23 devnull codeswitch(t, eflag);
239 f08fdedc 2003-11-23 devnull break;
240 f08fdedc 2003-11-23 devnull case TWIDDLE:
241 f08fdedc 2003-11-23 devnull emitf(Xmark);
242 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
243 f08fdedc 2003-11-23 devnull emitf(Xmark);
244 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
245 f08fdedc 2003-11-23 devnull emitf(Xmatch);
246 c8f53842 2007-03-26 devnull if(eflag)
247 c8f53842 2007-03-26 devnull emitf(Xeflag);
248 f08fdedc 2003-11-23 devnull break;
249 f08fdedc 2003-11-23 devnull case WHILE:
250 c8f53842 2007-03-26 devnull q = codep;
251 f08fdedc 2003-11-23 devnull outcode(c0, 0);
252 c8f53842 2007-03-26 devnull if(q==codep)
253 c8f53842 2007-03-26 devnull emitf(Xsettrue); /* empty condition == while(true) */
254 f08fdedc 2003-11-23 devnull emitf(Xtrue);
255 c8f53842 2007-03-26 devnull p = emiti(0);
256 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
257 f08fdedc 2003-11-23 devnull emitf(Xjump);
258 f08fdedc 2003-11-23 devnull emiti(q);
259 f08fdedc 2003-11-23 devnull stuffdot(p);
260 f08fdedc 2003-11-23 devnull break;
261 f08fdedc 2003-11-23 devnull case WORDS:
262 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
263 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
264 f08fdedc 2003-11-23 devnull break;
265 f08fdedc 2003-11-23 devnull case FOR:
266 f08fdedc 2003-11-23 devnull emitf(Xmark);
267 f08fdedc 2003-11-23 devnull if(c1){
268 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
269 f08fdedc 2003-11-23 devnull emitf(Xglob);
270 f08fdedc 2003-11-23 devnull }
271 f08fdedc 2003-11-23 devnull else{
272 f08fdedc 2003-11-23 devnull emitf(Xmark);
273 f08fdedc 2003-11-23 devnull emitf(Xword);
274 f08fdedc 2003-11-23 devnull emits(strdup("*"));
275 f08fdedc 2003-11-23 devnull emitf(Xdol);
276 f08fdedc 2003-11-23 devnull }
277 f08fdedc 2003-11-23 devnull emitf(Xmark); /* dummy value for Xlocal */
278 f08fdedc 2003-11-23 devnull emitf(Xmark);
279 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
280 f08fdedc 2003-11-23 devnull emitf(Xlocal);
281 c8f53842 2007-03-26 devnull p = emitf(Xfor);
282 c8f53842 2007-03-26 devnull q = emiti(0);
283 f08fdedc 2003-11-23 devnull outcode(c2, eflag);
284 f08fdedc 2003-11-23 devnull emitf(Xjump);
285 f08fdedc 2003-11-23 devnull emiti(p);
286 f08fdedc 2003-11-23 devnull stuffdot(q);
287 f08fdedc 2003-11-23 devnull emitf(Xunlocal);
288 f08fdedc 2003-11-23 devnull break;
289 f08fdedc 2003-11-23 devnull case WORD:
290 f08fdedc 2003-11-23 devnull emitf(Xword);
291 f08fdedc 2003-11-23 devnull emits(strdup(t->str));
292 f08fdedc 2003-11-23 devnull break;
293 f08fdedc 2003-11-23 devnull case DUP:
294 f08fdedc 2003-11-23 devnull if(t->rtype==DUPFD){
295 f08fdedc 2003-11-23 devnull emitf(Xdup);
296 f08fdedc 2003-11-23 devnull emiti(t->fd0);
297 f08fdedc 2003-11-23 devnull emiti(t->fd1);
298 f08fdedc 2003-11-23 devnull }
299 f08fdedc 2003-11-23 devnull else{
300 f08fdedc 2003-11-23 devnull emitf(Xclose);
301 f08fdedc 2003-11-23 devnull emiti(t->fd0);
302 f08fdedc 2003-11-23 devnull }
303 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
304 f08fdedc 2003-11-23 devnull emitf(Xpopredir);
305 f08fdedc 2003-11-23 devnull break;
306 f08fdedc 2003-11-23 devnull case PIPEFD:
307 f08fdedc 2003-11-23 devnull emitf(Xpipefd);
308 f08fdedc 2003-11-23 devnull emiti(t->rtype);
309 c8f53842 2007-03-26 devnull if(havefork){
310 c8f53842 2007-03-26 devnull p = emiti(0);
311 c8f53842 2007-03-26 devnull outcode(c0, eflag);
312 c8f53842 2007-03-26 devnull emitf(Xexit);
313 c8f53842 2007-03-26 devnull stuffdot(p);
314 c8f53842 2007-03-26 devnull } else {
315 c8f53842 2007-03-26 devnull emits(fnstr(c0));
316 c8f53842 2007-03-26 devnull }
317 f08fdedc 2003-11-23 devnull break;
318 f08fdedc 2003-11-23 devnull case REDIR:
319 f08fdedc 2003-11-23 devnull emitf(Xmark);
320 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
321 f08fdedc 2003-11-23 devnull emitf(Xglob);
322 f08fdedc 2003-11-23 devnull switch(t->rtype){
323 f08fdedc 2003-11-23 devnull case APPEND:
324 f08fdedc 2003-11-23 devnull emitf(Xappend);
325 f08fdedc 2003-11-23 devnull break;
326 f08fdedc 2003-11-23 devnull case WRITE:
327 f08fdedc 2003-11-23 devnull emitf(Xwrite);
328 f08fdedc 2003-11-23 devnull break;
329 f08fdedc 2003-11-23 devnull case READ:
330 f08fdedc 2003-11-23 devnull case HERE:
331 f08fdedc 2003-11-23 devnull emitf(Xread);
332 f08fdedc 2003-11-23 devnull break;
333 c8f53842 2007-03-26 devnull case RDWR:
334 c8f53842 2007-03-26 devnull emitf(Xrdwr);
335 c8f53842 2007-03-26 devnull break;
336 f08fdedc 2003-11-23 devnull }
337 f08fdedc 2003-11-23 devnull emiti(t->fd0);
338 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
339 f08fdedc 2003-11-23 devnull emitf(Xpopredir);
340 f08fdedc 2003-11-23 devnull break;
341 f08fdedc 2003-11-23 devnull case '=':
342 c8f53842 2007-03-26 devnull tt = t;
343 c8f53842 2007-03-26 devnull for(;t && t->type=='=';t = c2);
344 f08fdedc 2003-11-23 devnull if(t){
345 c8f53842 2007-03-26 devnull for(t = tt;t->type=='=';t = c2){
346 f08fdedc 2003-11-23 devnull emitf(Xmark);
347 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
348 f08fdedc 2003-11-23 devnull emitf(Xmark);
349 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
350 f08fdedc 2003-11-23 devnull emitf(Xlocal);
351 f08fdedc 2003-11-23 devnull }
352 362264eb 2008-08-14 rsc outcode(t, eflag);
353 362264eb 2008-08-14 rsc for(t = tt; t->type=='='; t = c2)
354 362264eb 2008-08-14 rsc emitf(Xunlocal);
355 f08fdedc 2003-11-23 devnull }
356 f08fdedc 2003-11-23 devnull else{
357 c8f53842 2007-03-26 devnull for(t = tt;t;t = c2){
358 f08fdedc 2003-11-23 devnull emitf(Xmark);
359 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
360 f08fdedc 2003-11-23 devnull emitf(Xmark);
361 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
362 f08fdedc 2003-11-23 devnull emitf(Xassign);
363 f08fdedc 2003-11-23 devnull }
364 f08fdedc 2003-11-23 devnull }
365 c8f53842 2007-03-26 devnull t = tt; /* so tests below will work */
366 f08fdedc 2003-11-23 devnull break;
367 f08fdedc 2003-11-23 devnull case PIPE:
368 f08fdedc 2003-11-23 devnull emitf(Xpipe);
369 f08fdedc 2003-11-23 devnull emiti(t->fd0);
370 f08fdedc 2003-11-23 devnull emiti(t->fd1);
371 c8f53842 2007-03-26 devnull if(havefork){
372 c8f53842 2007-03-26 devnull p = emiti(0);
373 c8f53842 2007-03-26 devnull q = emiti(0);
374 c8f53842 2007-03-26 devnull outcode(c0, eflag);
375 c8f53842 2007-03-26 devnull emitf(Xexit);
376 c8f53842 2007-03-26 devnull stuffdot(p);
377 c8f53842 2007-03-26 devnull } else {
378 c8f53842 2007-03-26 devnull emits(fnstr(c0));
379 c8f53842 2007-03-26 devnull q = emiti(0);
380 c8f53842 2007-03-26 devnull }
381 f08fdedc 2003-11-23 devnull outcode(c1, eflag);
382 f08fdedc 2003-11-23 devnull emitf(Xreturn);
383 f08fdedc 2003-11-23 devnull stuffdot(q);
384 f08fdedc 2003-11-23 devnull emitf(Xpipewait);
385 f08fdedc 2003-11-23 devnull break;
386 f08fdedc 2003-11-23 devnull }
387 f08fdedc 2003-11-23 devnull if(t->type!=NOT && t->type!=';')
388 c8f53842 2007-03-26 devnull runq->iflast = t->type==IF;
389 c8f53842 2007-03-26 devnull else if(c0) runq->iflast = c0->type==IF;
390 f08fdedc 2003-11-23 devnull }
391 f08fdedc 2003-11-23 devnull /*
392 f08fdedc 2003-11-23 devnull * switch code looks like this:
393 f08fdedc 2003-11-23 devnull * Xmark
394 f08fdedc 2003-11-23 devnull * (get switch value)
395 f08fdedc 2003-11-23 devnull * Xjump 1f
396 f08fdedc 2003-11-23 devnull * out: Xjump leave
397 f08fdedc 2003-11-23 devnull * 1: Xmark
398 f08fdedc 2003-11-23 devnull * (get case values)
399 f08fdedc 2003-11-23 devnull * Xcase 1f
400 f08fdedc 2003-11-23 devnull * (commands)
401 f08fdedc 2003-11-23 devnull * Xjump out
402 f08fdedc 2003-11-23 devnull * 1: Xmark
403 f08fdedc 2003-11-23 devnull * (get case values)
404 f08fdedc 2003-11-23 devnull * Xcase 1f
405 f08fdedc 2003-11-23 devnull * (commands)
406 f08fdedc 2003-11-23 devnull * Xjump out
407 f08fdedc 2003-11-23 devnull * 1:
408 f08fdedc 2003-11-23 devnull * leave:
409 f08fdedc 2003-11-23 devnull * Xpopm
410 f08fdedc 2003-11-23 devnull */
411 c8f53842 2007-03-26 devnull
412 c8f53842 2007-03-26 devnull void
413 c8f53842 2007-03-26 devnull codeswitch(tree *t, int eflag)
414 f08fdedc 2003-11-23 devnull {
415 f08fdedc 2003-11-23 devnull int leave; /* patch jump address to leave switch */
416 f08fdedc 2003-11-23 devnull int out; /* jump here to leave switch */
417 f08fdedc 2003-11-23 devnull int nextcase; /* patch jump address to next case */
418 f08fdedc 2003-11-23 devnull tree *tt;
419 f08fdedc 2003-11-23 devnull if(c1->child[0]==nil
420 f08fdedc 2003-11-23 devnull || c1->child[0]->type!=';'
421 f08fdedc 2003-11-23 devnull || !iscase(c1->child[0]->child[0])){
422 f08fdedc 2003-11-23 devnull yyerror("case missing in switch");
423 f08fdedc 2003-11-23 devnull return;
424 f08fdedc 2003-11-23 devnull }
425 f08fdedc 2003-11-23 devnull emitf(Xmark);
426 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
427 f08fdedc 2003-11-23 devnull emitf(Xjump);
428 c8f53842 2007-03-26 devnull nextcase = emiti(0);
429 c8f53842 2007-03-26 devnull out = emitf(Xjump);
430 c8f53842 2007-03-26 devnull leave = emiti(0);
431 f08fdedc 2003-11-23 devnull stuffdot(nextcase);
432 c8f53842 2007-03-26 devnull t = c1->child[0];
433 f08fdedc 2003-11-23 devnull while(t->type==';'){
434 c8f53842 2007-03-26 devnull tt = c1;
435 f08fdedc 2003-11-23 devnull emitf(Xmark);
436 c8f53842 2007-03-26 devnull for(t = c0->child[0];t->type==ARGLIST;t = c0) outcode(c1, eflag);
437 f08fdedc 2003-11-23 devnull emitf(Xcase);
438 c8f53842 2007-03-26 devnull nextcase = emiti(0);
439 c8f53842 2007-03-26 devnull t = tt;
440 f08fdedc 2003-11-23 devnull for(;;){
441 f08fdedc 2003-11-23 devnull if(t->type==';'){
442 f08fdedc 2003-11-23 devnull if(iscase(c0)) break;
443 f08fdedc 2003-11-23 devnull outcode(c0, eflag);
444 c8f53842 2007-03-26 devnull t = c1;
445 f08fdedc 2003-11-23 devnull }
446 f08fdedc 2003-11-23 devnull else{
447 f08fdedc 2003-11-23 devnull if(!iscase(t)) outcode(t, eflag);
448 f08fdedc 2003-11-23 devnull break;
449 f08fdedc 2003-11-23 devnull }
450 f08fdedc 2003-11-23 devnull }
451 f08fdedc 2003-11-23 devnull emitf(Xjump);
452 f08fdedc 2003-11-23 devnull emiti(out);
453 f08fdedc 2003-11-23 devnull stuffdot(nextcase);
454 f08fdedc 2003-11-23 devnull }
455 f08fdedc 2003-11-23 devnull stuffdot(leave);
456 f08fdedc 2003-11-23 devnull emitf(Xpopm);
457 f08fdedc 2003-11-23 devnull }
458 c8f53842 2007-03-26 devnull
459 c8f53842 2007-03-26 devnull int
460 c8f53842 2007-03-26 devnull iscase(tree *t)
461 f08fdedc 2003-11-23 devnull {
462 c8f53842 2007-03-26 devnull if(t->type!=SIMPLE)
463 c8f53842 2007-03-26 devnull return 0;
464 c8f53842 2007-03-26 devnull do t = c0; while(t->type==ARGLIST);
465 f08fdedc 2003-11-23 devnull return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0;
466 f08fdedc 2003-11-23 devnull }
467 c8f53842 2007-03-26 devnull
468 c8f53842 2007-03-26 devnull code*
469 c8f53842 2007-03-26 devnull codecopy(code *cp)
470 f08fdedc 2003-11-23 devnull {
471 f08fdedc 2003-11-23 devnull cp[0].i++;
472 f08fdedc 2003-11-23 devnull return cp;
473 f08fdedc 2003-11-23 devnull }
474 c8f53842 2007-03-26 devnull
475 c8f53842 2007-03-26 devnull void
476 c8f53842 2007-03-26 devnull codefree(code *cp)
477 f08fdedc 2003-11-23 devnull {
478 f08fdedc 2003-11-23 devnull code *p;
479 c8f53842 2007-03-26 devnull if(--cp[0].i!=0)
480 c8f53842 2007-03-26 devnull return;
481 c8f53842 2007-03-26 devnull for(p = cp+1;p->f;p++){
482 f08fdedc 2003-11-23 devnull if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite
483 c8f53842 2007-03-26 devnull || p->f==Xrdwr
484 f08fdedc 2003-11-23 devnull || p->f==Xasync || p->f==Xbackq || p->f==Xcase || p->f==Xfalse
485 f08fdedc 2003-11-23 devnull || p->f==Xfor || p->f==Xjump
486 f08fdedc 2003-11-23 devnull || p->f==Xsubshell || p->f==Xtrue) p++;
487 f08fdedc 2003-11-23 devnull else if(p->f==Xdup || p->f==Xpipefd) p+=2;
488 f08fdedc 2003-11-23 devnull else if(p->f==Xpipe) p+=4;
489 f08fdedc 2003-11-23 devnull else if(p->f==Xword || p->f==Xdelhere) efree((++p)->s);
490 f08fdedc 2003-11-23 devnull else if(p->f==Xfn){
491 f08fdedc 2003-11-23 devnull efree(p[2].s);
492 f08fdedc 2003-11-23 devnull p+=2;
493 f08fdedc 2003-11-23 devnull }
494 f08fdedc 2003-11-23 devnull }
495 f08fdedc 2003-11-23 devnull efree((char *)cp);
496 f08fdedc 2003-11-23 devnull }