1 /* $Header: walk.c,v 3.0.1.4 90/03/01 10:32:45 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0.1.4 90/03/01 10:32:45 lwall
10 * patch9: a2p didn't put a $ on ExitValue
12 * Revision 3.0.1.3 89/12/21 20:32:35 lwall
13 * patch7: in a2p, user-defined functions didn't work on some machines
15 * Revision 3.0.1.2 89/11/17 15:53:00 lwall
16 * patch5: on Pyramids, index(s, '}' + 128) doesn't find meta-}
18 * Revision 3.0.1.1 89/11/11 05:09:33 lwall
19 * patch2: in a2p, awk script with no line actions still needs main loop
21 * Revision 3.0 89/10/18 15:35:48 lwall
32 bool realexit = FALSE;
33 bool saw_getline = FALSE;
34 bool subretnum = FALSE;
36 bool saw_argv0 = FALSE;
41 STR *curargs = Nullstr;
44 walk(useval,level,node,numericptr,minprec)
49 int minprec; /* minimum precedence without parens */
63 int prec = P_MAX; /* assume no parens needed */
70 type = ops[node].ival;
77 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
78 if (do_split && need_entire && !absmaxfld)
79 split_to_array = TRUE;
80 if (do_split && split_to_array)
81 set_array_base = TRUE;
83 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
85 if (fswitch && !const_FS)
87 if (saw_FS > 1 || saw_RS)
89 if (saw_ORS && need_entire)
92 str_cat(str,"$FS = '");
93 if (index("*+?.[]()|^$\\",fswitch))
95 sprintf(tokenbuf,"%c",fswitch);
96 str_cat(str,tokenbuf);
97 str_cat(str,"';\t\t# field separator from -F switch\n");
99 else if (saw_FS && !const_FS) {
100 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
103 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
106 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
109 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
111 if (str->str_cur > 20)
113 if (ops[node+2].ival) {
114 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
118 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
119 if (*fstr->str_ptr) {
121 str_cat(str,"line: ");
122 str_cat(str,"while (<>) {\n");
124 if (saw_FS && !const_FS)
127 str_cat(str,"chop;\t# strip record separator\n");
132 while (isalpha(*namelist)) {
133 for (d = tokenbuf,s=namelist;
134 isalpha(*s) || isdigit(*s) || *s == '_';
137 while (*s && !isalpha(*s)) s++;
139 nameary[++arymax] = savestr(tokenbuf);
145 emit_split(str,level);
151 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
154 str_cat(str,"while (<>) { } # (no line actions)\n");
155 if (ops[node+4].ival) {
159 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
164 str_cat(str,"exit $ExitValue;\n");
170 for (len = 0; len < 4; len++) {
171 if (saw_getline & (1 << len)) {
172 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
173 str_cat(str, tokenbuf);
176 str_cat(str," &Pick('',@_);\n");
178 str_cat(str," ($fh) = @_;\n");
182 str_cat(str," $FNRbase = $. if eof;\n");
185 str_cat(str," local($_)\n");
188 " if ($getline_ok = (($_ = <$fh>) ne ''))");
191 " if ($getline_ok = (($_ = <>) ne ''))");
192 str_cat(str, " {\n");
198 str_cat(str,"chop;\t# strip record separator\n");
201 if (do_split && !(len & 1)) {
203 emit_split(str,level);
208 str_cat(str,"}\n $_;\n}\n");
213 if (do_fancy_opens) {
216 local($mode,$name,$pipe) = @_;\n\
217 $fh = $opened{$name};\n\
219 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
220 open($fh,$mode.$name.$pipe);\n\
227 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
228 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
231 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
239 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
241 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
249 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
250 /* translate \nnn to [\nnn] */
251 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
252 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
264 for (d=tokenbuf; *d; d++)
266 str_cat(str,tokenbuf);
273 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
275 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
280 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
281 if (*tmpstr->str_ptr) {
284 str_scat(str,tmpstr);
285 str_cat(str,") {\n");
287 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
294 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
301 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
307 str = walk(1,level,ops[node+1].ival,&numarg,prec);
309 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
311 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
316 str = walk(1,level,ops[node+1].ival,&numarg,prec);
318 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
320 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
327 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
333 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
340 str = walk(1,level,ops[node+1].ival,&numarg,prec);
343 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
345 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
350 str = walk(1,level,ops[node+1].ival,&numarg,prec);
353 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
355 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
362 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
368 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
370 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
371 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
374 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
377 str_set(tmpstr,"eq");
378 else if (strEQ(t,"!="))
379 str_set(tmpstr,"ne");
380 else if (strEQ(t,"<"))
381 str_set(tmpstr,"lt");
382 else if (strEQ(t,"<="))
383 str_set(tmpstr,"le");
384 else if (strEQ(t,">"))
385 str_set(tmpstr,"gt");
386 else if (strEQ(t,">="))
387 str_set(tmpstr,"ge");
388 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
389 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
393 if (numeric & 1) /* numeric is very good guess */
401 str_scat(str,tmpstr);
404 str_scat(str,tmp2str);
411 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
418 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
420 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
421 if (strEQ(tmpstr->str_ptr,"~"))
424 str_scat(str,tmpstr);
428 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
436 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
443 type = ops[ops[node+1].ival].ival & 255;
444 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
446 type = ops[ops[node+2].ival].ival & 255;
448 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
453 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
455 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
456 str_scat(str,tmpstr);
457 if (str_len(tmpstr) > 1)
461 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
467 str = walk(1,level,ops[node+1].ival,&numarg,prec);
469 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
475 str = walk(1,level,ops[node+1].ival,&numarg,prec);
477 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
483 str = walk(1,level,ops[node+1].ival,&numarg,prec);
485 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
491 str = walk(1,level,ops[node+1].ival,&numarg,prec);
493 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
499 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
501 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
507 str = walk(1,level,ops[node+1].ival,&numarg,prec);
509 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
515 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
521 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
529 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
537 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
545 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
556 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
567 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
568 if (!*fstr->str_ptr) {
570 len = 2; /* a legal fiction */
577 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
578 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
579 if (!do_fancy_opens) {
581 if (*t == '"' || *t == '\'')
582 t = cpytill(tokenbuf,t+1,*t);
584 fatal("Internal error: OGETLINE %s", t);
586 s = savestr(tokenbuf);
587 for (t = tokenbuf; *t; t++) {
589 if (!isalpha(*t) && !isdigit(*t))
592 if (!index(tokenbuf,'_'))
594 tmp3str = hfetch(symtab,tokenbuf);
597 str_cat(opens,"open(");
598 str_cat(opens,tokenbuf);
602 str_cat(opens,tmpstr->str_ptr+1);
604 if (*fstr->str_ptr == '|')
607 if (*fstr->str_ptr == '|')
608 str_cat(opens,") || die 'Cannot pipe from \"");
610 str_cat(opens,") || die 'Cannot open file \"");
612 str_cat(opens,"'.\"");
615 str_cat(opens,"\".'");
616 str_cat(opens,"\".';\n");
617 hstore(symtab,tokenbuf,str_make("x"));
622 str_cat(tmpstr,tokenbuf);
625 if (*fstr->str_ptr == '|')
626 str_cat(tmpstr,", '|'");
630 tmpstr = str_make("");
631 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
632 str_cat(str,tokenbuf);
635 str_cat(str,",$getline_ok)");
636 saw_getline |= 1 << len;
640 str_set(str,"sprintf(");
641 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
647 str_set(str,"substr(");
648 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
651 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
655 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
659 str_cat(str,"999999");
664 str_set(str,ops[node+1].cval);
669 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
674 str_scat(str,tmpstr);
675 str_cat(str," = split(");
677 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
678 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
679 i = fstr->str_ptr[1] & 127;
680 if (index("*+?.[]()|^$\\",i))
681 sprintf(tokenbuf,"/\\%c/",i);
683 sprintf(tokenbuf,"/%c/",i);
684 str_cat(str,tokenbuf);
691 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
692 str_cat(str,tokenbuf);
699 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
701 str_cat(str,", 999)");
709 str_set(str,"index(");
710 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
713 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
721 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
724 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
726 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
732 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
733 curargs = str_new(0);
734 str_sset(curargs,fstr);
735 str_cat(curargs,",");
736 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
742 t = tmp2str->str_ptr;
743 while (t = instr(t,"return "))
747 for (t = s+7; *t; t++) {
748 if (*t == ';' || *t == '}')
753 tmp2str->str_cur -= 7;
759 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
763 str_cat(str,"local(");
765 str_cat(str,") = @_;");
768 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
771 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
774 str_scat(str,tmp2str);
782 tmp2str = str_new(0);
784 str_set(tmp2str,"1");
785 hstore(symtab,tmpstr->str_ptr,tmp2str);
792 str_cat(str,"return ");
793 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
799 str_cat(str,"return");
804 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
807 tmpstr = hfetch(symtab,str->str_ptr+3);
808 if (tmpstr && tmpstr->str_ptr)
809 numeric |= atoi(tmpstr->str_ptr);
810 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
824 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
825 if (strNE(tmpstr->str_ptr,"$_")) {
826 str_cat(tmpstr, " =~ s");
830 str_set(tmpstr, "s");
833 str_set(tmpstr, "s");
834 type = ops[ops[node+2].ival].ival;
837 tmp3str = str_new(0);
839 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
840 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
848 str_set(tmp2str,tokenbuf);
851 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
852 str_set(tmp3str,"($s_ = '\"'.(");
853 str_scat(tmp3str,tmp2str);
854 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
855 str_set(tmp2str,"eval $s_");
856 s = (*s == 'g' ? "ge" : "e");
859 type = ops[ops[node+1].ival].ival;
862 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
863 if (type == OREGEX) {
866 str_scat(str,tmp3str);
867 str_scat(str,tmpstr);
869 str_scat(str,tmp2str);
873 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
876 str_scat(str,tmp3str);
877 str_scat(str,tmpstr);
881 str_scat(str,tmp2str);
889 str_cat(str,"$s = ");
892 str_scat(str,tmp3str);
893 str_scat(str,tmpstr);
895 str_scat(str,tmp2str);
908 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
912 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
914 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
917 else if (*t == '\\') {
921 case '\\': case '"': case 'n': case 't':
923 default: /* hide this from perl */
932 str_cat(str,tokenbuf);
939 str_set(str,"defined $");
943 str_set(str,"delete $");
953 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
955 tmp2str = hfetch(symtab,tmpstr->str_ptr);
956 if (tmp2str && atoi(tmp2str->str_ptr))
958 if (strEQ(str->str_ptr,"$FNR")) {
961 str_set(str,"($.-$FNRbase)");
963 else if (strEQ(str->str_ptr,"$NR")) {
967 else if (strEQ(str->str_ptr,"$NF")) {
969 str_set(str,"$#Fld");
971 else if (strEQ(str->str_ptr,"$0"))
973 else if (strEQ(str->str_ptr,"$ARGC"))
974 str_set(str,"($#ARGV+1)");
979 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
980 ??? if (instr(curargs->str_ptr,tokenbuf))
981 str_cat(str,"\377"); /* can't translate yet */
984 str_cat(tmpstr,"[]");
985 tmp2str = hfetch(symtab,tmpstr->str_ptr);
986 if (tmp2str && atoi(tmp2str->str_ptr))
990 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
992 if (strEQ(str->str_ptr,"$ARGV[0")) {
993 str_set(str,"$ARGV0");
997 if (tmp2str && atoi(tmp2str->str_ptr))
998 strcpy(tokenbuf,"]");
1000 strcpy(tokenbuf,"}");
1002 str_cat(str,tokenbuf);
1009 if (split_to_array) {
1010 str_set(str,"$Fld");
1012 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1017 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1019 sprintf(tokenbuf,"$%s",nameary[i]);
1021 sprintf(tokenbuf,"$Fld%d",i);
1022 str_set(str,tokenbuf);
1027 str_set(str,"$Fld[");
1028 i = ops[node+1].ival;
1029 if ((ops[i].ival & 255) == OPAREN)
1031 tmpstr=walk(1,level,i,&numarg,P_MIN);
1032 str_scat(str,tmpstr);
1051 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1052 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1054 str_scat(str,tmpstr);
1060 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1061 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1063 str_scat(str,tmpstr);
1069 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1071 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1073 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
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));
1089 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1092 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1093 if (*tmpstr->str_ptr == ';') {
1095 str_cat(str,tmpstr->str_ptr+1);
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);
1109 fatal("Internal error: OCLOSE %s",t);
1110 s = savestr(tokenbuf);
1111 for (t = tokenbuf; *t; t++) {
1113 if (!isalpha(*t) && !isdigit(*t))
1116 if (!index(tokenbuf,'_'))
1120 str_set(str,"close ");
1121 str_cat(str,tokenbuf);
1124 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1127 str_set(str,tokenbuf);
1132 lparen = ""; /* set to parens if necessary */
1135 if (len == 3) { /* output redirection */
1136 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1137 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1138 if (!do_fancy_opens) {
1139 t = tmpstr->str_ptr;
1140 if (*t == '"' || *t == '\'')
1141 t = cpytill(tokenbuf,t+1,*t);
1143 fatal("Internal error: OPRINT");
1145 s = savestr(tokenbuf);
1146 for (t = tokenbuf; *t; t++) {
1148 if (!isalpha(*t) && !isdigit(*t))
1151 if (!index(tokenbuf,'_'))
1153 tmp3str = hfetch(symtab,tokenbuf);
1155 str_cat(opens,"open(");
1156 str_cat(opens,tokenbuf);
1157 str_cat(opens,", ");
1160 str_scat(opens,tmp2str);
1161 str_cat(opens,tmpstr->str_ptr+1);
1162 if (*tmp2str->str_ptr == '|')
1163 str_cat(opens,") || die 'Cannot pipe to \"");
1165 str_cat(opens,") || die 'Cannot create file \"");
1167 str_cat(opens,"'.\"");
1170 str_cat(opens,"\".'");
1171 str_cat(opens,"\".';\n");
1172 hstore(symtab,tokenbuf,str_make("x"));
1180 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1181 tmp2str->str_ptr, tmpstr->str_ptr);
1182 str_cat(str,tokenbuf);
1184 strcpy(tokenbuf,"$fh");
1192 strcpy(tokenbuf,"");
1193 str_cat(str,lparen); /* may be null */
1194 if (type == OPRINTF)
1195 str_cat(str,"printf");
1197 str_cat(str,"print");
1198 if (len == 3 || do_fancy_opens) {
1201 str_cat(str,tokenbuf);
1203 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1204 if (!*tmpstr->str_ptr && lval_field) {
1205 t = saw_OFS ? "$," : "' '";
1206 if (split_to_array) {
1207 sprintf(tokenbuf,"join(%s,@Fld)",t);
1208 str_cat(tmpstr,tokenbuf);
1211 for (i = 1; i < maxfld; i++) {
1213 sprintf(tokenbuf,"$%s, ",nameary[i]);
1215 sprintf(tokenbuf,"$Fld%d, ",i);
1216 str_cat(tmpstr,tokenbuf);
1218 if (maxfld <= arymax)
1219 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1221 sprintf(tokenbuf,"$Fld%d",maxfld);
1222 str_cat(tmpstr,tokenbuf);
1225 if (*tmpstr->str_ptr) {
1227 str_scat(str,tmpstr);
1232 str_cat(str,rparen); /* may be null */
1236 str = str_make("rand(1)");
1239 str = str_make("srand(");
1242 str = str_make("atan2(");
1245 str = str_make("sin(");
1248 str = str_make("cos(");
1251 str = str_make("system(");
1254 str = str_make("length(");
1257 str = str_make("log(");
1260 str = str_make("exp(");
1263 str = str_make("sqrt(");
1266 str = str_make("int(");
1270 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1272 tmpstr = str_new(0);;
1273 if (!*tmpstr->str_ptr) {
1275 t = saw_OFS ? "$," : "' '";
1276 if (split_to_array) {
1277 sprintf(tokenbuf,"join(%s,@Fld)",t);
1278 str_cat(tmpstr,tokenbuf);
1281 sprintf(tokenbuf,"join(%s, ",t);
1282 str_cat(tmpstr,tokenbuf);
1283 for (i = 1; i < maxfld; i++) {
1285 sprintf(tokenbuf,"$%s,",nameary[i]);
1287 sprintf(tokenbuf,"$Fld%d,",i);
1288 str_cat(tmpstr,tokenbuf);
1290 if (maxfld <= arymax)
1291 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1293 sprintf(tokenbuf,"$Fld%d)",maxfld);
1294 str_cat(tmpstr,tokenbuf);
1298 str_cat(tmpstr,"$_");
1300 if (strEQ(tmpstr->str_ptr,"$_")) {
1301 if (type == OLENGTH && !do_chop) {
1302 str = str_make("(length(");
1303 str_cat(tmpstr,") - 1");
1306 str_scat(str,tmpstr);
1312 str_set(str,"last");
1316 str_set(str,"next line");
1322 str_set(str,"exit");
1327 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1333 str_set(str,"$ExitValue = ");
1336 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1340 str_cat(str,"last line");
1345 str_set(str,"next");
1351 str_set(str,"if (");
1352 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1355 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1358 i = ops[node+3].ival;
1360 if ((ops[i].ival & 255) == OBLOCK) {
1363 if ((ops[i].ival & 255) != OIF)
1372 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1376 str_cat(str,"else ");
1377 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1384 str_set(str,"while (");
1385 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1388 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1393 str_set(str,"for (");
1394 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1397 t = s = tmpstr->str_ptr;
1398 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1405 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1406 if (i && (t = index(fstr->str_ptr,0377))) {
1407 if (strnEQ(fstr->str_ptr,s,i))
1414 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1417 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1421 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1422 d = index(tmpstr->str_ptr,'$');
1424 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1429 fatal("Illegal for loop: %s",d);
1431 for (t = s; i = *t; t++) {
1433 if (i == '}' || i == ']')
1441 tmp2str = hfetch(symtab,str->str_ptr);
1442 if (tmp2str && atoi(tmp2str->str_ptr)) {
1444 "foreach %s (@%s) ",
1450 "foreach %s (keys %%%s) ",
1454 str_set(str,tokenbuf);
1455 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1462 if (len >= 2 && ops[node+2].ival) {
1463 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1466 fixtab(str,++level);
1467 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1470 fixtab(str,--level);
1474 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1482 fatal("Garbage length in walk");
1483 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1484 for (i = 2; i<= len; i++) {
1485 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1497 if (useval && prec < minprec) { /* need parens? */
1498 fstr = str_new(str->str_cur+2);
1499 str_nset(fstr,"(",1);
1501 str_ncat(fstr,")",1);
1506 *numericptr = numeric;
1509 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1510 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1513 else if (*t == '\t')
1541 /* strip trailing white space */
1543 s = str->str_ptr+str->str_cur - 1;
1544 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1547 str->str_cur = s + 1 - str->str_ptr;
1548 if (s >= str->str_ptr && *s != '\n')
1559 s = str->str_ptr+str->str_cur - 1;
1560 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1562 if (s >= str->str_ptr && *s != ';' && *s != '}')
1566 emit_split(str,level)
1573 str_cat(str,"@Fld");
1576 for (i = 1; i < maxfld; i++) {
1578 sprintf(tokenbuf,"$%s,",nameary[i]);
1580 sprintf(tokenbuf,"$Fld%d,",i);
1581 str_cat(str,tokenbuf);
1583 if (maxfld <= arymax)
1584 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1586 sprintf(tokenbuf,"$Fld%d)",maxfld);
1587 str_cat(str,tokenbuf);
1590 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 999);\n",const_FS);
1591 str_cat(str,tokenbuf);
1594 str_cat(str," = split($FS, $_, 999);\n");
1596 str_cat(str," = split(' ', $_, 999);\n");
1600 prewalk(numit,level,node,numericptr)
1612 int numeric = FALSE;
1620 type = ops[node].ival;
1625 prewalk(0,level,ops[node+1].ival,&numarg);
1626 if (ops[node+2].ival) {
1627 prewalk(0,level,ops[node+2].ival,&numarg);
1630 prewalk(0,level,ops[node+3].ival,&numarg);
1632 if (ops[node+3].ival) {
1633 prewalk(0,level,ops[node+4].ival,&numarg);
1637 prewalk(0,level,ops[node+1].ival,&numarg);
1638 prewalk(0,level,ops[node+2].ival,&numarg);
1640 prewalk(0,level,ops[node+3].ival,&numarg);
1644 prewalk(1,level,ops[node+1].ival,&numarg);
1645 prewalk(1,level,ops[node+2].ival,&numarg);
1650 prewalk(0,level,ops[node+1].ival,&numarg);
1654 prewalk(0,level,ops[node+1].ival,&numarg);
1657 i = prewalk(0,level,ops[node+1].ival,&numarg);
1660 prewalk(0,level,ops[node+2].ival,&numarg);
1664 prewalk(0,level,ops[node+2].ival,&numarg);
1669 prewalk(0,level,ops[node+1].ival,&numarg);
1672 prewalk(0,level,ops[node+1].ival,&numarg);
1673 prewalk(0,level,ops[node+2].ival,&numarg);
1676 prewalk(0,level,ops[node+1].ival,&numarg);
1677 prewalk(0,level,ops[node+2].ival,&numarg);
1680 prewalk(0,level,ops[node+1].ival,&numarg);
1683 prewalk(0,level,ops[node+1].ival,&numarg);
1687 prewalk(0,level,ops[node+1].ival,&numarg);
1689 prewalk(0,level,ops[node+2].ival,&numarg);
1692 prewalk(0,level,ops[node+1].ival,&numarg);
1694 prewalk(0,level,ops[node+2].ival,&numarg);
1697 prewalk(0,level,ops[node+1].ival,&numarg);
1701 prewalk(0,level,ops[node+2].ival,&numarg);
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1704 prewalk(0,level,ops[node+3].ival,&numarg);
1709 prewalk(0,level,ops[node+1].ival,&numarg);
1713 prewalk(0,level,ops[node+2].ival,&numarg);
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1715 prewalk(0,level,ops[node+3].ival,&numarg);
1719 prewalk(0,level,ops[node+1].ival,&numarg);
1723 prewalk(0,level,ops[node+1].ival,&numarg);
1724 prewalk(0,level,ops[node+2].ival,&numarg);
1727 prewalk(0,level,ops[node+2].ival,&numarg);
1728 prewalk(0,level,ops[node+1].ival,&numarg);
1729 prewalk(0,level,ops[node+3].ival,&numarg);
1730 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1731 numericize(ops[node+2].ival);
1733 numericize(ops[node+3].ival);
1738 prewalk(1,level,ops[node+1].ival,&numarg);
1739 prewalk(1,level,ops[node+2].ival,&numarg);
1743 prewalk(1,level,ops[node+1].ival,&numarg);
1744 prewalk(1,level,ops[node+2].ival,&numarg);
1748 prewalk(1,level,ops[node+1].ival,&numarg);
1749 prewalk(1,level,ops[node+2].ival,&numarg);
1753 prewalk(1,level,ops[node+1].ival,&numarg);
1754 prewalk(1,level,ops[node+2].ival,&numarg);
1758 prewalk(1,level,ops[node+1].ival,&numarg);
1759 prewalk(1,level,ops[node+2].ival,&numarg);
1763 prewalk(1,level,ops[node+1].ival,&numarg);
1764 prewalk(1,level,ops[node+2].ival,&numarg);
1768 prewalk(1,level,ops[node+1].ival,&numarg);
1772 prewalk(1,level,ops[node+1].ival,&numarg);
1776 prewalk(1,level,ops[node+1].ival,&numarg);
1780 prewalk(1,level,ops[node+1].ival,&numarg);
1784 prewalk(1,level,ops[node+1].ival,&numarg);
1788 prewalk(1,level,ops[node+1].ival,&numarg);
1792 prewalk(0,level,ops[node+1].ival,&numarg);
1798 prewalk(0,level,ops[node+1].ival,&numarg);
1801 prewalk(0,level,ops[node+1].ival,&numarg);
1802 prewalk(1,level,ops[node+2].ival,&numarg);
1804 prewalk(1,level,ops[node+3].ival,&numarg);
1811 prewalk(0,level,ops[node+2].ival,&numarg);
1813 prewalk(0,level,ops[node+3].ival,&numarg);
1814 prewalk(0,level,ops[node+1].ival,&numarg);
1817 prewalk(0,level,ops[node+1].ival,&numarg);
1818 prewalk(0,level,ops[node+2].ival,&numarg);
1822 prewalk(0,level,ops[node+1].ival,&numarg);
1823 prewalk(0,level,ops[node+2].ival,&numarg);
1829 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1831 prewalk(0,level,ops[node+2].ival,&numarg);
1832 prewalk(0,level,ops[node+4].ival,&numarg);
1833 prewalk(0,level,ops[node+5].ival,&numarg);
1835 str_cat(tmpstr,"(");
1836 tmp2str = str_new(0);
1837 if (subretnum || numarg)
1838 str_set(tmp2str,"1");
1839 hstore(symtab,tmpstr->str_ptr,tmp2str);
1845 prewalk(0,level,ops[node+1].ival,&numarg);
1851 tmp2str = str_new(0);
1852 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1853 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1855 str_cat(tmp2str,"(");
1856 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1857 if (tmpstr && tmpstr->str_ptr)
1858 numeric |= atoi(tmpstr->str_ptr);
1859 prewalk(0,level,ops[node+2].ival,&numarg);
1865 prewalk(0,level,ops[node+3].ival,&numarg);
1866 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1867 prewalk(0,level,ops[node+1].ival,&numarg);
1871 prewalk(0,level,ops[node+1].ival,&numarg);
1875 prewalk(0,level,ops[node+1].ival,&numarg);
1881 prewalk(0,level,ops[node+1].ival,&numarg);
1887 prewalk(0,level,ops[node+2].ival,&numarg);
1891 prewalk(0,level,ops[node+1].ival,&numarg);
1894 i = ops[node+1].ival;
1895 prewalk(0,level,i,&numarg);
1908 prewalk(0,level,ops[node+1].ival,&numarg);
1909 prewalk(0,level,ops[node+2].ival,&numarg);
1910 prewalk(0,level,ops[node+3].ival,&numarg);
1915 prewalk(0,level,ops[node+1].ival,&numarg);
1916 prewalk(0,level,ops[node+2].ival,&numarg);
1920 prewalk(0,level,ops[node+1].ival,&numarg);
1922 prewalk(0,level,ops[node+2].ival,&numarg);
1927 prewalk(0,level,ops[node+1].ival,&numarg);
1931 if (len == 3) { /* output redirection */
1932 prewalk(0,level,ops[node+3].ival,&numarg);
1933 prewalk(0,level,ops[node+2].ival,&numarg);
1935 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1961 prewalk(type != OLENGTH && type != OSYSTEM,
1962 level,ops[node+1].ival,&numarg);
1970 prewalk(1,level,ops[node+1].ival,&numarg);
1978 prewalk(0,level,ops[node+1].ival,&numarg);
1979 prewalk(0,level,ops[node+2].ival,&numarg);
1981 prewalk(0,level,ops[node+3].ival,&numarg);
1985 prewalk(0,level,ops[node+1].ival,&numarg);
1986 prewalk(0,level,ops[node+2].ival,&numarg);
1989 prewalk(0,level,ops[node+1].ival,&numarg);
1990 prewalk(0,level,ops[node+2].ival,&numarg);
1991 prewalk(0,level,ops[node+3].ival,&numarg);
1992 prewalk(0,level,ops[node+4].ival,&numarg);
1995 prewalk(0,level,ops[node+2].ival,&numarg);
1996 prewalk(0,level,ops[node+1].ival,&numarg);
2000 prewalk(0,level,ops[node+2].ival,&numarg);
2003 prewalk(0,level,ops[node+1].ival,&numarg);
2010 fatal("Garbage length in prewalk");
2011 prewalk(0,level,ops[node+1].ival,&numarg);
2012 for (i = 2; i<= len; i++) {
2013 prewalk(0,level,ops[node+i].ival,&numarg);
2018 *numericptr = numeric;
2032 type = ops[node].ival;
2035 if (type == OVAR && len == 1) {
2036 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2037 tmp2str = str_make("1");
2038 hstore(symtab,tmpstr->str_ptr,tmp2str);