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