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