This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
silence a compiler warning
[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;
378cc40b
LW
22char *lparen;
23char *rparen;
55204971 24char *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);
39char *instr(char *big, char *little);
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);
841 if (type == OSTR) {
842 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
843 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
844 if (*t == '&')
c5cf9ec2 845 *d++ = '$' + (char)128;
a687059c 846 else if (*t == '$')
c5cf9ec2 847 *d++ = '\\' + (char)128;
a687059c
LW
848 *d = *t + 128;
849 }
850 *d = '\0';
851 str_set(tmp2str,tokenbuf);
07409e01 852 s = (char *) (gsub ? "/g" : "/");
a687059c
LW
853 }
854 else {
855 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
856 str_set(tmp3str,"($s_ = '\"'.(");
857 str_scat(tmp3str,tmp2str);
858 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
859 str_set(tmp2str,"eval $s_");
07409e01 860 s = (char *) (gsub ? "/ge" : "/e");
a687059c
LW
861 i++;
862 }
0335b3e4 863 str_cat(tmp2str,s);
a687059c
LW
864 type = ops[ops[node+1].ival].ival;
865 len = type >> 8;
866 type &= 255;
867 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
868 if (type == OREGEX) {
869 if (useval && i)
870 str_cat(str,"(");
871 str_scat(str,tmp3str);
872 str_scat(str,tmpstr);
873 str_scat(str,fstr);
874 str_scat(str,tmp2str);
a687059c
LW
875 }
876 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
877 if (useval && i)
878 str_cat(str,"(");
879 str_scat(str,tmp3str);
880 str_scat(str,tmpstr);
881 str_cat(str,"/");
882 str_scat(str,fstr);
883 str_cat(str,"/");
884 str_scat(str,tmp2str);
a687059c
LW
885 }
886 else {
887 i++;
888 if (useval)
889 str_cat(str,"(");
890 str_cat(str,"$s = ");
891 str_scat(str,fstr);
892 str_cat(str,", ");
893 str_scat(str,tmp3str);
894 str_scat(str,tmpstr);
895 str_cat(str,"/$s/");
896 str_scat(str,tmp2str);
a687059c
LW
897 }
898 if (useval && i)
899 str_cat(str,")");
900 str_free(fstr);
901 str_free(tmpstr);
902 str_free(tmp2str);
903 str_free(tmp3str);
904 numeric = 1;
0335b3e4 905 break; }
8d063cd8 906 case ONUM:
a687059c 907 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
908 numeric = 1;
909 break;
910 case OSTR:
a687059c 911 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 912 s = "'";
378cc40b
LW
913 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
914 if (*t == '\'')
915 s = "\"";
916 else if (*t == '\\') {
8d063cd8 917 s = "\"";
378cc40b
LW
918 *d++ = *t++ + 128;
919 switch (*t) {
fe14fcc3 920 case '\\': case '"': case 'n': case 't': case '$':
378cc40b
LW
921 break;
922 default: /* hide this from perl */
c5cf9ec2 923 *d++ = '\\' + (char)128;
378cc40b
LW
924 }
925 }
926 *d = *t + 128;
8d063cd8 927 }
378cc40b 928 *d = '\0';
8d063cd8
LW
929 str = str_new(0);
930 str_set(str,s);
378cc40b 931 str_cat(str,tokenbuf);
8d063cd8
LW
932 str_free(tmpstr);
933 str_cat(str,s);
934 break;
a687059c
LW
935 case ODEFINED:
936 prec = P_UNI;
937 str = str_new(0);
938 str_set(str,"defined $");
939 goto addvar;
940 case ODELETE:
941 str = str_new(0);
942 str_set(str,"delete $");
943 goto addvar;
944 case OSTAR:
945 str = str_new(0);
946 str_set(str,"*");
947 goto addvar;
8d063cd8
LW
948 case OVAR:
949 str = str_new(0);
950 str_set(str,"$");
a687059c
LW
951 addvar:
952 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
953 if (len == 1) {
954 tmp2str = hfetch(symtab,tmpstr->str_ptr);
955 if (tmp2str && atoi(tmp2str->str_ptr))
956 numeric = 2;
a687059c
LW
957 if (strEQ(str->str_ptr,"$FNR")) {
958 numeric = 1;
959 saw_FNR++;
960 str_set(str,"($.-$FNRbase)");
961 }
962 else if (strEQ(str->str_ptr,"$NR")) {
8d063cd8
LW
963 numeric = 1;
964 str_set(str,"$.");
965 }
966 else if (strEQ(str->str_ptr,"$NF")) {
967 numeric = 1;
968 str_set(str,"$#Fld");
969 }
970 else if (strEQ(str->str_ptr,"$0"))
971 str_set(str,"$_");
a687059c
LW
972 else if (strEQ(str->str_ptr,"$ARGC"))
973 str_set(str,"($#ARGV+1)");
8d063cd8
LW
974 }
975 else {
a687059c
LW
976#ifdef NOTDEF
977 if (curargs) {
978 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
979 ??? if (instr(curargs->str_ptr,tokenbuf))
980 str_cat(str,"\377"); /* can't translate yet */
981 }
982#endif
8d063cd8
LW
983 str_cat(tmpstr,"[]");
984 tmp2str = hfetch(symtab,tmpstr->str_ptr);
985 if (tmp2str && atoi(tmp2str->str_ptr))
986 str_cat(str,"[");
987 else
988 str_cat(str,"{");
a687059c 989 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8 990 str_free(fstr);
a687059c
LW
991 if (strEQ(str->str_ptr,"$ARGV[0")) {
992 str_set(str,"$ARGV0");
993 saw_argv0++;
994 }
995 else {
996 if (tmp2str && atoi(tmp2str->str_ptr))
997 strcpy(tokenbuf,"]");
998 else
999 strcpy(tokenbuf,"}");
c5cf9ec2 1000 *tokenbuf += (char)128;
a687059c
LW
1001 str_cat(str,tokenbuf);
1002 }
8d063cd8
LW
1003 }
1004 str_free(tmpstr);
1005 break;
1006 case OFLD:
1007 str = str_new(0);
1008 if (split_to_array) {
1009 str_set(str,"$Fld");
1010 str_cat(str,"[");
a687059c 1011 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1012 str_free(fstr);
1013 str_cat(str,"]");
1014 }
1015 else {
a687059c 1016 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
8d063cd8
LW
1017 if (i <= arymax)
1018 sprintf(tokenbuf,"$%s",nameary[i]);
1019 else
1020 sprintf(tokenbuf,"$Fld%d",i);
1021 str_set(str,tokenbuf);
1022 }
1023 break;
1024 case OVFLD:
1025 str = str_new(0);
1026 str_set(str,"$Fld[");
1027 i = ops[node+1].ival;
1028 if ((ops[i].ival & 255) == OPAREN)
1029 i = ops[i+1].ival;
a687059c 1030 tmpstr=walk(1,level,i,&numarg,P_MIN);
8d063cd8
LW
1031 str_scat(str,tmpstr);
1032 str_free(tmpstr);
1033 str_cat(str,"]");
1034 break;
1035 case OJUNK:
1036 goto def;
1037 case OSNEWLINE:
1038 str = str_new(2);
1039 str_set(str,";\n");
1040 tab(str,level);
1041 break;
1042 case ONEWLINE:
1043 str = str_new(1);
1044 str_set(str,"\n");
1045 tab(str,level);
1046 break;
1047 case OSCOMMENT:
1048 str = str_new(0);
1049 str_set(str,";");
a687059c 1050 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1051 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
c5cf9ec2 1052 *s += (char)128;
8d063cd8
LW
1053 str_scat(str,tmpstr);
1054 str_free(tmpstr);
1055 tab(str,level);
1056 break;
1057 case OCOMMENT:
1058 str = str_new(0);
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 OCOMMA:
a687059c
LW
1067 prec = P_COMMA;
1068 str = walk(1,level,ops[node+1].ival,&numarg,prec);
8d063cd8 1069 str_cat(str,", ");
a687059c
LW
1070 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1071 str_free(fstr);
1072 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
8d063cd8
LW
1073 str_free(fstr);
1074 break;
1075 case OSEMICOLON:
1076 str = str_new(1);
a687059c
LW
1077 str_set(str,";\n");
1078 tab(str,level);
8d063cd8
LW
1079 break;
1080 case OSTATES:
a687059c
LW
1081 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1082 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1083 str_free(fstr);
1084 break;
1085 case OSTATE:
1086 str = str_new(0);
1087 if (len >= 1) {
a687059c 1088 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1089 str_free(fstr);
1090 if (len >= 2) {
a687059c 1091 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
1092 if (*tmpstr->str_ptr == ';') {
1093 addsemi(str);
1094 str_cat(str,tmpstr->str_ptr+1);
1095 }
1096 str_free(tmpstr);
1097 }
1098 }
1099 break;
a687059c
LW
1100 case OCLOSE:
1101 str = str_make("close(");
1102 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1103 if (!do_fancy_opens) {
1104 t = tmpstr->str_ptr;
1105 if (*t == '"' || *t == '\'')
1106 t = cpytill(tokenbuf,t+1,*t);
1107 else
1108 fatal("Internal error: OCLOSE %s",t);
1109 s = savestr(tokenbuf);
1110 for (t = tokenbuf; *t; t++) {
1111 *t &= 127;
3f939f22
JH
1112 if (isLOWER(*t))
1113 *t = toUPPER(*t);
1114 if (!isALPHA(*t) && !isDIGIT(*t))
a687059c
LW
1115 *t = '_';
1116 }
a0d0e21e 1117 if (!strchr(tokenbuf,'_'))
d48672a2 1118 strcpy(t,"_FH");
a687059c
LW
1119 str_free(tmpstr);
1120 safefree(s);
1121 str_set(str,"close ");
1122 str_cat(str,tokenbuf);
1123 }
1124 else {
7c0587c8
LW
1125 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1126 tmpstr->str_ptr, tmpstr->str_ptr);
a687059c
LW
1127 str_free(tmpstr);
1128 str_set(str,tokenbuf);
1129 }
1130 break;
8d063cd8
LW
1131 case OPRINTF:
1132 case OPRINT:
378cc40b
LW
1133 lparen = ""; /* set to parens if necessary */
1134 rparen = "";
8d063cd8
LW
1135 str = str_new(0);
1136 if (len == 3) { /* output redirection */
a687059c
LW
1137 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1138 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
8d063cd8
LW
1139 if (!do_fancy_opens) {
1140 t = tmpstr->str_ptr;
1141 if (*t == '"' || *t == '\'')
1142 t = cpytill(tokenbuf,t+1,*t);
1143 else
1144 fatal("Internal error: OPRINT");
1145 d = savestr(t);
1146 s = savestr(tokenbuf);
1147 for (t = tokenbuf; *t; t++) {
1148 *t &= 127;
3f939f22
JH
1149 if (isLOWER(*t))
1150 *t = toUPPER(*t);
1151 if (!isALPHA(*t) && !isDIGIT(*t))
8d063cd8
LW
1152 *t = '_';
1153 }
a0d0e21e 1154 if (!strchr(tokenbuf,'_'))
d48672a2 1155 strcpy(t,"_FH");
a687059c
LW
1156 tmp3str = hfetch(symtab,tokenbuf);
1157 if (!tmp3str) {
1158 str_cat(opens,"open(");
1159 str_cat(opens,tokenbuf);
1160 str_cat(opens,", ");
1161 d[1] = '\0';
1162 str_cat(opens,d);
1163 str_scat(opens,tmp2str);
1164 str_cat(opens,tmpstr->str_ptr+1);
1165 if (*tmp2str->str_ptr == '|')
1166 str_cat(opens,") || die 'Cannot pipe to \"");
1167 else
1168 str_cat(opens,") || die 'Cannot create file \"");
1169 if (*d == '"')
1170 str_cat(opens,"'.\"");
1171 str_cat(opens,s);
1172 if (*d == '"')
1173 str_cat(opens,"\".'");
1174 str_cat(opens,"\".';\n");
1175 hstore(symtab,tokenbuf,str_make("x"));
1176 }
8d063cd8
LW
1177 str_free(tmpstr);
1178 str_free(tmp2str);
1179 safefree(s);
1180 safefree(d);
1181 }
1182 else {
a687059c 1183 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
8d063cd8
LW
1184 tmp2str->str_ptr, tmpstr->str_ptr);
1185 str_cat(str,tokenbuf);
1186 tab(str,level+1);
a687059c 1187 strcpy(tokenbuf,"$fh");
8d063cd8
LW
1188 str_free(tmpstr);
1189 str_free(tmp2str);
378cc40b
LW
1190 lparen = "(";
1191 rparen = ")";
8d063cd8
LW
1192 }
1193 }
1194 else
a687059c 1195 strcpy(tokenbuf,"");
378cc40b 1196 str_cat(str,lparen); /* may be null */
8d063cd8
LW
1197 if (type == OPRINTF)
1198 str_cat(str,"printf");
1199 else
1200 str_cat(str,"print");
d48672a2 1201 saw_fh = 0;
8d063cd8 1202 if (len == 3 || do_fancy_opens) {
d48672a2 1203 if (*tokenbuf) {
8d063cd8 1204 str_cat(str," ");
d48672a2
LW
1205 saw_fh = 1;
1206 }
8d063cd8
LW
1207 str_cat(str,tokenbuf);
1208 }
a687059c 1209 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1210 if (!*tmpstr->str_ptr && lval_field) {
2b260de0 1211 t = (char*)(saw_OFS ? "$," : "' '");
8d063cd8
LW
1212 if (split_to_array) {
1213 sprintf(tokenbuf,"join(%s,@Fld)",t);
1214 str_cat(tmpstr,tokenbuf);
1215 }
1216 else {
1217 for (i = 1; i < maxfld; i++) {
1218 if (i <= arymax)
1219 sprintf(tokenbuf,"$%s, ",nameary[i]);
1220 else
1221 sprintf(tokenbuf,"$Fld%d, ",i);
1222 str_cat(tmpstr,tokenbuf);
1223 }
1224 if (maxfld <= arymax)
1225 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1226 else
1227 sprintf(tokenbuf,"$Fld%d",maxfld);
1228 str_cat(tmpstr,tokenbuf);
1229 }
1230 }
1231 if (*tmpstr->str_ptr) {
1232 str_cat(str," ");
d48672a2
LW
1233 if (!saw_fh && *tmpstr->str_ptr == '(') {
1234 str_cat(str,"(");
1235 str_scat(str,tmpstr);
1236 str_cat(str,")");
1237 }
1238 else
1239 str_scat(str,tmpstr);
8d063cd8
LW
1240 }
1241 else {
1242 str_cat(str," $_");
1243 }
378cc40b 1244 str_cat(str,rparen); /* may be null */
8d063cd8
LW
1245 str_free(tmpstr);
1246 break;
a687059c
LW
1247 case ORAND:
1248 str = str_make("rand(1)");
1249 break;
1250 case OSRAND:
1251 str = str_make("srand(");
1252 goto maybe0;
1253 case OATAN2:
1254 str = str_make("atan2(");
1255 goto maybe0;
1256 case OSIN:
1257 str = str_make("sin(");
1258 goto maybe0;
1259 case OCOS:
1260 str = str_make("cos(");
1261 goto maybe0;
1262 case OSYSTEM:
1263 str = str_make("system(");
1264 goto maybe0;
8d063cd8
LW
1265 case OLENGTH:
1266 str = str_make("length(");
1267 goto maybe0;
1268 case OLOG:
1269 str = str_make("log(");
1270 goto maybe0;
1271 case OEXP:
1272 str = str_make("exp(");
1273 goto maybe0;
1274 case OSQRT:
1275 str = str_make("sqrt(");
1276 goto maybe0;
1277 case OINT:
1278 str = str_make("int(");
1279 maybe0:
1280 numeric = 1;
1281 if (len > 0)
a687059c 1282 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1283 else
db7c17d7 1284 tmpstr = str_new(0);
fe14fcc3 1285 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
8d063cd8 1286 if (lval_field) {
2b260de0 1287 t = (char*)(saw_OFS ? "$," : "' '");
8d063cd8
LW
1288 if (split_to_array) {
1289 sprintf(tokenbuf,"join(%s,@Fld)",t);
1290 str_cat(tmpstr,tokenbuf);
1291 }
1292 else {
1293 sprintf(tokenbuf,"join(%s, ",t);
1294 str_cat(tmpstr,tokenbuf);
1295 for (i = 1; i < maxfld; i++) {
1296 if (i <= arymax)
1297 sprintf(tokenbuf,"$%s,",nameary[i]);
1298 else
1299 sprintf(tokenbuf,"$Fld%d,",i);
1300 str_cat(tmpstr,tokenbuf);
1301 }
1302 if (maxfld <= arymax)
1303 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1304 else
1305 sprintf(tokenbuf,"$Fld%d)",maxfld);
1306 str_cat(tmpstr,tokenbuf);
1307 }
1308 }
1309 else
1310 str_cat(tmpstr,"$_");
1311 }
1312 if (strEQ(tmpstr->str_ptr,"$_")) {
1313 if (type == OLENGTH && !do_chop) {
1314 str = str_make("(length(");
1315 str_cat(tmpstr,") - 1");
1316 }
1317 }
1318 str_scat(str,tmpstr);
1319 str_free(tmpstr);
1320 str_cat(str,")");
1321 break;
1322 case OBREAK:
1323 str = str_new(0);
1324 str_set(str,"last");
1325 break;
1326 case ONEXT:
1327 str = str_new(0);
1328 str_set(str,"next line");
1329 break;
1330 case OEXIT:
1331 str = str_new(0);
1332 if (realexit) {
a687059c 1333 prec = P_UNI;
8d063cd8
LW
1334 str_set(str,"exit");
1335 if (len == 1) {
1336 str_cat(str," ");
1337 exitval = TRUE;
a687059c
LW
1338 str_scat(str,
1339 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
8d063cd8
LW
1340 str_free(fstr);
1341 }
1342 }
1343 else {
1344 if (len == 1) {
9f68db38 1345 str_set(str,"$ExitValue = ");
8d063cd8 1346 exitval = TRUE;
a687059c
LW
1347 str_scat(str,
1348 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
8d063cd8
LW
1349 str_free(fstr);
1350 str_cat(str,"; ");
1351 }
1352 str_cat(str,"last line");
1353 }
1354 break;
1355 case OCONTINUE:
1356 str = str_new(0);
1357 str_set(str,"next");
1358 break;
1359 case OREDIR:
1360 goto def;
1361 case OIF:
1362 str = str_new(0);
1363 str_set(str,"if (");
a687059c 1364 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1365 str_free(fstr);
1366 str_cat(str,") ");
a687059c 1367 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1368 str_free(fstr);
1369 if (len == 3) {
1370 i = ops[node+3].ival;
1371 if (i) {
1372 if ((ops[i].ival & 255) == OBLOCK) {
1373 i = ops[i+1].ival;
1374 if (i) {
1375 if ((ops[i].ival & 255) != OIF)
1376 i = 0;
1377 }
1378 }
1379 else
1380 i = 0;
1381 }
1382 if (i) {
1383 str_cat(str,"els");
a687059c 1384 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
8d063cd8
LW
1385 str_free(fstr);
1386 }
1387 else {
1388 str_cat(str,"else ");
a687059c 1389 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8
LW
1390 str_free(fstr);
1391 }
1392 }
1393 break;
1394 case OWHILE:
1395 str = str_new(0);
1396 str_set(str,"while (");
a687059c 1397 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1398 str_free(fstr);
1399 str_cat(str,") ");
a687059c 1400 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1401 str_free(fstr);
1402 break;
7c0587c8
LW
1403 case ODO:
1404 str = str_new(0);
1405 str_set(str,"do ");
1406 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1407 str_free(fstr);
1408 if (str->str_ptr[str->str_cur - 1] == '\n')
db7c17d7 1409 --str->str_cur;
7c0587c8
LW
1410 str_cat(str," while (");
1411 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1412 str_free(fstr);
1413 str_cat(str,");");
1414 break;
8d063cd8
LW
1415 case OFOR:
1416 str = str_new(0);
1417 str_set(str,"for (");
a687059c 1418 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1419 i = numarg;
1420 if (i) {
1421 t = s = tmpstr->str_ptr;
3f939f22 1422 while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
8d063cd8
LW
1423 t++;
1424 i = t - s;
1425 if (i < 2)
1426 i = 0;
1427 }
1428 str_cat(str,"; ");
a687059c 1429 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
a0d0e21e 1430 if (i && (t = strchr(fstr->str_ptr,0377))) {
8d063cd8
LW
1431 if (strnEQ(fstr->str_ptr,s,i))
1432 *t = ' ';
1433 }
1434 str_scat(str,fstr);
1435 str_free(fstr);
1436 str_free(tmpstr);
1437 str_cat(str,"; ");
a687059c 1438 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
8d063cd8
LW
1439 str_free(fstr);
1440 str_cat(str,") ");
a687059c 1441 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
8d063cd8
LW
1442 str_free(fstr);
1443 break;
1444 case OFORIN:
a687059c 1445 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
a0d0e21e 1446 d = strchr(tmpstr->str_ptr,'$');
a687059c
LW
1447 if (!d)
1448 fatal("Illegal for loop: %s",tmpstr->str_ptr);
a0d0e21e 1449 s = strchr(d,'{');
a687059c 1450 if (!s)
a0d0e21e 1451 s = strchr(d,'[');
a687059c
LW
1452 if (!s)
1453 fatal("Illegal for loop: %s",d);
1454 *s++ = '\0';
b7953727 1455 for (t = s; (i = *t); t++) {
ffed7fef
LW
1456 i &= 127;
1457 if (i == '}' || i == ']')
1458 break;
1459 }
1460 if (*t)
a687059c 1461 *t = '\0';
8d063cd8 1462 str = str_new(0);
a687059c 1463 str_set(str,d+1);
8d063cd8
LW
1464 str_cat(str,"[]");
1465 tmp2str = hfetch(symtab,str->str_ptr);
1466 if (tmp2str && atoi(tmp2str->str_ptr)) {
8d063cd8 1467 sprintf(tokenbuf,
62b28dd9 1468 "foreach %s ($[ .. $#%s) ",
a687059c
LW
1469 s,
1470 d+1);
8d063cd8
LW
1471 }
1472 else {
a687059c
LW
1473 sprintf(tokenbuf,
1474 "foreach %s (keys %%%s) ",
1475 s,
1476 d+1);
8d063cd8 1477 }
a687059c
LW
1478 str_set(str,tokenbuf);
1479 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1480 str_free(fstr);
8d063cd8
LW
1481 str_free(tmpstr);
1482 break;
1483 case OBLOCK:
1484 str = str_new(0);
1485 str_set(str,"{");
378cc40b 1486 if (len >= 2 && ops[node+2].ival) {
a687059c 1487 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
8d063cd8
LW
1488 str_free(fstr);
1489 }
1490 fixtab(str,++level);
a687059c 1491 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
8d063cd8
LW
1492 str_free(fstr);
1493 addsemi(str);
1494 fixtab(str,--level);
1495 str_cat(str,"}\n");
1496 tab(str,level);
378cc40b 1497 if (len >= 3) {
a687059c 1498 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
378cc40b
LW
1499 str_free(fstr);
1500 }
8d063cd8
LW
1501 break;
1502 default:
1503 def:
1504 if (len) {
1505 if (len > 5)
1506 fatal("Garbage length in walk");
a687059c 1507 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
8d063cd8 1508 for (i = 2; i<= len; i++) {
a687059c 1509 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
8d063cd8
LW
1510 str_free(fstr);
1511 }
1512 }
1513 else {
1514 str = Nullstr;
1515 }
1516 break;
1517 }
1518 if (!str)
1519 str = str_new(0);
a687059c
LW
1520
1521 if (useval && prec < minprec) { /* need parens? */
1522 fstr = str_new(str->str_cur+2);
1523 str_nset(fstr,"(",1);
1524 str_scat(fstr,str);
1525 str_ncat(fstr,")",1);
1526 str_free(str);
1527 str = fstr;
1528 }
1529
8d063cd8
LW
1530 *numericptr = numeric;
1531#ifdef DEBUGGING
1532 if (debug & 4) {
1533 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1534 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1535 if (*t == '\n')
1536 printf("\\n");
1537 else if (*t == '\t')
1538 printf("\\t");
1539 else
1540 putchar(*t);
1541 putchar('\n');
1542 }
1543#endif
1544 return str;
1545}
1546
748a9306 1547static void
f0f333f4 1548tab(register STR *str, register int lvl)
8d063cd8
LW
1549{
1550 while (lvl > 1) {
1551 str_cat(str,"\t");
1552 lvl -= 2;
1553 }
1554 if (lvl)
1555 str_cat(str," ");
1556}
1557
748a9306 1558static void
f0f333f4 1559fixtab(register STR *str, register int lvl)
8d063cd8
LW
1560{
1561 register char *s;
1562
1563 /* strip trailing white space */
1564
1565 s = str->str_ptr+str->str_cur - 1;
a687059c 1566 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
8d063cd8
LW
1567 s--;
1568 s[1] = '\0';
1569 str->str_cur = s + 1 - str->str_ptr;
1570 if (s >= str->str_ptr && *s != '\n')
1571 str_cat(str,"\n");
1572
1573 tab(str,lvl);
1574}
1575
748a9306 1576static void
f0f333f4 1577addsemi(register STR *str)
8d063cd8
LW
1578{
1579 register char *s;
1580
1581 s = str->str_ptr+str->str_cur - 1;
1582 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1583 s--;
1584 if (s >= str->str_ptr && *s != ';' && *s != '}')
1585 str_cat(str,";");
1586}
1587
56febc5e 1588static void
f0f333f4 1589emit_split(register STR *str, int level)
8d063cd8
LW
1590{
1591 register int i;
1592
1593 if (split_to_array)
1594 str_cat(str,"@Fld");
1595 else {
1596 str_cat(str,"(");
1597 for (i = 1; i < maxfld; i++) {
1598 if (i <= arymax)
1599 sprintf(tokenbuf,"$%s,",nameary[i]);
1600 else
1601 sprintf(tokenbuf,"$Fld%d,",i);
1602 str_cat(str,tokenbuf);
1603 }
1604 if (maxfld <= arymax)
1605 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1606 else
1607 sprintf(tokenbuf,"$Fld%d)",maxfld);
1608 str_cat(str,tokenbuf);
1609 }
1610 if (const_FS) {
4cec2b33 1611 sprintf(tokenbuf," = split(/[%c\\n]/, $_, -1);\n",const_FS);
8d063cd8
LW
1612 str_cat(str,tokenbuf);
1613 }
1614 else if (saw_FS)
4cec2b33 1615 str_cat(str," = split($FS, $_, -1);\n");
8d063cd8 1616 else
4cec2b33 1617 str_cat(str," = split(' ', $_, -1);\n");
8d063cd8
LW
1618 tab(str,level);
1619}
1620
9c8d0b29 1621int
f0f333f4 1622prewalk(int numit, int level, register int node, int *numericptr)
8d063cd8
LW
1623{
1624 register int len;
1625 register int type;
1626 register int i;
8d063cd8
LW
1627 int numarg;
1628 int numeric = FALSE;
a687059c
LW
1629 STR *tmpstr;
1630 STR *tmp2str;
8d063cd8
LW
1631
1632 if (!node) {
1633 *numericptr = 0;
1634 return 0;
1635 }
1636 type = ops[node].ival;
1637 len = type >> 8;
1638 type &= 255;
1639 switch (type) {
1640 case OPROG:
1641 prewalk(0,level,ops[node+1].ival,&numarg);
1642 if (ops[node+2].ival) {
1643 prewalk(0,level,ops[node+2].ival,&numarg);
1644 }
1645 ++level;
1646 prewalk(0,level,ops[node+3].ival,&numarg);
1647 --level;
1648 if (ops[node+3].ival) {
1649 prewalk(0,level,ops[node+4].ival,&numarg);
1650 }
1651 break;
1652 case OHUNKS:
1653 prewalk(0,level,ops[node+1].ival,&numarg);
1654 prewalk(0,level,ops[node+2].ival,&numarg);
1655 if (len == 3) {
1656 prewalk(0,level,ops[node+3].ival,&numarg);
1657 }
1658 break;
1659 case ORANGE:
1660 prewalk(1,level,ops[node+1].ival,&numarg);
1661 prewalk(1,level,ops[node+2].ival,&numarg);
1662 break;
1663 case OPAT:
1664 goto def;
1665 case OREGEX:
1666 prewalk(0,level,ops[node+1].ival,&numarg);
1667 break;
1668 case OHUNK:
1669 if (len == 1) {
1670 prewalk(0,level,ops[node+1].ival,&numarg);
1671 }
1672 else {
1673 i = prewalk(0,level,ops[node+1].ival,&numarg);
1674 if (i) {
1675 ++level;
1676 prewalk(0,level,ops[node+2].ival,&numarg);
1677 --level;
1678 }
1679 else {
1680 prewalk(0,level,ops[node+2].ival,&numarg);
1681 }
1682 }
1683 break;
1684 case OPPAREN:
1685 prewalk(0,level,ops[node+1].ival,&numarg);
1686 break;
1687 case OPANDAND:
1688 prewalk(0,level,ops[node+1].ival,&numarg);
1689 prewalk(0,level,ops[node+2].ival,&numarg);
1690 break;
1691 case OPOROR:
1692 prewalk(0,level,ops[node+1].ival,&numarg);
1693 prewalk(0,level,ops[node+2].ival,&numarg);
1694 break;
1695 case OPNOT:
1696 prewalk(0,level,ops[node+1].ival,&numarg);
1697 break;
1698 case OCPAREN:
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1700 numeric |= numarg;
1701 break;
1702 case OCANDAND:
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1704 numeric = 1;
1705 prewalk(0,level,ops[node+2].ival,&numarg);
1706 break;
1707 case OCOROR:
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 OCNOT:
1713 prewalk(0,level,ops[node+1].ival,&numarg);
1714 numeric = 1;
1715 break;
1716 case ORELOP:
1717 prewalk(0,level,ops[node+2].ival,&numarg);
1718 numeric |= numarg;
1719 prewalk(0,level,ops[node+1].ival,&numarg);
1720 prewalk(0,level,ops[node+3].ival,&numarg);
1721 numeric |= numarg;
1722 numeric = 1;
1723 break;
1724 case ORPAREN:
1725 prewalk(0,level,ops[node+1].ival,&numarg);
1726 numeric |= numarg;
1727 break;
1728 case OMATCHOP:
1729 prewalk(0,level,ops[node+2].ival,&numarg);
1730 prewalk(0,level,ops[node+1].ival,&numarg);
1731 prewalk(0,level,ops[node+3].ival,&numarg);
1732 numeric = 1;
1733 break;
1734 case OMPAREN:
1735 prewalk(0,level,ops[node+1].ival,&numarg);
1736 numeric |= numarg;
1737 break;
1738 case OCONCAT:
1739 prewalk(0,level,ops[node+1].ival,&numarg);
1740 prewalk(0,level,ops[node+2].ival,&numarg);
1741 break;
1742 case OASSIGN:
1743 prewalk(0,level,ops[node+2].ival,&numarg);
1744 prewalk(0,level,ops[node+1].ival,&numarg);
1745 prewalk(0,level,ops[node+3].ival,&numarg);
75f92628 1746 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
8d063cd8
LW
1747 numericize(ops[node+2].ival);
1748 if (!numarg)
1749 numericize(ops[node+3].ival);
1750 }
1751 numeric |= numarg;
1752 break;
1753 case OADD:
1754 prewalk(1,level,ops[node+1].ival,&numarg);
1755 prewalk(1,level,ops[node+2].ival,&numarg);
1756 numeric = 1;
1757 break;
a687059c 1758 case OSUBTRACT:
8d063cd8
LW
1759 prewalk(1,level,ops[node+1].ival,&numarg);
1760 prewalk(1,level,ops[node+2].ival,&numarg);
1761 numeric = 1;
1762 break;
1763 case OMULT:
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 ODIV:
1769 prewalk(1,level,ops[node+1].ival,&numarg);
1770 prewalk(1,level,ops[node+2].ival,&numarg);
1771 numeric = 1;
1772 break;
a687059c
LW
1773 case OPOW:
1774 prewalk(1,level,ops[node+1].ival,&numarg);
1775 prewalk(1,level,ops[node+2].ival,&numarg);
1776 numeric = 1;
1777 break;
8d063cd8
LW
1778 case OMOD:
1779 prewalk(1,level,ops[node+1].ival,&numarg);
1780 prewalk(1,level,ops[node+2].ival,&numarg);
1781 numeric = 1;
1782 break;
1783 case OPOSTINCR:
1784 prewalk(1,level,ops[node+1].ival,&numarg);
1785 numeric = 1;
1786 break;
1787 case OPOSTDECR:
1788 prewalk(1,level,ops[node+1].ival,&numarg);
1789 numeric = 1;
1790 break;
1791 case OPREINCR:
1792 prewalk(1,level,ops[node+1].ival,&numarg);
1793 numeric = 1;
1794 break;
1795 case OPREDECR:
1796 prewalk(1,level,ops[node+1].ival,&numarg);
1797 numeric = 1;
1798 break;
1799 case OUMINUS:
1800 prewalk(1,level,ops[node+1].ival,&numarg);
1801 numeric = 1;
1802 break;
1803 case OUPLUS:
1804 prewalk(1,level,ops[node+1].ival,&numarg);
1805 numeric = 1;
1806 break;
1807 case OPAREN:
1808 prewalk(0,level,ops[node+1].ival,&numarg);
1809 numeric |= numarg;
1810 break;
1811 case OGETLINE:
1812 break;
1813 case OSPRINTF:
1814 prewalk(0,level,ops[node+1].ival,&numarg);
1815 break;
1816 case OSUBSTR:
1817 prewalk(0,level,ops[node+1].ival,&numarg);
1818 prewalk(1,level,ops[node+2].ival,&numarg);
1819 if (len == 3) {
1820 prewalk(1,level,ops[node+3].ival,&numarg);
1821 }
1822 break;
1823 case OSTRING:
1824 break;
1825 case OSPLIT:
1826 numeric = 1;
1827 prewalk(0,level,ops[node+2].ival,&numarg);
1828 if (len == 3)
1829 prewalk(0,level,ops[node+3].ival,&numarg);
1830 prewalk(0,level,ops[node+1].ival,&numarg);
1831 break;
1832 case OINDEX:
1833 prewalk(0,level,ops[node+1].ival,&numarg);
1834 prewalk(0,level,ops[node+2].ival,&numarg);
1835 numeric = 1;
1836 break;
a687059c
LW
1837 case OMATCH:
1838 prewalk(0,level,ops[node+1].ival,&numarg);
1839 prewalk(0,level,ops[node+2].ival,&numarg);
1840 numeric = 1;
1841 break;
1842 case OUSERDEF:
1843 subretnum = FALSE;
1844 --level;
1845 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1846 ++level;
1847 prewalk(0,level,ops[node+2].ival,&numarg);
1848 prewalk(0,level,ops[node+4].ival,&numarg);
1849 prewalk(0,level,ops[node+5].ival,&numarg);
1850 --level;
1851 str_cat(tmpstr,"(");
1852 tmp2str = str_new(0);
1853 if (subretnum || numarg)
1854 str_set(tmp2str,"1");
1855 hstore(symtab,tmpstr->str_ptr,tmp2str);
1856 str_free(tmpstr);
1857 level++;
1858 break;
1859 case ORETURN:
1860 if (len > 0) {
1861 prewalk(0,level,ops[node+1].ival,&numarg);
1862 if (numarg)
1863 subretnum = TRUE;
1864 }
1865 break;
1866 case OUSERFUN:
1867 tmp2str = str_new(0);
1868 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
663a0e37 1869 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
a687059c
LW
1870 str_free(tmpstr);
1871 str_cat(tmp2str,"(");
1872 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1873 if (tmpstr && tmpstr->str_ptr)
1874 numeric |= atoi(tmpstr->str_ptr);
1875 prewalk(0,level,ops[node+2].ival,&numarg);
1876 str_free(tmp2str);
1877 break;
1878 case OGSUB:
1879 case OSUB:
1880 if (len >= 3)
1881 prewalk(0,level,ops[node+3].ival,&numarg);
1882 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1883 prewalk(0,level,ops[node+1].ival,&numarg);
1884 numeric = 1;
1885 break;
8d063cd8
LW
1886 case ONUM:
1887 prewalk(0,level,ops[node+1].ival,&numarg);
1888 numeric = 1;
1889 break;
1890 case OSTR:
1891 prewalk(0,level,ops[node+1].ival,&numarg);
1892 break;
a687059c
LW
1893 case ODEFINED:
1894 case ODELETE:
1895 case OSTAR:
8d063cd8
LW
1896 case OVAR:
1897 prewalk(0,level,ops[node+1].ival,&numarg);
1898 if (len == 1) {
1899 if (numit)
1900 numericize(node);
1901 }
1902 else {
1903 prewalk(0,level,ops[node+2].ival,&numarg);
1904 }
1905 break;
1906 case OFLD:
1907 prewalk(0,level,ops[node+1].ival,&numarg);
1908 break;
1909 case OVFLD:
1910 i = ops[node+1].ival;
1911 prewalk(0,level,i,&numarg);
1912 break;
1913 case OJUNK:
1914 goto def;
1915 case OSNEWLINE:
1916 break;
1917 case ONEWLINE:
1918 break;
1919 case OSCOMMENT:
1920 break;
1921 case OCOMMENT:
1922 break;
1923 case OCOMMA:
1924 prewalk(0,level,ops[node+1].ival,&numarg);
1925 prewalk(0,level,ops[node+2].ival,&numarg);
a687059c 1926 prewalk(0,level,ops[node+3].ival,&numarg);
8d063cd8
LW
1927 break;
1928 case OSEMICOLON:
1929 break;
1930 case OSTATES:
1931 prewalk(0,level,ops[node+1].ival,&numarg);
1932 prewalk(0,level,ops[node+2].ival,&numarg);
1933 break;
1934 case OSTATE:
1935 if (len >= 1) {
1936 prewalk(0,level,ops[node+1].ival,&numarg);
1937 if (len >= 2) {
1938 prewalk(0,level,ops[node+2].ival,&numarg);
1939 }
1940 }
1941 break;
a687059c
LW
1942 case OCLOSE:
1943 prewalk(0,level,ops[node+1].ival,&numarg);
1944 break;
8d063cd8
LW
1945 case OPRINTF:
1946 case OPRINT:
1947 if (len == 3) { /* output redirection */
1948 prewalk(0,level,ops[node+3].ival,&numarg);
1949 prewalk(0,level,ops[node+2].ival,&numarg);
1950 }
1951 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1952 break;
a687059c
LW
1953 case ORAND:
1954 break;
1955 case OSRAND:
1956 goto maybe0;
1957 case OATAN2:
1958 goto maybe0;
1959 case OSIN:
1960 goto maybe0;
1961 case OCOS:
1962 goto maybe0;
1963 case OSYSTEM:
1964 goto maybe0;
8d063cd8
LW
1965 case OLENGTH:
1966 goto maybe0;
1967 case OLOG:
1968 goto maybe0;
1969 case OEXP:
1970 goto maybe0;
1971 case OSQRT:
1972 goto maybe0;
1973 case OINT:
1974 maybe0:
1975 numeric = 1;
1976 if (len > 0)
a687059c
LW
1977 prewalk(type != OLENGTH && type != OSYSTEM,
1978 level,ops[node+1].ival,&numarg);
8d063cd8
LW
1979 break;
1980 case OBREAK:
1981 break;
1982 case ONEXT:
1983 break;
1984 case OEXIT:
1985 if (len == 1) {
1986 prewalk(1,level,ops[node+1].ival,&numarg);
1987 }
1988 break;
1989 case OCONTINUE:
1990 break;
1991 case OREDIR:
1992 goto def;
1993 case OIF:
1994 prewalk(0,level,ops[node+1].ival,&numarg);
1995 prewalk(0,level,ops[node+2].ival,&numarg);
1996 if (len == 3) {
1997 prewalk(0,level,ops[node+3].ival,&numarg);
1998 }
1999 break;
2000 case OWHILE:
2001 prewalk(0,level,ops[node+1].ival,&numarg);
2002 prewalk(0,level,ops[node+2].ival,&numarg);
2003 break;
2004 case OFOR:
2005 prewalk(0,level,ops[node+1].ival,&numarg);
2006 prewalk(0,level,ops[node+2].ival,&numarg);
2007 prewalk(0,level,ops[node+3].ival,&numarg);
2008 prewalk(0,level,ops[node+4].ival,&numarg);
2009 break;
2010 case OFORIN:
2011 prewalk(0,level,ops[node+2].ival,&numarg);
2012 prewalk(0,level,ops[node+1].ival,&numarg);
8d063cd8
LW
2013 break;
2014 case OBLOCK:
2015 if (len == 2) {
2016 prewalk(0,level,ops[node+2].ival,&numarg);
2017 }
2018 ++level;
2019 prewalk(0,level,ops[node+1].ival,&numarg);
2020 --level;
2021 break;
2022 default:
2023 def:
2024 if (len) {
2025 if (len > 5)
2026 fatal("Garbage length in prewalk");
2027 prewalk(0,level,ops[node+1].ival,&numarg);
2028 for (i = 2; i<= len; i++) {
2029 prewalk(0,level,ops[node+i].ival,&numarg);
2030 }
2031 }
2032 break;
2033 }
2034 *numericptr = numeric;
2035 return 1;
2036}
2037
748a9306 2038static void
f0f333f4 2039numericize(register int node)
8d063cd8
LW
2040{
2041 register int len;
2042 register int type;
8d063cd8
LW
2043 STR *tmpstr;
2044 STR *tmp2str;
2045 int numarg;
2046
2047 type = ops[node].ival;
2048 len = type >> 8;
2049 type &= 255;
2050 if (type == OVAR && len == 1) {
a687059c 2051 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
8d063cd8
LW
2052 tmp2str = str_make("1");
2053 hstore(symtab,tmpstr->str_ptr,tmp2str);
2054 }
2055}