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