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