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