perl 3.0 patch #32 patch #29, continued
[p5sagit/p5-mst-13.2.git] / evalargs.xc
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
5 /* $Header: evalargs.xc,v 3.0.1.7 90/10/15 16:48:11 lwall Locked $
6  *
7  * $Log:        evalargs.xc,v $
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  * 
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  * 
17  * Revision 3.0.1.5  90/03/27  15:54:42  lwall
18  * patch16: MSDOS support
19  * 
20  * Revision 3.0.1.4  90/02/28  17:38:37  lwall
21  * patch9: $#foo -= 2 didn't work
22  * 
23  * Revision 3.0.1.3  89/11/17  15:25:07  lwall
24  * patch5: constant numeric subscripts disappeared in ?:
25  * 
26  * Revision 3.0.1.2  89/11/11  04:33:05  lwall
27  * patch2: Configure now locates csh
28  * 
29  * Revision 3.0.1.1  89/10/26  23:12:55  lwall
30  * patch1: glob didn't free a temporary string
31  * 
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;
76             switch (optype) {
77                 case O_ITEM2: argtype = 2; break;
78                 case O_ITEM3: argtype = 3; break;
79                 default:      argtype = anum; break;
80             }
81             str = afetch(stab_array(argptr.arg_stab),
82                 arg[argtype].arg_len - arybase, TRUE);
83 #ifdef DEBUGGING
84             if (debug & 8) {
85                 (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
86                     arg[argtype].arg_len);
87                 tmps = buf;
88             }
89 #endif
90             goto do_crement;
91         case A_ARYSTAB:
92             switch (optype) {
93                 case O_ITEM2: argtype = 2; break;
94                 case O_ITEM3: argtype = 3; break;
95                 default:      argtype = anum; break;
96             }
97             st[++sp] = afetch(stab_array(argptr.arg_stab),
98                 arg[argtype].arg_len - arybase, FALSE);
99 #ifdef DEBUGGING
100             if (debug & 8) {
101                 (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
102                     arg[argtype].arg_len);
103                 tmps = buf;
104             }
105 #endif
106             break;
107         case A_STAR:
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();
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;
199             if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
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) {
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                 }
255                 statusvalue = mypclose(fp);
256             }
257             else
258                 statusvalue = -1;
259
260             if (gimme == G_SCALAR)
261                 st[++sp] = str;
262 #ifdef DEBUGGING
263             tmps = "BACK";
264 #endif
265             break;
266         case A_WANTARRAY:
267             {
268                 if (curcsv->wantarray == G_ARRAY)
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;
285 #ifdef MSDOS
286             record_separator = 0;
287 #else
288 #ifdef CSH
289             record_separator = 0;
290 #else
291             record_separator = '\n';
292 #endif  /* !CSH */
293 #endif  /* !MSDOS */
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 */
301             if (gimme == G_ARRAY)
302                 str = str_static(&str_undef);
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);
318                         if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
319                             (void)do_close(last_in_stab,FALSE); /* now it does*/
320                             stab_io(last_in_stab)->flags |= IOF_START;
321                         }
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);
327 #ifdef MSDOS
328                         str_set(tmpstr, "perlglob ");
329                         str_scat(tmpstr,str);
330                         str_cat(tmpstr," |");
331 #else
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'|");
342 #endif /* !CSH */
343 #endif /* !MSDOS */
344                         (void)do_open(last_in_stab,tmpstr->str_ptr,
345                           tmpstr->str_cur);
346                         fp = stab_io(last_in_stab)->ifp;
347                         str_free(tmpstr);
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) {
397                     if (++sp > stack->ary_max) {
398                         astore(stack, sp, Nullstr);
399                         st = stack->ary_array;
400                     }
401                     str = str_static(&str_undef);
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     }