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