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