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