1 /* $Header: walk.c,v 3.0.1.6 90/10/16 11:35:51 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.6 90/10/16 11:35:51 lwall
10 * patch29: a2p mistranslated certain weird field separators
12 * Revision 3.0.1.5 90/08/09 05:55:01 lwall
13 * patch19: a2p emited local($_) without a semicolon
14 * patch19: a2p didn't make explicit split on whitespace skip leading whitespace
15 * patch19: foreach on a normal array was iterating on values instead of indexes
17 * Revision 3.0.1.4 90/03/01 10:32:45 lwall
18 * patch9: a2p didn't put a $ on ExitValue
20 * Revision 3.0.1.3 89/12/21 20:32:35 lwall
21 * patch7: in a2p, user-defined functions didn't work on some machines
23 * Revision 3.0.1.2 89/11/17 15:53:00 lwall
24 * patch5: on Pyramids, index(s, '}' + 128) doesn't find meta-}
26 * Revision 3.0.1.1 89/11/11 05:09:33 lwall
27 * patch2: in a2p, awk script with no line actions still needs main loop
29 * Revision 3.0 89/10/18 15:35:48 lwall
40 bool realexit = FALSE;
41 bool saw_getline = FALSE;
42 bool subretnum = FALSE;
44 bool saw_argv0 = FALSE;
49 STR *curargs = Nullstr;
52 walk(useval,level,node,numericptr,minprec)
57 int minprec; /* minimum precedence without parens */
71 int prec = P_MAX; /* assume no parens needed */
78 type = ops[node].ival;
85 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
86 if (do_split && need_entire && !absmaxfld)
87 split_to_array = TRUE;
88 if (do_split && split_to_array)
89 set_array_base = TRUE;
91 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
93 if (fswitch && !const_FS)
95 if (saw_FS > 1 || saw_RS)
97 if (saw_ORS && need_entire)
100 str_cat(str,"$FS = '");
101 if (index("*+?.[]()|^$\\",fswitch))
103 sprintf(tokenbuf,"%c",fswitch);
104 str_cat(str,tokenbuf);
105 str_cat(str,"';\t\t# field separator from -F switch\n");
107 else if (saw_FS && !const_FS) {
108 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
111 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
114 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
117 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
119 if (str->str_cur > 20)
121 if (ops[node+2].ival) {
122 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
126 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
127 if (*fstr->str_ptr) {
129 str_cat(str,"line: ");
130 str_cat(str,"while (<>) {\n");
132 if (saw_FS && !const_FS)
135 str_cat(str,"chop;\t# strip record separator\n");
140 while (isalpha(*namelist)) {
141 for (d = tokenbuf,s=namelist;
142 isalpha(*s) || isdigit(*s) || *s == '_';
145 while (*s && !isalpha(*s)) s++;
147 nameary[++arymax] = savestr(tokenbuf);
153 emit_split(str,level);
159 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
162 str_cat(str,"while (<>) { } # (no line actions)\n");
163 if (ops[node+4].ival) {
167 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
172 str_cat(str,"exit $ExitValue;\n");
178 for (len = 0; len < 4; len++) {
179 if (saw_getline & (1 << len)) {
180 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
181 str_cat(str, tokenbuf);
184 str_cat(str," &Pick('',@_);\n");
186 str_cat(str," ($fh) = @_;\n");
190 str_cat(str," $FNRbase = $. if eof;\n");
193 str_cat(str," local($_);\n");
196 " if ($getline_ok = (($_ = <$fh>) ne ''))");
199 " if ($getline_ok = (($_ = <>) ne ''))");
200 str_cat(str, " {\n");
206 str_cat(str,"chop;\t# strip record separator\n");
209 if (do_split && !(len & 1)) {
211 emit_split(str,level);
216 str_cat(str,"}\n $_;\n}\n");
221 if (do_fancy_opens) {
224 local($mode,$name,$pipe) = @_;\n\
225 $fh = $opened{$name};\n\
227 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
228 open($fh,$mode.$name.$pipe);\n\
235 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
236 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
239 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
247 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
249 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
257 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
258 /* translate \nnn to [\nnn] */
259 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
260 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
272 for (d=tokenbuf; *d; d++)
274 str_cat(str,tokenbuf);
281 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
283 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
288 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
289 if (*tmpstr->str_ptr) {
292 str_scat(str,tmpstr);
293 str_cat(str,") {\n");
295 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
302 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
309 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
315 str = walk(1,level,ops[node+1].ival,&numarg,prec);
317 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
319 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
324 str = walk(1,level,ops[node+1].ival,&numarg,prec);
326 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
328 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
335 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
340 str = walk(1,level,ops[node+1].ival,&numarg,prec);
342 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));
351 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
358 str = walk(1,level,ops[node+1].ival,&numarg,prec);
361 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
363 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
368 str = walk(1,level,ops[node+1].ival,&numarg,prec);
371 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
373 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
380 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
386 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
388 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
389 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
392 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
395 str_set(tmpstr,"eq");
396 else if (strEQ(t,"!="))
397 str_set(tmpstr,"ne");
398 else if (strEQ(t,"<"))
399 str_set(tmpstr,"lt");
400 else if (strEQ(t,"<="))
401 str_set(tmpstr,"le");
402 else if (strEQ(t,">"))
403 str_set(tmpstr,"gt");
404 else if (strEQ(t,">="))
405 str_set(tmpstr,"ge");
406 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
407 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
411 if (numeric & 1) /* numeric is very good guess */
419 str_scat(str,tmpstr);
422 str_scat(str,tmp2str);
429 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
436 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
438 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
439 if (strEQ(tmpstr->str_ptr,"~"))
442 str_scat(str,tmpstr);
446 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
454 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
461 type = ops[ops[node+1].ival].ival & 255;
462 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
464 type = ops[ops[node+2].ival].ival & 255;
466 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
471 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
473 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
474 str_scat(str,tmpstr);
475 if (str_len(tmpstr) > 1)
479 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
485 str = walk(1,level,ops[node+1].ival,&numarg,prec);
487 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
493 str = walk(1,level,ops[node+1].ival,&numarg,prec);
495 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
501 str = walk(1,level,ops[node+1].ival,&numarg,prec);
503 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
509 str = walk(1,level,ops[node+1].ival,&numarg,prec);
511 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
517 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
519 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
525 str = walk(1,level,ops[node+1].ival,&numarg,prec);
527 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
533 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
539 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
547 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
555 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
563 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
574 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
585 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
586 if (!*fstr->str_ptr) {
588 len = 2; /* a legal fiction */
595 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
596 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
597 if (!do_fancy_opens) {
599 if (*t == '"' || *t == '\'')
600 t = cpytill(tokenbuf,t+1,*t);
602 fatal("Internal error: OGETLINE %s", t);
604 s = savestr(tokenbuf);
605 for (t = tokenbuf; *t; t++) {
607 if (!isalpha(*t) && !isdigit(*t))
610 if (!index(tokenbuf,'_'))
612 tmp3str = hfetch(symtab,tokenbuf);
615 str_cat(opens,"open(");
616 str_cat(opens,tokenbuf);
620 str_cat(opens,tmpstr->str_ptr+1);
622 if (*fstr->str_ptr == '|')
625 if (*fstr->str_ptr == '|')
626 str_cat(opens,") || die 'Cannot pipe from \"");
628 str_cat(opens,") || die 'Cannot open file \"");
630 str_cat(opens,"'.\"");
633 str_cat(opens,"\".'");
634 str_cat(opens,"\".';\n");
635 hstore(symtab,tokenbuf,str_make("x"));
640 str_cat(tmpstr,tokenbuf);
643 if (*fstr->str_ptr == '|')
644 str_cat(tmpstr,", '|'");
648 tmpstr = str_make("");
649 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
650 str_cat(str,tokenbuf);
653 str_cat(str,",$getline_ok)");
654 saw_getline |= 1 << len;
658 str_set(str,"sprintf(");
659 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
665 str_set(str,"substr(");
666 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
669 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
673 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
677 str_cat(str,"999999");
682 str_set(str,ops[node+1].cval);
687 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
692 str_scat(str,tmpstr);
693 str_cat(str," = split(");
695 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
696 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
697 i = fstr->str_ptr[1] & 127;
698 if (index("*+?.[]()|^$\\",i))
699 sprintf(tokenbuf,"/\\%c/",i);
701 sprintf(tokenbuf,"' '");
703 sprintf(tokenbuf,"/%c/",i);
704 str_cat(str,tokenbuf);
711 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
712 str_cat(str,tokenbuf);
719 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
721 str_cat(str,", 9999)");
729 str_set(str,"index(");
730 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
733 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
741 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
744 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
746 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
752 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
753 curargs = str_new(0);
754 str_sset(curargs,fstr);
755 str_cat(curargs,",");
756 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
762 t = tmp2str->str_ptr;
763 while (t = instr(t,"return "))
767 for (t = s+7; *t; t++) {
768 if (*t == ';' || *t == '}')
773 tmp2str->str_cur -= 7;
779 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
783 str_cat(str,"local(");
785 str_cat(str,") = @_;");
788 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
791 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
794 str_scat(str,tmp2str);
802 tmp2str = str_new(0);
804 str_set(tmp2str,"1");
805 hstore(symtab,tmpstr->str_ptr,tmp2str);
812 str_cat(str,"return ");
813 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
819 str_cat(str,"return");
824 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
827 tmpstr = hfetch(symtab,str->str_ptr+3);
828 if (tmpstr && tmpstr->str_ptr)
829 numeric |= atoi(tmpstr->str_ptr);
830 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
844 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
845 if (strNE(tmpstr->str_ptr,"$_")) {
846 str_cat(tmpstr, " =~ s");
850 str_set(tmpstr, "s");
853 str_set(tmpstr, "s");
854 type = ops[ops[node+2].ival].ival;
857 tmp3str = str_new(0);
859 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
860 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
868 str_set(tmp2str,tokenbuf);
871 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
872 str_set(tmp3str,"($s_ = '\"'.(");
873 str_scat(tmp3str,tmp2str);
874 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
875 str_set(tmp2str,"eval $s_");
876 s = (*s == 'g' ? "ge" : "e");
879 type = ops[ops[node+1].ival].ival;
882 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
883 if (type == OREGEX) {
886 str_scat(str,tmp3str);
887 str_scat(str,tmpstr);
889 str_scat(str,tmp2str);
893 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
896 str_scat(str,tmp3str);
897 str_scat(str,tmpstr);
901 str_scat(str,tmp2str);
909 str_cat(str,"$s = ");
912 str_scat(str,tmp3str);
913 str_scat(str,tmpstr);
915 str_scat(str,tmp2str);
928 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
932 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
934 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
937 else if (*t == '\\') {
941 case '\\': case '"': case 'n': case 't':
943 default: /* hide this from perl */
952 str_cat(str,tokenbuf);
959 str_set(str,"defined $");
963 str_set(str,"delete $");
973 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
975 tmp2str = hfetch(symtab,tmpstr->str_ptr);
976 if (tmp2str && atoi(tmp2str->str_ptr))
978 if (strEQ(str->str_ptr,"$FNR")) {
981 str_set(str,"($.-$FNRbase)");
983 else if (strEQ(str->str_ptr,"$NR")) {
987 else if (strEQ(str->str_ptr,"$NF")) {
989 str_set(str,"$#Fld");
991 else if (strEQ(str->str_ptr,"$0"))
993 else if (strEQ(str->str_ptr,"$ARGC"))
994 str_set(str,"($#ARGV+1)");
999 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
1000 ??? if (instr(curargs->str_ptr,tokenbuf))
1001 str_cat(str,"\377"); /* can't translate yet */
1004 str_cat(tmpstr,"[]");
1005 tmp2str = hfetch(symtab,tmpstr->str_ptr);
1006 if (tmp2str && atoi(tmp2str->str_ptr))
1010 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1012 if (strEQ(str->str_ptr,"$ARGV[0")) {
1013 str_set(str,"$ARGV0");
1017 if (tmp2str && atoi(tmp2str->str_ptr))
1018 strcpy(tokenbuf,"]");
1020 strcpy(tokenbuf,"}");
1022 str_cat(str,tokenbuf);
1029 if (split_to_array) {
1030 str_set(str,"$Fld");
1032 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1037 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1039 sprintf(tokenbuf,"$%s",nameary[i]);
1041 sprintf(tokenbuf,"$Fld%d",i);
1042 str_set(str,tokenbuf);
1047 str_set(str,"$Fld[");
1048 i = ops[node+1].ival;
1049 if ((ops[i].ival & 255) == OPAREN)
1051 tmpstr=walk(1,level,i,&numarg,P_MIN);
1052 str_scat(str,tmpstr);
1071 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1072 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1074 str_scat(str,tmpstr);
1080 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1081 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1083 str_scat(str,tmpstr);
1089 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1091 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1093 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1102 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1103 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1109 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1112 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1113 if (*tmpstr->str_ptr == ';') {
1115 str_cat(str,tmpstr->str_ptr+1);
1122 str = str_make("close(");
1123 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1124 if (!do_fancy_opens) {
1125 t = tmpstr->str_ptr;
1126 if (*t == '"' || *t == '\'')
1127 t = cpytill(tokenbuf,t+1,*t);
1129 fatal("Internal error: OCLOSE %s",t);
1130 s = savestr(tokenbuf);
1131 for (t = tokenbuf; *t; t++) {
1133 if (!isalpha(*t) && !isdigit(*t))
1136 if (!index(tokenbuf,'_'))
1140 str_set(str,"close ");
1141 str_cat(str,tokenbuf);
1144 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1147 str_set(str,tokenbuf);
1152 lparen = ""; /* set to parens if necessary */
1155 if (len == 3) { /* output redirection */
1156 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1157 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1158 if (!do_fancy_opens) {
1159 t = tmpstr->str_ptr;
1160 if (*t == '"' || *t == '\'')
1161 t = cpytill(tokenbuf,t+1,*t);
1163 fatal("Internal error: OPRINT");
1165 s = savestr(tokenbuf);
1166 for (t = tokenbuf; *t; t++) {
1168 if (!isalpha(*t) && !isdigit(*t))
1171 if (!index(tokenbuf,'_'))
1173 tmp3str = hfetch(symtab,tokenbuf);
1175 str_cat(opens,"open(");
1176 str_cat(opens,tokenbuf);
1177 str_cat(opens,", ");
1180 str_scat(opens,tmp2str);
1181 str_cat(opens,tmpstr->str_ptr+1);
1182 if (*tmp2str->str_ptr == '|')
1183 str_cat(opens,") || die 'Cannot pipe to \"");
1185 str_cat(opens,") || die 'Cannot create file \"");
1187 str_cat(opens,"'.\"");
1190 str_cat(opens,"\".'");
1191 str_cat(opens,"\".';\n");
1192 hstore(symtab,tokenbuf,str_make("x"));
1200 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1201 tmp2str->str_ptr, tmpstr->str_ptr);
1202 str_cat(str,tokenbuf);
1204 strcpy(tokenbuf,"$fh");
1212 strcpy(tokenbuf,"");
1213 str_cat(str,lparen); /* may be null */
1214 if (type == OPRINTF)
1215 str_cat(str,"printf");
1217 str_cat(str,"print");
1218 if (len == 3 || do_fancy_opens) {
1221 str_cat(str,tokenbuf);
1223 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1224 if (!*tmpstr->str_ptr && lval_field) {
1225 t = saw_OFS ? "$," : "' '";
1226 if (split_to_array) {
1227 sprintf(tokenbuf,"join(%s,@Fld)",t);
1228 str_cat(tmpstr,tokenbuf);
1231 for (i = 1; i < maxfld; i++) {
1233 sprintf(tokenbuf,"$%s, ",nameary[i]);
1235 sprintf(tokenbuf,"$Fld%d, ",i);
1236 str_cat(tmpstr,tokenbuf);
1238 if (maxfld <= arymax)
1239 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1241 sprintf(tokenbuf,"$Fld%d",maxfld);
1242 str_cat(tmpstr,tokenbuf);
1245 if (*tmpstr->str_ptr) {
1247 str_scat(str,tmpstr);
1252 str_cat(str,rparen); /* may be null */
1256 str = str_make("rand(1)");
1259 str = str_make("srand(");
1262 str = str_make("atan2(");
1265 str = str_make("sin(");
1268 str = str_make("cos(");
1271 str = str_make("system(");
1274 str = str_make("length(");
1277 str = str_make("log(");
1280 str = str_make("exp(");
1283 str = str_make("sqrt(");
1286 str = str_make("int(");
1290 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1292 tmpstr = str_new(0);;
1293 if (!*tmpstr->str_ptr) {
1295 t = saw_OFS ? "$," : "' '";
1296 if (split_to_array) {
1297 sprintf(tokenbuf,"join(%s,@Fld)",t);
1298 str_cat(tmpstr,tokenbuf);
1301 sprintf(tokenbuf,"join(%s, ",t);
1302 str_cat(tmpstr,tokenbuf);
1303 for (i = 1; i < maxfld; i++) {
1305 sprintf(tokenbuf,"$%s,",nameary[i]);
1307 sprintf(tokenbuf,"$Fld%d,",i);
1308 str_cat(tmpstr,tokenbuf);
1310 if (maxfld <= arymax)
1311 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1313 sprintf(tokenbuf,"$Fld%d)",maxfld);
1314 str_cat(tmpstr,tokenbuf);
1318 str_cat(tmpstr,"$_");
1320 if (strEQ(tmpstr->str_ptr,"$_")) {
1321 if (type == OLENGTH && !do_chop) {
1322 str = str_make("(length(");
1323 str_cat(tmpstr,") - 1");
1326 str_scat(str,tmpstr);
1332 str_set(str,"last");
1336 str_set(str,"next line");
1342 str_set(str,"exit");
1347 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1353 str_set(str,"$ExitValue = ");
1356 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1360 str_cat(str,"last line");
1365 str_set(str,"next");
1371 str_set(str,"if (");
1372 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1375 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1378 i = ops[node+3].ival;
1380 if ((ops[i].ival & 255) == OBLOCK) {
1383 if ((ops[i].ival & 255) != OIF)
1392 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1396 str_cat(str,"else ");
1397 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1404 str_set(str,"while (");
1405 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1408 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1413 str_set(str,"for (");
1414 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1417 t = s = tmpstr->str_ptr;
1418 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1425 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1426 if (i && (t = index(fstr->str_ptr,0377))) {
1427 if (strnEQ(fstr->str_ptr,s,i))
1434 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1437 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1441 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1442 d = index(tmpstr->str_ptr,'$');
1444 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1449 fatal("Illegal for loop: %s",d);
1451 for (t = s; i = *t; t++) {
1453 if (i == '}' || i == ']')
1461 tmp2str = hfetch(symtab,str->str_ptr);
1462 if (tmp2str && atoi(tmp2str->str_ptr)) {
1464 "foreach %s ($[ .. $#%s) ",
1470 "foreach %s (keys %%%s) ",
1474 str_set(str,tokenbuf);
1475 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1482 if (len >= 2 && ops[node+2].ival) {
1483 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1486 fixtab(str,++level);
1487 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1490 fixtab(str,--level);
1494 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1502 fatal("Garbage length in walk");
1503 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1504 for (i = 2; i<= len; i++) {
1505 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1517 if (useval && prec < minprec) { /* need parens? */
1518 fstr = str_new(str->str_cur+2);
1519 str_nset(fstr,"(",1);
1521 str_ncat(fstr,")",1);
1526 *numericptr = numeric;
1529 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1530 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1533 else if (*t == '\t')
1561 /* strip trailing white space */
1563 s = str->str_ptr+str->str_cur - 1;
1564 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1567 str->str_cur = s + 1 - str->str_ptr;
1568 if (s >= str->str_ptr && *s != '\n')
1579 s = str->str_ptr+str->str_cur - 1;
1580 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1582 if (s >= str->str_ptr && *s != ';' && *s != '}')
1586 emit_split(str,level)
1593 str_cat(str,"@Fld");
1596 for (i = 1; i < maxfld; i++) {
1598 sprintf(tokenbuf,"$%s,",nameary[i]);
1600 sprintf(tokenbuf,"$Fld%d,",i);
1601 str_cat(str,tokenbuf);
1603 if (maxfld <= arymax)
1604 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1606 sprintf(tokenbuf,"$Fld%d)",maxfld);
1607 str_cat(str,tokenbuf);
1610 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1611 str_cat(str,tokenbuf);
1614 str_cat(str," = split($FS, $_, 9999);\n");
1616 str_cat(str," = split(' ', $_, 9999);\n");
1620 prewalk(numit,level,node,numericptr)
1632 int numeric = FALSE;
1640 type = ops[node].ival;
1645 prewalk(0,level,ops[node+1].ival,&numarg);
1646 if (ops[node+2].ival) {
1647 prewalk(0,level,ops[node+2].ival,&numarg);
1650 prewalk(0,level,ops[node+3].ival,&numarg);
1652 if (ops[node+3].ival) {
1653 prewalk(0,level,ops[node+4].ival,&numarg);
1657 prewalk(0,level,ops[node+1].ival,&numarg);
1658 prewalk(0,level,ops[node+2].ival,&numarg);
1660 prewalk(0,level,ops[node+3].ival,&numarg);
1664 prewalk(1,level,ops[node+1].ival,&numarg);
1665 prewalk(1,level,ops[node+2].ival,&numarg);
1670 prewalk(0,level,ops[node+1].ival,&numarg);
1674 prewalk(0,level,ops[node+1].ival,&numarg);
1677 i = prewalk(0,level,ops[node+1].ival,&numarg);
1680 prewalk(0,level,ops[node+2].ival,&numarg);
1684 prewalk(0,level,ops[node+2].ival,&numarg);
1689 prewalk(0,level,ops[node+1].ival,&numarg);
1692 prewalk(0,level,ops[node+1].ival,&numarg);
1693 prewalk(0,level,ops[node+2].ival,&numarg);
1696 prewalk(0,level,ops[node+1].ival,&numarg);
1697 prewalk(0,level,ops[node+2].ival,&numarg);
1700 prewalk(0,level,ops[node+1].ival,&numarg);
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1707 prewalk(0,level,ops[node+1].ival,&numarg);
1709 prewalk(0,level,ops[node+2].ival,&numarg);
1712 prewalk(0,level,ops[node+1].ival,&numarg);
1714 prewalk(0,level,ops[node+2].ival,&numarg);
1717 prewalk(0,level,ops[node+1].ival,&numarg);
1721 prewalk(0,level,ops[node+2].ival,&numarg);
1723 prewalk(0,level,ops[node+1].ival,&numarg);
1724 prewalk(0,level,ops[node+3].ival,&numarg);
1729 prewalk(0,level,ops[node+1].ival,&numarg);
1733 prewalk(0,level,ops[node+2].ival,&numarg);
1734 prewalk(0,level,ops[node+1].ival,&numarg);
1735 prewalk(0,level,ops[node+3].ival,&numarg);
1739 prewalk(0,level,ops[node+1].ival,&numarg);
1743 prewalk(0,level,ops[node+1].ival,&numarg);
1744 prewalk(0,level,ops[node+2].ival,&numarg);
1747 prewalk(0,level,ops[node+2].ival,&numarg);
1748 prewalk(0,level,ops[node+1].ival,&numarg);
1749 prewalk(0,level,ops[node+3].ival,&numarg);
1750 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1751 numericize(ops[node+2].ival);
1753 numericize(ops[node+3].ival);
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);
1769 prewalk(1,level,ops[node+2].ival,&numarg);
1773 prewalk(1,level,ops[node+1].ival,&numarg);
1774 prewalk(1,level,ops[node+2].ival,&numarg);
1778 prewalk(1,level,ops[node+1].ival,&numarg);
1779 prewalk(1,level,ops[node+2].ival,&numarg);
1783 prewalk(1,level,ops[node+1].ival,&numarg);
1784 prewalk(1,level,ops[node+2].ival,&numarg);
1788 prewalk(1,level,ops[node+1].ival,&numarg);
1792 prewalk(1,level,ops[node+1].ival,&numarg);
1796 prewalk(1,level,ops[node+1].ival,&numarg);
1800 prewalk(1,level,ops[node+1].ival,&numarg);
1804 prewalk(1,level,ops[node+1].ival,&numarg);
1808 prewalk(1,level,ops[node+1].ival,&numarg);
1812 prewalk(0,level,ops[node+1].ival,&numarg);
1818 prewalk(0,level,ops[node+1].ival,&numarg);
1821 prewalk(0,level,ops[node+1].ival,&numarg);
1822 prewalk(1,level,ops[node+2].ival,&numarg);
1824 prewalk(1,level,ops[node+3].ival,&numarg);
1831 prewalk(0,level,ops[node+2].ival,&numarg);
1833 prewalk(0,level,ops[node+3].ival,&numarg);
1834 prewalk(0,level,ops[node+1].ival,&numarg);
1837 prewalk(0,level,ops[node+1].ival,&numarg);
1838 prewalk(0,level,ops[node+2].ival,&numarg);
1842 prewalk(0,level,ops[node+1].ival,&numarg);
1843 prewalk(0,level,ops[node+2].ival,&numarg);
1849 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1851 prewalk(0,level,ops[node+2].ival,&numarg);
1852 prewalk(0,level,ops[node+4].ival,&numarg);
1853 prewalk(0,level,ops[node+5].ival,&numarg);
1855 str_cat(tmpstr,"(");
1856 tmp2str = str_new(0);
1857 if (subretnum || numarg)
1858 str_set(tmp2str,"1");
1859 hstore(symtab,tmpstr->str_ptr,tmp2str);
1865 prewalk(0,level,ops[node+1].ival,&numarg);
1871 tmp2str = str_new(0);
1872 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1873 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1875 str_cat(tmp2str,"(");
1876 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1877 if (tmpstr && tmpstr->str_ptr)
1878 numeric |= atoi(tmpstr->str_ptr);
1879 prewalk(0,level,ops[node+2].ival,&numarg);
1885 prewalk(0,level,ops[node+3].ival,&numarg);
1886 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1887 prewalk(0,level,ops[node+1].ival,&numarg);
1891 prewalk(0,level,ops[node+1].ival,&numarg);
1895 prewalk(0,level,ops[node+1].ival,&numarg);
1901 prewalk(0,level,ops[node+1].ival,&numarg);
1907 prewalk(0,level,ops[node+2].ival,&numarg);
1911 prewalk(0,level,ops[node+1].ival,&numarg);
1914 i = ops[node+1].ival;
1915 prewalk(0,level,i,&numarg);
1928 prewalk(0,level,ops[node+1].ival,&numarg);
1929 prewalk(0,level,ops[node+2].ival,&numarg);
1930 prewalk(0,level,ops[node+3].ival,&numarg);
1935 prewalk(0,level,ops[node+1].ival,&numarg);
1936 prewalk(0,level,ops[node+2].ival,&numarg);
1940 prewalk(0,level,ops[node+1].ival,&numarg);
1942 prewalk(0,level,ops[node+2].ival,&numarg);
1947 prewalk(0,level,ops[node+1].ival,&numarg);
1951 if (len == 3) { /* output redirection */
1952 prewalk(0,level,ops[node+3].ival,&numarg);
1953 prewalk(0,level,ops[node+2].ival,&numarg);
1955 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1981 prewalk(type != OLENGTH && type != OSYSTEM,
1982 level,ops[node+1].ival,&numarg);
1990 prewalk(1,level,ops[node+1].ival,&numarg);
1998 prewalk(0,level,ops[node+1].ival,&numarg);
1999 prewalk(0,level,ops[node+2].ival,&numarg);
2001 prewalk(0,level,ops[node+3].ival,&numarg);
2005 prewalk(0,level,ops[node+1].ival,&numarg);
2006 prewalk(0,level,ops[node+2].ival,&numarg);
2009 prewalk(0,level,ops[node+1].ival,&numarg);
2010 prewalk(0,level,ops[node+2].ival,&numarg);
2011 prewalk(0,level,ops[node+3].ival,&numarg);
2012 prewalk(0,level,ops[node+4].ival,&numarg);
2015 prewalk(0,level,ops[node+2].ival,&numarg);
2016 prewalk(0,level,ops[node+1].ival,&numarg);
2020 prewalk(0,level,ops[node+2].ival,&numarg);
2023 prewalk(0,level,ops[node+1].ival,&numarg);
2030 fatal("Garbage length in prewalk");
2031 prewalk(0,level,ops[node+1].ival,&numarg);
2032 for (i = 2; i<= len; i++) {
2033 prewalk(0,level,ops[node+i].ival,&numarg);
2038 *numericptr = numeric;
2052 type = ops[node].ival;
2055 if (type == OVAR && len == 1) {
2056 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2057 tmp2str = str_make("1");
2058 hstore(symtab,tmpstr->str_ptr,tmp2str);