blead 25801: Symbian batch of today
[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 *
4bb101f2 3 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
07409e01 4 * 2000, 2001, 2002, 2005 by Larry Wall and others
a687059c 5 *
d48672a2 6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8d063cd8 8 *
9 * $Log: walk.c,v $
8d063cd8 10 */
11
8d063cd8 12#include "EXTERN.h"
8d063cd8 13#include "a2p.h"
9c8d0b29 14#include "util.h"
8d063cd8 15
16bool exitval = FALSE;
17bool realexit = FALSE;
378cc40b 18bool saw_getline = FALSE;
a687059c 19bool subretnum = FALSE;
20bool saw_FNR = FALSE;
21bool saw_argv0 = FALSE;
d48672a2 22bool saw_fh = FALSE;
8d063cd8 23int maxtmp = 0;
378cc40b 24char *lparen;
25char *rparen;
55204971 26char *limit;
a687059c 27STR *subs;
28STR *curargs = Nullstr;
8d063cd8 29
20ce7b12 30static void addsemi ( STR *str );
31static void emit_split ( STR *str, int level );
32static void fixtab ( STR *str, int lvl );
33static void numericize ( int node );
34static void tab ( STR *str, int lvl );
56febc5e 35
20ce7b12 36int prewalk ( int numit, int level, int node, int *numericptr );
37STR * walk ( int useval, int level, int node, int *numericptr, int minprec );
011f1a1a 38#ifdef NETWARE
39char *savestr(char *str);
40char *cpytill(register char *to, register char *from, register int delim);
41char *instr(char *big, char *little);
42#endif
9c8d0b29 43
8d063cd8 44STR *
f0f333f4 45walk(int useval, int level, register int node, int *numericptr, int minprec)
46
47
48
49
50 /* 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;
0335b3e4 60 char *d, *s;
8d063cd8 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) {
3f939f22 77 while (isALPHA(*namelist)) {
d48672a2 78 for (d = tokenbuf,s=namelist;
3f939f22 79 isALPHA(*s) || isDIGIT(*s) || *s == '_';
d48672a2 80 *d++ = *s++) ;
81 *d = '\0';
3f939f22 82 while (*s && !isALPHA(*s)) s++;
d48672a2 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) {
7bdaec8a 141 str_cat(str,"chomp;\t# strip record separator\n");
a687059c 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 }
a5571d59 153 else if (old_awk)
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++;
7bdaec8a 198 str_cat(str,"chomp;\t# strip record separator\n");
a687059c 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++) {
3f939f22 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++)
c5cf9ec2 262 *d += (char)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;
3f939f22 597 if (isLOWER(*t))
598 *t = toUPPER(*t);
599 if (!isALPHA(*t) && !isDIGIT(*t))
a687059c 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);
8d063cd8 663 if (len == 3) {
4cec2b33 664 str_cat(str,", ");
a687059c 665 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
8d063cd8 666 str_free(fstr);
667 }
8d063cd8 668 str_cat(str,")");
669 break;
670 case OSTRING:
671 str = str_new(0);
672 str_set(str,ops[node+1].cval);
673 break;
674 case OSPLIT:
675 str = str_new(0);
4cec2b33 676 limit = ", -1)";
8d063cd8 677 numeric = 1;
a687059c 678 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 679 if (useval)
680 str_set(str,"(@");
681 else
682 str_set(str,"@");
683 str_scat(str,tmpstr);
684 str_cat(str," = split(");
685 if (len == 3) {
a687059c 686 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
8d063cd8 687 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
688 i = fstr->str_ptr[1] & 127;
a0d0e21e 689 if (strchr("*+?.[]()|^$\\",i))
8d063cd8 690 sprintf(tokenbuf,"/\\%c/",i);
20188a90 691 else if (i == ' ')
62b28dd9 692 sprintf(tokenbuf,"' '");
8d063cd8 693 else
694 sprintf(tokenbuf,"/%c/",i);
695 str_cat(str,tokenbuf);
696 }
697 else
698 str_scat(str,fstr);
699 str_free(fstr);
700 }
701 else if (const_FS) {
702 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
703 str_cat(str,tokenbuf);
704 }
705 else if (saw_FS)
706 str_cat(str,"$FS");
55204971 707 else {
9bb9d9f7 708 str_cat(str,"' '");
55204971 709 limit = ")";
710 }
8d063cd8 711 str_cat(str,", ");
a687059c 712 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 713 str_free(fstr);
55204971 714 str_cat(str,limit);
8d063cd8 715 if (useval) {
716 str_cat(str,")");
717 }
718 str_free(tmpstr);
719 break;
720 case OINDEX:
721 str = str_new(0);
722 str_set(str,"index(");
a687059c 723 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 724 str_free(fstr);
725 str_cat(str,", ");
a687059c 726 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8 727 str_free(fstr);
728 str_cat(str,")");
729 numeric = 1;
730 break;
a687059c 731 case OMATCH:
732 str = str_new(0);
733 prec = P_ANDAND;
734 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
735 str_free(fstr);
736 str_cat(str," =~ ");
737 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
738 str_free(fstr);
739 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
740 numeric = 1;
741 break;
742 case OUSERDEF:
743 str = str_new(0);
744 subretnum = FALSE;
745 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
746 curargs = str_new(0);
747 str_sset(curargs,fstr);
748 str_cat(curargs,",");
749 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
750 str_free(curargs);
751 curargs = Nullstr;
752 level--;
753 subretnum |= numarg;
754 s = Nullch;
755 t = tmp2str->str_ptr;
b7953727 756 while ((t = instr(t,"return ")))
a687059c 757 s = t++;
758 if (s) {
759 i = 0;
760 for (t = s+7; *t; t++) {
761 if (*t == ';' || *t == '}')
762 i++;
763 }
764 if (i == 1) {
765 strcpy(s,s+7);
766 tmp2str->str_cur -= 7;
767 }
768 }
769 str_set(str,"\n");
770 tab(str,level);
771 str_cat(str,"sub ");
772 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
773 str_cat(str," {\n");
774 tab(str,++level);
775 if (fstr->str_cur) {
776 str_cat(str,"local(");
777 str_scat(str,fstr);
778 str_cat(str,") = @_;");
779 }
780 str_free(fstr);
781 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
782 str_free(fstr);
783 fixtab(str,level);
784 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
785 str_free(fstr);
786 fixtab(str,level);
787 str_scat(str,tmp2str);
788 str_free(tmp2str);
789 fixtab(str,--level);
790 str_cat(str,"}\n");
791 tab(str,level);
792 str_scat(subs,str);
793 str_set(str,"");
794 str_cat(tmpstr,"(");
795 tmp2str = str_new(0);
796 if (subretnum)
797 str_set(tmp2str,"1");
798 hstore(symtab,tmpstr->str_ptr,tmp2str);
799 str_free(tmpstr);
800 level++;
801 break;
802 case ORETURN:
803 str = str_new(0);
804 if (len > 0) {
805 str_cat(str,"return ");
806 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
807 str_free(fstr);
808 if (numarg)
809 subretnum = TRUE;
810 }
811 else
812 str_cat(str,"return");
813 break;
814 case OUSERFUN:
815 str = str_new(0);
816 str_set(str,"&");
817 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
818 str_free(fstr);
819 str_cat(str,"(");
820 tmpstr = hfetch(symtab,str->str_ptr+3);
821 if (tmpstr && tmpstr->str_ptr)
822 numeric |= atoi(tmpstr->str_ptr);
823 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
824 str_free(fstr);
825 str_cat(str,")");
826 break;
827 case OGSUB:
0335b3e4 828 case OSUB: {
829 int gsub = type == OGSUB ? 1 : 0;
a687059c 830 str = str_new(0);
831 tmpstr = str_new(0);
832 i = 0;
833 if (len == 3) {
834 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
835 if (strNE(tmpstr->str_ptr,"$_")) {
836 str_cat(tmpstr, " =~ s");
837 i++;
838 }
839 else
840 str_set(tmpstr, "s");
841 }
842 else
843 str_set(tmpstr, "s");
844 type = ops[ops[node+2].ival].ival;
845 len = type >> 8;
846 type &= 255;
847 tmp3str = str_new(0);
848 if (type == OSTR) {
849 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
850 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
851 if (*t == '&')
c5cf9ec2 852 *d++ = '$' + (char)128;
a687059c 853 else if (*t == '$')
c5cf9ec2 854 *d++ = '\\' + (char)128;
a687059c 855 *d = *t + 128;
856 }
857 *d = '\0';
858 str_set(tmp2str,tokenbuf);
07409e01 859 s = (char *) (gsub ? "/g" : "/");
a687059c 860 }
861 else {
862 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
863 str_set(tmp3str,"($s_ = '\"'.(");
864 str_scat(tmp3str,tmp2str);
865 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
866 str_set(tmp2str,"eval $s_");
07409e01 867 s = (char *) (gsub ? "/ge" : "/e");
a687059c 868 i++;
869 }
0335b3e4 870 str_cat(tmp2str,s);
a687059c 871 type = ops[ops[node+1].ival].ival;
872 len = type >> 8;
873 type &= 255;
874 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
875 if (type == OREGEX) {
876 if (useval && i)
877 str_cat(str,"(");
878 str_scat(str,tmp3str);
879 str_scat(str,tmpstr);
880 str_scat(str,fstr);
881 str_scat(str,tmp2str);
a687059c 882 }
883 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
884 if (useval && i)
885 str_cat(str,"(");
886 str_scat(str,tmp3str);
887 str_scat(str,tmpstr);
888 str_cat(str,"/");
889 str_scat(str,fstr);
890 str_cat(str,"/");
891 str_scat(str,tmp2str);
a687059c 892 }
893 else {
894 i++;
895 if (useval)
896 str_cat(str,"(");
897 str_cat(str,"$s = ");
898 str_scat(str,fstr);
899 str_cat(str,", ");
900 str_scat(str,tmp3str);
901 str_scat(str,tmpstr);
902 str_cat(str,"/$s/");
903 str_scat(str,tmp2str);
a687059c 904 }
905 if (useval && i)
906 str_cat(str,")");
907 str_free(fstr);
908 str_free(tmpstr);
909 str_free(tmp2str);
910 str_free(tmp3str);
911 numeric = 1;
0335b3e4 912 break; }
8d063cd8 913 case ONUM:
a687059c 914 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 915 numeric = 1;
916 break;
917 case OSTR:
a687059c 918 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 919 s = "'";
378cc40b 920 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
921 if (*t == '\'')
922 s = "\"";
923 else if (*t == '\\') {
8d063cd8 924 s = "\"";
378cc40b 925 *d++ = *t++ + 128;
926 switch (*t) {
fe14fcc3 927 case '\\': case '"': case 'n': case 't': case '$':
378cc40b 928 break;
929 default: /* hide this from perl */
c5cf9ec2 930 *d++ = '\\' + (char)128;
378cc40b 931 }
932 }
933 *d = *t + 128;
8d063cd8 934 }
378cc40b 935 *d = '\0';
8d063cd8 936 str = str_new(0);
937 str_set(str,s);
378cc40b 938 str_cat(str,tokenbuf);
8d063cd8 939 str_free(tmpstr);
940 str_cat(str,s);
941 break;
a687059c 942 case ODEFINED:
943 prec = P_UNI;
944 str = str_new(0);
945 str_set(str,"defined $");
946 goto addvar;
947 case ODELETE:
948 str = str_new(0);
949 str_set(str,"delete $");
950 goto addvar;
951 case OSTAR:
952 str = str_new(0);
953 str_set(str,"*");
954 goto addvar;
8d063cd8 955 case OVAR:
956 str = str_new(0);
957 str_set(str,"$");
a687059c 958 addvar:
959 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 960 if (len == 1) {
961 tmp2str = hfetch(symtab,tmpstr->str_ptr);
962 if (tmp2str && atoi(tmp2str->str_ptr))
963 numeric = 2;
a687059c 964 if (strEQ(str->str_ptr,"$FNR")) {
965 numeric = 1;
966 saw_FNR++;
967 str_set(str,"($.-$FNRbase)");
968 }
969 else if (strEQ(str->str_ptr,"$NR")) {
8d063cd8 970 numeric = 1;
971 str_set(str,"$.");
972 }
973 else if (strEQ(str->str_ptr,"$NF")) {
974 numeric = 1;
975 str_set(str,"$#Fld");
976 }
977 else if (strEQ(str->str_ptr,"$0"))
978 str_set(str,"$_");
a687059c 979 else if (strEQ(str->str_ptr,"$ARGC"))
980 str_set(str,"($#ARGV+1)");
8d063cd8 981 }
982 else {
a687059c 983#ifdef NOTDEF
984 if (curargs) {
985 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
986 ??? if (instr(curargs->str_ptr,tokenbuf))
987 str_cat(str,"\377"); /* can't translate yet */
988 }
989#endif
8d063cd8 990 str_cat(tmpstr,"[]");
991 tmp2str = hfetch(symtab,tmpstr->str_ptr);
992 if (tmp2str && atoi(tmp2str->str_ptr))
993 str_cat(str,"[");
994 else
995 str_cat(str,"{");
a687059c 996 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 997 str_free(fstr);
a687059c 998 if (strEQ(str->str_ptr,"$ARGV[0")) {
999 str_set(str,"$ARGV0");
1000 saw_argv0++;
1001 }
1002 else {
1003 if (tmp2str && atoi(tmp2str->str_ptr))
1004 strcpy(tokenbuf,"]");
1005 else
1006 strcpy(tokenbuf,"}");
c5cf9ec2 1007 *tokenbuf += (char)128;
a687059c 1008 str_cat(str,tokenbuf);
1009 }
8d063cd8 1010 }
1011 str_free(tmpstr);
1012 break;
1013 case OFLD:
1014 str = str_new(0);
1015 if (split_to_array) {
1016 str_set(str,"$Fld");
1017 str_cat(str,"[");
a687059c 1018 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1019 str_free(fstr);
1020 str_cat(str,"]");
1021 }
1022 else {
a687059c 1023 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
8d063cd8 1024 if (i <= arymax)
1025 sprintf(tokenbuf,"$%s",nameary[i]);
1026 else
1027 sprintf(tokenbuf,"$Fld%d",i);
1028 str_set(str,tokenbuf);
1029 }
1030 break;
1031 case OVFLD:
1032 str = str_new(0);
1033 str_set(str,"$Fld[");
1034 i = ops[node+1].ival;
1035 if ((ops[i].ival & 255) == OPAREN)
1036 i = ops[i+1].ival;
a687059c 1037 tmpstr=walk(1,level,i,&numarg,P_MIN);
8d063cd8 1038 str_scat(str,tmpstr);
1039 str_free(tmpstr);
1040 str_cat(str,"]");
1041 break;
1042 case OJUNK:
1043 goto def;
1044 case OSNEWLINE:
1045 str = str_new(2);
1046 str_set(str,";\n");
1047 tab(str,level);
1048 break;
1049 case ONEWLINE:
1050 str = str_new(1);
1051 str_set(str,"\n");
1052 tab(str,level);
1053 break;
1054 case OSCOMMENT:
1055 str = str_new(0);
1056 str_set(str,";");
a687059c 1057 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1058 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
c5cf9ec2 1059 *s += (char)128;
8d063cd8 1060 str_scat(str,tmpstr);
1061 str_free(tmpstr);
1062 tab(str,level);
1063 break;
1064 case OCOMMENT:
1065 str = str_new(0);
a687059c 1066 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1067 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
c5cf9ec2 1068 *s += (char)128;
8d063cd8 1069 str_scat(str,tmpstr);
1070 str_free(tmpstr);
1071 tab(str,level);
1072 break;
1073 case OCOMMA:
a687059c 1074 prec = P_COMMA;
1075 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 1076 str_cat(str,", ");
a687059c 1077 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1078 str_free(fstr);
1079 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 1080 str_free(fstr);
1081 break;
1082 case OSEMICOLON:
1083 str = str_new(1);
a687059c 1084 str_set(str,";\n");
1085 tab(str,level);
8d063cd8 1086 break;
1087 case OSTATES:
a687059c 1088 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1089 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1090 str_free(fstr);
1091 break;
1092 case OSTATE:
1093 str = str_new(0);
1094 if (len >= 1) {
a687059c 1095 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1096 str_free(fstr);
1097 if (len >= 2) {
a687059c 1098 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1099 if (*tmpstr->str_ptr == ';') {
1100 addsemi(str);
1101 str_cat(str,tmpstr->str_ptr+1);
1102 }
1103 str_free(tmpstr);
1104 }
1105 }
1106 break;
a687059c 1107 case OCLOSE:
1108 str = str_make("close(");
1109 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1110 if (!do_fancy_opens) {
1111 t = tmpstr->str_ptr;
1112 if (*t == '"' || *t == '\'')
1113 t = cpytill(tokenbuf,t+1,*t);
1114 else
1115 fatal("Internal error: OCLOSE %s",t);
1116 s = savestr(tokenbuf);
1117 for (t = tokenbuf; *t; t++) {
1118 *t &= 127;
3f939f22 1119 if (isLOWER(*t))
1120 *t = toUPPER(*t);
1121 if (!isALPHA(*t) && !isDIGIT(*t))
a687059c 1122 *t = '_';
1123 }
a0d0e21e 1124 if (!strchr(tokenbuf,'_'))
d48672a2 1125 strcpy(t,"_FH");
a687059c 1126 str_free(tmpstr);
1127 safefree(s);
1128 str_set(str,"close ");
1129 str_cat(str,tokenbuf);
1130 }
1131 else {
7c0587c8 1132 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1133 tmpstr->str_ptr, tmpstr->str_ptr);
a687059c 1134 str_free(tmpstr);
1135 str_set(str,tokenbuf);
1136 }
1137 break;
8d063cd8 1138 case OPRINTF:
1139 case OPRINT:
378cc40b 1140 lparen = ""; /* set to parens if necessary */
1141 rparen = "";
8d063cd8 1142 str = str_new(0);
1143 if (len == 3) { /* output redirection */
a687059c 1144 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1145 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1146 if (!do_fancy_opens) {
1147 t = tmpstr->str_ptr;
1148 if (*t == '"' || *t == '\'')
1149 t = cpytill(tokenbuf,t+1,*t);
1150 else
1151 fatal("Internal error: OPRINT");
1152 d = savestr(t);
1153 s = savestr(tokenbuf);
1154 for (t = tokenbuf; *t; t++) {
1155 *t &= 127;
3f939f22 1156 if (isLOWER(*t))
1157 *t = toUPPER(*t);
1158 if (!isALPHA(*t) && !isDIGIT(*t))
8d063cd8 1159 *t = '_';
1160 }
a0d0e21e 1161 if (!strchr(tokenbuf,'_'))
d48672a2 1162 strcpy(t,"_FH");
a687059c 1163 tmp3str = hfetch(symtab,tokenbuf);
1164 if (!tmp3str) {
1165 str_cat(opens,"open(");
1166 str_cat(opens,tokenbuf);
1167 str_cat(opens,", ");
1168 d[1] = '\0';
1169 str_cat(opens,d);
1170 str_scat(opens,tmp2str);
1171 str_cat(opens,tmpstr->str_ptr+1);
1172 if (*tmp2str->str_ptr == '|')
1173 str_cat(opens,") || die 'Cannot pipe to \"");
1174 else
1175 str_cat(opens,") || die 'Cannot create file \"");
1176 if (*d == '"')
1177 str_cat(opens,"'.\"");
1178 str_cat(opens,s);
1179 if (*d == '"')
1180 str_cat(opens,"\".'");
1181 str_cat(opens,"\".';\n");
1182 hstore(symtab,tokenbuf,str_make("x"));
1183 }
8d063cd8 1184 str_free(tmpstr);
1185 str_free(tmp2str);
1186 safefree(s);
1187 safefree(d);
1188 }
1189 else {
a687059c 1190 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8 1191 tmp2str->str_ptr, tmpstr->str_ptr);
1192 str_cat(str,tokenbuf);
1193 tab(str,level+1);
a687059c 1194 strcpy(tokenbuf,"$fh");
8d063cd8 1195 str_free(tmpstr);
1196 str_free(tmp2str);
378cc40b 1197 lparen = "(";
1198 rparen = ")";
8d063cd8 1199 }
1200 }
1201 else
a687059c 1202 strcpy(tokenbuf,"");
378cc40b 1203 str_cat(str,lparen); /* may be null */
8d063cd8 1204 if (type == OPRINTF)
1205 str_cat(str,"printf");
1206 else
1207 str_cat(str,"print");
d48672a2 1208 saw_fh = 0;
8d063cd8 1209 if (len == 3 || do_fancy_opens) {
d48672a2 1210 if (*tokenbuf) {
8d063cd8 1211 str_cat(str," ");
d48672a2 1212 saw_fh = 1;
1213 }
8d063cd8 1214 str_cat(str,tokenbuf);
1215 }
a687059c 1216 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1217 if (!*tmpstr->str_ptr && lval_field) {
2b260de0 1218 t = (char*)(saw_OFS ? "$," : "' '");
8d063cd8 1219 if (split_to_array) {
1220 sprintf(tokenbuf,"join(%s,@Fld)",t);
1221 str_cat(tmpstr,tokenbuf);
1222 }
1223 else {
1224 for (i = 1; i < maxfld; i++) {
1225 if (i <= arymax)
1226 sprintf(tokenbuf,"$%s, ",nameary[i]);
1227 else
1228 sprintf(tokenbuf,"$Fld%d, ",i);
1229 str_cat(tmpstr,tokenbuf);
1230 }
1231 if (maxfld <= arymax)
1232 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1233 else
1234 sprintf(tokenbuf,"$Fld%d",maxfld);
1235 str_cat(tmpstr,tokenbuf);
1236 }
1237 }
1238 if (*tmpstr->str_ptr) {
1239 str_cat(str," ");
d48672a2 1240 if (!saw_fh && *tmpstr->str_ptr == '(') {
1241 str_cat(str,"(");
1242 str_scat(str,tmpstr);
1243 str_cat(str,")");
1244 }
1245 else
1246 str_scat(str,tmpstr);
8d063cd8 1247 }
1248 else {
1249 str_cat(str," $_");
1250 }
378cc40b 1251 str_cat(str,rparen); /* may be null */
8d063cd8 1252 str_free(tmpstr);
1253 break;
a687059c 1254 case ORAND:
1255 str = str_make("rand(1)");
1256 break;
1257 case OSRAND:
1258 str = str_make("srand(");
1259 goto maybe0;
1260 case OATAN2:
1261 str = str_make("atan2(");
1262 goto maybe0;
1263 case OSIN:
1264 str = str_make("sin(");
1265 goto maybe0;
1266 case OCOS:
1267 str = str_make("cos(");
1268 goto maybe0;
1269 case OSYSTEM:
1270 str = str_make("system(");
1271 goto maybe0;
8d063cd8 1272 case OLENGTH:
1273 str = str_make("length(");
1274 goto maybe0;
1275 case OLOG:
1276 str = str_make("log(");
1277 goto maybe0;
1278 case OEXP:
1279 str = str_make("exp(");
1280 goto maybe0;
1281 case OSQRT:
1282 str = str_make("sqrt(");
1283 goto maybe0;
1284 case OINT:
1285 str = str_make("int(");
1286 maybe0:
1287 numeric = 1;
1288 if (len > 0)
a687059c 1289 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1290 else
db7c17d7 1291 tmpstr = str_new(0);
fe14fcc3 1292 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
8d063cd8 1293 if (lval_field) {
2b260de0 1294 t = (char*)(saw_OFS ? "$," : "' '");
8d063cd8 1295 if (split_to_array) {
1296 sprintf(tokenbuf,"join(%s,@Fld)",t);
1297 str_cat(tmpstr,tokenbuf);
1298 }
1299 else {
1300 sprintf(tokenbuf,"join(%s, ",t);
1301 str_cat(tmpstr,tokenbuf);
1302 for (i = 1; i < maxfld; i++) {
1303 if (i <= arymax)
1304 sprintf(tokenbuf,"$%s,",nameary[i]);
1305 else
1306 sprintf(tokenbuf,"$Fld%d,",i);
1307 str_cat(tmpstr,tokenbuf);
1308 }
1309 if (maxfld <= arymax)
1310 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1311 else
1312 sprintf(tokenbuf,"$Fld%d)",maxfld);
1313 str_cat(tmpstr,tokenbuf);
1314 }
1315 }
1316 else
1317 str_cat(tmpstr,"$_");
1318 }
1319 if (strEQ(tmpstr->str_ptr,"$_")) {
1320 if (type == OLENGTH && !do_chop) {
1321 str = str_make("(length(");
1322 str_cat(tmpstr,") - 1");
1323 }
1324 }
1325 str_scat(str,tmpstr);
1326 str_free(tmpstr);
1327 str_cat(str,")");
1328 break;
1329 case OBREAK:
1330 str = str_new(0);
1331 str_set(str,"last");
1332 break;
1333 case ONEXT:
1334 str = str_new(0);
1335 str_set(str,"next line");
1336 break;
1337 case OEXIT:
1338 str = str_new(0);
1339 if (realexit) {
a687059c 1340 prec = P_UNI;
8d063cd8 1341 str_set(str,"exit");
1342 if (len == 1) {
1343 str_cat(str," ");
1344 exitval = TRUE;
a687059c 1345 str_scat(str,
1346 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 1347 str_free(fstr);
1348 }
1349 }
1350 else {
1351 if (len == 1) {
9f68db38 1352 str_set(str,"$ExitValue = ");
8d063cd8 1353 exitval = TRUE;
a687059c 1354 str_scat(str,
1355 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
8d063cd8 1356 str_free(fstr);
1357 str_cat(str,"; ");
1358 }
1359 str_cat(str,"last line");
1360 }
1361 break;
1362 case OCONTINUE:
1363 str = str_new(0);
1364 str_set(str,"next");
1365 break;
1366 case OREDIR:
1367 goto def;
1368 case OIF:
1369 str = str_new(0);
1370 str_set(str,"if (");
a687059c 1371 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1372 str_free(fstr);
1373 str_cat(str,") ");
a687059c 1374 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1375 str_free(fstr);
1376 if (len == 3) {
1377 i = ops[node+3].ival;
1378 if (i) {
1379 if ((ops[i].ival & 255) == OBLOCK) {
1380 i = ops[i+1].ival;
1381 if (i) {
1382 if ((ops[i].ival & 255) != OIF)
1383 i = 0;
1384 }
1385 }
1386 else
1387 i = 0;
1388 }
1389 if (i) {
1390 str_cat(str,"els");
a687059c 1391 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
8d063cd8 1392 str_free(fstr);
1393 }
1394 else {
1395 str_cat(str,"else ");
a687059c 1396 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1397 str_free(fstr);
1398 }
1399 }
1400 break;
1401 case OWHILE:
1402 str = str_new(0);
1403 str_set(str,"while (");
a687059c 1404 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1405 str_free(fstr);
1406 str_cat(str,") ");
a687059c 1407 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1408 str_free(fstr);
1409 break;
7c0587c8 1410 case ODO:
1411 str = str_new(0);
1412 str_set(str,"do ");
1413 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1414 str_free(fstr);
1415 if (str->str_ptr[str->str_cur - 1] == '\n')
db7c17d7 1416 --str->str_cur;
7c0587c8 1417 str_cat(str," while (");
1418 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1419 str_free(fstr);
1420 str_cat(str,");");
1421 break;
8d063cd8 1422 case OFOR:
1423 str = str_new(0);
1424 str_set(str,"for (");
a687059c 1425 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1426 i = numarg;
1427 if (i) {
1428 t = s = tmpstr->str_ptr;
3f939f22 1429 while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
8d063cd8 1430 t++;
1431 i = t - s;
1432 if (i < 2)
1433 i = 0;
1434 }
1435 str_cat(str,"; ");
a687059c 1436 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
a0d0e21e 1437 if (i && (t = strchr(fstr->str_ptr,0377))) {
8d063cd8 1438 if (strnEQ(fstr->str_ptr,s,i))
1439 *t = ' ';
1440 }
1441 str_scat(str,fstr);
1442 str_free(fstr);
1443 str_free(tmpstr);
1444 str_cat(str,"; ");
a687059c 1445 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1446 str_free(fstr);
1447 str_cat(str,") ");
a687059c 1448 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 1449 str_free(fstr);
1450 break;
1451 case OFORIN:
a687059c 1452 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
a0d0e21e 1453 d = strchr(tmpstr->str_ptr,'$');
a687059c 1454 if (!d)
1455 fatal("Illegal for loop: %s",tmpstr->str_ptr);
a0d0e21e 1456 s = strchr(d,'{');
a687059c 1457 if (!s)
a0d0e21e 1458 s = strchr(d,'[');
a687059c 1459 if (!s)
1460 fatal("Illegal for loop: %s",d);
1461 *s++ = '\0';
b7953727 1462 for (t = s; (i = *t); t++) {
ffed7fef 1463 i &= 127;
1464 if (i == '}' || i == ']')
1465 break;
1466 }
1467 if (*t)
a687059c 1468 *t = '\0';
8d063cd8 1469 str = str_new(0);
a687059c 1470 str_set(str,d+1);
8d063cd8 1471 str_cat(str,"[]");
1472 tmp2str = hfetch(symtab,str->str_ptr);
1473 if (tmp2str && atoi(tmp2str->str_ptr)) {
8d063cd8 1474 sprintf(tokenbuf,
62b28dd9 1475 "foreach %s ($[ .. $#%s) ",
a687059c 1476 s,
1477 d+1);
8d063cd8 1478 }
1479 else {
a687059c 1480 sprintf(tokenbuf,
1481 "foreach %s (keys %%%s) ",
1482 s,
1483 d+1);
8d063cd8 1484 }
a687059c 1485 str_set(str,tokenbuf);
1486 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1487 str_free(fstr);
8d063cd8 1488 str_free(tmpstr);
1489 break;
1490 case OBLOCK:
1491 str = str_new(0);
1492 str_set(str,"{");
378cc40b 1493 if (len >= 2 && ops[node+2].ival) {
a687059c 1494 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1495 str_free(fstr);
1496 }
1497 fixtab(str,++level);
a687059c 1498 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1499 str_free(fstr);
1500 addsemi(str);
1501 fixtab(str,--level);
1502 str_cat(str,"}\n");
1503 tab(str,level);
378cc40b 1504 if (len >= 3) {
a687059c 1505 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
378cc40b 1506 str_free(fstr);
1507 }
8d063cd8 1508 break;
1509 default:
1510 def:
1511 if (len) {
1512 if (len > 5)
1513 fatal("Garbage length in walk");
a687059c 1514 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1515 for (i = 2; i<= len; i++) {
a687059c 1516 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
8d063cd8 1517 str_free(fstr);
1518 }
1519 }
1520 else {
1521 str = Nullstr;
1522 }
1523 break;
1524 }
1525 if (!str)
1526 str = str_new(0);
a687059c 1527
1528 if (useval && prec < minprec) { /* need parens? */
1529 fstr = str_new(str->str_cur+2);
1530 str_nset(fstr,"(",1);
1531 str_scat(fstr,str);
1532 str_ncat(fstr,")",1);
1533 str_free(str);
1534 str = fstr;
1535 }
1536
8d063cd8 1537 *numericptr = numeric;
1538#ifdef DEBUGGING
1539 if (debug & 4) {
1540 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1541 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1542 if (*t == '\n')
1543 printf("\\n");
1544 else if (*t == '\t')
1545 printf("\\t");
1546 else
1547 putchar(*t);
1548 putchar('\n');
1549 }
1550#endif
1551 return str;
1552}
1553
748a9306 1554static void
f0f333f4 1555tab(register STR *str, register int lvl)
8d063cd8 1556{
1557 while (lvl > 1) {
1558 str_cat(str,"\t");
1559 lvl -= 2;
1560 }
1561 if (lvl)
1562 str_cat(str," ");
1563}
1564
748a9306 1565static void
f0f333f4 1566fixtab(register STR *str, register int lvl)
8d063cd8 1567{
1568 register char *s;
1569
1570 /* strip trailing white space */
1571
1572 s = str->str_ptr+str->str_cur - 1;
a687059c 1573 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
8d063cd8 1574 s--;
1575 s[1] = '\0';
1576 str->str_cur = s + 1 - str->str_ptr;
1577 if (s >= str->str_ptr && *s != '\n')
1578 str_cat(str,"\n");
1579
1580 tab(str,lvl);
1581}
1582
748a9306 1583static void
f0f333f4 1584addsemi(register STR *str)
8d063cd8 1585{
1586 register char *s;
1587
1588 s = str->str_ptr+str->str_cur - 1;
1589 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1590 s--;
1591 if (s >= str->str_ptr && *s != ';' && *s != '}')
1592 str_cat(str,";");
1593}
1594
56febc5e 1595static void
f0f333f4 1596emit_split(register STR *str, int level)
8d063cd8 1597{
1598 register int i;
1599
1600 if (split_to_array)
1601 str_cat(str,"@Fld");
1602 else {
1603 str_cat(str,"(");
1604 for (i = 1; i < maxfld; i++) {
1605 if (i <= arymax)
1606 sprintf(tokenbuf,"$%s,",nameary[i]);
1607 else
1608 sprintf(tokenbuf,"$Fld%d,",i);
1609 str_cat(str,tokenbuf);
1610 }
1611 if (maxfld <= arymax)
1612 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1613 else
1614 sprintf(tokenbuf,"$Fld%d)",maxfld);
1615 str_cat(str,tokenbuf);
1616 }
1617 if (const_FS) {
4cec2b33 1618 sprintf(tokenbuf," = split(/[%c\\n]/, $_, -1);\n",const_FS);
8d063cd8 1619 str_cat(str,tokenbuf);
1620 }
1621 else if (saw_FS)
4cec2b33 1622 str_cat(str," = split($FS, $_, -1);\n");
8d063cd8 1623 else
4cec2b33 1624 str_cat(str," = split(' ', $_, -1);\n");
8d063cd8 1625 tab(str,level);
1626}
1627
9c8d0b29 1628int
f0f333f4 1629prewalk(int numit, int level, register int node, int *numericptr)
8d063cd8 1630{
1631 register int len;
1632 register int type;
1633 register int i;
8d063cd8 1634 int numarg;
1635 int numeric = FALSE;
a687059c 1636 STR *tmpstr;
1637 STR *tmp2str;
8d063cd8 1638
1639 if (!node) {
1640 *numericptr = 0;
1641 return 0;
1642 }
1643 type = ops[node].ival;
1644 len = type >> 8;
1645 type &= 255;
1646 switch (type) {
1647 case OPROG:
1648 prewalk(0,level,ops[node+1].ival,&numarg);
1649 if (ops[node+2].ival) {
1650 prewalk(0,level,ops[node+2].ival,&numarg);
1651 }
1652 ++level;
1653 prewalk(0,level,ops[node+3].ival,&numarg);
1654 --level;
1655 if (ops[node+3].ival) {
1656 prewalk(0,level,ops[node+4].ival,&numarg);
1657 }
1658 break;
1659 case OHUNKS:
1660 prewalk(0,level,ops[node+1].ival,&numarg);
1661 prewalk(0,level,ops[node+2].ival,&numarg);
1662 if (len == 3) {
1663 prewalk(0,level,ops[node+3].ival,&numarg);
1664 }
1665 break;
1666 case ORANGE:
1667 prewalk(1,level,ops[node+1].ival,&numarg);
1668 prewalk(1,level,ops[node+2].ival,&numarg);
1669 break;
1670 case OPAT:
1671 goto def;
1672 case OREGEX:
1673 prewalk(0,level,ops[node+1].ival,&numarg);
1674 break;
1675 case OHUNK:
1676 if (len == 1) {
1677 prewalk(0,level,ops[node+1].ival,&numarg);
1678 }
1679 else {
1680 i = prewalk(0,level,ops[node+1].ival,&numarg);
1681 if (i) {
1682 ++level;
1683 prewalk(0,level,ops[node+2].ival,&numarg);
1684 --level;
1685 }
1686 else {
1687 prewalk(0,level,ops[node+2].ival,&numarg);
1688 }
1689 }
1690 break;
1691 case OPPAREN:
1692 prewalk(0,level,ops[node+1].ival,&numarg);
1693 break;
1694 case OPANDAND:
1695 prewalk(0,level,ops[node+1].ival,&numarg);
1696 prewalk(0,level,ops[node+2].ival,&numarg);
1697 break;
1698 case OPOROR:
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1700 prewalk(0,level,ops[node+2].ival,&numarg);
1701 break;
1702 case OPNOT:
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1704 break;
1705 case OCPAREN:
1706 prewalk(0,level,ops[node+1].ival,&numarg);
1707 numeric |= numarg;
1708 break;
1709 case OCANDAND:
1710 prewalk(0,level,ops[node+1].ival,&numarg);
1711 numeric = 1;
1712 prewalk(0,level,ops[node+2].ival,&numarg);
1713 break;
1714 case OCOROR:
1715 prewalk(0,level,ops[node+1].ival,&numarg);
1716 numeric = 1;
1717 prewalk(0,level,ops[node+2].ival,&numarg);
1718 break;
1719 case OCNOT:
1720 prewalk(0,level,ops[node+1].ival,&numarg);
1721 numeric = 1;
1722 break;
1723 case ORELOP:
1724 prewalk(0,level,ops[node+2].ival,&numarg);
1725 numeric |= numarg;
1726 prewalk(0,level,ops[node+1].ival,&numarg);
1727 prewalk(0,level,ops[node+3].ival,&numarg);
1728 numeric |= numarg;
1729 numeric = 1;
1730 break;
1731 case ORPAREN:
1732 prewalk(0,level,ops[node+1].ival,&numarg);
1733 numeric |= numarg;
1734 break;
1735 case OMATCHOP:
1736 prewalk(0,level,ops[node+2].ival,&numarg);
1737 prewalk(0,level,ops[node+1].ival,&numarg);
1738 prewalk(0,level,ops[node+3].ival,&numarg);
1739 numeric = 1;
1740 break;
1741 case OMPAREN:
1742 prewalk(0,level,ops[node+1].ival,&numarg);
1743 numeric |= numarg;
1744 break;
1745 case OCONCAT:
1746 prewalk(0,level,ops[node+1].ival,&numarg);
1747 prewalk(0,level,ops[node+2].ival,&numarg);
1748 break;
1749 case OASSIGN:
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);
75f92628 1753 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
8d063cd8 1754 numericize(ops[node+2].ival);
1755 if (!numarg)
1756 numericize(ops[node+3].ival);
1757 }
1758 numeric |= numarg;
1759 break;
1760 case OADD:
1761 prewalk(1,level,ops[node+1].ival,&numarg);
1762 prewalk(1,level,ops[node+2].ival,&numarg);
1763 numeric = 1;
1764 break;
a687059c 1765 case OSUBTRACT:
8d063cd8 1766 prewalk(1,level,ops[node+1].ival,&numarg);
1767 prewalk(1,level,ops[node+2].ival,&numarg);
1768 numeric = 1;
1769 break;
1770 case OMULT:
1771 prewalk(1,level,ops[node+1].ival,&numarg);
1772 prewalk(1,level,ops[node+2].ival,&numarg);
1773 numeric = 1;
1774 break;
1775 case ODIV:
1776 prewalk(1,level,ops[node+1].ival,&numarg);
1777 prewalk(1,level,ops[node+2].ival,&numarg);
1778 numeric = 1;
1779 break;
a687059c 1780 case OPOW:
1781 prewalk(1,level,ops[node+1].ival,&numarg);
1782 prewalk(1,level,ops[node+2].ival,&numarg);
1783 numeric = 1;
1784 break;
8d063cd8 1785 case OMOD:
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 OPOSTINCR:
1791 prewalk(1,level,ops[node+1].ival,&numarg);
1792 numeric = 1;
1793 break;
1794 case OPOSTDECR:
1795 prewalk(1,level,ops[node+1].ival,&numarg);
1796 numeric = 1;
1797 break;
1798 case OPREINCR:
1799 prewalk(1,level,ops[node+1].ival,&numarg);
1800 numeric = 1;
1801 break;
1802 case OPREDECR:
1803 prewalk(1,level,ops[node+1].ival,&numarg);
1804 numeric = 1;
1805 break;
1806 case OUMINUS:
1807 prewalk(1,level,ops[node+1].ival,&numarg);
1808 numeric = 1;
1809 break;
1810 case OUPLUS:
1811 prewalk(1,level,ops[node+1].ival,&numarg);
1812 numeric = 1;
1813 break;
1814 case OPAREN:
1815 prewalk(0,level,ops[node+1].ival,&numarg);
1816 numeric |= numarg;
1817 break;
1818 case OGETLINE:
1819 break;
1820 case OSPRINTF:
1821 prewalk(0,level,ops[node+1].ival,&numarg);
1822 break;
1823 case OSUBSTR:
1824 prewalk(0,level,ops[node+1].ival,&numarg);
1825 prewalk(1,level,ops[node+2].ival,&numarg);
1826 if (len == 3) {
1827 prewalk(1,level,ops[node+3].ival,&numarg);
1828 }
1829 break;
1830 case OSTRING:
1831 break;
1832 case OSPLIT:
1833 numeric = 1;
1834 prewalk(0,level,ops[node+2].ival,&numarg);
1835 if (len == 3)
1836 prewalk(0,level,ops[node+3].ival,&numarg);
1837 prewalk(0,level,ops[node+1].ival,&numarg);
1838 break;
1839 case OINDEX:
1840 prewalk(0,level,ops[node+1].ival,&numarg);
1841 prewalk(0,level,ops[node+2].ival,&numarg);
1842 numeric = 1;
1843 break;
a687059c 1844 case OMATCH:
1845 prewalk(0,level,ops[node+1].ival,&numarg);
1846 prewalk(0,level,ops[node+2].ival,&numarg);
1847 numeric = 1;
1848 break;
1849 case OUSERDEF:
1850 subretnum = FALSE;
1851 --level;
1852 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1853 ++level;
1854 prewalk(0,level,ops[node+2].ival,&numarg);
1855 prewalk(0,level,ops[node+4].ival,&numarg);
1856 prewalk(0,level,ops[node+5].ival,&numarg);
1857 --level;
1858 str_cat(tmpstr,"(");
1859 tmp2str = str_new(0);
1860 if (subretnum || numarg)
1861 str_set(tmp2str,"1");
1862 hstore(symtab,tmpstr->str_ptr,tmp2str);
1863 str_free(tmpstr);
1864 level++;
1865 break;
1866 case ORETURN:
1867 if (len > 0) {
1868 prewalk(0,level,ops[node+1].ival,&numarg);
1869 if (numarg)
1870 subretnum = TRUE;
1871 }
1872 break;
1873 case OUSERFUN:
1874 tmp2str = str_new(0);
1875 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
663a0e37 1876 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
a687059c 1877 str_free(tmpstr);
1878 str_cat(tmp2str,"(");
1879 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1880 if (tmpstr && tmpstr->str_ptr)
1881 numeric |= atoi(tmpstr->str_ptr);
1882 prewalk(0,level,ops[node+2].ival,&numarg);
1883 str_free(tmp2str);
1884 break;
1885 case OGSUB:
1886 case OSUB:
1887 if (len >= 3)
1888 prewalk(0,level,ops[node+3].ival,&numarg);
1889 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1890 prewalk(0,level,ops[node+1].ival,&numarg);
1891 numeric = 1;
1892 break;
8d063cd8 1893 case ONUM:
1894 prewalk(0,level,ops[node+1].ival,&numarg);
1895 numeric = 1;
1896 break;
1897 case OSTR:
1898 prewalk(0,level,ops[node+1].ival,&numarg);
1899 break;
a687059c 1900 case ODEFINED:
1901 case ODELETE:
1902 case OSTAR:
8d063cd8 1903 case OVAR:
1904 prewalk(0,level,ops[node+1].ival,&numarg);
1905 if (len == 1) {
1906 if (numit)
1907 numericize(node);
1908 }
1909 else {
1910 prewalk(0,level,ops[node+2].ival,&numarg);
1911 }
1912 break;
1913 case OFLD:
1914 prewalk(0,level,ops[node+1].ival,&numarg);
1915 break;
1916 case OVFLD:
1917 i = ops[node+1].ival;
1918 prewalk(0,level,i,&numarg);
1919 break;
1920 case OJUNK:
1921 goto def;
1922 case OSNEWLINE:
1923 break;
1924 case ONEWLINE:
1925 break;
1926 case OSCOMMENT:
1927 break;
1928 case OCOMMENT:
1929 break;
1930 case OCOMMA:
1931 prewalk(0,level,ops[node+1].ival,&numarg);
1932 prewalk(0,level,ops[node+2].ival,&numarg);
a687059c 1933 prewalk(0,level,ops[node+3].ival,&numarg);
8d063cd8 1934 break;
1935 case OSEMICOLON:
1936 break;
1937 case OSTATES:
1938 prewalk(0,level,ops[node+1].ival,&numarg);
1939 prewalk(0,level,ops[node+2].ival,&numarg);
1940 break;
1941 case OSTATE:
1942 if (len >= 1) {
1943 prewalk(0,level,ops[node+1].ival,&numarg);
1944 if (len >= 2) {
1945 prewalk(0,level,ops[node+2].ival,&numarg);
1946 }
1947 }
1948 break;
a687059c 1949 case OCLOSE:
1950 prewalk(0,level,ops[node+1].ival,&numarg);
1951 break;
8d063cd8 1952 case OPRINTF:
1953 case OPRINT:
1954 if (len == 3) { /* output redirection */
1955 prewalk(0,level,ops[node+3].ival,&numarg);
1956 prewalk(0,level,ops[node+2].ival,&numarg);
1957 }
1958 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1959 break;
a687059c 1960 case ORAND:
1961 break;
1962 case OSRAND:
1963 goto maybe0;
1964 case OATAN2:
1965 goto maybe0;
1966 case OSIN:
1967 goto maybe0;
1968 case OCOS:
1969 goto maybe0;
1970 case OSYSTEM:
1971 goto maybe0;
8d063cd8 1972 case OLENGTH:
1973 goto maybe0;
1974 case OLOG:
1975 goto maybe0;
1976 case OEXP:
1977 goto maybe0;
1978 case OSQRT:
1979 goto maybe0;
1980 case OINT:
1981 maybe0:
1982 numeric = 1;
1983 if (len > 0)
a687059c 1984 prewalk(type != OLENGTH && type != OSYSTEM,
1985 level,ops[node+1].ival,&numarg);
8d063cd8 1986 break;
1987 case OBREAK:
1988 break;
1989 case ONEXT:
1990 break;
1991 case OEXIT:
1992 if (len == 1) {
1993 prewalk(1,level,ops[node+1].ival,&numarg);
1994 }
1995 break;
1996 case OCONTINUE:
1997 break;
1998 case OREDIR:
1999 goto def;
2000 case OIF:
2001 prewalk(0,level,ops[node+1].ival,&numarg);
2002 prewalk(0,level,ops[node+2].ival,&numarg);
2003 if (len == 3) {
2004 prewalk(0,level,ops[node+3].ival,&numarg);
2005 }
2006 break;
2007 case OWHILE:
2008 prewalk(0,level,ops[node+1].ival,&numarg);
2009 prewalk(0,level,ops[node+2].ival,&numarg);
2010 break;
2011 case OFOR:
2012 prewalk(0,level,ops[node+1].ival,&numarg);
2013 prewalk(0,level,ops[node+2].ival,&numarg);
2014 prewalk(0,level,ops[node+3].ival,&numarg);
2015 prewalk(0,level,ops[node+4].ival,&numarg);
2016 break;
2017 case OFORIN:
2018 prewalk(0,level,ops[node+2].ival,&numarg);
2019 prewalk(0,level,ops[node+1].ival,&numarg);
8d063cd8 2020 break;
2021 case OBLOCK:
2022 if (len == 2) {
2023 prewalk(0,level,ops[node+2].ival,&numarg);
2024 }
2025 ++level;
2026 prewalk(0,level,ops[node+1].ival,&numarg);
2027 --level;
2028 break;
2029 default:
2030 def:
2031 if (len) {
2032 if (len > 5)
2033 fatal("Garbage length in prewalk");
2034 prewalk(0,level,ops[node+1].ival,&numarg);
2035 for (i = 2; i<= len; i++) {
2036 prewalk(0,level,ops[node+i].ival,&numarg);
2037 }
2038 }
2039 break;
2040 }
2041 *numericptr = numeric;
2042 return 1;
2043}
2044
748a9306 2045static void
f0f333f4 2046numericize(register int node)
8d063cd8 2047{
2048 register int len;
2049 register int type;
8d063cd8 2050 STR *tmpstr;
2051 STR *tmp2str;
2052 int numarg;
2053
2054 type = ops[node].ival;
2055 len = type >> 8;
2056 type &= 255;
2057 if (type == OVAR && len == 1) {
a687059c 2058 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 2059 tmp2str = str_make("1");
2060 hstore(symtab,tmpstr->str_ptr,tmp2str);
2061 }
2062}