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