Commit | Line | Data |
a687059c |
1 | /* This file is included by eval.c. It's separate from eval.c to keep |
2 | * kit sizes from getting too big. |
3 | */ |
4 | |
0d3e774c |
5 | /* $Header: evalargs.xc,v 3.0.1.3 89/11/17 15:25:07 lwall Locked $ |
a687059c |
6 | * |
7 | * $Log: evalargs.xc,v $ |
0d3e774c |
8 | * Revision 3.0.1.3 89/11/17 15:25:07 lwall |
9 | * patch5: constant numeric subscripts disappeared in ?: |
10 | * |
bf38876a |
11 | * Revision 3.0.1.2 89/11/11 04:33:05 lwall |
12 | * patch2: Configure now locates csh |
13 | * |
03a14243 |
14 | * Revision 3.0.1.1 89/10/26 23:12:55 lwall |
15 | * patch1: glob didn't free a temporary string |
16 | * |
a687059c |
17 | * Revision 3.0 89/10/18 15:17:16 lwall |
18 | * 3.0 baseline |
19 | * |
20 | */ |
21 | |
22 | for (anum = 1; anum <= maxarg; anum++) { |
23 | argflags = arg[anum].arg_flags; |
24 | argtype = arg[anum].arg_type; |
25 | argptr = arg[anum].arg_ptr; |
26 | re_eval: |
27 | switch (argtype) { |
28 | default: |
29 | st[++sp] = &str_undef; |
30 | #ifdef DEBUGGING |
31 | tmps = "NULL"; |
32 | #endif |
33 | break; |
34 | case A_EXPR: |
35 | #ifdef DEBUGGING |
36 | if (debug & 8) { |
37 | tmps = "EXPR"; |
38 | deb("%d.EXPR =>\n",anum); |
39 | } |
40 | #endif |
41 | sp = eval(argptr.arg_arg, |
42 | (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp); |
43 | if (sp + (maxarg - anum) > stack->ary_max) |
44 | astore(stack, sp + (maxarg - anum), Nullstr); |
45 | st = stack->ary_array; /* possibly reallocated */ |
46 | break; |
47 | case A_CMD: |
48 | #ifdef DEBUGGING |
49 | if (debug & 8) { |
50 | tmps = "CMD"; |
51 | deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd); |
52 | } |
53 | #endif |
54 | sp = cmd_exec(argptr.arg_cmd, gimme, sp); |
55 | if (sp + (maxarg - anum) > stack->ary_max) |
56 | astore(stack, sp + (maxarg - anum), Nullstr); |
57 | st = stack->ary_array; /* possibly reallocated */ |
58 | break; |
59 | case A_LARYSTAB: |
60 | ++sp; |
0d3e774c |
61 | switch (optype) { |
62 | case O_ITEM2: argtype = 2; break; |
63 | case O_ITEM3: argtype = 3; break; |
64 | default: argtype = anum; break; |
65 | } |
a687059c |
66 | str = afetch(stab_array(argptr.arg_stab), |
0d3e774c |
67 | arg[argtype].arg_len - arybase, TRUE); |
a687059c |
68 | #ifdef DEBUGGING |
69 | if (debug & 8) { |
70 | (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab), |
0d3e774c |
71 | arg[argtype].arg_len); |
a687059c |
72 | tmps = buf; |
73 | } |
74 | #endif |
75 | goto do_crement; |
76 | case A_ARYSTAB: |
0d3e774c |
77 | switch (optype) { |
78 | case O_ITEM2: argtype = 2; break; |
79 | case O_ITEM3: argtype = 3; break; |
80 | default: argtype = anum; break; |
81 | } |
a687059c |
82 | st[++sp] = afetch(stab_array(argptr.arg_stab), |
0d3e774c |
83 | arg[argtype].arg_len - arybase, FALSE); |
a687059c |
84 | if (!st[sp]) |
85 | st[sp] = &str_undef; |
86 | #ifdef DEBUGGING |
87 | if (debug & 8) { |
88 | (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab), |
0d3e774c |
89 | arg[argtype].arg_len); |
a687059c |
90 | tmps = buf; |
91 | } |
92 | #endif |
93 | break; |
94 | case A_STAR: |
95 | st[++sp] = (STR*)argptr.arg_stab; |
96 | #ifdef DEBUGGING |
97 | if (debug & 8) { |
98 | (void)sprintf(buf,"STAR *%s",stab_name(argptr.arg_stab)); |
99 | tmps = buf; |
100 | } |
101 | #endif |
102 | break; |
103 | case A_LSTAR: |
104 | str = st[++sp] = (STR*)argptr.arg_stab; |
105 | #ifdef DEBUGGING |
106 | if (debug & 8) { |
107 | (void)sprintf(buf,"LSTAR *%s",stab_name(argptr.arg_stab)); |
108 | tmps = buf; |
109 | } |
110 | #endif |
111 | break; |
112 | case A_STAB: |
113 | st[++sp] = STAB_STR(argptr.arg_stab); |
114 | #ifdef DEBUGGING |
115 | if (debug & 8) { |
116 | (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab)); |
117 | tmps = buf; |
118 | } |
119 | #endif |
120 | break; |
121 | case A_LEXPR: |
122 | #ifdef DEBUGGING |
123 | if (debug & 8) { |
124 | tmps = "LEXPR"; |
125 | deb("%d.LEXPR =>\n",anum); |
126 | } |
127 | #endif |
128 | if (argflags & AF_ARYOK) { |
129 | sp = eval(argptr.arg_arg, G_ARRAY, sp); |
130 | if (sp + (maxarg - anum) > stack->ary_max) |
131 | astore(stack, sp + (maxarg - anum), Nullstr); |
132 | st = stack->ary_array; /* possibly reallocated */ |
133 | } |
134 | else { |
135 | sp = eval(argptr.arg_arg, G_SCALAR, sp); |
136 | st = stack->ary_array; /* possibly reallocated */ |
137 | str = st[sp]; |
138 | goto do_crement; |
139 | } |
140 | break; |
141 | case A_LVAL: |
142 | #ifdef DEBUGGING |
143 | if (debug & 8) { |
144 | (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab)); |
145 | tmps = buf; |
146 | } |
147 | #endif |
148 | ++sp; |
149 | str = STAB_STR(argptr.arg_stab); |
150 | if (!str) |
151 | fatal("panic: A_LVAL"); |
152 | do_crement: |
153 | assigning = TRUE; |
154 | if (argflags & AF_PRE) { |
155 | if (argflags & AF_UP) |
156 | str_inc(str); |
157 | else |
158 | str_dec(str); |
159 | STABSET(str); |
160 | st[sp] = str; |
161 | str = arg->arg_ptr.arg_str; |
162 | } |
163 | else if (argflags & AF_POST) { |
164 | st[sp] = str_static(str); |
165 | if (argflags & AF_UP) |
166 | str_inc(str); |
167 | else |
168 | str_dec(str); |
169 | STABSET(str); |
170 | str = arg->arg_ptr.arg_str; |
171 | } |
172 | else |
173 | st[sp] = str; |
174 | break; |
175 | case A_LARYLEN: |
176 | ++sp; |
177 | stab = argptr.arg_stab; |
178 | str = stab_array(argptr.arg_stab)->ary_magic; |
179 | if (argflags & (AF_PRE|AF_POST)) |
180 | str_numset(str,(double)(stab_array(stab)->ary_fill+arybase)); |
181 | #ifdef DEBUGGING |
182 | tmps = "LARYLEN"; |
183 | #endif |
184 | if (!str) |
185 | fatal("panic: A_LEXPR"); |
186 | goto do_crement; |
187 | case A_ARYLEN: |
188 | stab = argptr.arg_stab; |
189 | st[++sp] = stab_array(stab)->ary_magic; |
190 | str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase)); |
191 | #ifdef DEBUGGING |
192 | tmps = "ARYLEN"; |
193 | #endif |
194 | break; |
195 | case A_SINGLE: |
196 | st[++sp] = argptr.arg_str; |
197 | #ifdef DEBUGGING |
198 | tmps = "SINGLE"; |
199 | #endif |
200 | break; |
201 | case A_DOUBLE: |
202 | (void) interp(str,argptr.arg_str,sp); |
203 | st = stack->ary_array; |
204 | st[++sp] = str; |
205 | #ifdef DEBUGGING |
206 | tmps = "DOUBLE"; |
207 | #endif |
208 | break; |
209 | case A_BACKTICK: |
210 | tmps = str_get(interp(str,argptr.arg_str,sp)); |
211 | st = stack->ary_array; |
212 | #ifdef TAINT |
213 | taintproper("Insecure dependency in ``"); |
214 | #endif |
215 | fp = mypopen(tmps,"r"); |
216 | str_set(str,""); |
217 | if (fp) { |
218 | while (str_gets(str,fp,str->str_cur) != Nullch) |
219 | ; |
220 | statusvalue = mypclose(fp); |
221 | } |
222 | else |
223 | statusvalue = -1; |
224 | |
225 | st[++sp] = str; |
226 | #ifdef DEBUGGING |
227 | tmps = "BACK"; |
228 | #endif |
229 | break; |
230 | case A_WANTARRAY: |
231 | { |
232 | extern int wantarray; |
233 | |
234 | if (wantarray == G_ARRAY) |
235 | st[++sp] = &str_yes; |
236 | else |
237 | st[++sp] = &str_no; |
238 | } |
239 | #ifdef DEBUGGING |
240 | tmps = "WANTARRAY"; |
241 | #endif |
242 | break; |
243 | case A_INDREAD: |
244 | last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE); |
245 | old_record_separator = record_separator; |
246 | goto do_read; |
247 | case A_GLOB: |
248 | argflags |= AF_POST; /* enable newline chopping */ |
249 | last_in_stab = argptr.arg_stab; |
250 | old_record_separator = record_separator; |
bf38876a |
251 | #ifdef CSH |
252 | record_separator = 0; |
253 | #else |
254 | record_separator = '\n'; |
255 | #endif |
a687059c |
256 | goto do_read; |
257 | case A_READ: |
258 | last_in_stab = argptr.arg_stab; |
259 | old_record_separator = record_separator; |
260 | do_read: |
261 | if (anum > 1) /* assign to scalar */ |
262 | gimme = G_SCALAR; /* force context to scalar */ |
263 | ++sp; |
264 | fp = Nullfp; |
265 | if (stab_io(last_in_stab)) { |
266 | fp = stab_io(last_in_stab)->ifp; |
267 | if (!fp) { |
268 | if (stab_io(last_in_stab)->flags & IOF_ARGV) { |
269 | if (stab_io(last_in_stab)->flags & IOF_START) { |
270 | stab_io(last_in_stab)->flags &= ~IOF_START; |
271 | stab_io(last_in_stab)->lines = 0; |
272 | if (alen(stab_array(last_in_stab)) < 0) { |
273 | tmpstr = str_make("-",1); /* assume stdin */ |
274 | (void)apush(stab_array(last_in_stab), tmpstr); |
275 | } |
276 | } |
277 | fp = nextargv(last_in_stab); |
bf38876a |
278 | if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */ |
a687059c |
279 | (void)do_close(last_in_stab,FALSE); /* now it does*/ |
bf38876a |
280 | stab_io(last_in_stab)->flags |= IOF_START; |
281 | } |
a687059c |
282 | } |
283 | else if (argtype == A_GLOB) { |
284 | (void) interp(str,stab_val(last_in_stab),sp); |
285 | st = stack->ary_array; |
286 | tmpstr = Str_new(55,0); |
bf38876a |
287 | #ifdef CSH |
288 | str_nset(tmpstr,cshname,cshlen); |
289 | str_cat(tmpstr," -cf 'set nonomatch; glob "); |
290 | str_scat(tmpstr,str); |
291 | str_cat(tmpstr,"'|"); |
292 | #else |
293 | str_set(tmpstr, "echo "); |
294 | str_scat(tmpstr,str); |
295 | str_cat(tmpstr, |
296 | "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|"); |
297 | #endif |
a687059c |
298 | (void)do_open(last_in_stab,tmpstr->str_ptr); |
299 | fp = stab_io(last_in_stab)->ifp; |
03a14243 |
300 | str_free(tmpstr); |
a687059c |
301 | } |
302 | } |
303 | } |
304 | if (!fp && dowarn) |
305 | warn("Read on closed filehandle <%s>",stab_name(last_in_stab)); |
306 | keepgoing: |
307 | if (!fp) |
308 | st[sp] = &str_undef; |
309 | else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) { |
310 | clearerr(fp); |
311 | if (stab_io(last_in_stab)->flags & IOF_ARGV) { |
312 | fp = nextargv(last_in_stab); |
313 | if (fp) |
314 | goto keepgoing; |
315 | (void)do_close(last_in_stab,FALSE); |
316 | stab_io(last_in_stab)->flags |= IOF_START; |
317 | } |
318 | else if (argflags & AF_POST) { |
319 | (void)do_close(last_in_stab,FALSE); |
320 | } |
321 | st[sp] = &str_undef; |
322 | record_separator = old_record_separator; |
323 | if (gimme == G_ARRAY) { |
324 | --sp; |
325 | goto array_return; |
326 | } |
327 | break; |
328 | } |
329 | else { |
330 | stab_io(last_in_stab)->lines++; |
331 | st[sp] = str; |
332 | #ifdef TAINT |
333 | str->str_tainted = 1; /* Anything from the outside world...*/ |
334 | #endif |
335 | if (argflags & AF_POST) { |
336 | if (str->str_cur > 0) |
337 | str->str_cur--; |
338 | if (str->str_ptr[str->str_cur] == record_separator) |
339 | str->str_ptr[str->str_cur] = '\0'; |
340 | else |
341 | str->str_cur++; |
342 | for (tmps = str->str_ptr; *tmps; tmps++) |
343 | if (!isalpha(*tmps) && !isdigit(*tmps) && |
344 | index("$&*(){}[]'\";\\|?<>~`",*tmps)) |
345 | break; |
346 | if (*tmps && stat(str->str_ptr,&statbuf) < 0) |
347 | goto keepgoing; /* unmatched wildcard? */ |
348 | } |
349 | if (gimme == G_ARRAY) { |
350 | st[sp] = str_static(st[sp]); |
351 | if (++sp > stack->ary_max) { |
352 | astore(stack, sp, Nullstr); |
353 | st = stack->ary_array; |
354 | } |
355 | goto keepgoing; |
356 | } |
357 | } |
358 | record_separator = old_record_separator; |
359 | #ifdef DEBUGGING |
360 | tmps = "READ"; |
361 | #endif |
362 | break; |
363 | } |
364 | #ifdef DEBUGGING |
365 | if (debug & 8) |
366 | deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp])); |
367 | #endif |
368 | if (anum < 8) |
369 | arglast[anum] = sp; |
370 | } |