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