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