perl 3.0 patch #38 (combined patch)
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
CommitLineData
20188a90 1/* $Header: walk.c,v 3.0.1.6 90/10/16 11:35:51 lwall Locked $
a687059c 2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
8d063cd8 7 *
8 * $Log: walk.c,v $
20188a90 9 * Revision 3.0.1.6 90/10/16 11:35:51 lwall
10 * patch29: a2p mistranslated certain weird field separators
11 *
62b28dd9 12 * Revision 3.0.1.5 90/08/09 05:55:01 lwall
13 * patch19: a2p emited local($_) without a semicolon
14 * patch19: a2p didn't make explicit split on whitespace skip leading whitespace
15 * patch19: foreach on a normal array was iterating on values instead of indexes
16 *
9f68db38 17 * Revision 3.0.1.4 90/03/01 10:32:45 lwall
18 * patch9: a2p didn't put a $ on ExitValue
19 *
663a0e37 20 * Revision 3.0.1.3 89/12/21 20:32:35 lwall
21 * patch7: in a2p, user-defined functions didn't work on some machines
22 *
ffed7fef 23 * Revision 3.0.1.2 89/11/17 15:53:00 lwall
24 * patch5: on Pyramids, index(s, '}' + 128) doesn't find meta-}
25 *
ae986130 26 * Revision 3.0.1.1 89/11/11 05:09:33 lwall
27 * patch2: in a2p, awk script with no line actions still needs main loop
28 *
a687059c 29 * Revision 3.0 89/10/18 15:35:48 lwall
30 * 3.0 baseline
8d063cd8 31 *
32 */
33
34#include "handy.h"
35#include "EXTERN.h"
36#include "util.h"
37#include "a2p.h"
38
39bool exitval = FALSE;
40bool realexit = FALSE;
378cc40b 41bool saw_getline = FALSE;
a687059c 42bool subretnum = FALSE;
43bool saw_FNR = FALSE;
44bool saw_argv0 = FALSE;
8d063cd8 45int maxtmp = 0;
378cc40b 46char *lparen;
47char *rparen;
a687059c 48STR *subs;
49STR *curargs = Nullstr;
8d063cd8 50
51STR *
a687059c 52walk(useval,level,node,numericptr,minprec)
8d063cd8 53int useval;
54int level;
55register int node;
56int *numericptr;
a687059c 57int minprec; /* minimum precedence without parens */
8d063cd8 58{
59 register int len;
60 register STR *str;
61 register int type;
62 register int i;
63 register STR *tmpstr;
64 STR *tmp2str;
a687059c 65 STR *tmp3str;
8d063cd8 66 char *t;
67 char *d, *s;
68 int numarg;
69 int numeric = FALSE;
70 STR *fstr;
a687059c 71 int prec = P_MAX; /* assume no parens needed */
8d063cd8 72 char *index();
73
74 if (!node) {
75 *numericptr = 0;
76 return str_make("");
77 }
78 type = ops[node].ival;
79 len = type >> 8;
80 type &= 255;
81 switch (type) {
82 case OPROG:
8d063cd8 83 opens = str_new(0);
a687059c 84 subs = str_new(0);
85 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 86 if (do_split && need_entire && !absmaxfld)
87 split_to_array = TRUE;
88 if (do_split && split_to_array)
89 set_array_base = TRUE;
90 if (set_array_base) {
91 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
92 }
93 if (fswitch && !const_FS)
94 const_FS = fswitch;
95 if (saw_FS > 1 || saw_RS)
96 const_FS = 0;
97 if (saw_ORS && need_entire)
98 do_chop = TRUE;
99 if (fswitch) {
100 str_cat(str,"$FS = '");
101 if (index("*+?.[]()|^$\\",fswitch))
102 str_cat(str,"\\");
103 sprintf(tokenbuf,"%c",fswitch);
104 str_cat(str,tokenbuf);
105 str_cat(str,"';\t\t# field separator from -F switch\n");
106 }
107 else if (saw_FS && !const_FS) {
9bb9d9f7 108 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
8d063cd8 109 }
110 if (saw_OFS) {
a559c259 111 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
8d063cd8 112 }
113 if (saw_ORS) {
a559c259 114 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
8d063cd8 115 }
a687059c 116 if (saw_argv0) {
117 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
118 }
8d063cd8 119 if (str->str_cur > 20)
120 str_cat(str,"\n");
121 if (ops[node+2].ival) {
a687059c 122 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 123 str_free(fstr);
124 str_cat(str,"\n\n");
125 }
a687059c 126 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
127 if (*fstr->str_ptr) {
128 if (saw_line_op)
129 str_cat(str,"line: ");
130 str_cat(str,"while (<>) {\n");
131 tab(str,++level);
132 if (saw_FS && !const_FS)
133 do_chop = TRUE;
134 if (do_chop) {
135 str_cat(str,"chop;\t# strip record separator\n");
136 tab(str,level);
8d063cd8 137 }
a687059c 138 arymax = 0;
139 if (namelist) {
140 while (isalpha(*namelist)) {
141 for (d = tokenbuf,s=namelist;
142 isalpha(*s) || isdigit(*s) || *s == '_';
143 *d++ = *s++) ;
144 *d = '\0';
145 while (*s && !isalpha(*s)) s++;
146 namelist = s;
147 nameary[++arymax] = savestr(tokenbuf);
148 }
149 }
150 if (maxfld < arymax)
151 maxfld = arymax;
152 if (do_split)
153 emit_split(str,level);
154 str_scat(str,fstr);
155 str_free(fstr);
156 fixtab(str,--level);
157 str_cat(str,"}\n");
158 if (saw_FNR)
159 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
8d063cd8 160 }
a687059c 161 else
ae986130 162 str_cat(str,"while (<>) { } # (no line actions)\n");
8d063cd8 163 if (ops[node+4].ival) {
164 realexit = TRUE;
165 str_cat(str,"\n");
166 tab(str,level);
a687059c 167 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 168 str_free(fstr);
169 str_cat(str,"\n");
170 }
171 if (exitval)
9f68db38 172 str_cat(str,"exit $ExitValue;\n");
a687059c 173 if (subs->str_ptr) {
174 str_cat(str,"\n");
175 str_scat(str,subs);
176 }
378cc40b 177 if (saw_getline) {
a687059c 178 for (len = 0; len < 4; len++) {
179 if (saw_getline & (1 << len)) {
180 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
181 str_cat(str, tokenbuf);
182 if (len & 2) {
183 if (do_fancy_opens)
184 str_cat(str," &Pick('',@_);\n");
185 else
186 str_cat(str," ($fh) = @_;\n");
187 }
188 else {
189 if (saw_FNR)
190 str_cat(str," $FNRbase = $. if eof;\n");
191 }
192 if (len & 1)
62b28dd9 193 str_cat(str," local($_);\n");
a687059c 194 if (len & 2)
195 str_cat(str,
196 " if ($getline_ok = (($_ = <$fh>) ne ''))");
197 else
198 str_cat(str,
199 " if ($getline_ok = (($_ = <>) ne ''))");
200 str_cat(str, " {\n");
201 level += 2;
202 tab(str,level);
203 i = 0;
204 if (do_chop) {
205 i++;
206 str_cat(str,"chop;\t# strip record separator\n");
207 tab(str,level);
208 }
209 if (do_split && !(len & 1)) {
210 i++;
211 emit_split(str,level);
212 }
213 if (!i)
214 str_cat(str,";\n");
215 fixtab(str,--level);
216 str_cat(str,"}\n $_;\n}\n");
217 --level;
218 }
378cc40b 219 }
378cc40b 220 }
8d063cd8 221 if (do_fancy_opens) {
222 str_cat(str,"\n\
223sub Pick {\n\
a687059c 224 local($mode,$name,$pipe) = @_;\n\
8d063cd8 225 $fh = $opened{$name};\n\
226 if (!$fh) {\n\
a687059c 227 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
228 open($fh,$mode.$name.$pipe);\n\
8d063cd8 229 }\n\
8d063cd8 230}\n\
231");
232 }
233 break;
234 case OHUNKS:
a687059c 235 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
236 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 237 str_free(fstr);
238 if (len == 3) {
a687059c 239 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 240 str_free(fstr);
241 }
242 else {
243 }
244 break;
245 case ORANGE:
a687059c 246 prec = P_DOTDOT;
247 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 248 str_cat(str," .. ");
a687059c 249 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 250 str_free(fstr);
251 break;
252 case OPAT:
253 goto def;
254 case OREGEX:
255 str = str_new(0);
256 str_set(str,"/");
a687059c 257 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 258 /* translate \nnn to [\nnn] */
259 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
a687059c 260 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
8d063cd8 261 *d++ = '[';
262 *d++ = *s++;
263 *d++ = *s++;
264 *d++ = *s++;
265 *d++ = *s;
266 *d = ']';
267 }
268 else
269 *d = *s;
270 }
271 *d = '\0';
378cc40b 272 for (d=tokenbuf; *d; d++)
273 *d += 128;
8d063cd8 274 str_cat(str,tokenbuf);
275 str_free(tmpstr);
276 str_cat(str,"/");
277 break;
278 case OHUNK:
279 if (len == 1) {
280 str = str_new(0);
a687059c 281 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
8d063cd8 282 str_cat(str," if ");
a687059c 283 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 284 str_free(fstr);
285 str_cat(str,";");
286 }
287 else {
a687059c 288 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 289 if (*tmpstr->str_ptr) {
290 str = str_new(0);
291 str_set(str,"if (");
292 str_scat(str,tmpstr);
293 str_cat(str,") {\n");
294 tab(str,++level);
a687059c 295 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 296 str_free(fstr);
297 fixtab(str,--level);
298 str_cat(str,"}\n");
299 tab(str,level);
300 }
301 else {
a687059c 302 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 303 }
304 }
305 break;
306 case OPPAREN:
307 str = str_new(0);
308 str_set(str,"(");
a687059c 309 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 310 str_free(fstr);
311 str_cat(str,")");
312 break;
313 case OPANDAND:
a687059c 314 prec = P_ANDAND;
315 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 316 str_cat(str," && ");
a687059c 317 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
318 str_free(fstr);
319 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 320 str_free(fstr);
321 break;
322 case OPOROR:
a687059c 323 prec = P_OROR;
324 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 325 str_cat(str," || ");
a687059c 326 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
327 str_free(fstr);
328 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 329 str_free(fstr);
330 break;
331 case OPNOT:
a687059c 332 prec = P_UNARY;
8d063cd8 333 str = str_new(0);
334 str_set(str,"!");
a687059c 335 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 336 str_free(fstr);
337 break;
62b28dd9 338 case OCOND:
339 prec = P_COND;
340 str = walk(1,level,ops[node+1].ival,&numarg,prec);
341 str_cat(str," ? ");
342 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
343 str_free(fstr);
344 str_cat(str," : ");
345 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
346 str_free(fstr);
347 break;
8d063cd8 348 case OCPAREN:
349 str = str_new(0);
350 str_set(str,"(");
a687059c 351 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 352 str_free(fstr);
353 numeric |= numarg;
354 str_cat(str,")");
355 break;
356 case OCANDAND:
a687059c 357 prec = P_ANDAND;
358 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 359 numeric = 1;
360 str_cat(str," && ");
a687059c 361 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
362 str_free(fstr);
363 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 364 str_free(fstr);
365 break;
366 case OCOROR:
a687059c 367 prec = P_OROR;
368 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 369 numeric = 1;
370 str_cat(str," || ");
a687059c 371 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
372 str_free(fstr);
373 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 374 str_free(fstr);
375 break;
376 case OCNOT:
a687059c 377 prec = P_UNARY;
8d063cd8 378 str = str_new(0);
379 str_set(str,"!");
a687059c 380 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 381 str_free(fstr);
382 numeric = 1;
383 break;
384 case ORELOP:
a687059c 385 prec = P_REL;
386 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 387 numeric |= numarg;
a687059c 388 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
389 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
8d063cd8 390 numeric |= numarg;
a687059c 391 if (!numeric ||
392 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
8d063cd8 393 t = tmpstr->str_ptr;
394 if (strEQ(t,"=="))
395 str_set(tmpstr,"eq");
396 else if (strEQ(t,"!="))
397 str_set(tmpstr,"ne");
398 else if (strEQ(t,"<"))
399 str_set(tmpstr,"lt");
400 else if (strEQ(t,"<="))
401 str_set(tmpstr,"le");
402 else if (strEQ(t,">"))
403 str_set(tmpstr,"gt");
404 else if (strEQ(t,">="))
405 str_set(tmpstr,"ge");
406 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
407 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
408 numeric |= 2;
409 }
410 if (numeric & 2) {
411 if (numeric & 1) /* numeric is very good guess */
412 str_cat(str," ");
413 else
414 str_cat(str,"\377");
415 numeric = 1;
416 }
417 else
418 str_cat(str," ");
419 str_scat(str,tmpstr);
420 str_free(tmpstr);
421 str_cat(str," ");
422 str_scat(str,tmp2str);
423 str_free(tmp2str);
424 numeric = 1;
425 break;
426 case ORPAREN:
427 str = str_new(0);
428 str_set(str,"(");
a687059c 429 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 430 str_free(fstr);
431 numeric |= numarg;
432 str_cat(str,")");
433 break;
434 case OMATCHOP:
a687059c 435 prec = P_MATCH;
436 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 437 str_cat(str," ");
a687059c 438 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 439 if (strEQ(tmpstr->str_ptr,"~"))
440 str_cat(str,"=~");
441 else {
442 str_scat(str,tmpstr);
443 str_free(tmpstr);
444 }
445 str_cat(str," ");
a687059c 446 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 447 str_free(fstr);
448 numeric = 1;
449 break;
450 case OMPAREN:
451 str = str_new(0);
452 str_set(str,"(");
a687059c 453 str_scat(str,
454 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 455 str_free(fstr);
456 numeric |= numarg;
457 str_cat(str,")");
458 break;
459 case OCONCAT:
a687059c 460 prec = P_ADD;
461 type = ops[ops[node+1].ival].ival & 255;
462 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
8d063cd8 463 str_cat(str," . ");
a687059c 464 type = ops[ops[node+2].ival].ival & 255;
465 str_scat(str,
466 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
8d063cd8 467 str_free(fstr);
468 break;
469 case OASSIGN:
a687059c 470 prec = P_ASSIGN;
471 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 472 str_cat(str," ");
a687059c 473 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 474 str_scat(str,tmpstr);
475 if (str_len(tmpstr) > 1)
476 numeric = 1;
477 str_free(tmpstr);
478 str_cat(str," ");
a687059c 479 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
8d063cd8 480 str_free(fstr);
481 numeric |= numarg;
8d063cd8 482 break;
483 case OADD:
a687059c 484 prec = P_ADD;
485 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 486 str_cat(str," + ");
a687059c 487 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 488 str_free(fstr);
489 numeric = 1;
490 break;
a687059c 491 case OSUBTRACT:
492 prec = P_ADD;
493 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 494 str_cat(str," - ");
a687059c 495 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 496 str_free(fstr);
497 numeric = 1;
498 break;
499 case OMULT:
a687059c 500 prec = P_MUL;
501 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 502 str_cat(str," * ");
a687059c 503 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 504 str_free(fstr);
505 numeric = 1;
506 break;
507 case ODIV:
a687059c 508 prec = P_MUL;
509 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 510 str_cat(str," / ");
a687059c 511 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
512 str_free(fstr);
513 numeric = 1;
514 break;
515 case OPOW:
516 prec = P_POW;
517 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
518 str_cat(str," ** ");
519 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
8d063cd8 520 str_free(fstr);
521 numeric = 1;
522 break;
523 case OMOD:
a687059c 524 prec = P_MUL;
525 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 526 str_cat(str," % ");
a687059c 527 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 528 str_free(fstr);
529 numeric = 1;
530 break;
531 case OPOSTINCR:
a687059c 532 prec = P_AUTO;
533 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 534 str_cat(str,"++");
535 numeric = 1;
536 break;
537 case OPOSTDECR:
a687059c 538 prec = P_AUTO;
539 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 540 str_cat(str,"--");
541 numeric = 1;
542 break;
543 case OPREINCR:
a687059c 544 prec = P_AUTO;
8d063cd8 545 str = str_new(0);
546 str_set(str,"++");
a687059c 547 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 548 str_free(fstr);
549 numeric = 1;
550 break;
551 case OPREDECR:
a687059c 552 prec = P_AUTO;
8d063cd8 553 str = str_new(0);
554 str_set(str,"--");
a687059c 555 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 556 str_free(fstr);
557 numeric = 1;
558 break;
559 case OUMINUS:
a687059c 560 prec = P_UNARY;
8d063cd8 561 str = str_new(0);
562 str_set(str,"-");
a687059c 563 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 564 str_free(fstr);
565 numeric = 1;
566 break;
567 case OUPLUS:
568 numeric = 1;
569 goto def;
570 case OPAREN:
571 str = str_new(0);
572 str_set(str,"(");
a687059c 573 str_scat(str,
574 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 575 str_free(fstr);
576 str_cat(str,")");
577 numeric |= numarg;
578 break;
579 case OGETLINE:
580 str = str_new(0);
a687059c 581 if (useval)
582 str_cat(str,"(");
583 if (len > 0) {
584 str_cat(str,"$");
585 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
586 if (!*fstr->str_ptr) {
587 str_cat(str,"_");
588 len = 2; /* a legal fiction */
589 }
590 str_free(fstr);
591 }
592 else
593 str_cat(str,"$_");
594 if (len > 1) {
595 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
596 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
597 if (!do_fancy_opens) {
598 t = tmpstr->str_ptr;
599 if (*t == '"' || *t == '\'')
600 t = cpytill(tokenbuf,t+1,*t);
601 else
602 fatal("Internal error: OGETLINE %s", t);
603 d = savestr(t);
604 s = savestr(tokenbuf);
605 for (t = tokenbuf; *t; t++) {
606 *t &= 127;
607 if (!isalpha(*t) && !isdigit(*t))
608 *t = '_';
609 }
610 if (!index(tokenbuf,'_'))
611 strcpy(t,"_fh");
612 tmp3str = hfetch(symtab,tokenbuf);
613 if (!tmp3str) {
614 do_opens = TRUE;
615 str_cat(opens,"open(");
616 str_cat(opens,tokenbuf);
617 str_cat(opens,", ");
618 d[1] = '\0';
619 str_cat(opens,d);
620 str_cat(opens,tmpstr->str_ptr+1);
621 opens->str_cur--;
622 if (*fstr->str_ptr == '|')
623 str_cat(opens,"|");
624 str_cat(opens,d);
625 if (*fstr->str_ptr == '|')
626 str_cat(opens,") || die 'Cannot pipe from \"");
627 else
628 str_cat(opens,") || die 'Cannot open file \"");
629 if (*d == '"')
630 str_cat(opens,"'.\"");
631 str_cat(opens,s);
632 if (*d == '"')
633 str_cat(opens,"\".'");
634 str_cat(opens,"\".';\n");
635 hstore(symtab,tokenbuf,str_make("x"));
636 }
637 safefree(s);
638 safefree(d);
639 str_set(tmpstr,"'");
640 str_cat(tmpstr,tokenbuf);
641 str_cat(tmpstr,"'");
642 }
643 if (*fstr->str_ptr == '|')
644 str_cat(tmpstr,", '|'");
645 str_free(fstr);
646 }
647 else
648 tmpstr = str_make("");
649 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
650 str_cat(str,tokenbuf);
651 str_free(tmpstr);
652 if (useval)
653 str_cat(str,",$getline_ok)");
654 saw_getline |= 1 << len;
8d063cd8 655 break;
656 case OSPRINTF:
657 str = str_new(0);
658 str_set(str,"sprintf(");
a687059c 659 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 660 str_free(fstr);
661 str_cat(str,")");
662 break;
663 case OSUBSTR:
664 str = str_new(0);
665 str_set(str,"substr(");
a687059c 666 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 667 str_free(fstr);
668 str_cat(str,", ");
a687059c 669 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8 670 str_free(fstr);
671 str_cat(str,", ");
672 if (len == 3) {
a687059c 673 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
8d063cd8 674 str_free(fstr);
675 }
676 else
677 str_cat(str,"999999");
678 str_cat(str,")");
679 break;
680 case OSTRING:
681 str = str_new(0);
682 str_set(str,ops[node+1].cval);
683 break;
684 case OSPLIT:
685 str = str_new(0);
686 numeric = 1;
a687059c 687 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 688 if (useval)
689 str_set(str,"(@");
690 else
691 str_set(str,"@");
692 str_scat(str,tmpstr);
693 str_cat(str," = split(");
694 if (len == 3) {
a687059c 695 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
8d063cd8 696 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
697 i = fstr->str_ptr[1] & 127;
698 if (index("*+?.[]()|^$\\",i))
699 sprintf(tokenbuf,"/\\%c/",i);
20188a90 700 else if (i == ' ')
62b28dd9 701 sprintf(tokenbuf,"' '");
8d063cd8 702 else
703 sprintf(tokenbuf,"/%c/",i);
704 str_cat(str,tokenbuf);
705 }
706 else
707 str_scat(str,fstr);
708 str_free(fstr);
709 }
710 else if (const_FS) {
711 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
712 str_cat(str,tokenbuf);
713 }
714 else if (saw_FS)
715 str_cat(str,"$FS");
716 else
9bb9d9f7 717 str_cat(str,"' '");
8d063cd8 718 str_cat(str,", ");
a687059c 719 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 720 str_free(fstr);
62b28dd9 721 str_cat(str,", 9999)");
8d063cd8 722 if (useval) {
723 str_cat(str,")");
724 }
725 str_free(tmpstr);
726 break;
727 case OINDEX:
728 str = str_new(0);
729 str_set(str,"index(");
a687059c 730 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 731 str_free(fstr);
732 str_cat(str,", ");
a687059c 733 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8 734 str_free(fstr);
735 str_cat(str,")");
736 numeric = 1;
737 break;
a687059c 738 case OMATCH:
739 str = str_new(0);
740 prec = P_ANDAND;
741 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
742 str_free(fstr);
743 str_cat(str," =~ ");
744 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
745 str_free(fstr);
746 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
747 numeric = 1;
748 break;
749 case OUSERDEF:
750 str = str_new(0);
751 subretnum = FALSE;
752 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
753 curargs = str_new(0);
754 str_sset(curargs,fstr);
755 str_cat(curargs,",");
756 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
757 str_free(curargs);
758 curargs = Nullstr;
759 level--;
760 subretnum |= numarg;
761 s = Nullch;
762 t = tmp2str->str_ptr;
763 while (t = instr(t,"return "))
764 s = t++;
765 if (s) {
766 i = 0;
767 for (t = s+7; *t; t++) {
768 if (*t == ';' || *t == '}')
769 i++;
770 }
771 if (i == 1) {
772 strcpy(s,s+7);
773 tmp2str->str_cur -= 7;
774 }
775 }
776 str_set(str,"\n");
777 tab(str,level);
778 str_cat(str,"sub ");
779 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
780 str_cat(str," {\n");
781 tab(str,++level);
782 if (fstr->str_cur) {
783 str_cat(str,"local(");
784 str_scat(str,fstr);
785 str_cat(str,") = @_;");
786 }
787 str_free(fstr);
788 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
789 str_free(fstr);
790 fixtab(str,level);
791 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
792 str_free(fstr);
793 fixtab(str,level);
794 str_scat(str,tmp2str);
795 str_free(tmp2str);
796 fixtab(str,--level);
797 str_cat(str,"}\n");
798 tab(str,level);
799 str_scat(subs,str);
800 str_set(str,"");
801 str_cat(tmpstr,"(");
802 tmp2str = str_new(0);
803 if (subretnum)
804 str_set(tmp2str,"1");
805 hstore(symtab,tmpstr->str_ptr,tmp2str);
806 str_free(tmpstr);
807 level++;
808 break;
809 case ORETURN:
810 str = str_new(0);
811 if (len > 0) {
812 str_cat(str,"return ");
813 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
814 str_free(fstr);
815 if (numarg)
816 subretnum = TRUE;
817 }
818 else
819 str_cat(str,"return");
820 break;
821 case OUSERFUN:
822 str = str_new(0);
823 str_set(str,"&");
824 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
825 str_free(fstr);
826 str_cat(str,"(");
827 tmpstr = hfetch(symtab,str->str_ptr+3);
828 if (tmpstr && tmpstr->str_ptr)
829 numeric |= atoi(tmpstr->str_ptr);
830 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
831 str_free(fstr);
832 str_cat(str,")");
833 break;
834 case OGSUB:
835 case OSUB:
836 if (type == OGSUB)
837 s = "g";
838 else
839 s = "";
840 str = str_new(0);
841 tmpstr = str_new(0);
842 i = 0;
843 if (len == 3) {
844 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
845 if (strNE(tmpstr->str_ptr,"$_")) {
846 str_cat(tmpstr, " =~ s");
847 i++;
848 }
849 else
850 str_set(tmpstr, "s");
851 }
852 else
853 str_set(tmpstr, "s");
854 type = ops[ops[node+2].ival].ival;
855 len = type >> 8;
856 type &= 255;
857 tmp3str = str_new(0);
858 if (type == OSTR) {
859 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
860 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
861 if (*t == '&')
862 *d++ = '$' + 128;
863 else if (*t == '$')
864 *d++ = '\\' + 128;
865 *d = *t + 128;
866 }
867 *d = '\0';
868 str_set(tmp2str,tokenbuf);
869 }
870 else {
871 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
872 str_set(tmp3str,"($s_ = '\"'.(");
873 str_scat(tmp3str,tmp2str);
874 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
875 str_set(tmp2str,"eval $s_");
876 s = (*s == 'g' ? "ge" : "e");
877 i++;
878 }
879 type = ops[ops[node+1].ival].ival;
880 len = type >> 8;
881 type &= 255;
882 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
883 if (type == OREGEX) {
884 if (useval && i)
885 str_cat(str,"(");
886 str_scat(str,tmp3str);
887 str_scat(str,tmpstr);
888 str_scat(str,fstr);
889 str_scat(str,tmp2str);
890 str_cat(str,"/");
891 str_cat(str,s);
892 }
893 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
894 if (useval && i)
895 str_cat(str,"(");
896 str_scat(str,tmp3str);
897 str_scat(str,tmpstr);
898 str_cat(str,"/");
899 str_scat(str,fstr);
900 str_cat(str,"/");
901 str_scat(str,tmp2str);
902 str_cat(str,"/");
903 str_cat(str,s);
904 }
905 else {
906 i++;
907 if (useval)
908 str_cat(str,"(");
909 str_cat(str,"$s = ");
910 str_scat(str,fstr);
911 str_cat(str,", ");
912 str_scat(str,tmp3str);
913 str_scat(str,tmpstr);
914 str_cat(str,"/$s/");
915 str_scat(str,tmp2str);
916 str_cat(str,"/");
917 str_cat(str,s);
918 }
919 if (useval && i)
920 str_cat(str,")");
921 str_free(fstr);
922 str_free(tmpstr);
923 str_free(tmp2str);
924 str_free(tmp3str);
925 numeric = 1;
926 break;
8d063cd8 927 case ONUM:
a687059c 928 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 929 numeric = 1;
930 break;
931 case OSTR:
a687059c 932 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 933 s = "'";
378cc40b 934 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
935 if (*t == '\'')
936 s = "\"";
937 else if (*t == '\\') {
8d063cd8 938 s = "\"";
378cc40b 939 *d++ = *t++ + 128;
940 switch (*t) {
941 case '\\': case '"': case 'n': case 't':
942 break;
943 default: /* hide this from perl */
944 *d++ = '\\' + 128;
945 }
946 }
947 *d = *t + 128;
8d063cd8 948 }
378cc40b 949 *d = '\0';
8d063cd8 950 str = str_new(0);
951 str_set(str,s);
378cc40b 952 str_cat(str,tokenbuf);
8d063cd8 953 str_free(tmpstr);
954 str_cat(str,s);
955 break;
a687059c 956 case ODEFINED:
957 prec = P_UNI;
958 str = str_new(0);
959 str_set(str,"defined $");
960 goto addvar;
961 case ODELETE:
962 str = str_new(0);
963 str_set(str,"delete $");
964 goto addvar;
965 case OSTAR:
966 str = str_new(0);
967 str_set(str,"*");
968 goto addvar;
8d063cd8 969 case OVAR:
970 str = str_new(0);
971 str_set(str,"$");
a687059c 972 addvar:
973 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 974 if (len == 1) {
975 tmp2str = hfetch(symtab,tmpstr->str_ptr);
976 if (tmp2str && atoi(tmp2str->str_ptr))
977 numeric = 2;
a687059c 978 if (strEQ(str->str_ptr,"$FNR")) {
979 numeric = 1;
980 saw_FNR++;
981 str_set(str,"($.-$FNRbase)");
982 }
983 else if (strEQ(str->str_ptr,"$NR")) {
8d063cd8 984 numeric = 1;
985 str_set(str,"$.");
986 }
987 else if (strEQ(str->str_ptr,"$NF")) {
988 numeric = 1;
989 str_set(str,"$#Fld");
990 }
991 else if (strEQ(str->str_ptr,"$0"))
992 str_set(str,"$_");
a687059c 993 else if (strEQ(str->str_ptr,"$ARGC"))
994 str_set(str,"($#ARGV+1)");
8d063cd8 995 }
996 else {
a687059c 997#ifdef NOTDEF
998 if (curargs) {
999 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
1000 ??? if (instr(curargs->str_ptr,tokenbuf))
1001 str_cat(str,"\377"); /* can't translate yet */
1002 }
1003#endif
8d063cd8 1004 str_cat(tmpstr,"[]");
1005 tmp2str = hfetch(symtab,tmpstr->str_ptr);
1006 if (tmp2str && atoi(tmp2str->str_ptr))
1007 str_cat(str,"[");
1008 else
1009 str_cat(str,"{");
a687059c 1010 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1011 str_free(fstr);
a687059c 1012 if (strEQ(str->str_ptr,"$ARGV[0")) {
1013 str_set(str,"$ARGV0");
1014 saw_argv0++;
1015 }
1016 else {
1017 if (tmp2str && atoi(tmp2str->str_ptr))
1018 strcpy(tokenbuf,"]");
1019 else
1020 strcpy(tokenbuf,"}");
1021 *tokenbuf += 128;
1022 str_cat(str,tokenbuf);
1023 }
8d063cd8 1024 }
1025 str_free(tmpstr);
1026 break;
1027 case OFLD:
1028 str = str_new(0);
1029 if (split_to_array) {
1030 str_set(str,"$Fld");
1031 str_cat(str,"[");
a687059c 1032 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1033 str_free(fstr);
1034 str_cat(str,"]");
1035 }
1036 else {
a687059c 1037 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
8d063cd8 1038 if (i <= arymax)
1039 sprintf(tokenbuf,"$%s",nameary[i]);
1040 else
1041 sprintf(tokenbuf,"$Fld%d",i);
1042 str_set(str,tokenbuf);
1043 }
1044 break;
1045 case OVFLD:
1046 str = str_new(0);
1047 str_set(str,"$Fld[");
1048 i = ops[node+1].ival;
1049 if ((ops[i].ival & 255) == OPAREN)
1050 i = ops[i+1].ival;
a687059c 1051 tmpstr=walk(1,level,i,&numarg,P_MIN);
8d063cd8 1052 str_scat(str,tmpstr);
1053 str_free(tmpstr);
1054 str_cat(str,"]");
1055 break;
1056 case OJUNK:
1057 goto def;
1058 case OSNEWLINE:
1059 str = str_new(2);
1060 str_set(str,";\n");
1061 tab(str,level);
1062 break;
1063 case ONEWLINE:
1064 str = str_new(1);
1065 str_set(str,"\n");
1066 tab(str,level);
1067 break;
1068 case OSCOMMENT:
1069 str = str_new(0);
1070 str_set(str,";");
a687059c 1071 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1072 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1073 *s += 128;
1074 str_scat(str,tmpstr);
1075 str_free(tmpstr);
1076 tab(str,level);
1077 break;
1078 case OCOMMENT:
1079 str = str_new(0);
a687059c 1080 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1081 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1082 *s += 128;
1083 str_scat(str,tmpstr);
1084 str_free(tmpstr);
1085 tab(str,level);
1086 break;
1087 case OCOMMA:
a687059c 1088 prec = P_COMMA;
1089 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 1090 str_cat(str,", ");
a687059c 1091 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1092 str_free(fstr);
1093 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 1094 str_free(fstr);
1095 break;
1096 case OSEMICOLON:
1097 str = str_new(1);
a687059c 1098 str_set(str,";\n");
1099 tab(str,level);
8d063cd8 1100 break;
1101 case OSTATES:
a687059c 1102 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1103 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1104 str_free(fstr);
1105 break;
1106 case OSTATE:
1107 str = str_new(0);
1108 if (len >= 1) {
a687059c 1109 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1110 str_free(fstr);
1111 if (len >= 2) {
a687059c 1112 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1113 if (*tmpstr->str_ptr == ';') {
1114 addsemi(str);
1115 str_cat(str,tmpstr->str_ptr+1);
1116 }
1117 str_free(tmpstr);
1118 }
1119 }
1120 break;
a687059c 1121 case OCLOSE:
1122 str = str_make("close(");
1123 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1124 if (!do_fancy_opens) {
1125 t = tmpstr->str_ptr;
1126 if (*t == '"' || *t == '\'')
1127 t = cpytill(tokenbuf,t+1,*t);
1128 else
1129 fatal("Internal error: OCLOSE %s",t);
1130 s = savestr(tokenbuf);
1131 for (t = tokenbuf; *t; t++) {
1132 *t &= 127;
1133 if (!isalpha(*t) && !isdigit(*t))
1134 *t = '_';
1135 }
1136 if (!index(tokenbuf,'_'))
1137 strcpy(t,"_fh");
1138 str_free(tmpstr);
1139 safefree(s);
1140 str_set(str,"close ");
1141 str_cat(str,tokenbuf);
1142 }
1143 else {
1144 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1145 tmpstr->str_ptr);
1146 str_free(tmpstr);
1147 str_set(str,tokenbuf);
1148 }
1149 break;
8d063cd8 1150 case OPRINTF:
1151 case OPRINT:
378cc40b 1152 lparen = ""; /* set to parens if necessary */
1153 rparen = "";
8d063cd8 1154 str = str_new(0);
1155 if (len == 3) { /* output redirection */
a687059c 1156 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1157 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1158 if (!do_fancy_opens) {
1159 t = tmpstr->str_ptr;
1160 if (*t == '"' || *t == '\'')
1161 t = cpytill(tokenbuf,t+1,*t);
1162 else
1163 fatal("Internal error: OPRINT");
1164 d = savestr(t);
1165 s = savestr(tokenbuf);
1166 for (t = tokenbuf; *t; t++) {
1167 *t &= 127;
1168 if (!isalpha(*t) && !isdigit(*t))
1169 *t = '_';
1170 }
1171 if (!index(tokenbuf,'_'))
1172 strcpy(t,"_fh");
a687059c 1173 tmp3str = hfetch(symtab,tokenbuf);
1174 if (!tmp3str) {
1175 str_cat(opens,"open(");
1176 str_cat(opens,tokenbuf);
1177 str_cat(opens,", ");
1178 d[1] = '\0';
1179 str_cat(opens,d);
1180 str_scat(opens,tmp2str);
1181 str_cat(opens,tmpstr->str_ptr+1);
1182 if (*tmp2str->str_ptr == '|')
1183 str_cat(opens,") || die 'Cannot pipe to \"");
1184 else
1185 str_cat(opens,") || die 'Cannot create file \"");
1186 if (*d == '"')
1187 str_cat(opens,"'.\"");
1188 str_cat(opens,s);
1189 if (*d == '"')
1190 str_cat(opens,"\".'");
1191 str_cat(opens,"\".';\n");
1192 hstore(symtab,tokenbuf,str_make("x"));
1193 }
8d063cd8 1194 str_free(tmpstr);
1195 str_free(tmp2str);
1196 safefree(s);
1197 safefree(d);
1198 }
1199 else {
a687059c 1200 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8 1201 tmp2str->str_ptr, tmpstr->str_ptr);
1202 str_cat(str,tokenbuf);
1203 tab(str,level+1);
a687059c 1204 strcpy(tokenbuf,"$fh");
8d063cd8 1205 str_free(tmpstr);
1206 str_free(tmp2str);
378cc40b 1207 lparen = "(";
1208 rparen = ")";
8d063cd8 1209 }
1210 }
1211 else
a687059c 1212 strcpy(tokenbuf,"");
378cc40b 1213 str_cat(str,lparen); /* may be null */
8d063cd8 1214 if (type == OPRINTF)
1215 str_cat(str,"printf");
1216 else
1217 str_cat(str,"print");
1218 if (len == 3 || do_fancy_opens) {
1219 if (*tokenbuf)
1220 str_cat(str," ");
1221 str_cat(str,tokenbuf);
1222 }
a687059c 1223 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1224 if (!*tmpstr->str_ptr && lval_field) {
1225 t = saw_OFS ? "$," : "' '";
1226 if (split_to_array) {
1227 sprintf(tokenbuf,"join(%s,@Fld)",t);
1228 str_cat(tmpstr,tokenbuf);
1229 }
1230 else {
1231 for (i = 1; i < maxfld; i++) {
1232 if (i <= arymax)
1233 sprintf(tokenbuf,"$%s, ",nameary[i]);
1234 else
1235 sprintf(tokenbuf,"$Fld%d, ",i);
1236 str_cat(tmpstr,tokenbuf);
1237 }
1238 if (maxfld <= arymax)
1239 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1240 else
1241 sprintf(tokenbuf,"$Fld%d",maxfld);
1242 str_cat(tmpstr,tokenbuf);
1243 }
1244 }
1245 if (*tmpstr->str_ptr) {
1246 str_cat(str," ");
1247 str_scat(str,tmpstr);
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);;
1293 if (!*tmpstr->str_ptr) {
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}