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