perl 4.0 patch 14: patch #11, continued
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
CommitLineData
d48672a2 1/* $RCSfile: walk.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:22:04 $
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 $
d48672a2 9 * Revision 4.0.1.1 91/06/07 12:22:04 lwall
10 * patch4: new copyright notice
11 * patch4: a2p didn't correctly implement -n switch
12 *
fe14fcc3 13 * Revision 4.0 91/03/20 01:58:36 lwall
14 * 4.0 baseline.
8d063cd8 15 *
16 */
17
18#include "handy.h"
19#include "EXTERN.h"
20#include "util.h"
21#include "a2p.h"
22
23bool exitval = FALSE;
24bool realexit = FALSE;
378cc40b 25bool saw_getline = FALSE;
a687059c 26bool subretnum = FALSE;
27bool saw_FNR = FALSE;
28bool saw_argv0 = FALSE;
d48672a2 29bool saw_fh = FALSE;
8d063cd8 30int maxtmp = 0;
378cc40b 31char *lparen;
32char *rparen;
a687059c 33STR *subs;
34STR *curargs = Nullstr;
8d063cd8 35
36STR *
a687059c 37walk(useval,level,node,numericptr,minprec)
8d063cd8 38int useval;
39int level;
40register int node;
41int *numericptr;
a687059c 42int minprec; /* minimum precedence without parens */
8d063cd8 43{
44 register int len;
45 register STR *str;
46 register int type;
47 register int i;
48 register STR *tmpstr;
49 STR *tmp2str;
a687059c 50 STR *tmp3str;
8d063cd8 51 char *t;
52 char *d, *s;
53 int numarg;
54 int numeric = FALSE;
55 STR *fstr;
a687059c 56 int prec = P_MAX; /* assume no parens needed */
8d063cd8 57 char *index();
58
59 if (!node) {
60 *numericptr = 0;
61 return str_make("");
62 }
63 type = ops[node].ival;
64 len = type >> 8;
65 type &= 255;
66 switch (type) {
67 case OPROG:
d48672a2 68 arymax = 0;
69 if (namelist) {
70 while (isalpha(*namelist)) {
71 for (d = tokenbuf,s=namelist;
72 isalpha(*s) || isdigit(*s) || *s == '_';
73 *d++ = *s++) ;
74 *d = '\0';
75 while (*s && !isalpha(*s)) s++;
76 namelist = s;
77 nameary[++arymax] = savestr(tokenbuf);
78 }
79 }
80 if (maxfld < arymax)
81 maxfld = arymax;
8d063cd8 82 opens = str_new(0);
a687059c 83 subs = str_new(0);
84 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 85 if (do_split && need_entire && !absmaxfld)
86 split_to_array = TRUE;
87 if (do_split && split_to_array)
88 set_array_base = TRUE;
89 if (set_array_base) {
90 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
91 }
92 if (fswitch && !const_FS)
93 const_FS = fswitch;
94 if (saw_FS > 1 || saw_RS)
95 const_FS = 0;
96 if (saw_ORS && need_entire)
97 do_chop = TRUE;
98 if (fswitch) {
99 str_cat(str,"$FS = '");
100 if (index("*+?.[]()|^$\\",fswitch))
101 str_cat(str,"\\");
102 sprintf(tokenbuf,"%c",fswitch);
103 str_cat(str,tokenbuf);
104 str_cat(str,"';\t\t# field separator from -F switch\n");
105 }
106 else if (saw_FS && !const_FS) {
9bb9d9f7 107 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
8d063cd8 108 }
109 if (saw_OFS) {
a559c259 110 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
8d063cd8 111 }
112 if (saw_ORS) {
a559c259 113 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
8d063cd8 114 }
a687059c 115 if (saw_argv0) {
116 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
117 }
8d063cd8 118 if (str->str_cur > 20)
119 str_cat(str,"\n");
120 if (ops[node+2].ival) {
a687059c 121 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 122 str_free(fstr);
123 str_cat(str,"\n\n");
124 }
a687059c 125 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
126 if (*fstr->str_ptr) {
127 if (saw_line_op)
128 str_cat(str,"line: ");
129 str_cat(str,"while (<>) {\n");
130 tab(str,++level);
131 if (saw_FS && !const_FS)
132 do_chop = TRUE;
133 if (do_chop) {
134 str_cat(str,"chop;\t# strip record separator\n");
135 tab(str,level);
8d063cd8 136 }
a687059c 137 if (do_split)
138 emit_split(str,level);
139 str_scat(str,fstr);
140 str_free(fstr);
141 fixtab(str,--level);
142 str_cat(str,"}\n");
143 if (saw_FNR)
144 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
8d063cd8 145 }
a687059c 146 else
ae986130 147 str_cat(str,"while (<>) { } # (no line actions)\n");
8d063cd8 148 if (ops[node+4].ival) {
149 realexit = TRUE;
150 str_cat(str,"\n");
151 tab(str,level);
a687059c 152 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 153 str_free(fstr);
154 str_cat(str,"\n");
155 }
156 if (exitval)
9f68db38 157 str_cat(str,"exit $ExitValue;\n");
a687059c 158 if (subs->str_ptr) {
159 str_cat(str,"\n");
160 str_scat(str,subs);
161 }
378cc40b 162 if (saw_getline) {
a687059c 163 for (len = 0; len < 4; len++) {
164 if (saw_getline & (1 << len)) {
165 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
166 str_cat(str, tokenbuf);
167 if (len & 2) {
168 if (do_fancy_opens)
169 str_cat(str," &Pick('',@_);\n");
170 else
171 str_cat(str," ($fh) = @_;\n");
172 }
173 else {
174 if (saw_FNR)
175 str_cat(str," $FNRbase = $. if eof;\n");
176 }
177 if (len & 1)
62b28dd9 178 str_cat(str," local($_);\n");
a687059c 179 if (len & 2)
180 str_cat(str,
181 " if ($getline_ok = (($_ = <$fh>) ne ''))");
182 else
183 str_cat(str,
184 " if ($getline_ok = (($_ = <>) ne ''))");
185 str_cat(str, " {\n");
186 level += 2;
187 tab(str,level);
188 i = 0;
189 if (do_chop) {
190 i++;
191 str_cat(str,"chop;\t# strip record separator\n");
192 tab(str,level);
193 }
194 if (do_split && !(len & 1)) {
195 i++;
196 emit_split(str,level);
197 }
198 if (!i)
199 str_cat(str,";\n");
200 fixtab(str,--level);
201 str_cat(str,"}\n $_;\n}\n");
202 --level;
203 }
378cc40b 204 }
378cc40b 205 }
8d063cd8 206 if (do_fancy_opens) {
207 str_cat(str,"\n\
208sub Pick {\n\
a687059c 209 local($mode,$name,$pipe) = @_;\n\
8d063cd8 210 $fh = $opened{$name};\n\
211 if (!$fh) {\n\
a687059c 212 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
213 open($fh,$mode.$name.$pipe);\n\
8d063cd8 214 }\n\
8d063cd8 215}\n\
216");
217 }
218 break;
219 case OHUNKS:
a687059c 220 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
221 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 222 str_free(fstr);
223 if (len == 3) {
a687059c 224 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 225 str_free(fstr);
226 }
227 else {
228 }
229 break;
230 case ORANGE:
a687059c 231 prec = P_DOTDOT;
232 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 233 str_cat(str," .. ");
a687059c 234 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 235 str_free(fstr);
236 break;
237 case OPAT:
238 goto def;
239 case OREGEX:
240 str = str_new(0);
241 str_set(str,"/");
a687059c 242 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 243 /* translate \nnn to [\nnn] */
244 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
a687059c 245 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
8d063cd8 246 *d++ = '[';
247 *d++ = *s++;
248 *d++ = *s++;
249 *d++ = *s++;
250 *d++ = *s;
251 *d = ']';
252 }
253 else
254 *d = *s;
255 }
256 *d = '\0';
378cc40b 257 for (d=tokenbuf; *d; d++)
258 *d += 128;
8d063cd8 259 str_cat(str,tokenbuf);
260 str_free(tmpstr);
261 str_cat(str,"/");
262 break;
263 case OHUNK:
264 if (len == 1) {
265 str = str_new(0);
a687059c 266 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
8d063cd8 267 str_cat(str," if ");
a687059c 268 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 269 str_free(fstr);
270 str_cat(str,";");
271 }
272 else {
a687059c 273 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 274 if (*tmpstr->str_ptr) {
275 str = str_new(0);
276 str_set(str,"if (");
277 str_scat(str,tmpstr);
278 str_cat(str,") {\n");
279 tab(str,++level);
a687059c 280 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 281 str_free(fstr);
282 fixtab(str,--level);
283 str_cat(str,"}\n");
284 tab(str,level);
285 }
286 else {
a687059c 287 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 288 }
289 }
290 break;
291 case OPPAREN:
292 str = str_new(0);
293 str_set(str,"(");
a687059c 294 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 295 str_free(fstr);
296 str_cat(str,")");
297 break;
298 case OPANDAND:
a687059c 299 prec = P_ANDAND;
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 OPOROR:
a687059c 308 prec = P_OROR;
309 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 310 str_cat(str," || ");
a687059c 311 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
312 str_free(fstr);
313 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 314 str_free(fstr);
315 break;
316 case OPNOT:
a687059c 317 prec = P_UNARY;
8d063cd8 318 str = str_new(0);
319 str_set(str,"!");
a687059c 320 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 321 str_free(fstr);
322 break;
62b28dd9 323 case OCOND:
324 prec = P_COND;
325 str = walk(1,level,ops[node+1].ival,&numarg,prec);
326 str_cat(str," ? ");
327 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
328 str_free(fstr);
329 str_cat(str," : ");
330 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
331 str_free(fstr);
332 break;
8d063cd8 333 case OCPAREN:
334 str = str_new(0);
335 str_set(str,"(");
a687059c 336 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 337 str_free(fstr);
338 numeric |= numarg;
339 str_cat(str,")");
340 break;
341 case OCANDAND:
a687059c 342 prec = P_ANDAND;
343 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 344 numeric = 1;
345 str_cat(str," && ");
a687059c 346 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
347 str_free(fstr);
348 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 349 str_free(fstr);
350 break;
351 case OCOROR:
a687059c 352 prec = P_OROR;
353 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 354 numeric = 1;
355 str_cat(str," || ");
a687059c 356 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
357 str_free(fstr);
358 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 359 str_free(fstr);
360 break;
361 case OCNOT:
a687059c 362 prec = P_UNARY;
8d063cd8 363 str = str_new(0);
364 str_set(str,"!");
a687059c 365 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 366 str_free(fstr);
367 numeric = 1;
368 break;
369 case ORELOP:
a687059c 370 prec = P_REL;
371 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 372 numeric |= numarg;
a687059c 373 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
374 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
8d063cd8 375 numeric |= numarg;
a687059c 376 if (!numeric ||
377 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
8d063cd8 378 t = tmpstr->str_ptr;
379 if (strEQ(t,"=="))
380 str_set(tmpstr,"eq");
381 else if (strEQ(t,"!="))
382 str_set(tmpstr,"ne");
383 else if (strEQ(t,"<"))
384 str_set(tmpstr,"lt");
385 else if (strEQ(t,"<="))
386 str_set(tmpstr,"le");
387 else if (strEQ(t,">"))
388 str_set(tmpstr,"gt");
389 else if (strEQ(t,">="))
390 str_set(tmpstr,"ge");
391 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
392 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
393 numeric |= 2;
394 }
395 if (numeric & 2) {
396 if (numeric & 1) /* numeric is very good guess */
397 str_cat(str," ");
398 else
399 str_cat(str,"\377");
400 numeric = 1;
401 }
402 else
403 str_cat(str," ");
404 str_scat(str,tmpstr);
405 str_free(tmpstr);
406 str_cat(str," ");
407 str_scat(str,tmp2str);
408 str_free(tmp2str);
409 numeric = 1;
410 break;
411 case ORPAREN:
412 str = str_new(0);
413 str_set(str,"(");
a687059c 414 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 415 str_free(fstr);
416 numeric |= numarg;
417 str_cat(str,")");
418 break;
419 case OMATCHOP:
a687059c 420 prec = P_MATCH;
421 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 422 str_cat(str," ");
a687059c 423 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 424 if (strEQ(tmpstr->str_ptr,"~"))
425 str_cat(str,"=~");
426 else {
427 str_scat(str,tmpstr);
428 str_free(tmpstr);
429 }
430 str_cat(str," ");
a687059c 431 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 432 str_free(fstr);
433 numeric = 1;
434 break;
435 case OMPAREN:
436 str = str_new(0);
437 str_set(str,"(");
a687059c 438 str_scat(str,
439 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 440 str_free(fstr);
441 numeric |= numarg;
442 str_cat(str,")");
443 break;
444 case OCONCAT:
a687059c 445 prec = P_ADD;
446 type = ops[ops[node+1].ival].ival & 255;
447 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
8d063cd8 448 str_cat(str," . ");
a687059c 449 type = ops[ops[node+2].ival].ival & 255;
450 str_scat(str,
451 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
8d063cd8 452 str_free(fstr);
453 break;
454 case OASSIGN:
a687059c 455 prec = P_ASSIGN;
456 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 457 str_cat(str," ");
a687059c 458 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 459 str_scat(str,tmpstr);
460 if (str_len(tmpstr) > 1)
461 numeric = 1;
462 str_free(tmpstr);
463 str_cat(str," ");
a687059c 464 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
8d063cd8 465 str_free(fstr);
466 numeric |= numarg;
8d063cd8 467 break;
468 case OADD:
a687059c 469 prec = P_ADD;
470 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 471 str_cat(str," + ");
a687059c 472 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 473 str_free(fstr);
474 numeric = 1;
475 break;
a687059c 476 case OSUBTRACT:
477 prec = P_ADD;
478 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 479 str_cat(str," - ");
a687059c 480 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 481 str_free(fstr);
482 numeric = 1;
483 break;
484 case OMULT:
a687059c 485 prec = P_MUL;
486 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 487 str_cat(str," * ");
a687059c 488 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 489 str_free(fstr);
490 numeric = 1;
491 break;
492 case ODIV:
a687059c 493 prec = P_MUL;
494 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 495 str_cat(str," / ");
a687059c 496 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
497 str_free(fstr);
498 numeric = 1;
499 break;
500 case OPOW:
501 prec = P_POW;
502 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
503 str_cat(str," ** ");
504 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
8d063cd8 505 str_free(fstr);
506 numeric = 1;
507 break;
508 case OMOD:
a687059c 509 prec = P_MUL;
510 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 511 str_cat(str," % ");
a687059c 512 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 513 str_free(fstr);
514 numeric = 1;
515 break;
516 case OPOSTINCR:
a687059c 517 prec = P_AUTO;
518 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 519 str_cat(str,"++");
520 numeric = 1;
521 break;
522 case OPOSTDECR:
a687059c 523 prec = P_AUTO;
524 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 525 str_cat(str,"--");
526 numeric = 1;
527 break;
528 case OPREINCR:
a687059c 529 prec = P_AUTO;
8d063cd8 530 str = str_new(0);
531 str_set(str,"++");
a687059c 532 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 533 str_free(fstr);
534 numeric = 1;
535 break;
536 case OPREDECR:
a687059c 537 prec = P_AUTO;
8d063cd8 538 str = str_new(0);
539 str_set(str,"--");
a687059c 540 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 541 str_free(fstr);
542 numeric = 1;
543 break;
544 case OUMINUS:
a687059c 545 prec = P_UNARY;
8d063cd8 546 str = str_new(0);
547 str_set(str,"-");
a687059c 548 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 549 str_free(fstr);
550 numeric = 1;
551 break;
552 case OUPLUS:
553 numeric = 1;
554 goto def;
555 case OPAREN:
556 str = str_new(0);
557 str_set(str,"(");
a687059c 558 str_scat(str,
559 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 560 str_free(fstr);
561 str_cat(str,")");
562 numeric |= numarg;
563 break;
564 case OGETLINE:
565 str = str_new(0);
a687059c 566 if (useval)
567 str_cat(str,"(");
568 if (len > 0) {
569 str_cat(str,"$");
570 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
571 if (!*fstr->str_ptr) {
572 str_cat(str,"_");
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;
d48672a2 592 if (islower(*t))
593 *t = toupper(*t);
a687059c 594 if (!isalpha(*t) && !isdigit(*t))
595 *t = '_';
596 }
597 if (!index(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);
673 numeric = 1;
a687059c 674 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 675 if (useval)
676 str_set(str,"(@");
677 else
678 str_set(str,"@");
679 str_scat(str,tmpstr);
680 str_cat(str," = split(");
681 if (len == 3) {
a687059c 682 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
8d063cd8 683 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
684 i = fstr->str_ptr[1] & 127;
685 if (index("*+?.[]()|^$\\",i))
686 sprintf(tokenbuf,"/\\%c/",i);
20188a90 687 else if (i == ' ')
62b28dd9 688 sprintf(tokenbuf,"' '");
8d063cd8 689 else
690 sprintf(tokenbuf,"/%c/",i);
691 str_cat(str,tokenbuf);
692 }
693 else
694 str_scat(str,fstr);
695 str_free(fstr);
696 }
697 else if (const_FS) {
698 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
699 str_cat(str,tokenbuf);
700 }
701 else if (saw_FS)
702 str_cat(str,"$FS");
703 else
9bb9d9f7 704 str_cat(str,"' '");
8d063cd8 705 str_cat(str,", ");
a687059c 706 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 707 str_free(fstr);
62b28dd9 708 str_cat(str,", 9999)");
8d063cd8 709 if (useval) {
710 str_cat(str,")");
711 }
712 str_free(tmpstr);
713 break;
714 case OINDEX:
715 str = str_new(0);
716 str_set(str,"index(");
a687059c 717 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 718 str_free(fstr);
719 str_cat(str,", ");
a687059c 720 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8 721 str_free(fstr);
722 str_cat(str,")");
723 numeric = 1;
724 break;
a687059c 725 case OMATCH:
726 str = str_new(0);
727 prec = P_ANDAND;
728 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
729 str_free(fstr);
730 str_cat(str," =~ ");
731 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
732 str_free(fstr);
733 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
734 numeric = 1;
735 break;
736 case OUSERDEF:
737 str = str_new(0);
738 subretnum = FALSE;
739 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
740 curargs = str_new(0);
741 str_sset(curargs,fstr);
742 str_cat(curargs,",");
743 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
744 str_free(curargs);
745 curargs = Nullstr;
746 level--;
747 subretnum |= numarg;
748 s = Nullch;
749 t = tmp2str->str_ptr;
750 while (t = instr(t,"return "))
751 s = t++;
752 if (s) {
753 i = 0;
754 for (t = s+7; *t; t++) {
755 if (*t == ';' || *t == '}')
756 i++;
757 }
758 if (i == 1) {
759 strcpy(s,s+7);
760 tmp2str->str_cur -= 7;
761 }
762 }
763 str_set(str,"\n");
764 tab(str,level);
765 str_cat(str,"sub ");
766 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
767 str_cat(str," {\n");
768 tab(str,++level);
769 if (fstr->str_cur) {
770 str_cat(str,"local(");
771 str_scat(str,fstr);
772 str_cat(str,") = @_;");
773 }
774 str_free(fstr);
775 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
776 str_free(fstr);
777 fixtab(str,level);
778 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
779 str_free(fstr);
780 fixtab(str,level);
781 str_scat(str,tmp2str);
782 str_free(tmp2str);
783 fixtab(str,--level);
784 str_cat(str,"}\n");
785 tab(str,level);
786 str_scat(subs,str);
787 str_set(str,"");
788 str_cat(tmpstr,"(");
789 tmp2str = str_new(0);
790 if (subretnum)
791 str_set(tmp2str,"1");
792 hstore(symtab,tmpstr->str_ptr,tmp2str);
793 str_free(tmpstr);
794 level++;
795 break;
796 case ORETURN:
797 str = str_new(0);
798 if (len > 0) {
799 str_cat(str,"return ");
800 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
801 str_free(fstr);
802 if (numarg)
803 subretnum = TRUE;
804 }
805 else
806 str_cat(str,"return");
807 break;
808 case OUSERFUN:
809 str = str_new(0);
810 str_set(str,"&");
811 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
812 str_free(fstr);
813 str_cat(str,"(");
814 tmpstr = hfetch(symtab,str->str_ptr+3);
815 if (tmpstr && tmpstr->str_ptr)
816 numeric |= atoi(tmpstr->str_ptr);
817 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
818 str_free(fstr);
819 str_cat(str,")");
820 break;
821 case OGSUB:
822 case OSUB:
823 if (type == OGSUB)
824 s = "g";
825 else
826 s = "";
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 == '&')
849 *d++ = '$' + 128;
850 else if (*t == '$')
851 *d++ = '\\' + 128;
852 *d = *t + 128;
853 }
854 *d = '\0';
855 str_set(tmp2str,tokenbuf);
856 }
857 else {
858 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
859 str_set(tmp3str,"($s_ = '\"'.(");
860 str_scat(tmp3str,tmp2str);
861 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
862 str_set(tmp2str,"eval $s_");
863 s = (*s == 'g' ? "ge" : "e");
864 i++;
865 }
866 type = ops[ops[node+1].ival].ival;
867 len = type >> 8;
868 type &= 255;
869 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
870 if (type == OREGEX) {
871 if (useval && i)
872 str_cat(str,"(");
873 str_scat(str,tmp3str);
874 str_scat(str,tmpstr);
875 str_scat(str,fstr);
876 str_scat(str,tmp2str);
877 str_cat(str,"/");
878 str_cat(str,s);
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);
889 str_cat(str,"/");
890 str_cat(str,s);
891 }
892 else {
893 i++;
894 if (useval)
895 str_cat(str,"(");
896 str_cat(str,"$s = ");
897 str_scat(str,fstr);
898 str_cat(str,", ");
899 str_scat(str,tmp3str);
900 str_scat(str,tmpstr);
901 str_cat(str,"/$s/");
902 str_scat(str,tmp2str);
903 str_cat(str,"/");
904 str_cat(str,s);
905 }
906 if (useval && i)
907 str_cat(str,")");
908 str_free(fstr);
909 str_free(tmpstr);
910 str_free(tmp2str);
911 str_free(tmp3str);
912 numeric = 1;
913 break;
8d063cd8 914 case ONUM:
a687059c 915 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 916 numeric = 1;
917 break;
918 case OSTR:
a687059c 919 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 920 s = "'";
378cc40b 921 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
922 if (*t == '\'')
923 s = "\"";
924 else if (*t == '\\') {
8d063cd8 925 s = "\"";
378cc40b 926 *d++ = *t++ + 128;
927 switch (*t) {
fe14fcc3 928 case '\\': case '"': case 'n': case 't': case '$':
378cc40b 929 break;
930 default: /* hide this from perl */
931 *d++ = '\\' + 128;
932 }
933 }
934 *d = *t + 128;
8d063cd8 935 }
378cc40b 936 *d = '\0';
8d063cd8 937 str = str_new(0);
938 str_set(str,s);
378cc40b 939 str_cat(str,tokenbuf);
8d063cd8 940 str_free(tmpstr);
941 str_cat(str,s);
942 break;
a687059c 943 case ODEFINED:
944 prec = P_UNI;
945 str = str_new(0);
946 str_set(str,"defined $");
947 goto addvar;
948 case ODELETE:
949 str = str_new(0);
950 str_set(str,"delete $");
951 goto addvar;
952 case OSTAR:
953 str = str_new(0);
954 str_set(str,"*");
955 goto addvar;
8d063cd8 956 case OVAR:
957 str = str_new(0);
958 str_set(str,"$");
a687059c 959 addvar:
960 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 961 if (len == 1) {
962 tmp2str = hfetch(symtab,tmpstr->str_ptr);
963 if (tmp2str && atoi(tmp2str->str_ptr))
964 numeric = 2;
a687059c 965 if (strEQ(str->str_ptr,"$FNR")) {
966 numeric = 1;
967 saw_FNR++;
968 str_set(str,"($.-$FNRbase)");
969 }
970 else if (strEQ(str->str_ptr,"$NR")) {
8d063cd8 971 numeric = 1;
972 str_set(str,"$.");
973 }
974 else if (strEQ(str->str_ptr,"$NF")) {
975 numeric = 1;
976 str_set(str,"$#Fld");
977 }
978 else if (strEQ(str->str_ptr,"$0"))
979 str_set(str,"$_");
a687059c 980 else if (strEQ(str->str_ptr,"$ARGC"))
981 str_set(str,"($#ARGV+1)");
8d063cd8 982 }
983 else {
a687059c 984#ifdef NOTDEF
985 if (curargs) {
986 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
987 ??? if (instr(curargs->str_ptr,tokenbuf))
988 str_cat(str,"\377"); /* can't translate yet */
989 }
990#endif
8d063cd8 991 str_cat(tmpstr,"[]");
992 tmp2str = hfetch(symtab,tmpstr->str_ptr);
993 if (tmp2str && atoi(tmp2str->str_ptr))
994 str_cat(str,"[");
995 else
996 str_cat(str,"{");
a687059c 997 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 998 str_free(fstr);
a687059c 999 if (strEQ(str->str_ptr,"$ARGV[0")) {
1000 str_set(str,"$ARGV0");
1001 saw_argv0++;
1002 }
1003 else {
1004 if (tmp2str && atoi(tmp2str->str_ptr))
1005 strcpy(tokenbuf,"]");
1006 else
1007 strcpy(tokenbuf,"}");
1008 *tokenbuf += 128;
1009 str_cat(str,tokenbuf);
1010 }
8d063cd8 1011 }
1012 str_free(tmpstr);
1013 break;
1014 case OFLD:
1015 str = str_new(0);
1016 if (split_to_array) {
1017 str_set(str,"$Fld");
1018 str_cat(str,"[");
a687059c 1019 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1020 str_free(fstr);
1021 str_cat(str,"]");
1022 }
1023 else {
a687059c 1024 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
8d063cd8 1025 if (i <= arymax)
1026 sprintf(tokenbuf,"$%s",nameary[i]);
1027 else
1028 sprintf(tokenbuf,"$Fld%d",i);
1029 str_set(str,tokenbuf);
1030 }
1031 break;
1032 case OVFLD:
1033 str = str_new(0);
1034 str_set(str,"$Fld[");
1035 i = ops[node+1].ival;
1036 if ((ops[i].ival & 255) == OPAREN)
1037 i = ops[i+1].ival;
a687059c 1038 tmpstr=walk(1,level,i,&numarg,P_MIN);
8d063cd8 1039 str_scat(str,tmpstr);
1040 str_free(tmpstr);
1041 str_cat(str,"]");
1042 break;
1043 case OJUNK:
1044 goto def;
1045 case OSNEWLINE:
1046 str = str_new(2);
1047 str_set(str,";\n");
1048 tab(str,level);
1049 break;
1050 case ONEWLINE:
1051 str = str_new(1);
1052 str_set(str,"\n");
1053 tab(str,level);
1054 break;
1055 case OSCOMMENT:
1056 str = str_new(0);
1057 str_set(str,";");
a687059c 1058 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1059 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1060 *s += 128;
1061 str_scat(str,tmpstr);
1062 str_free(tmpstr);
1063 tab(str,level);
1064 break;
1065 case OCOMMENT:
1066 str = str_new(0);
a687059c 1067 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1068 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1069 *s += 128;
1070 str_scat(str,tmpstr);
1071 str_free(tmpstr);
1072 tab(str,level);
1073 break;
1074 case OCOMMA:
a687059c 1075 prec = P_COMMA;
1076 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 1077 str_cat(str,", ");
a687059c 1078 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1079 str_free(fstr);
1080 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 1081 str_free(fstr);
1082 break;
1083 case OSEMICOLON:
1084 str = str_new(1);
a687059c 1085 str_set(str,";\n");
1086 tab(str,level);
8d063cd8 1087 break;
1088 case OSTATES:
a687059c 1089 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1090 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1091 str_free(fstr);
1092 break;
1093 case OSTATE:
1094 str = str_new(0);
1095 if (len >= 1) {
a687059c 1096 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1097 str_free(fstr);
1098 if (len >= 2) {
a687059c 1099 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1100 if (*tmpstr->str_ptr == ';') {
1101 addsemi(str);
1102 str_cat(str,tmpstr->str_ptr+1);
1103 }
1104 str_free(tmpstr);
1105 }
1106 }
1107 break;
a687059c 1108 case OCLOSE:
1109 str = str_make("close(");
1110 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1111 if (!do_fancy_opens) {
1112 t = tmpstr->str_ptr;
1113 if (*t == '"' || *t == '\'')
1114 t = cpytill(tokenbuf,t+1,*t);
1115 else
1116 fatal("Internal error: OCLOSE %s",t);
1117 s = savestr(tokenbuf);
1118 for (t = tokenbuf; *t; t++) {
1119 *t &= 127;
d48672a2 1120 if (islower(*t))
1121 *t = toupper(*t);
a687059c 1122 if (!isalpha(*t) && !isdigit(*t))
1123 *t = '_';
1124 }
1125 if (!index(tokenbuf,'_'))
d48672a2 1126 strcpy(t,"_FH");
a687059c 1127 str_free(tmpstr);
1128 safefree(s);
1129 str_set(str,"close ");
1130 str_cat(str,tokenbuf);
1131 }
1132 else {
1133 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1134 tmpstr->str_ptr);
1135 str_free(tmpstr);
1136 str_set(str,tokenbuf);
1137 }
1138 break;
8d063cd8 1139 case OPRINTF:
1140 case OPRINT:
378cc40b 1141 lparen = ""; /* set to parens if necessary */
1142 rparen = "";
8d063cd8 1143 str = str_new(0);
1144 if (len == 3) { /* output redirection */
a687059c 1145 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1146 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1147 if (!do_fancy_opens) {
1148 t = tmpstr->str_ptr;
1149 if (*t == '"' || *t == '\'')
1150 t = cpytill(tokenbuf,t+1,*t);
1151 else
1152 fatal("Internal error: OPRINT");
1153 d = savestr(t);
1154 s = savestr(tokenbuf);
1155 for (t = tokenbuf; *t; t++) {
1156 *t &= 127;
d48672a2 1157 if (islower(*t))
1158 *t = toupper(*t);
8d063cd8 1159 if (!isalpha(*t) && !isdigit(*t))
1160 *t = '_';
1161 }
1162 if (!index(tokenbuf,'_'))
d48672a2 1163 strcpy(t,"_FH");
a687059c 1164 tmp3str = hfetch(symtab,tokenbuf);
1165 if (!tmp3str) {
1166 str_cat(opens,"open(");
1167 str_cat(opens,tokenbuf);
1168 str_cat(opens,", ");
1169 d[1] = '\0';
1170 str_cat(opens,d);
1171 str_scat(opens,tmp2str);
1172 str_cat(opens,tmpstr->str_ptr+1);
1173 if (*tmp2str->str_ptr == '|')
1174 str_cat(opens,") || die 'Cannot pipe to \"");
1175 else
1176 str_cat(opens,") || die 'Cannot create file \"");
1177 if (*d == '"')
1178 str_cat(opens,"'.\"");
1179 str_cat(opens,s);
1180 if (*d == '"')
1181 str_cat(opens,"\".'");
1182 str_cat(opens,"\".';\n");
1183 hstore(symtab,tokenbuf,str_make("x"));
1184 }
8d063cd8 1185 str_free(tmpstr);
1186 str_free(tmp2str);
1187 safefree(s);
1188 safefree(d);
1189 }
1190 else {
a687059c 1191 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8 1192 tmp2str->str_ptr, tmpstr->str_ptr);
1193 str_cat(str,tokenbuf);
1194 tab(str,level+1);
a687059c 1195 strcpy(tokenbuf,"$fh");
8d063cd8 1196 str_free(tmpstr);
1197 str_free(tmp2str);
378cc40b 1198 lparen = "(";
1199 rparen = ")";
8d063cd8 1200 }
1201 }
1202 else
a687059c 1203 strcpy(tokenbuf,"");
378cc40b 1204 str_cat(str,lparen); /* may be null */
8d063cd8 1205 if (type == OPRINTF)
1206 str_cat(str,"printf");
1207 else
1208 str_cat(str,"print");
d48672a2 1209 saw_fh = 0;
8d063cd8 1210 if (len == 3 || do_fancy_opens) {
d48672a2 1211 if (*tokenbuf) {
8d063cd8 1212 str_cat(str," ");
d48672a2 1213 saw_fh = 1;
1214 }
8d063cd8 1215 str_cat(str,tokenbuf);
1216 }
a687059c 1217 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1218 if (!*tmpstr->str_ptr && lval_field) {
1219 t = saw_OFS ? "$," : "' '";
1220 if (split_to_array) {
1221 sprintf(tokenbuf,"join(%s,@Fld)",t);
1222 str_cat(tmpstr,tokenbuf);
1223 }
1224 else {
1225 for (i = 1; i < maxfld; i++) {
1226 if (i <= arymax)
1227 sprintf(tokenbuf,"$%s, ",nameary[i]);
1228 else
1229 sprintf(tokenbuf,"$Fld%d, ",i);
1230 str_cat(tmpstr,tokenbuf);
1231 }
1232 if (maxfld <= arymax)
1233 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1234 else
1235 sprintf(tokenbuf,"$Fld%d",maxfld);
1236 str_cat(tmpstr,tokenbuf);
1237 }
1238 }
1239 if (*tmpstr->str_ptr) {
1240 str_cat(str," ");
d48672a2 1241 if (!saw_fh && *tmpstr->str_ptr == '(') {
1242 str_cat(str,"(");
1243 str_scat(str,tmpstr);
1244 str_cat(str,")");
1245 }
1246 else
1247 str_scat(str,tmpstr);
8d063cd8 1248 }
1249 else {
1250 str_cat(str," $_");
1251 }
378cc40b 1252 str_cat(str,rparen); /* may be null */
8d063cd8 1253 str_free(tmpstr);
1254 break;
a687059c 1255 case ORAND:
1256 str = str_make("rand(1)");
1257 break;
1258 case OSRAND:
1259 str = str_make("srand(");
1260 goto maybe0;
1261 case OATAN2:
1262 str = str_make("atan2(");
1263 goto maybe0;
1264 case OSIN:
1265 str = str_make("sin(");
1266 goto maybe0;
1267 case OCOS:
1268 str = str_make("cos(");
1269 goto maybe0;
1270 case OSYSTEM:
1271 str = str_make("system(");
1272 goto maybe0;
8d063cd8 1273 case OLENGTH:
1274 str = str_make("length(");
1275 goto maybe0;
1276 case OLOG:
1277 str = str_make("log(");
1278 goto maybe0;
1279 case OEXP:
1280 str = str_make("exp(");
1281 goto maybe0;
1282 case OSQRT:
1283 str = str_make("sqrt(");
1284 goto maybe0;
1285 case OINT:
1286 str = str_make("int(");
1287 maybe0:
1288 numeric = 1;
1289 if (len > 0)
a687059c 1290 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1291 else
1292 tmpstr = str_new(0);;
fe14fcc3 1293 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
8d063cd8 1294 if (lval_field) {
1295 t = saw_OFS ? "$," : "' '";
1296 if (split_to_array) {
1297 sprintf(tokenbuf,"join(%s,@Fld)",t);
1298 str_cat(tmpstr,tokenbuf);
1299 }
1300 else {
1301 sprintf(tokenbuf,"join(%s, ",t);
1302 str_cat(tmpstr,tokenbuf);
1303 for (i = 1; i < maxfld; i++) {
1304 if (i <= arymax)
1305 sprintf(tokenbuf,"$%s,",nameary[i]);
1306 else
1307 sprintf(tokenbuf,"$Fld%d,",i);
1308 str_cat(tmpstr,tokenbuf);
1309 }
1310 if (maxfld <= arymax)
1311 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1312 else
1313 sprintf(tokenbuf,"$Fld%d)",maxfld);
1314 str_cat(tmpstr,tokenbuf);
1315 }
1316 }
1317 else
1318 str_cat(tmpstr,"$_");
1319 }
1320 if (strEQ(tmpstr->str_ptr,"$_")) {
1321 if (type == OLENGTH && !do_chop) {
1322 str = str_make("(length(");
1323 str_cat(tmpstr,") - 1");
1324 }
1325 }
1326 str_scat(str,tmpstr);
1327 str_free(tmpstr);
1328 str_cat(str,")");
1329 break;
1330 case OBREAK:
1331 str = str_new(0);
1332 str_set(str,"last");
1333 break;
1334 case ONEXT:
1335 str = str_new(0);
1336 str_set(str,"next line");
1337 break;
1338 case OEXIT:
1339 str = str_new(0);
1340 if (realexit) {
a687059c 1341 prec = P_UNI;
8d063cd8 1342 str_set(str,"exit");
1343 if (len == 1) {
1344 str_cat(str," ");
1345 exitval = TRUE;
a687059c 1346 str_scat(str,
1347 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 1348 str_free(fstr);
1349 }
1350 }
1351 else {
1352 if (len == 1) {
9f68db38 1353 str_set(str,"$ExitValue = ");
8d063cd8 1354 exitval = TRUE;
a687059c 1355 str_scat(str,
1356 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
8d063cd8 1357 str_free(fstr);
1358 str_cat(str,"; ");
1359 }
1360 str_cat(str,"last line");
1361 }
1362 break;
1363 case OCONTINUE:
1364 str = str_new(0);
1365 str_set(str,"next");
1366 break;
1367 case OREDIR:
1368 goto def;
1369 case OIF:
1370 str = str_new(0);
1371 str_set(str,"if (");
a687059c 1372 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1373 str_free(fstr);
1374 str_cat(str,") ");
a687059c 1375 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1376 str_free(fstr);
1377 if (len == 3) {
1378 i = ops[node+3].ival;
1379 if (i) {
1380 if ((ops[i].ival & 255) == OBLOCK) {
1381 i = ops[i+1].ival;
1382 if (i) {
1383 if ((ops[i].ival & 255) != OIF)
1384 i = 0;
1385 }
1386 }
1387 else
1388 i = 0;
1389 }
1390 if (i) {
1391 str_cat(str,"els");
a687059c 1392 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
8d063cd8 1393 str_free(fstr);
1394 }
1395 else {
1396 str_cat(str,"else ");
a687059c 1397 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1398 str_free(fstr);
1399 }
1400 }
1401 break;
1402 case OWHILE:
1403 str = str_new(0);
1404 str_set(str,"while (");
a687059c 1405 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1406 str_free(fstr);
1407 str_cat(str,") ");
a687059c 1408 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1409 str_free(fstr);
1410 break;
1411 case OFOR:
1412 str = str_new(0);
1413 str_set(str,"for (");
a687059c 1414 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1415 i = numarg;
1416 if (i) {
1417 t = s = tmpstr->str_ptr;
1418 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1419 t++;
1420 i = t - s;
1421 if (i < 2)
1422 i = 0;
1423 }
1424 str_cat(str,"; ");
a687059c 1425 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1426 if (i && (t = index(fstr->str_ptr,0377))) {
1427 if (strnEQ(fstr->str_ptr,s,i))
1428 *t = ' ';
1429 }
1430 str_scat(str,fstr);
1431 str_free(fstr);
1432 str_free(tmpstr);
1433 str_cat(str,"; ");
a687059c 1434 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1435 str_free(fstr);
1436 str_cat(str,") ");
a687059c 1437 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 1438 str_free(fstr);
1439 break;
1440 case OFORIN:
a687059c 1441 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1442 d = index(tmpstr->str_ptr,'$');
1443 if (!d)
1444 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1445 s = index(d,'{');
1446 if (!s)
1447 s = index(d,'[');
1448 if (!s)
1449 fatal("Illegal for loop: %s",d);
1450 *s++ = '\0';
ffed7fef 1451 for (t = s; i = *t; t++) {
1452 i &= 127;
1453 if (i == '}' || i == ']')
1454 break;
1455 }
1456 if (*t)
a687059c 1457 *t = '\0';
8d063cd8 1458 str = str_new(0);
a687059c 1459 str_set(str,d+1);
8d063cd8 1460 str_cat(str,"[]");
1461 tmp2str = hfetch(symtab,str->str_ptr);
1462 if (tmp2str && atoi(tmp2str->str_ptr)) {
8d063cd8 1463 sprintf(tokenbuf,
62b28dd9 1464 "foreach %s ($[ .. $#%s) ",
a687059c 1465 s,
1466 d+1);
8d063cd8 1467 }
1468 else {
a687059c 1469 sprintf(tokenbuf,
1470 "foreach %s (keys %%%s) ",
1471 s,
1472 d+1);
8d063cd8 1473 }
a687059c 1474 str_set(str,tokenbuf);
1475 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1476 str_free(fstr);
8d063cd8 1477 str_free(tmpstr);
1478 break;
1479 case OBLOCK:
1480 str = str_new(0);
1481 str_set(str,"{");
378cc40b 1482 if (len >= 2 && ops[node+2].ival) {
a687059c 1483 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1484 str_free(fstr);
1485 }
1486 fixtab(str,++level);
a687059c 1487 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1488 str_free(fstr);
1489 addsemi(str);
1490 fixtab(str,--level);
1491 str_cat(str,"}\n");
1492 tab(str,level);
378cc40b 1493 if (len >= 3) {
a687059c 1494 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
378cc40b 1495 str_free(fstr);
1496 }
8d063cd8 1497 break;
1498 default:
1499 def:
1500 if (len) {
1501 if (len > 5)
1502 fatal("Garbage length in walk");
a687059c 1503 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1504 for (i = 2; i<= len; i++) {
a687059c 1505 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
8d063cd8 1506 str_free(fstr);
1507 }
1508 }
1509 else {
1510 str = Nullstr;
1511 }
1512 break;
1513 }
1514 if (!str)
1515 str = str_new(0);
a687059c 1516
1517 if (useval && prec < minprec) { /* need parens? */
1518 fstr = str_new(str->str_cur+2);
1519 str_nset(fstr,"(",1);
1520 str_scat(fstr,str);
1521 str_ncat(fstr,")",1);
1522 str_free(str);
1523 str = fstr;
1524 }
1525
8d063cd8 1526 *numericptr = numeric;
1527#ifdef DEBUGGING
1528 if (debug & 4) {
1529 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1530 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1531 if (*t == '\n')
1532 printf("\\n");
1533 else if (*t == '\t')
1534 printf("\\t");
1535 else
1536 putchar(*t);
1537 putchar('\n');
1538 }
1539#endif
1540 return str;
1541}
1542
1543tab(str,lvl)
1544register STR *str;
1545register int lvl;
1546{
1547 while (lvl > 1) {
1548 str_cat(str,"\t");
1549 lvl -= 2;
1550 }
1551 if (lvl)
1552 str_cat(str," ");
1553}
1554
1555fixtab(str,lvl)
1556register STR *str;
1557register int lvl;
1558{
1559 register char *s;
1560
1561 /* strip trailing white space */
1562
1563 s = str->str_ptr+str->str_cur - 1;
a687059c 1564 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
8d063cd8 1565 s--;
1566 s[1] = '\0';
1567 str->str_cur = s + 1 - str->str_ptr;
1568 if (s >= str->str_ptr && *s != '\n')
1569 str_cat(str,"\n");
1570
1571 tab(str,lvl);
1572}
1573
1574addsemi(str)
1575register STR *str;
1576{
1577 register char *s;
1578
1579 s = str->str_ptr+str->str_cur - 1;
1580 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1581 s--;
1582 if (s >= str->str_ptr && *s != ';' && *s != '}')
1583 str_cat(str,";");
1584}
1585
1586emit_split(str,level)
1587register STR *str;
1588int level;
1589{
1590 register int i;
1591
1592 if (split_to_array)
1593 str_cat(str,"@Fld");
1594 else {
1595 str_cat(str,"(");
1596 for (i = 1; i < maxfld; i++) {
1597 if (i <= arymax)
1598 sprintf(tokenbuf,"$%s,",nameary[i]);
1599 else
1600 sprintf(tokenbuf,"$Fld%d,",i);
1601 str_cat(str,tokenbuf);
1602 }
1603 if (maxfld <= arymax)
1604 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1605 else
1606 sprintf(tokenbuf,"$Fld%d)",maxfld);
1607 str_cat(str,tokenbuf);
1608 }
1609 if (const_FS) {
62b28dd9 1610 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
8d063cd8 1611 str_cat(str,tokenbuf);
1612 }
1613 else if (saw_FS)
62b28dd9 1614 str_cat(str," = split($FS, $_, 9999);\n");
8d063cd8 1615 else
62b28dd9 1616 str_cat(str," = split(' ', $_, 9999);\n");
8d063cd8 1617 tab(str,level);
1618}
1619
1620prewalk(numit,level,node,numericptr)
1621int numit;
1622int level;
1623register int node;
1624int *numericptr;
1625{
1626 register int len;
1627 register int type;
1628 register int i;
1629 char *t;
1630 char *d, *s;
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);
1750 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
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
2042numericize(node)
2043register int node;
2044{
2045 register int len;
2046 register int type;
2047 register int i;
2048 STR *tmpstr;
2049 STR *tmp2str;
2050 int numarg;
2051
2052 type = ops[node].ival;
2053 len = type >> 8;
2054 type &= 255;
2055 if (type == OVAR && len == 1) {
a687059c 2056 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 2057 tmp2str = str_make("1");
2058 hstore(symtab,tmpstr->str_ptr,tmp2str);
2059 }
2060}