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