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