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