perl 3.0 patch #26 patch #19, 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.6 90/08/09 03:37:15 lwall Locked $
6  *
7  * $Log:        evalargs.xc,v $
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  * 
13  * Revision 3.0.1.5  90/03/27  15:54:42  lwall
14  * patch16: MSDOS support
15  * 
16  * Revision 3.0.1.4  90/02/28  17:38:37  lwall
17  * patch9: $#foo -= 2 didn't work
18  * 
19  * Revision 3.0.1.3  89/11/17  15:25:07  lwall
20  * patch5: constant numeric subscripts disappeared in ?:
21  * 
22  * Revision 3.0.1.2  89/11/11  04:33:05  lwall
23  * patch2: Configure now locates csh
24  * 
25  * Revision 3.0.1.1  89/10/26  23:12:55  lwall
26  * patch1: glob didn't free a temporary string
27  * 
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;
72             switch (optype) {
73                 case O_ITEM2: argtype = 2; break;
74                 case O_ITEM3: argtype = 3; break;
75                 default:      argtype = anum; break;
76             }
77             str = afetch(stab_array(argptr.arg_stab),
78                 arg[argtype].arg_len - arybase, TRUE);
79 #ifdef DEBUGGING
80             if (debug & 8) {
81                 (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
82                     arg[argtype].arg_len);
83                 tmps = buf;
84             }
85 #endif
86             goto do_crement;
87         case A_ARYSTAB:
88             switch (optype) {
89                 case O_ITEM2: argtype = 2; break;
90                 case O_ITEM3: argtype = 3; break;
91                 default:      argtype = anum; break;
92             }
93             st[++sp] = afetch(stab_array(argptr.arg_stab),
94                 arg[argtype].arg_len - arybase, FALSE);
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),
100                     arg[argtype].arg_len);
101                 tmps = buf;
102             }
103 #endif
104             break;
105         case A_STAR:
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();
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;
197             if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
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) {
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                 }
253                 statusvalue = mypclose(fp);
254             }
255             else
256                 statusvalue = -1;
257
258             if (gimme == G_SCALAR)
259                 st[++sp] = str;
260 #ifdef DEBUGGING
261             tmps = "BACK";
262 #endif
263             break;
264         case A_WANTARRAY:
265             {
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;
283 #ifdef MSDOS
284             record_separator = 0;
285 #else
286 #ifdef CSH
287             record_separator = 0;
288 #else
289             record_separator = '\n';
290 #endif  /* !CSH */
291 #endif  /* !MSDOS */
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 */
299             if (gimme == G_ARRAY)
300                 str = str_static(&str_undef);
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);
316                         if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
317                             (void)do_close(last_in_stab,FALSE); /* now it does*/
318                             stab_io(last_in_stab)->flags |= IOF_START;
319                         }
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);
325 #ifdef MSDOS
326                         str_set(tmpstr, "glob ");
327                         str_scat(tmpstr,str);
328                         str_cat(tmpstr," |");
329 #else
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'|");
340 #endif /* !CSH */
341 #endif /* !MSDOS */
342                         (void)do_open(last_in_stab,tmpstr->str_ptr,
343                           tmpstr->str_cur);
344                         fp = stab_io(last_in_stab)->ifp;
345                         str_free(tmpstr);
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) {
395                     if (++sp > stack->ary_max) {
396                         astore(stack, sp, Nullstr);
397                         st = stack->ary_array;
398                     }
399                     str = str_static(&str_undef);
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     }