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