This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Further ANSI changes now builds and passes (most) tests
[perl5.git] / x2p / walk.c
CommitLineData
79072805 1/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
a687059c 2 *
9607fc9c 3 * Copyright (c) 1991-1997, Larry Wall
a687059c 4 *
d48672a2
LW
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
8d063cd8
LW
7 *
8 * $Log: walk.c,v $
8d063cd8
LW
9 */
10
8d063cd8 11#include "EXTERN.h"
8d063cd8 12#include "a2p.h"
9c8d0b29 13#include "util.h"
8d063cd8
LW
14
15bool exitval = FALSE;
16bool realexit = FALSE;
378cc40b 17bool saw_getline = FALSE;
a687059c
LW
18bool subretnum = FALSE;
19bool saw_FNR = FALSE;
20bool saw_argv0 = FALSE;
d48672a2 21bool saw_fh = FALSE;
8d063cd8 22int maxtmp = 0;
378cc40b
LW
23char *lparen;
24char *rparen;
55204971 25char *limit;
a687059c
LW
26STR *subs;
27STR *curargs = Nullstr;
8d063cd8 28
56febc5e
AD
29static void addsemi _(( STR *str ));
30static void emit_split _(( STR *str, int level ));
31static void fixtab _(( STR *str, int lvl ));
32static void numericize _(( int node ));
33static void tab _(( STR *str, int lvl ));
34
9c8d0b29 35int prewalk _(( int numit, int level, int node, int *numericptr ));
9c8d0b29
AD
36STR * walk _(( int useval, int level, int node, int *numericptr, int minprec ));
37
38
8d063cd8 39STR *
f0f333f4
NIS
40walk(int useval, int level, register int node, int *numericptr, int minprec)
41
42
43
44
45 /* minimum precedence without parens */
8d063cd8
LW
46{
47 register int len;
48 register STR *str;
49 register int type;
50 register int i;
51 register STR *tmpstr;
52 STR *tmp2str;
a687059c 53 STR *tmp3str;
8d063cd8
LW
54 char *t;
55 char *d, *s;
56 int numarg;
57 int numeric = FALSE;
58 STR *fstr;
a687059c 59 int prec = P_MAX; /* assume no parens needed */
8d063cd8
LW
60
61 if (!node) {
62 *numericptr = 0;
63 return str_make("");
64 }
65 type = ops[node].ival;
66 len = type >> 8;
67 type &= 255;
68 switch (type) {
69 case OPROG:
d48672a2
LW
70 arymax = 0;
71 if (namelist) {
72 while (isalpha(*namelist)) {
73 for (d = tokenbuf,s=namelist;
74 isalpha(*s) || isdigit(*s) || *s == '_';
75 *d++ = *s++) ;
76 *d = '\0';
77 while (*s && !isalpha(*s)) s++;
78 namelist = s;
79 nameary[++arymax] = savestr(tokenbuf);
80 }
81 }
82 if (maxfld < arymax)
83 maxfld = arymax;
8d063cd8 84 opens = str_new(0);
a687059c
LW
85 subs = str_new(0);
86 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
87 if (do_split && need_entire && !absmaxfld)
88 split_to_array = TRUE;
89 if (do_split && split_to_array)
90 set_array_base = TRUE;
91 if (set_array_base) {
92 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
93 }
94 if (fswitch && !const_FS)
95 const_FS = fswitch;
96 if (saw_FS > 1 || saw_RS)
97 const_FS = 0;
98 if (saw_ORS && need_entire)
99 do_chop = TRUE;
100 if (fswitch) {
101 str_cat(str,"$FS = '");
a0d0e21e 102 if (strchr("*+?.[]()|^$\\",fswitch))
8d063cd8
LW
103 str_cat(str,"\\");
104 sprintf(tokenbuf,"%c",fswitch);
105 str_cat(str,tokenbuf);
106 str_cat(str,"';\t\t# field separator from -F switch\n");
107 }
108 else if (saw_FS && !const_FS) {
9bb9d9f7 109 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
8d063cd8
LW
110 }
111 if (saw_OFS) {
a559c259 112 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
8d063cd8
LW
113 }
114 if (saw_ORS) {
a559c259 115 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
8d063cd8 116 }
a687059c
LW
117 if (saw_argv0) {
118 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
119 }
8d063cd8
LW
120 if (str->str_cur > 20)
121 str_cat(str,"\n");
122 if (ops[node+2].ival) {
a687059c 123 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
124 str_free(fstr);
125 str_cat(str,"\n\n");
126 }
a687059c
LW
127 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
128 if (*fstr->str_ptr) {
129 if (saw_line_op)
130 str_cat(str,"line: ");
131 str_cat(str,"while (<>) {\n");
132 tab(str,++level);
133 if (saw_FS && !const_FS)
134 do_chop = TRUE;
135 if (do_chop) {
136 str_cat(str,"chop;\t# strip record separator\n");
137 tab(str,level);
8d063cd8 138 }
a687059c
LW
139 if (do_split)
140 emit_split(str,level);
141 str_scat(str,fstr);
142 str_free(fstr);
143 fixtab(str,--level);
144 str_cat(str,"}\n");
145 if (saw_FNR)
146 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
8d063cd8 147 }
a5571d59 148 else if (old_awk)
ae986130 149 str_cat(str,"while (<>) { } # (no line actions)\n");
8d063cd8
LW
150 if (ops[node+4].ival) {
151 realexit = TRUE;
152 str_cat(str,"\n");
153 tab(str,level);
a687059c 154 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8
LW
155 str_free(fstr);
156 str_cat(str,"\n");
157 }
158 if (exitval)
9f68db38 159 str_cat(str,"exit $ExitValue;\n");
a687059c
LW
160 if (subs->str_ptr) {
161 str_cat(str,"\n");
162 str_scat(str,subs);
163 }
378cc40b 164 if (saw_getline) {
a687059c
LW
165 for (len = 0; len < 4; len++) {
166 if (saw_getline & (1 << len)) {
167 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
168 str_cat(str, tokenbuf);
169 if (len & 2) {
170 if (do_fancy_opens)
171 str_cat(str," &Pick('',@_);\n");
172 else
173 str_cat(str," ($fh) = @_;\n");
174 }
175 else {
176 if (saw_FNR)
177 str_cat(str," $FNRbase = $. if eof;\n");
178 }
179 if (len & 1)
62b28dd9 180 str_cat(str," local($_);\n");
a687059c
LW
181 if (len & 2)
182 str_cat(str,
183 " if ($getline_ok = (($_ = <$fh>) ne ''))");
184 else
185 str_cat(str,
186 " if ($getline_ok = (($_ = <>) ne ''))");
187 str_cat(str, " {\n");
188 level += 2;
189 tab(str,level);
190 i = 0;
191 if (do_chop) {
192 i++;
193 str_cat(str,"chop;\t# strip record separator\n");
194 tab(str,level);
195 }
196 if (do_split && !(len & 1)) {
197 i++;
198 emit_split(str,level);
199 }
200 if (!i)
201 str_cat(str,";\n");
202 fixtab(str,--level);
203 str_cat(str,"}\n $_;\n}\n");
204 --level;
205 }
378cc40b 206 }
378cc40b 207 }
8d063cd8
LW
208 if (do_fancy_opens) {
209 str_cat(str,"\n\
210sub Pick {\n\
a687059c 211 local($mode,$name,$pipe) = @_;\n\
7c0587c8
LW
212 $fh = $name;\n\
213 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
8d063cd8
LW
214}\n\
215");
216 }
217 break;
218 case OHUNKS:
a687059c
LW
219 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
220 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
221 str_free(fstr);
222 if (len == 3) {
a687059c 223 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8
LW
224 str_free(fstr);
225 }
226 else {
227 }
228 break;
229 case ORANGE:
a687059c
LW
230 prec = P_DOTDOT;
231 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 232 str_cat(str," .. ");
a687059c 233 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8
LW
234 str_free(fstr);
235 break;
236 case OPAT:
237 goto def;
238 case OREGEX:
239 str = str_new(0);
240 str_set(str,"/");
a687059c 241 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
242 /* translate \nnn to [\nnn] */
243 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
a687059c 244 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
8d063cd8
LW
245 *d++ = '[';
246 *d++ = *s++;
247 *d++ = *s++;
248 *d++ = *s++;
249 *d++ = *s;
250 *d = ']';
251 }
252 else
253 *d = *s;
254 }
255 *d = '\0';
378cc40b
LW
256 for (d=tokenbuf; *d; d++)
257 *d += 128;
8d063cd8
LW
258 str_cat(str,tokenbuf);
259 str_free(tmpstr);
260 str_cat(str,"/");
261 break;
262 case OHUNK:
263 if (len == 1) {
264 str = str_new(0);
a687059c 265 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
8d063cd8 266 str_cat(str," if ");
a687059c 267 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
268 str_free(fstr);
269 str_cat(str,";");
270 }
271 else {
a687059c 272 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
273 if (*tmpstr->str_ptr) {
274 str = str_new(0);
275 str_set(str,"if (");
276 str_scat(str,tmpstr);
277 str_cat(str,") {\n");
278 tab(str,++level);
a687059c 279 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
280 str_free(fstr);
281 fixtab(str,--level);
282 str_cat(str,"}\n");
283 tab(str,level);
284 }
285 else {
a687059c 286 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
287 }
288 }
289 break;
290 case OPPAREN:
291 str = str_new(0);
292 str_set(str,"(");
a687059c 293 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
294 str_free(fstr);
295 str_cat(str,")");
296 break;
297 case OPANDAND:
a687059c
LW
298 prec = P_ANDAND;
299 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 300 str_cat(str," && ");
a687059c
LW
301 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
302 str_free(fstr);
303 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
304 str_free(fstr);
305 break;
306 case OPOROR:
a687059c
LW
307 prec = P_OROR;
308 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 309 str_cat(str," || ");
a687059c
LW
310 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
311 str_free(fstr);
312 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
313 str_free(fstr);
314 break;
315 case OPNOT:
a687059c 316 prec = P_UNARY;
8d063cd8
LW
317 str = str_new(0);
318 str_set(str,"!");
a687059c 319 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8
LW
320 str_free(fstr);
321 break;
62b28dd9
LW
322 case OCOND:
323 prec = P_COND;
324 str = walk(1,level,ops[node+1].ival,&numarg,prec);
325 str_cat(str," ? ");
326 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
327 str_free(fstr);
328 str_cat(str," : ");
329 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
330 str_free(fstr);
331 break;
8d063cd8
LW
332 case OCPAREN:
333 str = str_new(0);
334 str_set(str,"(");
a687059c 335 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
336 str_free(fstr);
337 numeric |= numarg;
338 str_cat(str,")");
339 break;
340 case OCANDAND:
a687059c
LW
341 prec = P_ANDAND;
342 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8
LW
343 numeric = 1;
344 str_cat(str," && ");
a687059c
LW
345 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
346 str_free(fstr);
347 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
348 str_free(fstr);
349 break;
350 case OCOROR:
a687059c
LW
351 prec = P_OROR;
352 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8
LW
353 numeric = 1;
354 str_cat(str," || ");
a687059c
LW
355 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
356 str_free(fstr);
357 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
358 str_free(fstr);
359 break;
360 case OCNOT:
a687059c 361 prec = P_UNARY;
8d063cd8
LW
362 str = str_new(0);
363 str_set(str,"!");
a687059c 364 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8
LW
365 str_free(fstr);
366 numeric = 1;
367 break;
368 case ORELOP:
a687059c
LW
369 prec = P_REL;
370 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 371 numeric |= numarg;
a687059c
LW
372 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
373 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
8d063cd8 374 numeric |= numarg;
a687059c
LW
375 if (!numeric ||
376 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
8d063cd8
LW
377 t = tmpstr->str_ptr;
378 if (strEQ(t,"=="))
379 str_set(tmpstr,"eq");
380 else if (strEQ(t,"!="))
381 str_set(tmpstr,"ne");
382 else if (strEQ(t,"<"))
383 str_set(tmpstr,"lt");
384 else if (strEQ(t,"<="))
385 str_set(tmpstr,"le");
386 else if (strEQ(t,">"))
387 str_set(tmpstr,"gt");
388 else if (strEQ(t,">="))
389 str_set(tmpstr,"ge");
a0d0e21e
LW
390 if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
391 !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
8d063cd8
LW
392 numeric |= 2;
393 }
394 if (numeric & 2) {
395 if (numeric & 1) /* numeric is very good guess */
396 str_cat(str," ");
397 else
398 str_cat(str,"\377");
399 numeric = 1;
400 }
401 else
402 str_cat(str," ");
403 str_scat(str,tmpstr);
404 str_free(tmpstr);
405 str_cat(str," ");
406 str_scat(str,tmp2str);
407 str_free(tmp2str);
408 numeric = 1;
409 break;
410 case ORPAREN:
411 str = str_new(0);
412 str_set(str,"(");
a687059c 413 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
414 str_free(fstr);
415 numeric |= numarg;
416 str_cat(str,")");
417 break;
418 case OMATCHOP:
a687059c
LW
419 prec = P_MATCH;
420 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 421 str_cat(str," ");
a687059c 422 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
423 if (strEQ(tmpstr->str_ptr,"~"))
424 str_cat(str,"=~");
425 else {
426 str_scat(str,tmpstr);
427 str_free(tmpstr);
428 }
429 str_cat(str," ");
a687059c 430 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
431 str_free(fstr);
432 numeric = 1;
433 break;
434 case OMPAREN:
435 str = str_new(0);
436 str_set(str,"(");
a687059c
LW
437 str_scat(str,
438 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
439 str_free(fstr);
440 numeric |= numarg;
441 str_cat(str,")");
442 break;
443 case OCONCAT:
a687059c
LW
444 prec = P_ADD;
445 type = ops[ops[node+1].ival].ival & 255;
446 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
8d063cd8 447 str_cat(str," . ");
a687059c
LW
448 type = ops[ops[node+2].ival].ival & 255;
449 str_scat(str,
450 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
8d063cd8
LW
451 str_free(fstr);
452 break;
453 case OASSIGN:
a687059c
LW
454 prec = P_ASSIGN;
455 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 456 str_cat(str," ");
a687059c 457 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
458 str_scat(str,tmpstr);
459 if (str_len(tmpstr) > 1)
460 numeric = 1;
461 str_free(tmpstr);
462 str_cat(str," ");
a687059c 463 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
8d063cd8
LW
464 str_free(fstr);
465 numeric |= numarg;
7c0587c8
LW
466 if (strEQ(str->str_ptr,"$/ = ''"))
467 str_set(str, "$/ = \"\\n\\n\"");
8d063cd8
LW
468 break;
469 case OADD:
a687059c
LW
470 prec = P_ADD;
471 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 472 str_cat(str," + ");
a687059c 473 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8
LW
474 str_free(fstr);
475 numeric = 1;
476 break;
a687059c
LW
477 case OSUBTRACT:
478 prec = P_ADD;
479 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 480 str_cat(str," - ");
a687059c 481 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8
LW
482 str_free(fstr);
483 numeric = 1;
484 break;
485 case OMULT:
a687059c
LW
486 prec = P_MUL;
487 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 488 str_cat(str," * ");
a687059c 489 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8
LW
490 str_free(fstr);
491 numeric = 1;
492 break;
493 case ODIV:
a687059c
LW
494 prec = P_MUL;
495 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 496 str_cat(str," / ");
a687059c
LW
497 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
498 str_free(fstr);
499 numeric = 1;
500 break;
501 case OPOW:
502 prec = P_POW;
503 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
504 str_cat(str," ** ");
505 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
8d063cd8
LW
506 str_free(fstr);
507 numeric = 1;
508 break;
509 case OMOD:
a687059c
LW
510 prec = P_MUL;
511 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 512 str_cat(str," % ");
a687059c 513 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8
LW
514 str_free(fstr);
515 numeric = 1;
516 break;
517 case OPOSTINCR:
a687059c
LW
518 prec = P_AUTO;
519 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8
LW
520 str_cat(str,"++");
521 numeric = 1;
522 break;
523 case OPOSTDECR:
a687059c
LW
524 prec = P_AUTO;
525 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8
LW
526 str_cat(str,"--");
527 numeric = 1;
528 break;
529 case OPREINCR:
a687059c 530 prec = P_AUTO;
8d063cd8
LW
531 str = str_new(0);
532 str_set(str,"++");
a687059c 533 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8
LW
534 str_free(fstr);
535 numeric = 1;
536 break;
537 case OPREDECR:
a687059c 538 prec = P_AUTO;
8d063cd8
LW
539 str = str_new(0);
540 str_set(str,"--");
a687059c 541 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8
LW
542 str_free(fstr);
543 numeric = 1;
544 break;
545 case OUMINUS:
a687059c 546 prec = P_UNARY;
8d063cd8
LW
547 str = str_new(0);
548 str_set(str,"-");
a687059c 549 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8
LW
550 str_free(fstr);
551 numeric = 1;
552 break;
553 case OUPLUS:
554 numeric = 1;
555 goto def;
556 case OPAREN:
557 str = str_new(0);
558 str_set(str,"(");
a687059c
LW
559 str_scat(str,
560 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
561 str_free(fstr);
562 str_cat(str,")");
563 numeric |= numarg;
564 break;
565 case OGETLINE:
566 str = str_new(0);
a687059c
LW
567 if (useval)
568 str_cat(str,"(");
569 if (len > 0) {
a687059c
LW
570 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
571 if (!*fstr->str_ptr) {
7c0587c8 572 str_cat(str,"$_");
a687059c
LW
573 len = 2; /* a legal fiction */
574 }
575 str_free(fstr);
576 }
577 else
578 str_cat(str,"$_");
579 if (len > 1) {
580 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
581 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
582 if (!do_fancy_opens) {
583 t = tmpstr->str_ptr;
584 if (*t == '"' || *t == '\'')
585 t = cpytill(tokenbuf,t+1,*t);
586 else
587 fatal("Internal error: OGETLINE %s", t);
588 d = savestr(t);
589 s = savestr(tokenbuf);
590 for (t = tokenbuf; *t; t++) {
591 *t &= 127;
d48672a2
LW
592 if (islower(*t))
593 *t = toupper(*t);
a687059c
LW
594 if (!isalpha(*t) && !isdigit(*t))
595 *t = '_';
596 }
a0d0e21e 597 if (!strchr(tokenbuf,'_'))
d48672a2 598 strcpy(t,"_FH");
a687059c
LW
599 tmp3str = hfetch(symtab,tokenbuf);
600 if (!tmp3str) {
601 do_opens = TRUE;
602 str_cat(opens,"open(");
603 str_cat(opens,tokenbuf);
604 str_cat(opens,", ");
605 d[1] = '\0';
606 str_cat(opens,d);
607 str_cat(opens,tmpstr->str_ptr+1);
608 opens->str_cur--;
609 if (*fstr->str_ptr == '|')
610 str_cat(opens,"|");
611 str_cat(opens,d);
612 if (*fstr->str_ptr == '|')
613 str_cat(opens,") || die 'Cannot pipe from \"");
614 else
615 str_cat(opens,") || die 'Cannot open file \"");
616 if (*d == '"')
617 str_cat(opens,"'.\"");
618 str_cat(opens,s);
619 if (*d == '"')
620 str_cat(opens,"\".'");
621 str_cat(opens,"\".';\n");
622 hstore(symtab,tokenbuf,str_make("x"));
623 }
624 safefree(s);
625 safefree(d);
626 str_set(tmpstr,"'");
627 str_cat(tmpstr,tokenbuf);
628 str_cat(tmpstr,"'");
629 }
630 if (*fstr->str_ptr == '|')
631 str_cat(tmpstr,", '|'");
632 str_free(fstr);
633 }
634 else
635 tmpstr = str_make("");
636 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
637 str_cat(str,tokenbuf);
638 str_free(tmpstr);
639 if (useval)
640 str_cat(str,",$getline_ok)");
641 saw_getline |= 1 << len;
8d063cd8
LW
642 break;
643 case OSPRINTF:
644 str = str_new(0);
645 str_set(str,"sprintf(");
a687059c 646 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
647 str_free(fstr);
648 str_cat(str,")");
649 break;
650 case OSUBSTR:
651 str = str_new(0);
652 str_set(str,"substr(");
a687059c 653 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8
LW
654 str_free(fstr);
655 str_cat(str,", ");
a687059c 656 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8
LW
657 str_free(fstr);
658 str_cat(str,", ");
659 if (len == 3) {
a687059c 660 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
8d063cd8
LW
661 str_free(fstr);
662 }
663 else
664 str_cat(str,"999999");
665 str_cat(str,")");
666 break;
667 case OSTRING:
668 str = str_new(0);
669 str_set(str,ops[node+1].cval);
670 break;
671 case OSPLIT:
672 str = str_new(0);
55204971 673 limit = ", 9999)";
8d063cd8 674 numeric = 1;
a687059c 675 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
676 if (useval)
677 str_set(str,"(@");
678 else
679 str_set(str,"@");
680 str_scat(str,tmpstr);
681 str_cat(str," = split(");
682 if (len == 3) {
a687059c 683 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
8d063cd8
LW
684 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
685 i = fstr->str_ptr[1] & 127;
a0d0e21e 686 if (strchr("*+?.[]()|^$\\",i))
8d063cd8 687 sprintf(tokenbuf,"/\\%c/",i);
20188a90 688 else if (i == ' ')
62b28dd9 689 sprintf(tokenbuf,"' '");
8d063cd8
LW
690 else
691 sprintf(tokenbuf,"/%c/",i);
692 str_cat(str,tokenbuf);
693 }
694 else
695 str_scat(str,fstr);
696 str_free(fstr);
697 }
698 else if (const_FS) {
699 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
700 str_cat(str,tokenbuf);
701 }
702 else if (saw_FS)
703 str_cat(str,"$FS");
55204971 704 else {
9bb9d9f7 705 str_cat(str,"' '");
55204971
LW
706 limit = ")";
707 }
8d063cd8 708 str_cat(str,", ");
a687059c 709 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 710 str_free(fstr);
55204971 711 str_cat(str,limit);
8d063cd8
LW
712 if (useval) {
713 str_cat(str,")");
714 }
715 str_free(tmpstr);
716 break;
717 case OINDEX:
718 str = str_new(0);
719 str_set(str,"index(");
a687059c 720 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8
LW
721 str_free(fstr);
722 str_cat(str,", ");
a687059c 723 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8
LW
724 str_free(fstr);
725 str_cat(str,")");
726 numeric = 1;
727 break;
a687059c
LW
728 case OMATCH:
729 str = str_new(0);
730 prec = P_ANDAND;
731 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
732 str_free(fstr);
733 str_cat(str," =~ ");
734 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
735 str_free(fstr);
736 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
737 numeric = 1;
738 break;
739 case OUSERDEF:
740 str = str_new(0);
741 subretnum = FALSE;
742 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
743 curargs = str_new(0);
744 str_sset(curargs,fstr);
745 str_cat(curargs,",");
746 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
747 str_free(curargs);
748 curargs = Nullstr;
749 level--;
750 subretnum |= numarg;
751 s = Nullch;
752 t = tmp2str->str_ptr;
753 while (t = instr(t,"return "))
754 s = t++;
755 if (s) {
756 i = 0;
757 for (t = s+7; *t; t++) {
758 if (*t == ';' || *t == '}')
759 i++;
760 }
761 if (i == 1) {
762 strcpy(s,s+7);
763 tmp2str->str_cur -= 7;
764 }
765 }
766 str_set(str,"\n");
767 tab(str,level);
768 str_cat(str,"sub ");
769 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
770 str_cat(str," {\n");
771 tab(str,++level);
772 if (fstr->str_cur) {
773 str_cat(str,"local(");
774 str_scat(str,fstr);
775 str_cat(str,") = @_;");
776 }
777 str_free(fstr);
778 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
779 str_free(fstr);
780 fixtab(str,level);
781 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
782 str_free(fstr);
783 fixtab(str,level);
784 str_scat(str,tmp2str);
785 str_free(tmp2str);
786 fixtab(str,--level);
787 str_cat(str,"}\n");
788 tab(str,level);
789 str_scat(subs,str);
790 str_set(str,"");
791 str_cat(tmpstr,"(");
792 tmp2str = str_new(0);
793 if (subretnum)
794 str_set(tmp2str,"1");
795 hstore(symtab,tmpstr->str_ptr,tmp2str);
796 str_free(tmpstr);
797 level++;
798 break;
799 case ORETURN:
800 str = str_new(0);
801 if (len > 0) {
802 str_cat(str,"return ");
803 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
804 str_free(fstr);
805 if (numarg)
806 subretnum = TRUE;
807 }
808 else
809 str_cat(str,"return");
810 break;
811 case OUSERFUN:
812 str = str_new(0);
813 str_set(str,"&");
814 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
815 str_free(fstr);
816 str_cat(str,"(");
817 tmpstr = hfetch(symtab,str->str_ptr+3);
818 if (tmpstr && tmpstr->str_ptr)
819 numeric |= atoi(tmpstr->str_ptr);
820 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
821 str_free(fstr);
822 str_cat(str,")");
823 break;
824 case OGSUB:
825 case OSUB:
826 if (type == OGSUB)
827 s = "g";
828 else
829 s = "";
830 str = str_new(0);
831 tmpstr = str_new(0);
832 i = 0;
833 if (len == 3) {
834 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
835 if (strNE(tmpstr->str_ptr,"$_")) {
836 str_cat(tmpstr, " =~ s");
837 i++;
838 }
839 else
840 str_set(tmpstr, "s");
841 }
842 else
843 str_set(tmpstr, "s");
844 type = ops[ops[node+2].ival].ival;
845 len = type >> 8;
846 type &= 255;
847 tmp3str = str_new(0);
848 if (type == OSTR) {
849 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
850 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
851 if (*t == '&')
852 *d++ = '$' + 128;
853 else if (*t == '$')
854 *d++ = '\\' + 128;
855 *d = *t + 128;
856 }
857 *d = '\0';
858 str_set(tmp2str,tokenbuf);
859 }
860 else {
861 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
862 str_set(tmp3str,"($s_ = '\"'.(");
863 str_scat(tmp3str,tmp2str);
864 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
865 str_set(tmp2str,"eval $s_");
866 s = (*s == 'g' ? "ge" : "e");
867 i++;
868 }
869 type = ops[ops[node+1].ival].ival;
870 len = type >> 8;
871 type &= 255;
872 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
873 if (type == OREGEX) {
874 if (useval && i)
875 str_cat(str,"(");
876 str_scat(str,tmp3str);
877 str_scat(str,tmpstr);
878 str_scat(str,fstr);
879 str_scat(str,tmp2str);
880 str_cat(str,"/");
881 str_cat(str,s);
882 }
883 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
884 if (useval && i)
885 str_cat(str,"(");
886 str_scat(str,tmp3str);
887 str_scat(str,tmpstr);
888 str_cat(str,"/");
889 str_scat(str,fstr);
890 str_cat(str,"/");
891 str_scat(str,tmp2str);
892 str_cat(str,"/");
893 str_cat(str,s);
894 }
895 else {
896 i++;
897 if (useval)
898 str_cat(str,"(");
899 str_cat(str,"$s = ");
900 str_scat(str,fstr);
901 str_cat(str,", ");
902 str_scat(str,tmp3str);
903 str_scat(str,tmpstr);
904 str_cat(str,"/$s/");
905 str_scat(str,tmp2str);
906 str_cat(str,"/");
907 str_cat(str,s);
908 }
909 if (useval && i)
910 str_cat(str,")");
911 str_free(fstr);
912 str_free(tmpstr);
913 str_free(tmp2str);
914 str_free(tmp3str);
915 numeric = 1;
916 break;
8d063cd8 917 case ONUM:
a687059c 918 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
919 numeric = 1;
920 break;
921 case OSTR:
a687059c 922 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 923 s = "'";
378cc40b
LW
924 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
925 if (*t == '\'')
926 s = "\"";
927 else if (*t == '\\') {
8d063cd8 928 s = "\"";
378cc40b
LW
929 *d++ = *t++ + 128;
930 switch (*t) {
fe14fcc3 931 case '\\': case '"': case 'n': case 't': case '$':
378cc40b
LW
932 break;
933 default: /* hide this from perl */
934 *d++ = '\\' + 128;
935 }
936 }
937 *d = *t + 128;
8d063cd8 938 }
378cc40b 939 *d = '\0';
8d063cd8
LW
940 str = str_new(0);
941 str_set(str,s);
378cc40b 942 str_cat(str,tokenbuf);
8d063cd8
LW
943 str_free(tmpstr);
944 str_cat(str,s);
945 break;
a687059c
LW
946 case ODEFINED:
947 prec = P_UNI;
948 str = str_new(0);
949 str_set(str,"defined $");
950 goto addvar;
951 case ODELETE:
952 str = str_new(0);
953 str_set(str,"delete $");
954 goto addvar;
955 case OSTAR:
956 str = str_new(0);
957 str_set(str,"*");
958 goto addvar;
8d063cd8
LW
959 case OVAR:
960 str = str_new(0);
961 str_set(str,"$");
a687059c
LW
962 addvar:
963 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
964 if (len == 1) {
965 tmp2str = hfetch(symtab,tmpstr->str_ptr);
966 if (tmp2str && atoi(tmp2str->str_ptr))
967 numeric = 2;
a687059c
LW
968 if (strEQ(str->str_ptr,"$FNR")) {
969 numeric = 1;
970 saw_FNR++;
971 str_set(str,"($.-$FNRbase)");
972 }
973 else if (strEQ(str->str_ptr,"$NR")) {
8d063cd8
LW
974 numeric = 1;
975 str_set(str,"$.");
976 }
977 else if (strEQ(str->str_ptr,"$NF")) {
978 numeric = 1;
979 str_set(str,"$#Fld");
980 }
981 else if (strEQ(str->str_ptr,"$0"))
982 str_set(str,"$_");
a687059c
LW
983 else if (strEQ(str->str_ptr,"$ARGC"))
984 str_set(str,"($#ARGV+1)");
8d063cd8
LW
985 }
986 else {
a687059c
LW
987#ifdef NOTDEF
988 if (curargs) {
989 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
990 ??? if (instr(curargs->str_ptr,tokenbuf))
991 str_cat(str,"\377"); /* can't translate yet */
992 }
993#endif
8d063cd8
LW
994 str_cat(tmpstr,"[]");
995 tmp2str = hfetch(symtab,tmpstr->str_ptr);
996 if (tmp2str && atoi(tmp2str->str_ptr))
997 str_cat(str,"[");
998 else
999 str_cat(str,"{");
a687059c 1000 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1001 str_free(fstr);
a687059c
LW
1002 if (strEQ(str->str_ptr,"$ARGV[0")) {
1003 str_set(str,"$ARGV0");
1004 saw_argv0++;
1005 }
1006 else {
1007 if (tmp2str && atoi(tmp2str->str_ptr))
1008 strcpy(tokenbuf,"]");
1009 else
1010 strcpy(tokenbuf,"}");
1011 *tokenbuf += 128;
1012 str_cat(str,tokenbuf);
1013 }
8d063cd8
LW
1014 }
1015 str_free(tmpstr);
1016 break;
1017 case OFLD:
1018 str = str_new(0);
1019 if (split_to_array) {
1020 str_set(str,"$Fld");
1021 str_cat(str,"[");
a687059c 1022 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1023 str_free(fstr);
1024 str_cat(str,"]");
1025 }
1026 else {
a687059c 1027 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
8d063cd8
LW
1028 if (i <= arymax)
1029 sprintf(tokenbuf,"$%s",nameary[i]);
1030 else
1031 sprintf(tokenbuf,"$Fld%d",i);
1032 str_set(str,tokenbuf);
1033 }
1034 break;
1035 case OVFLD:
1036 str = str_new(0);
1037 str_set(str,"$Fld[");
1038 i = ops[node+1].ival;
1039 if ((ops[i].ival & 255) == OPAREN)
1040 i = ops[i+1].ival;
a687059c 1041 tmpstr=walk(1,level,i,&numarg,P_MIN);
8d063cd8
LW
1042 str_scat(str,tmpstr);
1043 str_free(tmpstr);
1044 str_cat(str,"]");
1045 break;
1046 case OJUNK:
1047 goto def;
1048 case OSNEWLINE:
1049 str = str_new(2);
1050 str_set(str,";\n");
1051 tab(str,level);
1052 break;
1053 case ONEWLINE:
1054 str = str_new(1);
1055 str_set(str,"\n");
1056 tab(str,level);
1057 break;
1058 case OSCOMMENT:
1059 str = str_new(0);
1060 str_set(str,";");
a687059c 1061 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
1062 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1063 *s += 128;
1064 str_scat(str,tmpstr);
1065 str_free(tmpstr);
1066 tab(str,level);
1067 break;
1068 case OCOMMENT:
1069 str = str_new(0);
a687059c 1070 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
1071 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1072 *s += 128;
1073 str_scat(str,tmpstr);
1074 str_free(tmpstr);
1075 tab(str,level);
1076 break;
1077 case OCOMMA:
a687059c
LW
1078 prec = P_COMMA;
1079 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 1080 str_cat(str,", ");
a687059c
LW
1081 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1082 str_free(fstr);
1083 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
1084 str_free(fstr);
1085 break;
1086 case OSEMICOLON:
1087 str = str_new(1);
a687059c
LW
1088 str_set(str,";\n");
1089 tab(str,level);
8d063cd8
LW
1090 break;
1091 case OSTATES:
a687059c
LW
1092 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1093 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1094 str_free(fstr);
1095 break;
1096 case OSTATE:
1097 str = str_new(0);
1098 if (len >= 1) {
a687059c 1099 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1100 str_free(fstr);
1101 if (len >= 2) {
a687059c 1102 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
1103 if (*tmpstr->str_ptr == ';') {
1104 addsemi(str);
1105 str_cat(str,tmpstr->str_ptr+1);
1106 }
1107 str_free(tmpstr);
1108 }
1109 }
1110 break;
a687059c
LW
1111 case OCLOSE:
1112 str = str_make("close(");
1113 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1114 if (!do_fancy_opens) {
1115 t = tmpstr->str_ptr;
1116 if (*t == '"' || *t == '\'')
1117 t = cpytill(tokenbuf,t+1,*t);
1118 else
1119 fatal("Internal error: OCLOSE %s",t);
1120 s = savestr(tokenbuf);
1121 for (t = tokenbuf; *t; t++) {
1122 *t &= 127;
d48672a2
LW
1123 if (islower(*t))
1124 *t = toupper(*t);
a687059c
LW
1125 if (!isalpha(*t) && !isdigit(*t))
1126 *t = '_';
1127 }
a0d0e21e 1128 if (!strchr(tokenbuf,'_'))
d48672a2 1129 strcpy(t,"_FH");
a687059c
LW
1130 str_free(tmpstr);
1131 safefree(s);
1132 str_set(str,"close ");
1133 str_cat(str,tokenbuf);
1134 }
1135 else {
7c0587c8
LW
1136 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1137 tmpstr->str_ptr, tmpstr->str_ptr);
a687059c
LW
1138 str_free(tmpstr);
1139 str_set(str,tokenbuf);
1140 }
1141 break;
8d063cd8
LW
1142 case OPRINTF:
1143 case OPRINT:
378cc40b
LW
1144 lparen = ""; /* set to parens if necessary */
1145 rparen = "";
8d063cd8
LW
1146 str = str_new(0);
1147 if (len == 3) { /* output redirection */
a687059c
LW
1148 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1149 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
1150 if (!do_fancy_opens) {
1151 t = tmpstr->str_ptr;
1152 if (*t == '"' || *t == '\'')
1153 t = cpytill(tokenbuf,t+1,*t);
1154 else
1155 fatal("Internal error: OPRINT");
1156 d = savestr(t);
1157 s = savestr(tokenbuf);
1158 for (t = tokenbuf; *t; t++) {
1159 *t &= 127;
d48672a2
LW
1160 if (islower(*t))
1161 *t = toupper(*t);
8d063cd8
LW
1162 if (!isalpha(*t) && !isdigit(*t))
1163 *t = '_';
1164 }
a0d0e21e 1165 if (!strchr(tokenbuf,'_'))
d48672a2 1166 strcpy(t,"_FH");
a687059c
LW
1167 tmp3str = hfetch(symtab,tokenbuf);
1168 if (!tmp3str) {
1169 str_cat(opens,"open(");
1170 str_cat(opens,tokenbuf);
1171 str_cat(opens,", ");
1172 d[1] = '\0';
1173 str_cat(opens,d);
1174 str_scat(opens,tmp2str);
1175 str_cat(opens,tmpstr->str_ptr+1);
1176 if (*tmp2str->str_ptr == '|')
1177 str_cat(opens,") || die 'Cannot pipe to \"");
1178 else
1179 str_cat(opens,") || die 'Cannot create file \"");
1180 if (*d == '"')
1181 str_cat(opens,"'.\"");
1182 str_cat(opens,s);
1183 if (*d == '"')
1184 str_cat(opens,"\".'");
1185 str_cat(opens,"\".';\n");
1186 hstore(symtab,tokenbuf,str_make("x"));
1187 }
8d063cd8
LW
1188 str_free(tmpstr);
1189 str_free(tmp2str);
1190 safefree(s);
1191 safefree(d);
1192 }
1193 else {
a687059c 1194 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8
LW
1195 tmp2str->str_ptr, tmpstr->str_ptr);
1196 str_cat(str,tokenbuf);
1197 tab(str,level+1);
a687059c 1198 strcpy(tokenbuf,"$fh");
8d063cd8
LW
1199 str_free(tmpstr);
1200 str_free(tmp2str);
378cc40b
LW
1201 lparen = "(";
1202 rparen = ")";
8d063cd8
LW
1203 }
1204 }
1205 else
a687059c 1206 strcpy(tokenbuf,"");
378cc40b 1207 str_cat(str,lparen); /* may be null */
8d063cd8
LW
1208 if (type == OPRINTF)
1209 str_cat(str,"printf");
1210 else
1211 str_cat(str,"print");
d48672a2 1212 saw_fh = 0;
8d063cd8 1213 if (len == 3 || do_fancy_opens) {
d48672a2 1214 if (*tokenbuf) {
8d063cd8 1215 str_cat(str," ");
d48672a2
LW
1216 saw_fh = 1;
1217 }
8d063cd8
LW
1218 str_cat(str,tokenbuf);
1219 }
a687059c 1220 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
1221 if (!*tmpstr->str_ptr && lval_field) {
1222 t = saw_OFS ? "$," : "' '";
1223 if (split_to_array) {
1224 sprintf(tokenbuf,"join(%s,@Fld)",t);
1225 str_cat(tmpstr,tokenbuf);
1226 }
1227 else {
1228 for (i = 1; i < maxfld; i++) {
1229 if (i <= arymax)
1230 sprintf(tokenbuf,"$%s, ",nameary[i]);
1231 else
1232 sprintf(tokenbuf,"$Fld%d, ",i);
1233 str_cat(tmpstr,tokenbuf);
1234 }
1235 if (maxfld <= arymax)
1236 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1237 else
1238 sprintf(tokenbuf,"$Fld%d",maxfld);
1239 str_cat(tmpstr,tokenbuf);
1240 }
1241 }
1242 if (*tmpstr->str_ptr) {
1243 str_cat(str," ");
d48672a2
LW
1244 if (!saw_fh && *tmpstr->str_ptr == '(') {
1245 str_cat(str,"(");
1246 str_scat(str,tmpstr);
1247 str_cat(str,")");
1248 }
1249 else
1250 str_scat(str,tmpstr);
8d063cd8
LW
1251 }
1252 else {
1253 str_cat(str," $_");
1254 }
378cc40b 1255 str_cat(str,rparen); /* may be null */
8d063cd8
LW
1256 str_free(tmpstr);
1257 break;
a687059c
LW
1258 case ORAND:
1259 str = str_make("rand(1)");
1260 break;
1261 case OSRAND:
1262 str = str_make("srand(");
1263 goto maybe0;
1264 case OATAN2:
1265 str = str_make("atan2(");
1266 goto maybe0;
1267 case OSIN:
1268 str = str_make("sin(");
1269 goto maybe0;
1270 case OCOS:
1271 str = str_make("cos(");
1272 goto maybe0;
1273 case OSYSTEM:
1274 str = str_make("system(");
1275 goto maybe0;
8d063cd8
LW
1276 case OLENGTH:
1277 str = str_make("length(");
1278 goto maybe0;
1279 case OLOG:
1280 str = str_make("log(");
1281 goto maybe0;
1282 case OEXP:
1283 str = str_make("exp(");
1284 goto maybe0;
1285 case OSQRT:
1286 str = str_make("sqrt(");
1287 goto maybe0;
1288 case OINT:
1289 str = str_make("int(");
1290 maybe0:
1291 numeric = 1;
1292 if (len > 0)
a687059c 1293 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
1294 else
1295 tmpstr = str_new(0);;
fe14fcc3 1296 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
8d063cd8
LW
1297 if (lval_field) {
1298 t = saw_OFS ? "$," : "' '";
1299 if (split_to_array) {
1300 sprintf(tokenbuf,"join(%s,@Fld)",t);
1301 str_cat(tmpstr,tokenbuf);
1302 }
1303 else {
1304 sprintf(tokenbuf,"join(%s, ",t);
1305 str_cat(tmpstr,tokenbuf);
1306 for (i = 1; i < maxfld; i++) {
1307 if (i <= arymax)
1308 sprintf(tokenbuf,"$%s,",nameary[i]);
1309 else
1310 sprintf(tokenbuf,"$Fld%d,",i);
1311 str_cat(tmpstr,tokenbuf);
1312 }
1313 if (maxfld <= arymax)
1314 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1315 else
1316 sprintf(tokenbuf,"$Fld%d)",maxfld);
1317 str_cat(tmpstr,tokenbuf);
1318 }
1319 }
1320 else
1321 str_cat(tmpstr,"$_");
1322 }
1323 if (strEQ(tmpstr->str_ptr,"$_")) {
1324 if (type == OLENGTH && !do_chop) {
1325 str = str_make("(length(");
1326 str_cat(tmpstr,") - 1");
1327 }
1328 }
1329 str_scat(str,tmpstr);
1330 str_free(tmpstr);
1331 str_cat(str,")");
1332 break;
1333 case OBREAK:
1334 str = str_new(0);
1335 str_set(str,"last");
1336 break;
1337 case ONEXT:
1338 str = str_new(0);
1339 str_set(str,"next line");
1340 break;
1341 case OEXIT:
1342 str = str_new(0);
1343 if (realexit) {
a687059c 1344 prec = P_UNI;
8d063cd8
LW
1345 str_set(str,"exit");
1346 if (len == 1) {
1347 str_cat(str," ");
1348 exitval = TRUE;
a687059c
LW
1349 str_scat(str,
1350 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8
LW
1351 str_free(fstr);
1352 }
1353 }
1354 else {
1355 if (len == 1) {
9f68db38 1356 str_set(str,"$ExitValue = ");
8d063cd8 1357 exitval = TRUE;
a687059c
LW
1358 str_scat(str,
1359 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
8d063cd8
LW
1360 str_free(fstr);
1361 str_cat(str,"; ");
1362 }
1363 str_cat(str,"last line");
1364 }
1365 break;
1366 case OCONTINUE:
1367 str = str_new(0);
1368 str_set(str,"next");
1369 break;
1370 case OREDIR:
1371 goto def;
1372 case OIF:
1373 str = str_new(0);
1374 str_set(str,"if (");
a687059c 1375 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1376 str_free(fstr);
1377 str_cat(str,") ");
a687059c 1378 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1379 str_free(fstr);
1380 if (len == 3) {
1381 i = ops[node+3].ival;
1382 if (i) {
1383 if ((ops[i].ival & 255) == OBLOCK) {
1384 i = ops[i+1].ival;
1385 if (i) {
1386 if ((ops[i].ival & 255) != OIF)
1387 i = 0;
1388 }
1389 }
1390 else
1391 i = 0;
1392 }
1393 if (i) {
1394 str_cat(str,"els");
a687059c 1395 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
8d063cd8
LW
1396 str_free(fstr);
1397 }
1398 else {
1399 str_cat(str,"else ");
a687059c 1400 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8
LW
1401 str_free(fstr);
1402 }
1403 }
1404 break;
1405 case OWHILE:
1406 str = str_new(0);
1407 str_set(str,"while (");
a687059c 1408 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1409 str_free(fstr);
1410 str_cat(str,") ");
a687059c 1411 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1412 str_free(fstr);
1413 break;
7c0587c8
LW
1414 case ODO:
1415 str = str_new(0);
1416 str_set(str,"do ");
1417 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1418 str_free(fstr);
1419 if (str->str_ptr[str->str_cur - 1] == '\n')
1420 --str->str_cur;;
1421 str_cat(str," while (");
1422 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1423 str_free(fstr);
1424 str_cat(str,");");
1425 break;
8d063cd8
LW
1426 case OFOR:
1427 str = str_new(0);
1428 str_set(str,"for (");
a687059c 1429 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1430 i = numarg;
1431 if (i) {
1432 t = s = tmpstr->str_ptr;
1433 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1434 t++;
1435 i = t - s;
1436 if (i < 2)
1437 i = 0;
1438 }
1439 str_cat(str,"; ");
a687059c 1440 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
a0d0e21e 1441 if (i && (t = strchr(fstr->str_ptr,0377))) {
8d063cd8
LW
1442 if (strnEQ(fstr->str_ptr,s,i))
1443 *t = ' ';
1444 }
1445 str_scat(str,fstr);
1446 str_free(fstr);
1447 str_free(tmpstr);
1448 str_cat(str,"; ");
a687059c 1449 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8
LW
1450 str_free(fstr);
1451 str_cat(str,") ");
a687059c 1452 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8
LW
1453 str_free(fstr);
1454 break;
1455 case OFORIN:
a687059c 1456 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
a0d0e21e 1457 d = strchr(tmpstr->str_ptr,'$');
a687059c
LW
1458 if (!d)
1459 fatal("Illegal for loop: %s",tmpstr->str_ptr);
a0d0e21e 1460 s = strchr(d,'{');
a687059c 1461 if (!s)
a0d0e21e 1462 s = strchr(d,'[');
a687059c
LW
1463 if (!s)
1464 fatal("Illegal for loop: %s",d);
1465 *s++ = '\0';
ffed7fef
LW
1466 for (t = s; i = *t; t++) {
1467 i &= 127;
1468 if (i == '}' || i == ']')
1469 break;
1470 }
1471 if (*t)
a687059c 1472 *t = '\0';
8d063cd8 1473 str = str_new(0);
a687059c 1474 str_set(str,d+1);
8d063cd8
LW
1475 str_cat(str,"[]");
1476 tmp2str = hfetch(symtab,str->str_ptr);
1477 if (tmp2str && atoi(tmp2str->str_ptr)) {
8d063cd8 1478 sprintf(tokenbuf,
62b28dd9 1479 "foreach %s ($[ .. $#%s) ",
a687059c
LW
1480 s,
1481 d+1);
8d063cd8
LW
1482 }
1483 else {
a687059c
LW
1484 sprintf(tokenbuf,
1485 "foreach %s (keys %%%s) ",
1486 s,
1487 d+1);
8d063cd8 1488 }
a687059c
LW
1489 str_set(str,tokenbuf);
1490 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1491 str_free(fstr);
8d063cd8
LW
1492 str_free(tmpstr);
1493 break;
1494 case OBLOCK:
1495 str = str_new(0);
1496 str_set(str,"{");
378cc40b 1497 if (len >= 2 && ops[node+2].ival) {
a687059c 1498 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1499 str_free(fstr);
1500 }
1501 fixtab(str,++level);
a687059c 1502 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1503 str_free(fstr);
1504 addsemi(str);
1505 fixtab(str,--level);
1506 str_cat(str,"}\n");
1507 tab(str,level);
378cc40b 1508 if (len >= 3) {
a687059c 1509 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
378cc40b
LW
1510 str_free(fstr);
1511 }
8d063cd8
LW
1512 break;
1513 default:
1514 def:
1515 if (len) {
1516 if (len > 5)
1517 fatal("Garbage length in walk");
a687059c 1518 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1519 for (i = 2; i<= len; i++) {
a687059c 1520 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
8d063cd8
LW
1521 str_free(fstr);
1522 }
1523 }
1524 else {
1525 str = Nullstr;
1526 }
1527 break;
1528 }
1529 if (!str)
1530 str = str_new(0);
a687059c
LW
1531
1532 if (useval && prec < minprec) { /* need parens? */
1533 fstr = str_new(str->str_cur+2);
1534 str_nset(fstr,"(",1);
1535 str_scat(fstr,str);
1536 str_ncat(fstr,")",1);
1537 str_free(str);
1538 str = fstr;
1539 }
1540
8d063cd8
LW
1541 *numericptr = numeric;
1542#ifdef DEBUGGING
1543 if (debug & 4) {
1544 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1545 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1546 if (*t == '\n')
1547 printf("\\n");
1548 else if (*t == '\t')
1549 printf("\\t");
1550 else
1551 putchar(*t);
1552 putchar('\n');
1553 }
1554#endif
1555 return str;
1556}
1557
748a9306 1558static void
f0f333f4 1559tab(register STR *str, register int lvl)
8d063cd8
LW
1560{
1561 while (lvl > 1) {
1562 str_cat(str,"\t");
1563 lvl -= 2;
1564 }
1565 if (lvl)
1566 str_cat(str," ");
1567}
1568
748a9306 1569static void
f0f333f4 1570fixtab(register STR *str, register int lvl)
8d063cd8
LW
1571{
1572 register char *s;
1573
1574 /* strip trailing white space */
1575
1576 s = str->str_ptr+str->str_cur - 1;
a687059c 1577 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
8d063cd8
LW
1578 s--;
1579 s[1] = '\0';
1580 str->str_cur = s + 1 - str->str_ptr;
1581 if (s >= str->str_ptr && *s != '\n')
1582 str_cat(str,"\n");
1583
1584 tab(str,lvl);
1585}
1586
748a9306 1587static void
f0f333f4 1588addsemi(register STR *str)
8d063cd8
LW
1589{
1590 register char *s;
1591
1592 s = str->str_ptr+str->str_cur - 1;
1593 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1594 s--;
1595 if (s >= str->str_ptr && *s != ';' && *s != '}')
1596 str_cat(str,";");
1597}
1598
56febc5e 1599static void
f0f333f4 1600emit_split(register STR *str, int level)
8d063cd8
LW
1601{
1602 register int i;
1603
1604 if (split_to_array)
1605 str_cat(str,"@Fld");
1606 else {
1607 str_cat(str,"(");
1608 for (i = 1; i < maxfld; i++) {
1609 if (i <= arymax)
1610 sprintf(tokenbuf,"$%s,",nameary[i]);
1611 else
1612 sprintf(tokenbuf,"$Fld%d,",i);
1613 str_cat(str,tokenbuf);
1614 }
1615 if (maxfld <= arymax)
1616 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1617 else
1618 sprintf(tokenbuf,"$Fld%d)",maxfld);
1619 str_cat(str,tokenbuf);
1620 }
1621 if (const_FS) {
62b28dd9 1622 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
8d063cd8
LW
1623 str_cat(str,tokenbuf);
1624 }
1625 else if (saw_FS)
62b28dd9 1626 str_cat(str," = split($FS, $_, 9999);\n");
8d063cd8 1627 else
62b28dd9 1628 str_cat(str," = split(' ', $_, 9999);\n");
8d063cd8
LW
1629 tab(str,level);
1630}
1631
9c8d0b29 1632int
f0f333f4 1633prewalk(int numit, int level, register int node, int *numericptr)
8d063cd8
LW
1634{
1635 register int len;
1636 register int type;
1637 register int i;
8d063cd8
LW
1638 int numarg;
1639 int numeric = FALSE;
a687059c
LW
1640 STR *tmpstr;
1641 STR *tmp2str;
8d063cd8
LW
1642
1643 if (!node) {
1644 *numericptr = 0;
1645 return 0;
1646 }
1647 type = ops[node].ival;
1648 len = type >> 8;
1649 type &= 255;
1650 switch (type) {
1651 case OPROG:
1652 prewalk(0,level,ops[node+1].ival,&numarg);
1653 if (ops[node+2].ival) {
1654 prewalk(0,level,ops[node+2].ival,&numarg);
1655 }
1656 ++level;
1657 prewalk(0,level,ops[node+3].ival,&numarg);
1658 --level;
1659 if (ops[node+3].ival) {
1660 prewalk(0,level,ops[node+4].ival,&numarg);
1661 }
1662 break;
1663 case OHUNKS:
1664 prewalk(0,level,ops[node+1].ival,&numarg);
1665 prewalk(0,level,ops[node+2].ival,&numarg);
1666 if (len == 3) {
1667 prewalk(0,level,ops[node+3].ival,&numarg);
1668 }
1669 break;
1670 case ORANGE:
1671 prewalk(1,level,ops[node+1].ival,&numarg);
1672 prewalk(1,level,ops[node+2].ival,&numarg);
1673 break;
1674 case OPAT:
1675 goto def;
1676 case OREGEX:
1677 prewalk(0,level,ops[node+1].ival,&numarg);
1678 break;
1679 case OHUNK:
1680 if (len == 1) {
1681 prewalk(0,level,ops[node+1].ival,&numarg);
1682 }
1683 else {
1684 i = prewalk(0,level,ops[node+1].ival,&numarg);
1685 if (i) {
1686 ++level;
1687 prewalk(0,level,ops[node+2].ival,&numarg);
1688 --level;
1689 }
1690 else {
1691 prewalk(0,level,ops[node+2].ival,&numarg);
1692 }
1693 }
1694 break;
1695 case OPPAREN:
1696 prewalk(0,level,ops[node+1].ival,&numarg);
1697 break;
1698 case OPANDAND:
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1700 prewalk(0,level,ops[node+2].ival,&numarg);
1701 break;
1702 case OPOROR:
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1704 prewalk(0,level,ops[node+2].ival,&numarg);
1705 break;
1706 case OPNOT:
1707 prewalk(0,level,ops[node+1].ival,&numarg);
1708 break;
1709 case OCPAREN:
1710 prewalk(0,level,ops[node+1].ival,&numarg);
1711 numeric |= numarg;
1712 break;
1713 case OCANDAND:
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1715 numeric = 1;
1716 prewalk(0,level,ops[node+2].ival,&numarg);
1717 break;
1718 case OCOROR:
1719 prewalk(0,level,ops[node+1].ival,&numarg);
1720 numeric = 1;
1721 prewalk(0,level,ops[node+2].ival,&numarg);
1722 break;
1723 case OCNOT:
1724 prewalk(0,level,ops[node+1].ival,&numarg);
1725 numeric = 1;
1726 break;
1727 case ORELOP:
1728 prewalk(0,level,ops[node+2].ival,&numarg);
1729 numeric |= numarg;
1730 prewalk(0,level,ops[node+1].ival,&numarg);
1731 prewalk(0,level,ops[node+3].ival,&numarg);
1732 numeric |= numarg;
1733 numeric = 1;
1734 break;
1735 case ORPAREN:
1736 prewalk(0,level,ops[node+1].ival,&numarg);
1737 numeric |= numarg;
1738 break;
1739 case OMATCHOP:
1740 prewalk(0,level,ops[node+2].ival,&numarg);
1741 prewalk(0,level,ops[node+1].ival,&numarg);
1742 prewalk(0,level,ops[node+3].ival,&numarg);
1743 numeric = 1;
1744 break;
1745 case OMPAREN:
1746 prewalk(0,level,ops[node+1].ival,&numarg);
1747 numeric |= numarg;
1748 break;
1749 case OCONCAT:
1750 prewalk(0,level,ops[node+1].ival,&numarg);
1751 prewalk(0,level,ops[node+2].ival,&numarg);
1752 break;
1753 case OASSIGN:
1754 prewalk(0,level,ops[node+2].ival,&numarg);
1755 prewalk(0,level,ops[node+1].ival,&numarg);
1756 prewalk(0,level,ops[node+3].ival,&numarg);
75f92628 1757 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
8d063cd8
LW
1758 numericize(ops[node+2].ival);
1759 if (!numarg)
1760 numericize(ops[node+3].ival);
1761 }
1762 numeric |= numarg;
1763 break;
1764 case OADD:
1765 prewalk(1,level,ops[node+1].ival,&numarg);
1766 prewalk(1,level,ops[node+2].ival,&numarg);
1767 numeric = 1;
1768 break;
a687059c 1769 case OSUBTRACT:
8d063cd8
LW
1770 prewalk(1,level,ops[node+1].ival,&numarg);
1771 prewalk(1,level,ops[node+2].ival,&numarg);
1772 numeric = 1;
1773 break;
1774 case OMULT:
1775 prewalk(1,level,ops[node+1].ival,&numarg);
1776 prewalk(1,level,ops[node+2].ival,&numarg);
1777 numeric = 1;
1778 break;
1779 case ODIV:
1780 prewalk(1,level,ops[node+1].ival,&numarg);
1781 prewalk(1,level,ops[node+2].ival,&numarg);
1782 numeric = 1;
1783 break;
a687059c
LW
1784 case OPOW:
1785 prewalk(1,level,ops[node+1].ival,&numarg);
1786 prewalk(1,level,ops[node+2].ival,&numarg);
1787 numeric = 1;
1788 break;
8d063cd8
LW
1789 case OMOD:
1790 prewalk(1,level,ops[node+1].ival,&numarg);
1791 prewalk(1,level,ops[node+2].ival,&numarg);
1792 numeric = 1;
1793 break;
1794 case OPOSTINCR:
1795 prewalk(1,level,ops[node+1].ival,&numarg);
1796 numeric = 1;
1797 break;
1798 case OPOSTDECR:
1799 prewalk(1,level,ops[node+1].ival,&numarg);
1800 numeric = 1;
1801 break;
1802 case OPREINCR:
1803 prewalk(1,level,ops[node+1].ival,&numarg);
1804 numeric = 1;
1805 break;
1806 case OPREDECR:
1807 prewalk(1,level,ops[node+1].ival,&numarg);
1808 numeric = 1;
1809 break;
1810 case OUMINUS:
1811 prewalk(1,level,ops[node+1].ival,&numarg);
1812 numeric = 1;
1813 break;
1814 case OUPLUS:
1815 prewalk(1,level,ops[node+1].ival,&numarg);
1816 numeric = 1;
1817 break;
1818 case OPAREN:
1819 prewalk(0,level,ops[node+1].ival,&numarg);
1820 numeric |= numarg;
1821 break;
1822 case OGETLINE:
1823 break;
1824 case OSPRINTF:
1825 prewalk(0,level,ops[node+1].ival,&numarg);
1826 break;
1827 case OSUBSTR:
1828 prewalk(0,level,ops[node+1].ival,&numarg);
1829 prewalk(1,level,ops[node+2].ival,&numarg);
1830 if (len == 3) {
1831 prewalk(1,level,ops[node+3].ival,&numarg);
1832 }
1833 break;
1834 case OSTRING:
1835 break;
1836 case OSPLIT:
1837 numeric = 1;
1838 prewalk(0,level,ops[node+2].ival,&numarg);
1839 if (len == 3)
1840 prewalk(0,level,ops[node+3].ival,&numarg);
1841 prewalk(0,level,ops[node+1].ival,&numarg);
1842 break;
1843 case OINDEX:
1844 prewalk(0,level,ops[node+1].ival,&numarg);
1845 prewalk(0,level,ops[node+2].ival,&numarg);
1846 numeric = 1;
1847 break;
a687059c
LW
1848 case OMATCH:
1849 prewalk(0,level,ops[node+1].ival,&numarg);
1850 prewalk(0,level,ops[node+2].ival,&numarg);
1851 numeric = 1;
1852 break;
1853 case OUSERDEF:
1854 subretnum = FALSE;
1855 --level;
1856 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1857 ++level;
1858 prewalk(0,level,ops[node+2].ival,&numarg);
1859 prewalk(0,level,ops[node+4].ival,&numarg);
1860 prewalk(0,level,ops[node+5].ival,&numarg);
1861 --level;
1862 str_cat(tmpstr,"(");
1863 tmp2str = str_new(0);
1864 if (subretnum || numarg)
1865 str_set(tmp2str,"1");
1866 hstore(symtab,tmpstr->str_ptr,tmp2str);
1867 str_free(tmpstr);
1868 level++;
1869 break;
1870 case ORETURN:
1871 if (len > 0) {
1872 prewalk(0,level,ops[node+1].ival,&numarg);
1873 if (numarg)
1874 subretnum = TRUE;
1875 }
1876 break;
1877 case OUSERFUN:
1878 tmp2str = str_new(0);
1879 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
663a0e37 1880 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
a687059c
LW
1881 str_free(tmpstr);
1882 str_cat(tmp2str,"(");
1883 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1884 if (tmpstr && tmpstr->str_ptr)
1885 numeric |= atoi(tmpstr->str_ptr);
1886 prewalk(0,level,ops[node+2].ival,&numarg);
1887 str_free(tmp2str);
1888 break;
1889 case OGSUB:
1890 case OSUB:
1891 if (len >= 3)
1892 prewalk(0,level,ops[node+3].ival,&numarg);
1893 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1894 prewalk(0,level,ops[node+1].ival,&numarg);
1895 numeric = 1;
1896 break;
8d063cd8
LW
1897 case ONUM:
1898 prewalk(0,level,ops[node+1].ival,&numarg);
1899 numeric = 1;
1900 break;
1901 case OSTR:
1902 prewalk(0,level,ops[node+1].ival,&numarg);
1903 break;
a687059c
LW
1904 case ODEFINED:
1905 case ODELETE:
1906 case OSTAR:
8d063cd8
LW
1907 case OVAR:
1908 prewalk(0,level,ops[node+1].ival,&numarg);
1909 if (len == 1) {
1910 if (numit)
1911 numericize(node);
1912 }
1913 else {
1914 prewalk(0,level,ops[node+2].ival,&numarg);
1915 }
1916 break;
1917 case OFLD:
1918 prewalk(0,level,ops[node+1].ival,&numarg);
1919 break;
1920 case OVFLD:
1921 i = ops[node+1].ival;
1922 prewalk(0,level,i,&numarg);
1923 break;
1924 case OJUNK:
1925 goto def;
1926 case OSNEWLINE:
1927 break;
1928 case ONEWLINE:
1929 break;
1930 case OSCOMMENT:
1931 break;
1932 case OCOMMENT:
1933 break;
1934 case OCOMMA:
1935 prewalk(0,level,ops[node+1].ival,&numarg);
1936 prewalk(0,level,ops[node+2].ival,&numarg);
a687059c 1937 prewalk(0,level,ops[node+3].ival,&numarg);
8d063cd8
LW
1938 break;
1939 case OSEMICOLON:
1940 break;
1941 case OSTATES:
1942 prewalk(0,level,ops[node+1].ival,&numarg);
1943 prewalk(0,level,ops[node+2].ival,&numarg);
1944 break;
1945 case OSTATE:
1946 if (len >= 1) {
1947 prewalk(0,level,ops[node+1].ival,&numarg);
1948 if (len >= 2) {
1949 prewalk(0,level,ops[node+2].ival,&numarg);
1950 }
1951 }
1952 break;
a687059c
LW
1953 case OCLOSE:
1954 prewalk(0,level,ops[node+1].ival,&numarg);
1955 break;
8d063cd8
LW
1956 case OPRINTF:
1957 case OPRINT:
1958 if (len == 3) { /* output redirection */
1959 prewalk(0,level,ops[node+3].ival,&numarg);
1960 prewalk(0,level,ops[node+2].ival,&numarg);
1961 }
1962 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1963 break;
a687059c
LW
1964 case ORAND:
1965 break;
1966 case OSRAND:
1967 goto maybe0;
1968 case OATAN2:
1969 goto maybe0;
1970 case OSIN:
1971 goto maybe0;
1972 case OCOS:
1973 goto maybe0;
1974 case OSYSTEM:
1975 goto maybe0;
8d063cd8
LW
1976 case OLENGTH:
1977 goto maybe0;
1978 case OLOG:
1979 goto maybe0;
1980 case OEXP:
1981 goto maybe0;
1982 case OSQRT:
1983 goto maybe0;
1984 case OINT:
1985 maybe0:
1986 numeric = 1;
1987 if (len > 0)
a687059c
LW
1988 prewalk(type != OLENGTH && type != OSYSTEM,
1989 level,ops[node+1].ival,&numarg);
8d063cd8
LW
1990 break;
1991 case OBREAK:
1992 break;
1993 case ONEXT:
1994 break;
1995 case OEXIT:
1996 if (len == 1) {
1997 prewalk(1,level,ops[node+1].ival,&numarg);
1998 }
1999 break;
2000 case OCONTINUE:
2001 break;
2002 case OREDIR:
2003 goto def;
2004 case OIF:
2005 prewalk(0,level,ops[node+1].ival,&numarg);
2006 prewalk(0,level,ops[node+2].ival,&numarg);
2007 if (len == 3) {
2008 prewalk(0,level,ops[node+3].ival,&numarg);
2009 }
2010 break;
2011 case OWHILE:
2012 prewalk(0,level,ops[node+1].ival,&numarg);
2013 prewalk(0,level,ops[node+2].ival,&numarg);
2014 break;
2015 case OFOR:
2016 prewalk(0,level,ops[node+1].ival,&numarg);
2017 prewalk(0,level,ops[node+2].ival,&numarg);
2018 prewalk(0,level,ops[node+3].ival,&numarg);
2019 prewalk(0,level,ops[node+4].ival,&numarg);
2020 break;
2021 case OFORIN:
2022 prewalk(0,level,ops[node+2].ival,&numarg);
2023 prewalk(0,level,ops[node+1].ival,&numarg);
8d063cd8
LW
2024 break;
2025 case OBLOCK:
2026 if (len == 2) {
2027 prewalk(0,level,ops[node+2].ival,&numarg);
2028 }
2029 ++level;
2030 prewalk(0,level,ops[node+1].ival,&numarg);
2031 --level;
2032 break;
2033 default:
2034 def:
2035 if (len) {
2036 if (len > 5)
2037 fatal("Garbage length in prewalk");
2038 prewalk(0,level,ops[node+1].ival,&numarg);
2039 for (i = 2; i<= len; i++) {
2040 prewalk(0,level,ops[node+i].ival,&numarg);
2041 }
2042 }
2043 break;
2044 }
2045 *numericptr = numeric;
2046 return 1;
2047}
2048
748a9306 2049static void
f0f333f4 2050numericize(register int node)
8d063cd8
LW
2051{
2052 register int len;
2053 register int type;
8d063cd8
LW
2054 STR *tmpstr;
2055 STR *tmp2str;
2056 int numarg;
2057
2058 type = ops[node].ival;
2059 len = type >> 8;
2060 type &= 255;
2061 if (type == OVAR && len == 1) {
a687059c 2062 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
2063 tmp2str = str_make("1");
2064 hstore(symtab,tmpstr->str_ptr,tmp2str);
2065 }
2066}