Commit | Line | Data |
a687059c |
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 | |
b1248f16 |
5 | /* $Header: evalargs.xc,v 3.0.1.5 90/03/27 15:54:42 lwall Locked $ |
a687059c |
6 | * |
7 | * $Log: evalargs.xc,v $ |
b1248f16 |
8 | * Revision 3.0.1.5 90/03/27 15:54:42 lwall |
9 | * patch16: MSDOS support |
10 | * |
ac58e20f |
11 | * Revision 3.0.1.4 90/02/28 17:38:37 lwall |
12 | * patch9: $#foo -= 2 didn't work |
13 | * |
0d3e774c |
14 | * Revision 3.0.1.3 89/11/17 15:25:07 lwall |
15 | * patch5: constant numeric subscripts disappeared in ?: |
16 | * |
bf38876a |
17 | * Revision 3.0.1.2 89/11/11 04:33:05 lwall |
18 | * patch2: Configure now locates csh |
19 | * |
03a14243 |
20 | * Revision 3.0.1.1 89/10/26 23:12:55 lwall |
21 | * patch1: glob didn't free a temporary string |
22 | * |
a687059c |
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; |
0d3e774c |
67 | switch (optype) { |
68 | case O_ITEM2: argtype = 2; break; |
69 | case O_ITEM3: argtype = 3; break; |
70 | default: argtype = anum; break; |
71 | } |
a687059c |
72 | str = afetch(stab_array(argptr.arg_stab), |
0d3e774c |
73 | arg[argtype].arg_len - arybase, TRUE); |
a687059c |
74 | #ifdef DEBUGGING |
75 | if (debug & 8) { |
76 | (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab), |
0d3e774c |
77 | arg[argtype].arg_len); |
a687059c |
78 | tmps = buf; |
79 | } |
80 | #endif |
81 | goto do_crement; |
82 | case A_ARYSTAB: |
0d3e774c |
83 | switch (optype) { |
84 | case O_ITEM2: argtype = 2; break; |
85 | case O_ITEM3: argtype = 3; break; |
86 | default: argtype = anum; break; |
87 | } |
a687059c |
88 | st[++sp] = afetch(stab_array(argptr.arg_stab), |
0d3e774c |
89 | arg[argtype].arg_len - arybase, FALSE); |
a687059c |
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), |
0d3e774c |
95 | arg[argtype].arg_len); |
a687059c |
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; |
ac58e20f |
185 | if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST)) |
a687059c |
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 | { |
a687059c |
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; |
b1248f16 |
255 | #ifdef MSDOS |
256 | record_separator = 0; |
257 | #else |
bf38876a |
258 | #ifdef CSH |
259 | record_separator = 0; |
260 | #else |
261 | record_separator = '\n'; |
b1248f16 |
262 | #endif /* !CSH */ |
263 | #endif /* !MSDOS */ |
a687059c |
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); |
bf38876a |
286 | if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */ |
a687059c |
287 | (void)do_close(last_in_stab,FALSE); /* now it does*/ |
bf38876a |
288 | stab_io(last_in_stab)->flags |= IOF_START; |
289 | } |
a687059c |
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); |
b1248f16 |
295 | #ifdef MSDOS |
296 | str_set(tmpstr, "glob "); |
297 | str_scat(tmpstr,str); |
298 | str_cat(tmpstr," |"); |
299 | #else |
bf38876a |
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'|"); |
b1248f16 |
310 | #endif /* !CSH */ |
311 | #endif /* !MSDOS */ |
ac58e20f |
312 | (void)do_open(last_in_stab,tmpstr->str_ptr, |
313 | tmpstr->str_cur); |
a687059c |
314 | fp = stab_io(last_in_stab)->ifp; |
03a14243 |
315 | str_free(tmpstr); |
a687059c |
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 | } |