perl 3.0 patch #44 patch #42, continued
[p5sagit/p5-mst-13.2.git] / evalargs.xc
CommitLineData
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 }