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 | |
03a14243 |
5 | /* $Header: evalargs.xc,v 3.0.1.1 89/10/26 23:12:55 lwall Locked $ |
a687059c |
6 | * |
7 | * $Log: evalargs.xc,v $ |
03a14243 |
8 | * Revision 3.0.1.1 89/10/26 23:12:55 lwall |
9 | * patch1: glob didn't free a temporary string |
10 | * |
a687059c |
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; |
03a14243 |
281 | str_free(tmpstr); |
a687059c |
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 | } |