perl 5.0 alpha 2
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
CommitLineData
79072805 1/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
a687059c 2 *
d48672a2 3 * Copyright (c) 1991, Larry Wall
a687059c 4 *
d48672a2 5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
8d063cd8 7 *
8 * $Log: walk.c,v $
79072805 9 * Revision 4.1 92/08/07 18:29:31 lwall
10 *
7c0587c8 11 * Revision 4.0.1.3 92/06/08 17:33:46 lwall
12 * patch20: in a2p, simplified the filehandle model
13 * patch20: in a2p, made RS="" translate to $/ = "\n\n"
14 * patch20: in a2p, do {...} while ... was missing some reconstruction code
15 * patch20: in a2p, getline should allow variable to be array element
16 *
55204971 17 * Revision 4.0.1.2 91/11/05 19:25:09 lwall
18 * patch11: in a2p, split on whitespace produced extra null field
19 *
d48672a2 20 * Revision 4.0.1.1 91/06/07 12:22:04 lwall
21 * patch4: new copyright notice
22 * patch4: a2p didn't correctly implement -n switch
23 *
fe14fcc3 24 * Revision 4.0 91/03/20 01:58:36 lwall
25 * 4.0 baseline.
8d063cd8 26 *
27 */
28
29#include "handy.h"
30#include "EXTERN.h"
31#include "util.h"
32#include "a2p.h"
33
34bool exitval = FALSE;
35bool realexit = FALSE;
378cc40b 36bool saw_getline = FALSE;
a687059c 37bool subretnum = FALSE;
38bool saw_FNR = FALSE;
39bool saw_argv0 = FALSE;
d48672a2 40bool saw_fh = FALSE;
8d063cd8 41int maxtmp = 0;
378cc40b 42char *lparen;
43char *rparen;
55204971 44char *limit;
a687059c 45STR *subs;
46STR *curargs = Nullstr;
8d063cd8 47
48STR *
a687059c 49walk(useval,level,node,numericptr,minprec)
8d063cd8 50int useval;
51int level;
52register int node;
53int *numericptr;
a687059c 54int minprec; /* minimum precedence without parens */
8d063cd8 55{
56 register int len;
57 register STR *str;
58 register int type;
59 register int i;
60 register STR *tmpstr;
61 STR *tmp2str;
a687059c 62 STR *tmp3str;
8d063cd8 63 char *t;
64 char *d, *s;
65 int numarg;
66 int numeric = FALSE;
67 STR *fstr;
a687059c 68 int prec = P_MAX; /* assume no parens needed */
8d063cd8 69 char *index();
70
71 if (!node) {
72 *numericptr = 0;
73 return str_make("");
74 }
75 type = ops[node].ival;
76 len = type >> 8;
77 type &= 255;
78 switch (type) {
79 case OPROG:
d48672a2 80 arymax = 0;
81 if (namelist) {
82 while (isalpha(*namelist)) {
83 for (d = tokenbuf,s=namelist;
84 isalpha(*s) || isdigit(*s) || *s == '_';
85 *d++ = *s++) ;
86 *d = '\0';
87 while (*s && !isalpha(*s)) s++;
88 namelist = s;
89 nameary[++arymax] = savestr(tokenbuf);
90 }
91 }
92 if (maxfld < arymax)
93 maxfld = arymax;
8d063cd8 94 opens = str_new(0);
a687059c 95 subs = str_new(0);
96 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 97 if (do_split && need_entire && !absmaxfld)
98 split_to_array = TRUE;
99 if (do_split && split_to_array)
100 set_array_base = TRUE;
101 if (set_array_base) {
102 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
103 }
104 if (fswitch && !const_FS)
105 const_FS = fswitch;
106 if (saw_FS > 1 || saw_RS)
107 const_FS = 0;
108 if (saw_ORS && need_entire)
109 do_chop = TRUE;
110 if (fswitch) {
111 str_cat(str,"$FS = '");
112 if (index("*+?.[]()|^$\\",fswitch))
113 str_cat(str,"\\");
114 sprintf(tokenbuf,"%c",fswitch);
115 str_cat(str,tokenbuf);
116 str_cat(str,"';\t\t# field separator from -F switch\n");
117 }
118 else if (saw_FS && !const_FS) {
9bb9d9f7 119 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
8d063cd8 120 }
121 if (saw_OFS) {
a559c259 122 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
8d063cd8 123 }
124 if (saw_ORS) {
a559c259 125 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
8d063cd8 126 }
a687059c 127 if (saw_argv0) {
128 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
129 }
8d063cd8 130 if (str->str_cur > 20)
131 str_cat(str,"\n");
132 if (ops[node+2].ival) {
a687059c 133 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 134 str_free(fstr);
135 str_cat(str,"\n\n");
136 }
a687059c 137 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
138 if (*fstr->str_ptr) {
139 if (saw_line_op)
140 str_cat(str,"line: ");
141 str_cat(str,"while (<>) {\n");
142 tab(str,++level);
143 if (saw_FS && !const_FS)
144 do_chop = TRUE;
145 if (do_chop) {
146 str_cat(str,"chop;\t# strip record separator\n");
147 tab(str,level);
8d063cd8 148 }
a687059c 149 if (do_split)
150 emit_split(str,level);
151 str_scat(str,fstr);
152 str_free(fstr);
153 fixtab(str,--level);
154 str_cat(str,"}\n");
155 if (saw_FNR)
156 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
8d063cd8 157 }
a687059c 158 else
ae986130 159 str_cat(str,"while (<>) { } # (no line actions)\n");
8d063cd8 160 if (ops[node+4].ival) {
161 realexit = TRUE;
162 str_cat(str,"\n");
163 tab(str,level);
a687059c 164 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 165 str_free(fstr);
166 str_cat(str,"\n");
167 }
168 if (exitval)
9f68db38 169 str_cat(str,"exit $ExitValue;\n");
a687059c 170 if (subs->str_ptr) {
171 str_cat(str,"\n");
172 str_scat(str,subs);
173 }
378cc40b 174 if (saw_getline) {
a687059c 175 for (len = 0; len < 4; len++) {
176 if (saw_getline & (1 << len)) {
177 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
178 str_cat(str, tokenbuf);
179 if (len & 2) {
180 if (do_fancy_opens)
181 str_cat(str," &Pick('',@_);\n");
182 else
183 str_cat(str," ($fh) = @_;\n");
184 }
185 else {
186 if (saw_FNR)
187 str_cat(str," $FNRbase = $. if eof;\n");
188 }
189 if (len & 1)
62b28dd9 190 str_cat(str," local($_);\n");
a687059c 191 if (len & 2)
192 str_cat(str,
193 " if ($getline_ok = (($_ = <$fh>) ne ''))");
194 else
195 str_cat(str,
196 " if ($getline_ok = (($_ = <>) ne ''))");
197 str_cat(str, " {\n");
198 level += 2;
199 tab(str,level);
200 i = 0;
201 if (do_chop) {
202 i++;
203 str_cat(str,"chop;\t# strip record separator\n");
204 tab(str,level);
205 }
206 if (do_split && !(len & 1)) {
207 i++;
208 emit_split(str,level);
209 }
210 if (!i)
211 str_cat(str,";\n");
212 fixtab(str,--level);
213 str_cat(str,"}\n $_;\n}\n");
214 --level;
215 }
378cc40b 216 }
378cc40b 217 }
8d063cd8 218 if (do_fancy_opens) {
219 str_cat(str,"\n\
220sub Pick {\n\
a687059c 221 local($mode,$name,$pipe) = @_;\n\
7c0587c8 222 $fh = $name;\n\
223 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
8d063cd8 224}\n\
225");
226 }
227 break;
228 case OHUNKS:
a687059c 229 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
230 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 231 str_free(fstr);
232 if (len == 3) {
a687059c 233 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 234 str_free(fstr);
235 }
236 else {
237 }
238 break;
239 case ORANGE:
a687059c 240 prec = P_DOTDOT;
241 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 242 str_cat(str," .. ");
a687059c 243 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 244 str_free(fstr);
245 break;
246 case OPAT:
247 goto def;
248 case OREGEX:
249 str = str_new(0);
250 str_set(str,"/");
a687059c 251 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 252 /* translate \nnn to [\nnn] */
253 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
a687059c 254 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
8d063cd8 255 *d++ = '[';
256 *d++ = *s++;
257 *d++ = *s++;
258 *d++ = *s++;
259 *d++ = *s;
260 *d = ']';
261 }
262 else
263 *d = *s;
264 }
265 *d = '\0';
378cc40b 266 for (d=tokenbuf; *d; d++)
267 *d += 128;
8d063cd8 268 str_cat(str,tokenbuf);
269 str_free(tmpstr);
270 str_cat(str,"/");
271 break;
272 case OHUNK:
273 if (len == 1) {
274 str = str_new(0);
a687059c 275 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
8d063cd8 276 str_cat(str," if ");
a687059c 277 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 278 str_free(fstr);
279 str_cat(str,";");
280 }
281 else {
a687059c 282 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 283 if (*tmpstr->str_ptr) {
284 str = str_new(0);
285 str_set(str,"if (");
286 str_scat(str,tmpstr);
287 str_cat(str,") {\n");
288 tab(str,++level);
a687059c 289 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 290 str_free(fstr);
291 fixtab(str,--level);
292 str_cat(str,"}\n");
293 tab(str,level);
294 }
295 else {
a687059c 296 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 297 }
298 }
299 break;
300 case OPPAREN:
301 str = str_new(0);
302 str_set(str,"(");
a687059c 303 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 304 str_free(fstr);
305 str_cat(str,")");
306 break;
307 case OPANDAND:
a687059c 308 prec = P_ANDAND;
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 OPOROR:
a687059c 317 prec = P_OROR;
318 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 319 str_cat(str," || ");
a687059c 320 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
321 str_free(fstr);
322 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 323 str_free(fstr);
324 break;
325 case OPNOT:
a687059c 326 prec = P_UNARY;
8d063cd8 327 str = str_new(0);
328 str_set(str,"!");
a687059c 329 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 330 str_free(fstr);
331 break;
62b28dd9 332 case OCOND:
333 prec = P_COND;
334 str = walk(1,level,ops[node+1].ival,&numarg,prec);
335 str_cat(str," ? ");
336 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
337 str_free(fstr);
338 str_cat(str," : ");
339 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
340 str_free(fstr);
341 break;
8d063cd8 342 case OCPAREN:
343 str = str_new(0);
344 str_set(str,"(");
a687059c 345 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 346 str_free(fstr);
347 numeric |= numarg;
348 str_cat(str,")");
349 break;
350 case OCANDAND:
a687059c 351 prec = P_ANDAND;
352 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 353 numeric = 1;
354 str_cat(str," && ");
a687059c 355 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
356 str_free(fstr);
357 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 358 str_free(fstr);
359 break;
360 case OCOROR:
a687059c 361 prec = P_OROR;
362 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 363 numeric = 1;
364 str_cat(str," || ");
a687059c 365 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
366 str_free(fstr);
367 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 368 str_free(fstr);
369 break;
370 case OCNOT:
a687059c 371 prec = P_UNARY;
8d063cd8 372 str = str_new(0);
373 str_set(str,"!");
a687059c 374 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 375 str_free(fstr);
376 numeric = 1;
377 break;
378 case ORELOP:
a687059c 379 prec = P_REL;
380 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 381 numeric |= numarg;
a687059c 382 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
383 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
8d063cd8 384 numeric |= numarg;
a687059c 385 if (!numeric ||
386 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
8d063cd8 387 t = tmpstr->str_ptr;
388 if (strEQ(t,"=="))
389 str_set(tmpstr,"eq");
390 else if (strEQ(t,"!="))
391 str_set(tmpstr,"ne");
392 else if (strEQ(t,"<"))
393 str_set(tmpstr,"lt");
394 else if (strEQ(t,"<="))
395 str_set(tmpstr,"le");
396 else if (strEQ(t,">"))
397 str_set(tmpstr,"gt");
398 else if (strEQ(t,">="))
399 str_set(tmpstr,"ge");
400 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
401 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
402 numeric |= 2;
403 }
404 if (numeric & 2) {
405 if (numeric & 1) /* numeric is very good guess */
406 str_cat(str," ");
407 else
408 str_cat(str,"\377");
409 numeric = 1;
410 }
411 else
412 str_cat(str," ");
413 str_scat(str,tmpstr);
414 str_free(tmpstr);
415 str_cat(str," ");
416 str_scat(str,tmp2str);
417 str_free(tmp2str);
418 numeric = 1;
419 break;
420 case ORPAREN:
421 str = str_new(0);
422 str_set(str,"(");
a687059c 423 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 424 str_free(fstr);
425 numeric |= numarg;
426 str_cat(str,")");
427 break;
428 case OMATCHOP:
a687059c 429 prec = P_MATCH;
430 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 431 str_cat(str," ");
a687059c 432 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 433 if (strEQ(tmpstr->str_ptr,"~"))
434 str_cat(str,"=~");
435 else {
436 str_scat(str,tmpstr);
437 str_free(tmpstr);
438 }
439 str_cat(str," ");
a687059c 440 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8 441 str_free(fstr);
442 numeric = 1;
443 break;
444 case OMPAREN:
445 str = str_new(0);
446 str_set(str,"(");
a687059c 447 str_scat(str,
448 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 449 str_free(fstr);
450 numeric |= numarg;
451 str_cat(str,")");
452 break;
453 case OCONCAT:
a687059c 454 prec = P_ADD;
455 type = ops[ops[node+1].ival].ival & 255;
456 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
8d063cd8 457 str_cat(str," . ");
a687059c 458 type = ops[ops[node+2].ival].ival & 255;
459 str_scat(str,
460 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
8d063cd8 461 str_free(fstr);
462 break;
463 case OASSIGN:
a687059c 464 prec = P_ASSIGN;
465 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
8d063cd8 466 str_cat(str," ");
a687059c 467 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 468 str_scat(str,tmpstr);
469 if (str_len(tmpstr) > 1)
470 numeric = 1;
471 str_free(tmpstr);
472 str_cat(str," ");
a687059c 473 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
8d063cd8 474 str_free(fstr);
475 numeric |= numarg;
7c0587c8 476 if (strEQ(str->str_ptr,"$/ = ''"))
477 str_set(str, "$/ = \"\\n\\n\"");
8d063cd8 478 break;
479 case OADD:
a687059c 480 prec = P_ADD;
481 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 482 str_cat(str," + ");
a687059c 483 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 484 str_free(fstr);
485 numeric = 1;
486 break;
a687059c 487 case OSUBTRACT:
488 prec = P_ADD;
489 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 490 str_cat(str," - ");
a687059c 491 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 492 str_free(fstr);
493 numeric = 1;
494 break;
495 case OMULT:
a687059c 496 prec = P_MUL;
497 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 498 str_cat(str," * ");
a687059c 499 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 500 str_free(fstr);
501 numeric = 1;
502 break;
503 case ODIV:
a687059c 504 prec = P_MUL;
505 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 506 str_cat(str," / ");
a687059c 507 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
508 str_free(fstr);
509 numeric = 1;
510 break;
511 case OPOW:
512 prec = P_POW;
513 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
514 str_cat(str," ** ");
515 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
8d063cd8 516 str_free(fstr);
517 numeric = 1;
518 break;
519 case OMOD:
a687059c 520 prec = P_MUL;
521 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 522 str_cat(str," % ");
a687059c 523 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
8d063cd8 524 str_free(fstr);
525 numeric = 1;
526 break;
527 case OPOSTINCR:
a687059c 528 prec = P_AUTO;
529 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 530 str_cat(str,"++");
531 numeric = 1;
532 break;
533 case OPOSTDECR:
a687059c 534 prec = P_AUTO;
535 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
8d063cd8 536 str_cat(str,"--");
537 numeric = 1;
538 break;
539 case OPREINCR:
a687059c 540 prec = P_AUTO;
8d063cd8 541 str = str_new(0);
542 str_set(str,"++");
a687059c 543 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 544 str_free(fstr);
545 numeric = 1;
546 break;
547 case OPREDECR:
a687059c 548 prec = P_AUTO;
8d063cd8 549 str = str_new(0);
550 str_set(str,"--");
a687059c 551 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 552 str_free(fstr);
553 numeric = 1;
554 break;
555 case OUMINUS:
a687059c 556 prec = P_UNARY;
8d063cd8 557 str = str_new(0);
558 str_set(str,"-");
a687059c 559 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
8d063cd8 560 str_free(fstr);
561 numeric = 1;
562 break;
563 case OUPLUS:
564 numeric = 1;
565 goto def;
566 case OPAREN:
567 str = str_new(0);
568 str_set(str,"(");
a687059c 569 str_scat(str,
570 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 571 str_free(fstr);
572 str_cat(str,")");
573 numeric |= numarg;
574 break;
575 case OGETLINE:
576 str = str_new(0);
a687059c 577 if (useval)
578 str_cat(str,"(");
579 if (len > 0) {
a687059c 580 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
581 if (!*fstr->str_ptr) {
7c0587c8 582 str_cat(str,"$_");
a687059c 583 len = 2; /* a legal fiction */
584 }
585 str_free(fstr);
586 }
587 else
588 str_cat(str,"$_");
589 if (len > 1) {
590 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
591 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
592 if (!do_fancy_opens) {
593 t = tmpstr->str_ptr;
594 if (*t == '"' || *t == '\'')
595 t = cpytill(tokenbuf,t+1,*t);
596 else
597 fatal("Internal error: OGETLINE %s", t);
598 d = savestr(t);
599 s = savestr(tokenbuf);
600 for (t = tokenbuf; *t; t++) {
601 *t &= 127;
d48672a2 602 if (islower(*t))
603 *t = toupper(*t);
a687059c 604 if (!isalpha(*t) && !isdigit(*t))
605 *t = '_';
606 }
607 if (!index(tokenbuf,'_'))
d48672a2 608 strcpy(t,"_FH");
a687059c 609 tmp3str = hfetch(symtab,tokenbuf);
610 if (!tmp3str) {
611 do_opens = TRUE;
612 str_cat(opens,"open(");
613 str_cat(opens,tokenbuf);
614 str_cat(opens,", ");
615 d[1] = '\0';
616 str_cat(opens,d);
617 str_cat(opens,tmpstr->str_ptr+1);
618 opens->str_cur--;
619 if (*fstr->str_ptr == '|')
620 str_cat(opens,"|");
621 str_cat(opens,d);
622 if (*fstr->str_ptr == '|')
623 str_cat(opens,") || die 'Cannot pipe from \"");
624 else
625 str_cat(opens,") || die 'Cannot open file \"");
626 if (*d == '"')
627 str_cat(opens,"'.\"");
628 str_cat(opens,s);
629 if (*d == '"')
630 str_cat(opens,"\".'");
631 str_cat(opens,"\".';\n");
632 hstore(symtab,tokenbuf,str_make("x"));
633 }
634 safefree(s);
635 safefree(d);
636 str_set(tmpstr,"'");
637 str_cat(tmpstr,tokenbuf);
638 str_cat(tmpstr,"'");
639 }
640 if (*fstr->str_ptr == '|')
641 str_cat(tmpstr,", '|'");
642 str_free(fstr);
643 }
644 else
645 tmpstr = str_make("");
646 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
647 str_cat(str,tokenbuf);
648 str_free(tmpstr);
649 if (useval)
650 str_cat(str,",$getline_ok)");
651 saw_getline |= 1 << len;
8d063cd8 652 break;
653 case OSPRINTF:
654 str = str_new(0);
655 str_set(str,"sprintf(");
a687059c 656 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 657 str_free(fstr);
658 str_cat(str,")");
659 break;
660 case OSUBSTR:
661 str = str_new(0);
662 str_set(str,"substr(");
a687059c 663 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
8d063cd8 664 str_free(fstr);
665 str_cat(str,", ");
a687059c 666 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
8d063cd8 667 str_free(fstr);
668 str_cat(str,", ");
669 if (len == 3) {
a687059c 670 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
8d063cd8 671 str_free(fstr);
672 }
673 else
674 str_cat(str,"999999");
675 str_cat(str,")");
676 break;
677 case OSTRING:
678 str = str_new(0);
679 str_set(str,ops[node+1].cval);
680 break;
681 case OSPLIT:
682 str = str_new(0);
55204971 683 limit = ", 9999)";
8d063cd8 684 numeric = 1;
a687059c 685 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 686 if (useval)
687 str_set(str,"(@");
688 else
689 str_set(str,"@");
690 str_scat(str,tmpstr);
691 str_cat(str," = split(");
692 if (len == 3) {
a687059c 693 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
8d063cd8 694 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
695 i = fstr->str_ptr[1] & 127;
696 if (index("*+?.[]()|^$\\",i))
697 sprintf(tokenbuf,"/\\%c/",i);
20188a90 698 else if (i == ' ')
62b28dd9 699 sprintf(tokenbuf,"' '");
8d063cd8 700 else
701 sprintf(tokenbuf,"/%c/",i);
702 str_cat(str,tokenbuf);
703 }
704 else
705 str_scat(str,fstr);
706 str_free(fstr);
707 }
708 else if (const_FS) {
709 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
710 str_cat(str,tokenbuf);
711 }
712 else if (saw_FS)
713 str_cat(str,"$FS");
55204971 714 else {
9bb9d9f7 715 str_cat(str,"' '");
55204971 716 limit = ")";
717 }
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);
55204971 721 str_cat(str,limit);
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) {
fe14fcc3 941 case '\\': case '"': case 'n': case 't': case '$':
378cc40b 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;
d48672a2 1133 if (islower(*t))
1134 *t = toupper(*t);
a687059c 1135 if (!isalpha(*t) && !isdigit(*t))
1136 *t = '_';
1137 }
1138 if (!index(tokenbuf,'_'))
d48672a2 1139 strcpy(t,"_FH");
a687059c 1140 str_free(tmpstr);
1141 safefree(s);
1142 str_set(str,"close ");
1143 str_cat(str,tokenbuf);
1144 }
1145 else {
7c0587c8 1146 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1147 tmpstr->str_ptr, tmpstr->str_ptr);
a687059c 1148 str_free(tmpstr);
1149 str_set(str,tokenbuf);
1150 }
1151 break;
8d063cd8 1152 case OPRINTF:
1153 case OPRINT:
378cc40b 1154 lparen = ""; /* set to parens if necessary */
1155 rparen = "";
8d063cd8 1156 str = str_new(0);
1157 if (len == 3) { /* output redirection */
a687059c 1158 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1159 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1160 if (!do_fancy_opens) {
1161 t = tmpstr->str_ptr;
1162 if (*t == '"' || *t == '\'')
1163 t = cpytill(tokenbuf,t+1,*t);
1164 else
1165 fatal("Internal error: OPRINT");
1166 d = savestr(t);
1167 s = savestr(tokenbuf);
1168 for (t = tokenbuf; *t; t++) {
1169 *t &= 127;
d48672a2 1170 if (islower(*t))
1171 *t = toupper(*t);
8d063cd8 1172 if (!isalpha(*t) && !isdigit(*t))
1173 *t = '_';
1174 }
1175 if (!index(tokenbuf,'_'))
d48672a2 1176 strcpy(t,"_FH");
a687059c 1177 tmp3str = hfetch(symtab,tokenbuf);
1178 if (!tmp3str) {
1179 str_cat(opens,"open(");
1180 str_cat(opens,tokenbuf);
1181 str_cat(opens,", ");
1182 d[1] = '\0';
1183 str_cat(opens,d);
1184 str_scat(opens,tmp2str);
1185 str_cat(opens,tmpstr->str_ptr+1);
1186 if (*tmp2str->str_ptr == '|')
1187 str_cat(opens,") || die 'Cannot pipe to \"");
1188 else
1189 str_cat(opens,") || die 'Cannot create file \"");
1190 if (*d == '"')
1191 str_cat(opens,"'.\"");
1192 str_cat(opens,s);
1193 if (*d == '"')
1194 str_cat(opens,"\".'");
1195 str_cat(opens,"\".';\n");
1196 hstore(symtab,tokenbuf,str_make("x"));
1197 }
8d063cd8 1198 str_free(tmpstr);
1199 str_free(tmp2str);
1200 safefree(s);
1201 safefree(d);
1202 }
1203 else {
a687059c 1204 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8 1205 tmp2str->str_ptr, tmpstr->str_ptr);
1206 str_cat(str,tokenbuf);
1207 tab(str,level+1);
a687059c 1208 strcpy(tokenbuf,"$fh");
8d063cd8 1209 str_free(tmpstr);
1210 str_free(tmp2str);
378cc40b 1211 lparen = "(";
1212 rparen = ")";
8d063cd8 1213 }
1214 }
1215 else
a687059c 1216 strcpy(tokenbuf,"");
378cc40b 1217 str_cat(str,lparen); /* may be null */
8d063cd8 1218 if (type == OPRINTF)
1219 str_cat(str,"printf");
1220 else
1221 str_cat(str,"print");
d48672a2 1222 saw_fh = 0;
8d063cd8 1223 if (len == 3 || do_fancy_opens) {
d48672a2 1224 if (*tokenbuf) {
8d063cd8 1225 str_cat(str," ");
d48672a2 1226 saw_fh = 1;
1227 }
8d063cd8 1228 str_cat(str,tokenbuf);
1229 }
a687059c 1230 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1231 if (!*tmpstr->str_ptr && lval_field) {
1232 t = saw_OFS ? "$," : "' '";
1233 if (split_to_array) {
1234 sprintf(tokenbuf,"join(%s,@Fld)",t);
1235 str_cat(tmpstr,tokenbuf);
1236 }
1237 else {
1238 for (i = 1; i < maxfld; i++) {
1239 if (i <= arymax)
1240 sprintf(tokenbuf,"$%s, ",nameary[i]);
1241 else
1242 sprintf(tokenbuf,"$Fld%d, ",i);
1243 str_cat(tmpstr,tokenbuf);
1244 }
1245 if (maxfld <= arymax)
1246 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1247 else
1248 sprintf(tokenbuf,"$Fld%d",maxfld);
1249 str_cat(tmpstr,tokenbuf);
1250 }
1251 }
1252 if (*tmpstr->str_ptr) {
1253 str_cat(str," ");
d48672a2 1254 if (!saw_fh && *tmpstr->str_ptr == '(') {
1255 str_cat(str,"(");
1256 str_scat(str,tmpstr);
1257 str_cat(str,")");
1258 }
1259 else
1260 str_scat(str,tmpstr);
8d063cd8 1261 }
1262 else {
1263 str_cat(str," $_");
1264 }
378cc40b 1265 str_cat(str,rparen); /* may be null */
8d063cd8 1266 str_free(tmpstr);
1267 break;
a687059c 1268 case ORAND:
1269 str = str_make("rand(1)");
1270 break;
1271 case OSRAND:
1272 str = str_make("srand(");
1273 goto maybe0;
1274 case OATAN2:
1275 str = str_make("atan2(");
1276 goto maybe0;
1277 case OSIN:
1278 str = str_make("sin(");
1279 goto maybe0;
1280 case OCOS:
1281 str = str_make("cos(");
1282 goto maybe0;
1283 case OSYSTEM:
1284 str = str_make("system(");
1285 goto maybe0;
8d063cd8 1286 case OLENGTH:
1287 str = str_make("length(");
1288 goto maybe0;
1289 case OLOG:
1290 str = str_make("log(");
1291 goto maybe0;
1292 case OEXP:
1293 str = str_make("exp(");
1294 goto maybe0;
1295 case OSQRT:
1296 str = str_make("sqrt(");
1297 goto maybe0;
1298 case OINT:
1299 str = str_make("int(");
1300 maybe0:
1301 numeric = 1;
1302 if (len > 0)
a687059c 1303 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1304 else
1305 tmpstr = str_new(0);;
fe14fcc3 1306 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
8d063cd8 1307 if (lval_field) {
1308 t = saw_OFS ? "$," : "' '";
1309 if (split_to_array) {
1310 sprintf(tokenbuf,"join(%s,@Fld)",t);
1311 str_cat(tmpstr,tokenbuf);
1312 }
1313 else {
1314 sprintf(tokenbuf,"join(%s, ",t);
1315 str_cat(tmpstr,tokenbuf);
1316 for (i = 1; i < maxfld; i++) {
1317 if (i <= arymax)
1318 sprintf(tokenbuf,"$%s,",nameary[i]);
1319 else
1320 sprintf(tokenbuf,"$Fld%d,",i);
1321 str_cat(tmpstr,tokenbuf);
1322 }
1323 if (maxfld <= arymax)
1324 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1325 else
1326 sprintf(tokenbuf,"$Fld%d)",maxfld);
1327 str_cat(tmpstr,tokenbuf);
1328 }
1329 }
1330 else
1331 str_cat(tmpstr,"$_");
1332 }
1333 if (strEQ(tmpstr->str_ptr,"$_")) {
1334 if (type == OLENGTH && !do_chop) {
1335 str = str_make("(length(");
1336 str_cat(tmpstr,") - 1");
1337 }
1338 }
1339 str_scat(str,tmpstr);
1340 str_free(tmpstr);
1341 str_cat(str,")");
1342 break;
1343 case OBREAK:
1344 str = str_new(0);
1345 str_set(str,"last");
1346 break;
1347 case ONEXT:
1348 str = str_new(0);
1349 str_set(str,"next line");
1350 break;
1351 case OEXIT:
1352 str = str_new(0);
1353 if (realexit) {
a687059c 1354 prec = P_UNI;
8d063cd8 1355 str_set(str,"exit");
1356 if (len == 1) {
1357 str_cat(str," ");
1358 exitval = TRUE;
a687059c 1359 str_scat(str,
1360 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8 1361 str_free(fstr);
1362 }
1363 }
1364 else {
1365 if (len == 1) {
9f68db38 1366 str_set(str,"$ExitValue = ");
8d063cd8 1367 exitval = TRUE;
a687059c 1368 str_scat(str,
1369 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
8d063cd8 1370 str_free(fstr);
1371 str_cat(str,"; ");
1372 }
1373 str_cat(str,"last line");
1374 }
1375 break;
1376 case OCONTINUE:
1377 str = str_new(0);
1378 str_set(str,"next");
1379 break;
1380 case OREDIR:
1381 goto def;
1382 case OIF:
1383 str = str_new(0);
1384 str_set(str,"if (");
a687059c 1385 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1386 str_free(fstr);
1387 str_cat(str,") ");
a687059c 1388 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1389 str_free(fstr);
1390 if (len == 3) {
1391 i = ops[node+3].ival;
1392 if (i) {
1393 if ((ops[i].ival & 255) == OBLOCK) {
1394 i = ops[i+1].ival;
1395 if (i) {
1396 if ((ops[i].ival & 255) != OIF)
1397 i = 0;
1398 }
1399 }
1400 else
1401 i = 0;
1402 }
1403 if (i) {
1404 str_cat(str,"els");
a687059c 1405 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
8d063cd8 1406 str_free(fstr);
1407 }
1408 else {
1409 str_cat(str,"else ");
a687059c 1410 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1411 str_free(fstr);
1412 }
1413 }
1414 break;
1415 case OWHILE:
1416 str = str_new(0);
1417 str_set(str,"while (");
a687059c 1418 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1419 str_free(fstr);
1420 str_cat(str,") ");
a687059c 1421 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1422 str_free(fstr);
1423 break;
7c0587c8 1424 case ODO:
1425 str = str_new(0);
1426 str_set(str,"do ");
1427 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1428 str_free(fstr);
1429 if (str->str_ptr[str->str_cur - 1] == '\n')
1430 --str->str_cur;;
1431 str_cat(str," while (");
1432 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1433 str_free(fstr);
1434 str_cat(str,");");
1435 break;
8d063cd8 1436 case OFOR:
1437 str = str_new(0);
1438 str_set(str,"for (");
a687059c 1439 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1440 i = numarg;
1441 if (i) {
1442 t = s = tmpstr->str_ptr;
1443 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1444 t++;
1445 i = t - s;
1446 if (i < 2)
1447 i = 0;
1448 }
1449 str_cat(str,"; ");
a687059c 1450 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8 1451 if (i && (t = index(fstr->str_ptr,0377))) {
1452 if (strnEQ(fstr->str_ptr,s,i))
1453 *t = ' ';
1454 }
1455 str_scat(str,fstr);
1456 str_free(fstr);
1457 str_free(tmpstr);
1458 str_cat(str,"; ");
a687059c 1459 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8 1460 str_free(fstr);
1461 str_cat(str,") ");
a687059c 1462 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8 1463 str_free(fstr);
1464 break;
1465 case OFORIN:
a687059c 1466 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1467 d = index(tmpstr->str_ptr,'$');
1468 if (!d)
1469 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1470 s = index(d,'{');
1471 if (!s)
1472 s = index(d,'[');
1473 if (!s)
1474 fatal("Illegal for loop: %s",d);
1475 *s++ = '\0';
ffed7fef 1476 for (t = s; i = *t; t++) {
1477 i &= 127;
1478 if (i == '}' || i == ']')
1479 break;
1480 }
1481 if (*t)
a687059c 1482 *t = '\0';
8d063cd8 1483 str = str_new(0);
a687059c 1484 str_set(str,d+1);
8d063cd8 1485 str_cat(str,"[]");
1486 tmp2str = hfetch(symtab,str->str_ptr);
1487 if (tmp2str && atoi(tmp2str->str_ptr)) {
8d063cd8 1488 sprintf(tokenbuf,
62b28dd9 1489 "foreach %s ($[ .. $#%s) ",
a687059c 1490 s,
1491 d+1);
8d063cd8 1492 }
1493 else {
a687059c 1494 sprintf(tokenbuf,
1495 "foreach %s (keys %%%s) ",
1496 s,
1497 d+1);
8d063cd8 1498 }
a687059c 1499 str_set(str,tokenbuf);
1500 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1501 str_free(fstr);
8d063cd8 1502 str_free(tmpstr);
1503 break;
1504 case OBLOCK:
1505 str = str_new(0);
1506 str_set(str,"{");
378cc40b 1507 if (len >= 2 && ops[node+2].ival) {
a687059c 1508 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 1509 str_free(fstr);
1510 }
1511 fixtab(str,++level);
a687059c 1512 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8 1513 str_free(fstr);
1514 addsemi(str);
1515 fixtab(str,--level);
1516 str_cat(str,"}\n");
1517 tab(str,level);
378cc40b 1518 if (len >= 3) {
a687059c 1519 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
378cc40b 1520 str_free(fstr);
1521 }
8d063cd8 1522 break;
1523 default:
1524 def:
1525 if (len) {
1526 if (len > 5)
1527 fatal("Garbage length in walk");
a687059c 1528 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1529 for (i = 2; i<= len; i++) {
a687059c 1530 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
8d063cd8 1531 str_free(fstr);
1532 }
1533 }
1534 else {
1535 str = Nullstr;
1536 }
1537 break;
1538 }
1539 if (!str)
1540 str = str_new(0);
a687059c 1541
1542 if (useval && prec < minprec) { /* need parens? */
1543 fstr = str_new(str->str_cur+2);
1544 str_nset(fstr,"(",1);
1545 str_scat(fstr,str);
1546 str_ncat(fstr,")",1);
1547 str_free(str);
1548 str = fstr;
1549 }
1550
8d063cd8 1551 *numericptr = numeric;
1552#ifdef DEBUGGING
1553 if (debug & 4) {
1554 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1555 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1556 if (*t == '\n')
1557 printf("\\n");
1558 else if (*t == '\t')
1559 printf("\\t");
1560 else
1561 putchar(*t);
1562 putchar('\n');
1563 }
1564#endif
1565 return str;
1566}
1567
1568tab(str,lvl)
1569register STR *str;
1570register int lvl;
1571{
1572 while (lvl > 1) {
1573 str_cat(str,"\t");
1574 lvl -= 2;
1575 }
1576 if (lvl)
1577 str_cat(str," ");
1578}
1579
1580fixtab(str,lvl)
1581register STR *str;
1582register int lvl;
1583{
1584 register char *s;
1585
1586 /* strip trailing white space */
1587
1588 s = str->str_ptr+str->str_cur - 1;
a687059c 1589 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
8d063cd8 1590 s--;
1591 s[1] = '\0';
1592 str->str_cur = s + 1 - str->str_ptr;
1593 if (s >= str->str_ptr && *s != '\n')
1594 str_cat(str,"\n");
1595
1596 tab(str,lvl);
1597}
1598
1599addsemi(str)
1600register STR *str;
1601{
1602 register char *s;
1603
1604 s = str->str_ptr+str->str_cur - 1;
1605 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1606 s--;
1607 if (s >= str->str_ptr && *s != ';' && *s != '}')
1608 str_cat(str,";");
1609}
1610
1611emit_split(str,level)
1612register STR *str;
1613int level;
1614{
1615 register int i;
1616
1617 if (split_to_array)
1618 str_cat(str,"@Fld");
1619 else {
1620 str_cat(str,"(");
1621 for (i = 1; i < maxfld; i++) {
1622 if (i <= arymax)
1623 sprintf(tokenbuf,"$%s,",nameary[i]);
1624 else
1625 sprintf(tokenbuf,"$Fld%d,",i);
1626 str_cat(str,tokenbuf);
1627 }
1628 if (maxfld <= arymax)
1629 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1630 else
1631 sprintf(tokenbuf,"$Fld%d)",maxfld);
1632 str_cat(str,tokenbuf);
1633 }
1634 if (const_FS) {
62b28dd9 1635 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
8d063cd8 1636 str_cat(str,tokenbuf);
1637 }
1638 else if (saw_FS)
62b28dd9 1639 str_cat(str," = split($FS, $_, 9999);\n");
8d063cd8 1640 else
62b28dd9 1641 str_cat(str," = split(' ', $_, 9999);\n");
8d063cd8 1642 tab(str,level);
1643}
1644
1645prewalk(numit,level,node,numericptr)
1646int numit;
1647int level;
1648register int node;
1649int *numericptr;
1650{
1651 register int len;
1652 register int type;
1653 register int i;
1654 char *t;
1655 char *d, *s;
1656 int numarg;
1657 int numeric = FALSE;
a687059c 1658 STR *tmpstr;
1659 STR *tmp2str;
8d063cd8 1660
1661 if (!node) {
1662 *numericptr = 0;
1663 return 0;
1664 }
1665 type = ops[node].ival;
1666 len = type >> 8;
1667 type &= 255;
1668 switch (type) {
1669 case OPROG:
1670 prewalk(0,level,ops[node+1].ival,&numarg);
1671 if (ops[node+2].ival) {
1672 prewalk(0,level,ops[node+2].ival,&numarg);
1673 }
1674 ++level;
1675 prewalk(0,level,ops[node+3].ival,&numarg);
1676 --level;
1677 if (ops[node+3].ival) {
1678 prewalk(0,level,ops[node+4].ival,&numarg);
1679 }
1680 break;
1681 case OHUNKS:
1682 prewalk(0,level,ops[node+1].ival,&numarg);
1683 prewalk(0,level,ops[node+2].ival,&numarg);
1684 if (len == 3) {
1685 prewalk(0,level,ops[node+3].ival,&numarg);
1686 }
1687 break;
1688 case ORANGE:
1689 prewalk(1,level,ops[node+1].ival,&numarg);
1690 prewalk(1,level,ops[node+2].ival,&numarg);
1691 break;
1692 case OPAT:
1693 goto def;
1694 case OREGEX:
1695 prewalk(0,level,ops[node+1].ival,&numarg);
1696 break;
1697 case OHUNK:
1698 if (len == 1) {
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1700 }
1701 else {
1702 i = prewalk(0,level,ops[node+1].ival,&numarg);
1703 if (i) {
1704 ++level;
1705 prewalk(0,level,ops[node+2].ival,&numarg);
1706 --level;
1707 }
1708 else {
1709 prewalk(0,level,ops[node+2].ival,&numarg);
1710 }
1711 }
1712 break;
1713 case OPPAREN:
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1715 break;
1716 case OPANDAND:
1717 prewalk(0,level,ops[node+1].ival,&numarg);
1718 prewalk(0,level,ops[node+2].ival,&numarg);
1719 break;
1720 case OPOROR:
1721 prewalk(0,level,ops[node+1].ival,&numarg);
1722 prewalk(0,level,ops[node+2].ival,&numarg);
1723 break;
1724 case OPNOT:
1725 prewalk(0,level,ops[node+1].ival,&numarg);
1726 break;
1727 case OCPAREN:
1728 prewalk(0,level,ops[node+1].ival,&numarg);
1729 numeric |= numarg;
1730 break;
1731 case OCANDAND:
1732 prewalk(0,level,ops[node+1].ival,&numarg);
1733 numeric = 1;
1734 prewalk(0,level,ops[node+2].ival,&numarg);
1735 break;
1736 case OCOROR:
1737 prewalk(0,level,ops[node+1].ival,&numarg);
1738 numeric = 1;
1739 prewalk(0,level,ops[node+2].ival,&numarg);
1740 break;
1741 case OCNOT:
1742 prewalk(0,level,ops[node+1].ival,&numarg);
1743 numeric = 1;
1744 break;
1745 case ORELOP:
1746 prewalk(0,level,ops[node+2].ival,&numarg);
1747 numeric |= numarg;
1748 prewalk(0,level,ops[node+1].ival,&numarg);
1749 prewalk(0,level,ops[node+3].ival,&numarg);
1750 numeric |= numarg;
1751 numeric = 1;
1752 break;
1753 case ORPAREN:
1754 prewalk(0,level,ops[node+1].ival,&numarg);
1755 numeric |= numarg;
1756 break;
1757 case OMATCHOP:
1758 prewalk(0,level,ops[node+2].ival,&numarg);
1759 prewalk(0,level,ops[node+1].ival,&numarg);
1760 prewalk(0,level,ops[node+3].ival,&numarg);
1761 numeric = 1;
1762 break;
1763 case OMPAREN:
1764 prewalk(0,level,ops[node+1].ival,&numarg);
1765 numeric |= numarg;
1766 break;
1767 case OCONCAT:
1768 prewalk(0,level,ops[node+1].ival,&numarg);
1769 prewalk(0,level,ops[node+2].ival,&numarg);
1770 break;
1771 case OASSIGN:
1772 prewalk(0,level,ops[node+2].ival,&numarg);
1773 prewalk(0,level,ops[node+1].ival,&numarg);
1774 prewalk(0,level,ops[node+3].ival,&numarg);
1775 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1776 numericize(ops[node+2].ival);
1777 if (!numarg)
1778 numericize(ops[node+3].ival);
1779 }
1780 numeric |= numarg;
1781 break;
1782 case OADD:
1783 prewalk(1,level,ops[node+1].ival,&numarg);
1784 prewalk(1,level,ops[node+2].ival,&numarg);
1785 numeric = 1;
1786 break;
a687059c 1787 case OSUBTRACT:
8d063cd8 1788 prewalk(1,level,ops[node+1].ival,&numarg);
1789 prewalk(1,level,ops[node+2].ival,&numarg);
1790 numeric = 1;
1791 break;
1792 case OMULT:
1793 prewalk(1,level,ops[node+1].ival,&numarg);
1794 prewalk(1,level,ops[node+2].ival,&numarg);
1795 numeric = 1;
1796 break;
1797 case ODIV:
1798 prewalk(1,level,ops[node+1].ival,&numarg);
1799 prewalk(1,level,ops[node+2].ival,&numarg);
1800 numeric = 1;
1801 break;
a687059c 1802 case OPOW:
1803 prewalk(1,level,ops[node+1].ival,&numarg);
1804 prewalk(1,level,ops[node+2].ival,&numarg);
1805 numeric = 1;
1806 break;
8d063cd8 1807 case OMOD:
1808 prewalk(1,level,ops[node+1].ival,&numarg);
1809 prewalk(1,level,ops[node+2].ival,&numarg);
1810 numeric = 1;
1811 break;
1812 case OPOSTINCR:
1813 prewalk(1,level,ops[node+1].ival,&numarg);
1814 numeric = 1;
1815 break;
1816 case OPOSTDECR:
1817 prewalk(1,level,ops[node+1].ival,&numarg);
1818 numeric = 1;
1819 break;
1820 case OPREINCR:
1821 prewalk(1,level,ops[node+1].ival,&numarg);
1822 numeric = 1;
1823 break;
1824 case OPREDECR:
1825 prewalk(1,level,ops[node+1].ival,&numarg);
1826 numeric = 1;
1827 break;
1828 case OUMINUS:
1829 prewalk(1,level,ops[node+1].ival,&numarg);
1830 numeric = 1;
1831 break;
1832 case OUPLUS:
1833 prewalk(1,level,ops[node+1].ival,&numarg);
1834 numeric = 1;
1835 break;
1836 case OPAREN:
1837 prewalk(0,level,ops[node+1].ival,&numarg);
1838 numeric |= numarg;
1839 break;
1840 case OGETLINE:
1841 break;
1842 case OSPRINTF:
1843 prewalk(0,level,ops[node+1].ival,&numarg);
1844 break;
1845 case OSUBSTR:
1846 prewalk(0,level,ops[node+1].ival,&numarg);
1847 prewalk(1,level,ops[node+2].ival,&numarg);
1848 if (len == 3) {
1849 prewalk(1,level,ops[node+3].ival,&numarg);
1850 }
1851 break;
1852 case OSTRING:
1853 break;
1854 case OSPLIT:
1855 numeric = 1;
1856 prewalk(0,level,ops[node+2].ival,&numarg);
1857 if (len == 3)
1858 prewalk(0,level,ops[node+3].ival,&numarg);
1859 prewalk(0,level,ops[node+1].ival,&numarg);
1860 break;
1861 case OINDEX:
1862 prewalk(0,level,ops[node+1].ival,&numarg);
1863 prewalk(0,level,ops[node+2].ival,&numarg);
1864 numeric = 1;
1865 break;
a687059c 1866 case OMATCH:
1867 prewalk(0,level,ops[node+1].ival,&numarg);
1868 prewalk(0,level,ops[node+2].ival,&numarg);
1869 numeric = 1;
1870 break;
1871 case OUSERDEF:
1872 subretnum = FALSE;
1873 --level;
1874 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1875 ++level;
1876 prewalk(0,level,ops[node+2].ival,&numarg);
1877 prewalk(0,level,ops[node+4].ival,&numarg);
1878 prewalk(0,level,ops[node+5].ival,&numarg);
1879 --level;
1880 str_cat(tmpstr,"(");
1881 tmp2str = str_new(0);
1882 if (subretnum || numarg)
1883 str_set(tmp2str,"1");
1884 hstore(symtab,tmpstr->str_ptr,tmp2str);
1885 str_free(tmpstr);
1886 level++;
1887 break;
1888 case ORETURN:
1889 if (len > 0) {
1890 prewalk(0,level,ops[node+1].ival,&numarg);
1891 if (numarg)
1892 subretnum = TRUE;
1893 }
1894 break;
1895 case OUSERFUN:
1896 tmp2str = str_new(0);
1897 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
663a0e37 1898 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
a687059c 1899 str_free(tmpstr);
1900 str_cat(tmp2str,"(");
1901 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1902 if (tmpstr && tmpstr->str_ptr)
1903 numeric |= atoi(tmpstr->str_ptr);
1904 prewalk(0,level,ops[node+2].ival,&numarg);
1905 str_free(tmp2str);
1906 break;
1907 case OGSUB:
1908 case OSUB:
1909 if (len >= 3)
1910 prewalk(0,level,ops[node+3].ival,&numarg);
1911 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1912 prewalk(0,level,ops[node+1].ival,&numarg);
1913 numeric = 1;
1914 break;
8d063cd8 1915 case ONUM:
1916 prewalk(0,level,ops[node+1].ival,&numarg);
1917 numeric = 1;
1918 break;
1919 case OSTR:
1920 prewalk(0,level,ops[node+1].ival,&numarg);
1921 break;
a687059c 1922 case ODEFINED:
1923 case ODELETE:
1924 case OSTAR:
8d063cd8 1925 case OVAR:
1926 prewalk(0,level,ops[node+1].ival,&numarg);
1927 if (len == 1) {
1928 if (numit)
1929 numericize(node);
1930 }
1931 else {
1932 prewalk(0,level,ops[node+2].ival,&numarg);
1933 }
1934 break;
1935 case OFLD:
1936 prewalk(0,level,ops[node+1].ival,&numarg);
1937 break;
1938 case OVFLD:
1939 i = ops[node+1].ival;
1940 prewalk(0,level,i,&numarg);
1941 break;
1942 case OJUNK:
1943 goto def;
1944 case OSNEWLINE:
1945 break;
1946 case ONEWLINE:
1947 break;
1948 case OSCOMMENT:
1949 break;
1950 case OCOMMENT:
1951 break;
1952 case OCOMMA:
1953 prewalk(0,level,ops[node+1].ival,&numarg);
1954 prewalk(0,level,ops[node+2].ival,&numarg);
a687059c 1955 prewalk(0,level,ops[node+3].ival,&numarg);
8d063cd8 1956 break;
1957 case OSEMICOLON:
1958 break;
1959 case OSTATES:
1960 prewalk(0,level,ops[node+1].ival,&numarg);
1961 prewalk(0,level,ops[node+2].ival,&numarg);
1962 break;
1963 case OSTATE:
1964 if (len >= 1) {
1965 prewalk(0,level,ops[node+1].ival,&numarg);
1966 if (len >= 2) {
1967 prewalk(0,level,ops[node+2].ival,&numarg);
1968 }
1969 }
1970 break;
a687059c 1971 case OCLOSE:
1972 prewalk(0,level,ops[node+1].ival,&numarg);
1973 break;
8d063cd8 1974 case OPRINTF:
1975 case OPRINT:
1976 if (len == 3) { /* output redirection */
1977 prewalk(0,level,ops[node+3].ival,&numarg);
1978 prewalk(0,level,ops[node+2].ival,&numarg);
1979 }
1980 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1981 break;
a687059c 1982 case ORAND:
1983 break;
1984 case OSRAND:
1985 goto maybe0;
1986 case OATAN2:
1987 goto maybe0;
1988 case OSIN:
1989 goto maybe0;
1990 case OCOS:
1991 goto maybe0;
1992 case OSYSTEM:
1993 goto maybe0;
8d063cd8 1994 case OLENGTH:
1995 goto maybe0;
1996 case OLOG:
1997 goto maybe0;
1998 case OEXP:
1999 goto maybe0;
2000 case OSQRT:
2001 goto maybe0;
2002 case OINT:
2003 maybe0:
2004 numeric = 1;
2005 if (len > 0)
a687059c 2006 prewalk(type != OLENGTH && type != OSYSTEM,
2007 level,ops[node+1].ival,&numarg);
8d063cd8 2008 break;
2009 case OBREAK:
2010 break;
2011 case ONEXT:
2012 break;
2013 case OEXIT:
2014 if (len == 1) {
2015 prewalk(1,level,ops[node+1].ival,&numarg);
2016 }
2017 break;
2018 case OCONTINUE:
2019 break;
2020 case OREDIR:
2021 goto def;
2022 case OIF:
2023 prewalk(0,level,ops[node+1].ival,&numarg);
2024 prewalk(0,level,ops[node+2].ival,&numarg);
2025 if (len == 3) {
2026 prewalk(0,level,ops[node+3].ival,&numarg);
2027 }
2028 break;
2029 case OWHILE:
2030 prewalk(0,level,ops[node+1].ival,&numarg);
2031 prewalk(0,level,ops[node+2].ival,&numarg);
2032 break;
2033 case OFOR:
2034 prewalk(0,level,ops[node+1].ival,&numarg);
2035 prewalk(0,level,ops[node+2].ival,&numarg);
2036 prewalk(0,level,ops[node+3].ival,&numarg);
2037 prewalk(0,level,ops[node+4].ival,&numarg);
2038 break;
2039 case OFORIN:
2040 prewalk(0,level,ops[node+2].ival,&numarg);
2041 prewalk(0,level,ops[node+1].ival,&numarg);
8d063cd8 2042 break;
2043 case OBLOCK:
2044 if (len == 2) {
2045 prewalk(0,level,ops[node+2].ival,&numarg);
2046 }
2047 ++level;
2048 prewalk(0,level,ops[node+1].ival,&numarg);
2049 --level;
2050 break;
2051 default:
2052 def:
2053 if (len) {
2054 if (len > 5)
2055 fatal("Garbage length in prewalk");
2056 prewalk(0,level,ops[node+1].ival,&numarg);
2057 for (i = 2; i<= len; i++) {
2058 prewalk(0,level,ops[node+i].ival,&numarg);
2059 }
2060 }
2061 break;
2062 }
2063 *numericptr = numeric;
2064 return 1;
2065}
2066
2067numericize(node)
2068register int node;
2069{
2070 register int len;
2071 register int type;
2072 register int i;
2073 STR *tmpstr;
2074 STR *tmp2str;
2075 int numarg;
2076
2077 type = ops[node].ival;
2078 len = type >> 8;
2079 type &= 255;
2080 if (type == OVAR && len == 1) {
a687059c 2081 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 2082 tmp2str = str_make("1");
2083 hstore(symtab,tmpstr->str_ptr,tmp2str);
2084 }
2085}