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