1 /* $RCSfile: walk.c,v $$Revision: 4.0.1.2 $$Date: 91/11/05 19:25:09 $
3 * Copyright (c) 1991, Larry Wall
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.
9 * Revision 4.0.1.2 91/11/05 19:25:09 lwall
10 * patch11: in a2p, split on whitespace produced extra null field
12 * Revision 4.0.1.1 91/06/07 12:22:04 lwall
13 * patch4: new copyright notice
14 * patch4: a2p didn't correctly implement -n switch
16 * Revision 4.0 91/03/20 01:58:36 lwall
27 bool realexit = FALSE;
28 bool saw_getline = FALSE;
29 bool subretnum = FALSE;
31 bool saw_argv0 = FALSE;
38 STR *curargs = Nullstr;
41 walk(useval,level,node,numericptr,minprec)
46 int minprec; /* minimum precedence without parens */
60 int prec = P_MAX; /* assume no parens needed */
67 type = ops[node].ival;
74 while (isalpha(*namelist)) {
75 for (d = tokenbuf,s=namelist;
76 isalpha(*s) || isdigit(*s) || *s == '_';
79 while (*s && !isalpha(*s)) s++;
81 nameary[++arymax] = savestr(tokenbuf);
88 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
89 if (do_split && need_entire && !absmaxfld)
90 split_to_array = TRUE;
91 if (do_split && split_to_array)
92 set_array_base = TRUE;
94 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
96 if (fswitch && !const_FS)
98 if (saw_FS > 1 || saw_RS)
100 if (saw_ORS && need_entire)
103 str_cat(str,"$FS = '");
104 if (index("*+?.[]()|^$\\",fswitch))
106 sprintf(tokenbuf,"%c",fswitch);
107 str_cat(str,tokenbuf);
108 str_cat(str,"';\t\t# field separator from -F switch\n");
110 else if (saw_FS && !const_FS) {
111 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
114 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
117 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
120 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
122 if (str->str_cur > 20)
124 if (ops[node+2].ival) {
125 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
129 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
130 if (*fstr->str_ptr) {
132 str_cat(str,"line: ");
133 str_cat(str,"while (<>) {\n");
135 if (saw_FS && !const_FS)
138 str_cat(str,"chop;\t# strip record separator\n");
142 emit_split(str,level);
148 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
151 str_cat(str,"while (<>) { } # (no line actions)\n");
152 if (ops[node+4].ival) {
156 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
161 str_cat(str,"exit $ExitValue;\n");
167 for (len = 0; len < 4; len++) {
168 if (saw_getline & (1 << len)) {
169 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
170 str_cat(str, tokenbuf);
173 str_cat(str," &Pick('',@_);\n");
175 str_cat(str," ($fh) = @_;\n");
179 str_cat(str," $FNRbase = $. if eof;\n");
182 str_cat(str," local($_);\n");
185 " if ($getline_ok = (($_ = <$fh>) ne ''))");
188 " if ($getline_ok = (($_ = <>) ne ''))");
189 str_cat(str, " {\n");
195 str_cat(str,"chop;\t# strip record separator\n");
198 if (do_split && !(len & 1)) {
200 emit_split(str,level);
205 str_cat(str,"}\n $_;\n}\n");
210 if (do_fancy_opens) {
213 local($mode,$name,$pipe) = @_;\n\
214 $fh = $opened{$name};\n\
216 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
217 open($fh,$mode.$name.$pipe);\n\
224 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
225 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
228 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
236 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
238 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
246 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
247 /* translate \nnn to [\nnn] */
248 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
249 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
261 for (d=tokenbuf; *d; d++)
263 str_cat(str,tokenbuf);
270 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
272 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
277 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
278 if (*tmpstr->str_ptr) {
281 str_scat(str,tmpstr);
282 str_cat(str,") {\n");
284 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
291 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
298 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
304 str = walk(1,level,ops[node+1].ival,&numarg,prec);
306 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
308 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
313 str = walk(1,level,ops[node+1].ival,&numarg,prec);
315 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
317 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
324 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
329 str = walk(1,level,ops[node+1].ival,&numarg,prec);
331 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
334 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
340 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
347 str = walk(1,level,ops[node+1].ival,&numarg,prec);
350 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
352 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
357 str = walk(1,level,ops[node+1].ival,&numarg,prec);
360 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
362 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
369 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
375 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
377 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
378 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
381 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
384 str_set(tmpstr,"eq");
385 else if (strEQ(t,"!="))
386 str_set(tmpstr,"ne");
387 else if (strEQ(t,"<"))
388 str_set(tmpstr,"lt");
389 else if (strEQ(t,"<="))
390 str_set(tmpstr,"le");
391 else if (strEQ(t,">"))
392 str_set(tmpstr,"gt");
393 else if (strEQ(t,">="))
394 str_set(tmpstr,"ge");
395 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
396 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
400 if (numeric & 1) /* numeric is very good guess */
408 str_scat(str,tmpstr);
411 str_scat(str,tmp2str);
418 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
425 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
427 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
428 if (strEQ(tmpstr->str_ptr,"~"))
431 str_scat(str,tmpstr);
435 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
443 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
450 type = ops[ops[node+1].ival].ival & 255;
451 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
453 type = ops[ops[node+2].ival].ival & 255;
455 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
460 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
462 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
463 str_scat(str,tmpstr);
464 if (str_len(tmpstr) > 1)
468 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
474 str = walk(1,level,ops[node+1].ival,&numarg,prec);
476 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
482 str = walk(1,level,ops[node+1].ival,&numarg,prec);
484 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
490 str = walk(1,level,ops[node+1].ival,&numarg,prec);
492 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
498 str = walk(1,level,ops[node+1].ival,&numarg,prec);
500 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
506 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
508 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
514 str = walk(1,level,ops[node+1].ival,&numarg,prec);
516 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
522 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
528 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
536 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
544 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
552 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
563 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
574 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
575 if (!*fstr->str_ptr) {
577 len = 2; /* a legal fiction */
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) {
588 if (*t == '"' || *t == '\'')
589 t = cpytill(tokenbuf,t+1,*t);
591 fatal("Internal error: OGETLINE %s", t);
593 s = savestr(tokenbuf);
594 for (t = tokenbuf; *t; t++) {
598 if (!isalpha(*t) && !isdigit(*t))
601 if (!index(tokenbuf,'_'))
603 tmp3str = hfetch(symtab,tokenbuf);
606 str_cat(opens,"open(");
607 str_cat(opens,tokenbuf);
611 str_cat(opens,tmpstr->str_ptr+1);
613 if (*fstr->str_ptr == '|')
616 if (*fstr->str_ptr == '|')
617 str_cat(opens,") || die 'Cannot pipe from \"");
619 str_cat(opens,") || die 'Cannot open file \"");
621 str_cat(opens,"'.\"");
624 str_cat(opens,"\".'");
625 str_cat(opens,"\".';\n");
626 hstore(symtab,tokenbuf,str_make("x"));
631 str_cat(tmpstr,tokenbuf);
634 if (*fstr->str_ptr == '|')
635 str_cat(tmpstr,", '|'");
639 tmpstr = str_make("");
640 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
641 str_cat(str,tokenbuf);
644 str_cat(str,",$getline_ok)");
645 saw_getline |= 1 << len;
649 str_set(str,"sprintf(");
650 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
656 str_set(str,"substr(");
657 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
660 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
664 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
668 str_cat(str,"999999");
673 str_set(str,ops[node+1].cval);
679 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
684 str_scat(str,tmpstr);
685 str_cat(str," = split(");
687 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
688 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
689 i = fstr->str_ptr[1] & 127;
690 if (index("*+?.[]()|^$\\",i))
691 sprintf(tokenbuf,"/\\%c/",i);
693 sprintf(tokenbuf,"' '");
695 sprintf(tokenbuf,"/%c/",i);
696 str_cat(str,tokenbuf);
703 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
704 str_cat(str,tokenbuf);
713 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
723 str_set(str,"index(");
724 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
727 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
735 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
738 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
740 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
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);
756 t = tmp2str->str_ptr;
757 while (t = instr(t,"return "))
761 for (t = s+7; *t; t++) {
762 if (*t == ';' || *t == '}')
767 tmp2str->str_cur -= 7;
773 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
777 str_cat(str,"local(");
779 str_cat(str,") = @_;");
782 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
785 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
788 str_scat(str,tmp2str);
796 tmp2str = str_new(0);
798 str_set(tmp2str,"1");
799 hstore(symtab,tmpstr->str_ptr,tmp2str);
806 str_cat(str,"return ");
807 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
813 str_cat(str,"return");
818 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
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));
838 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
839 if (strNE(tmpstr->str_ptr,"$_")) {
840 str_cat(tmpstr, " =~ s");
844 str_set(tmpstr, "s");
847 str_set(tmpstr, "s");
848 type = ops[ops[node+2].ival].ival;
851 tmp3str = str_new(0);
853 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
854 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
862 str_set(tmp2str,tokenbuf);
865 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
866 str_set(tmp3str,"($s_ = '\"'.(");
867 str_scat(tmp3str,tmp2str);
868 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
869 str_set(tmp2str,"eval $s_");
870 s = (*s == 'g' ? "ge" : "e");
873 type = ops[ops[node+1].ival].ival;
876 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
877 if (type == OREGEX) {
880 str_scat(str,tmp3str);
881 str_scat(str,tmpstr);
883 str_scat(str,tmp2str);
887 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
890 str_scat(str,tmp3str);
891 str_scat(str,tmpstr);
895 str_scat(str,tmp2str);
903 str_cat(str,"$s = ");
906 str_scat(str,tmp3str);
907 str_scat(str,tmpstr);
909 str_scat(str,tmp2str);
922 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
926 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
928 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
931 else if (*t == '\\') {
935 case '\\': case '"': case 'n': case 't': case '$':
937 default: /* hide this from perl */
946 str_cat(str,tokenbuf);
953 str_set(str,"defined $");
957 str_set(str,"delete $");
967 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
969 tmp2str = hfetch(symtab,tmpstr->str_ptr);
970 if (tmp2str && atoi(tmp2str->str_ptr))
972 if (strEQ(str->str_ptr,"$FNR")) {
975 str_set(str,"($.-$FNRbase)");
977 else if (strEQ(str->str_ptr,"$NR")) {
981 else if (strEQ(str->str_ptr,"$NF")) {
983 str_set(str,"$#Fld");
985 else if (strEQ(str->str_ptr,"$0"))
987 else if (strEQ(str->str_ptr,"$ARGC"))
988 str_set(str,"($#ARGV+1)");
993 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
994 ??? if (instr(curargs->str_ptr,tokenbuf))
995 str_cat(str,"\377"); /* can't translate yet */
998 str_cat(tmpstr,"[]");
999 tmp2str = hfetch(symtab,tmpstr->str_ptr);
1000 if (tmp2str && atoi(tmp2str->str_ptr))
1004 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1006 if (strEQ(str->str_ptr,"$ARGV[0")) {
1007 str_set(str,"$ARGV0");
1011 if (tmp2str && atoi(tmp2str->str_ptr))
1012 strcpy(tokenbuf,"]");
1014 strcpy(tokenbuf,"}");
1016 str_cat(str,tokenbuf);
1023 if (split_to_array) {
1024 str_set(str,"$Fld");
1026 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1031 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1033 sprintf(tokenbuf,"$%s",nameary[i]);
1035 sprintf(tokenbuf,"$Fld%d",i);
1036 str_set(str,tokenbuf);
1041 str_set(str,"$Fld[");
1042 i = ops[node+1].ival;
1043 if ((ops[i].ival & 255) == OPAREN)
1045 tmpstr=walk(1,level,i,&numarg,P_MIN);
1046 str_scat(str,tmpstr);
1065 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1066 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1068 str_scat(str,tmpstr);
1074 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1075 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1077 str_scat(str,tmpstr);
1083 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1085 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1087 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1096 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1097 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1103 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1106 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1107 if (*tmpstr->str_ptr == ';') {
1109 str_cat(str,tmpstr->str_ptr+1);
1116 str = str_make("close(");
1117 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1118 if (!do_fancy_opens) {
1119 t = tmpstr->str_ptr;
1120 if (*t == '"' || *t == '\'')
1121 t = cpytill(tokenbuf,t+1,*t);
1123 fatal("Internal error: OCLOSE %s",t);
1124 s = savestr(tokenbuf);
1125 for (t = tokenbuf; *t; t++) {
1129 if (!isalpha(*t) && !isdigit(*t))
1132 if (!index(tokenbuf,'_'))
1136 str_set(str,"close ");
1137 str_cat(str,tokenbuf);
1140 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1143 str_set(str,tokenbuf);
1148 lparen = ""; /* set to parens if necessary */
1151 if (len == 3) { /* output redirection */
1152 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1153 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1154 if (!do_fancy_opens) {
1155 t = tmpstr->str_ptr;
1156 if (*t == '"' || *t == '\'')
1157 t = cpytill(tokenbuf,t+1,*t);
1159 fatal("Internal error: OPRINT");
1161 s = savestr(tokenbuf);
1162 for (t = tokenbuf; *t; t++) {
1166 if (!isalpha(*t) && !isdigit(*t))
1169 if (!index(tokenbuf,'_'))
1171 tmp3str = hfetch(symtab,tokenbuf);
1173 str_cat(opens,"open(");
1174 str_cat(opens,tokenbuf);
1175 str_cat(opens,", ");
1178 str_scat(opens,tmp2str);
1179 str_cat(opens,tmpstr->str_ptr+1);
1180 if (*tmp2str->str_ptr == '|')
1181 str_cat(opens,") || die 'Cannot pipe to \"");
1183 str_cat(opens,") || die 'Cannot create file \"");
1185 str_cat(opens,"'.\"");
1188 str_cat(opens,"\".'");
1189 str_cat(opens,"\".';\n");
1190 hstore(symtab,tokenbuf,str_make("x"));
1198 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1199 tmp2str->str_ptr, tmpstr->str_ptr);
1200 str_cat(str,tokenbuf);
1202 strcpy(tokenbuf,"$fh");
1210 strcpy(tokenbuf,"");
1211 str_cat(str,lparen); /* may be null */
1212 if (type == OPRINTF)
1213 str_cat(str,"printf");
1215 str_cat(str,"print");
1217 if (len == 3 || do_fancy_opens) {
1222 str_cat(str,tokenbuf);
1224 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1225 if (!*tmpstr->str_ptr && lval_field) {
1226 t = saw_OFS ? "$," : "' '";
1227 if (split_to_array) {
1228 sprintf(tokenbuf,"join(%s,@Fld)",t);
1229 str_cat(tmpstr,tokenbuf);
1232 for (i = 1; i < maxfld; i++) {
1234 sprintf(tokenbuf,"$%s, ",nameary[i]);
1236 sprintf(tokenbuf,"$Fld%d, ",i);
1237 str_cat(tmpstr,tokenbuf);
1239 if (maxfld <= arymax)
1240 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1242 sprintf(tokenbuf,"$Fld%d",maxfld);
1243 str_cat(tmpstr,tokenbuf);
1246 if (*tmpstr->str_ptr) {
1248 if (!saw_fh && *tmpstr->str_ptr == '(') {
1250 str_scat(str,tmpstr);
1254 str_scat(str,tmpstr);
1259 str_cat(str,rparen); /* may be null */
1263 str = str_make("rand(1)");
1266 str = str_make("srand(");
1269 str = str_make("atan2(");
1272 str = str_make("sin(");
1275 str = str_make("cos(");
1278 str = str_make("system(");
1281 str = str_make("length(");
1284 str = str_make("log(");
1287 str = str_make("exp(");
1290 str = str_make("sqrt(");
1293 str = str_make("int(");
1297 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1299 tmpstr = str_new(0);;
1300 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1302 t = saw_OFS ? "$," : "' '";
1303 if (split_to_array) {
1304 sprintf(tokenbuf,"join(%s,@Fld)",t);
1305 str_cat(tmpstr,tokenbuf);
1308 sprintf(tokenbuf,"join(%s, ",t);
1309 str_cat(tmpstr,tokenbuf);
1310 for (i = 1; i < maxfld; i++) {
1312 sprintf(tokenbuf,"$%s,",nameary[i]);
1314 sprintf(tokenbuf,"$Fld%d,",i);
1315 str_cat(tmpstr,tokenbuf);
1317 if (maxfld <= arymax)
1318 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1320 sprintf(tokenbuf,"$Fld%d)",maxfld);
1321 str_cat(tmpstr,tokenbuf);
1325 str_cat(tmpstr,"$_");
1327 if (strEQ(tmpstr->str_ptr,"$_")) {
1328 if (type == OLENGTH && !do_chop) {
1329 str = str_make("(length(");
1330 str_cat(tmpstr,") - 1");
1333 str_scat(str,tmpstr);
1339 str_set(str,"last");
1343 str_set(str,"next line");
1349 str_set(str,"exit");
1354 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1360 str_set(str,"$ExitValue = ");
1363 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1367 str_cat(str,"last line");
1372 str_set(str,"next");
1378 str_set(str,"if (");
1379 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1382 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1385 i = ops[node+3].ival;
1387 if ((ops[i].ival & 255) == OBLOCK) {
1390 if ((ops[i].ival & 255) != OIF)
1399 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1403 str_cat(str,"else ");
1404 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1411 str_set(str,"while (");
1412 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1415 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1420 str_set(str,"for (");
1421 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1424 t = s = tmpstr->str_ptr;
1425 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1432 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1433 if (i && (t = index(fstr->str_ptr,0377))) {
1434 if (strnEQ(fstr->str_ptr,s,i))
1441 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1444 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1448 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1449 d = index(tmpstr->str_ptr,'$');
1451 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1456 fatal("Illegal for loop: %s",d);
1458 for (t = s; i = *t; t++) {
1460 if (i == '}' || i == ']')
1468 tmp2str = hfetch(symtab,str->str_ptr);
1469 if (tmp2str && atoi(tmp2str->str_ptr)) {
1471 "foreach %s ($[ .. $#%s) ",
1477 "foreach %s (keys %%%s) ",
1481 str_set(str,tokenbuf);
1482 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1489 if (len >= 2 && ops[node+2].ival) {
1490 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1493 fixtab(str,++level);
1494 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1497 fixtab(str,--level);
1501 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1509 fatal("Garbage length in walk");
1510 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1511 for (i = 2; i<= len; i++) {
1512 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1524 if (useval && prec < minprec) { /* need parens? */
1525 fstr = str_new(str->str_cur+2);
1526 str_nset(fstr,"(",1);
1528 str_ncat(fstr,")",1);
1533 *numericptr = numeric;
1536 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1537 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1540 else if (*t == '\t')
1568 /* strip trailing white space */
1570 s = str->str_ptr+str->str_cur - 1;
1571 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1574 str->str_cur = s + 1 - str->str_ptr;
1575 if (s >= str->str_ptr && *s != '\n')
1586 s = str->str_ptr+str->str_cur - 1;
1587 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1589 if (s >= str->str_ptr && *s != ';' && *s != '}')
1593 emit_split(str,level)
1600 str_cat(str,"@Fld");
1603 for (i = 1; i < maxfld; i++) {
1605 sprintf(tokenbuf,"$%s,",nameary[i]);
1607 sprintf(tokenbuf,"$Fld%d,",i);
1608 str_cat(str,tokenbuf);
1610 if (maxfld <= arymax)
1611 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1613 sprintf(tokenbuf,"$Fld%d)",maxfld);
1614 str_cat(str,tokenbuf);
1617 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1618 str_cat(str,tokenbuf);
1621 str_cat(str," = split($FS, $_, 9999);\n");
1623 str_cat(str," = split(' ', $_, 9999);\n");
1627 prewalk(numit,level,node,numericptr)
1639 int numeric = FALSE;
1647 type = ops[node].ival;
1652 prewalk(0,level,ops[node+1].ival,&numarg);
1653 if (ops[node+2].ival) {
1654 prewalk(0,level,ops[node+2].ival,&numarg);
1657 prewalk(0,level,ops[node+3].ival,&numarg);
1659 if (ops[node+3].ival) {
1660 prewalk(0,level,ops[node+4].ival,&numarg);
1664 prewalk(0,level,ops[node+1].ival,&numarg);
1665 prewalk(0,level,ops[node+2].ival,&numarg);
1667 prewalk(0,level,ops[node+3].ival,&numarg);
1671 prewalk(1,level,ops[node+1].ival,&numarg);
1672 prewalk(1,level,ops[node+2].ival,&numarg);
1677 prewalk(0,level,ops[node+1].ival,&numarg);
1681 prewalk(0,level,ops[node+1].ival,&numarg);
1684 i = prewalk(0,level,ops[node+1].ival,&numarg);
1687 prewalk(0,level,ops[node+2].ival,&numarg);
1691 prewalk(0,level,ops[node+2].ival,&numarg);
1696 prewalk(0,level,ops[node+1].ival,&numarg);
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1700 prewalk(0,level,ops[node+2].ival,&numarg);
1703 prewalk(0,level,ops[node+1].ival,&numarg);
1704 prewalk(0,level,ops[node+2].ival,&numarg);
1707 prewalk(0,level,ops[node+1].ival,&numarg);
1710 prewalk(0,level,ops[node+1].ival,&numarg);
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1716 prewalk(0,level,ops[node+2].ival,&numarg);
1719 prewalk(0,level,ops[node+1].ival,&numarg);
1721 prewalk(0,level,ops[node+2].ival,&numarg);
1724 prewalk(0,level,ops[node+1].ival,&numarg);
1728 prewalk(0,level,ops[node+2].ival,&numarg);
1730 prewalk(0,level,ops[node+1].ival,&numarg);
1731 prewalk(0,level,ops[node+3].ival,&numarg);
1736 prewalk(0,level,ops[node+1].ival,&numarg);
1740 prewalk(0,level,ops[node+2].ival,&numarg);
1741 prewalk(0,level,ops[node+1].ival,&numarg);
1742 prewalk(0,level,ops[node+3].ival,&numarg);
1746 prewalk(0,level,ops[node+1].ival,&numarg);
1750 prewalk(0,level,ops[node+1].ival,&numarg);
1751 prewalk(0,level,ops[node+2].ival,&numarg);
1754 prewalk(0,level,ops[node+2].ival,&numarg);
1755 prewalk(0,level,ops[node+1].ival,&numarg);
1756 prewalk(0,level,ops[node+3].ival,&numarg);
1757 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1758 numericize(ops[node+2].ival);
1760 numericize(ops[node+3].ival);
1765 prewalk(1,level,ops[node+1].ival,&numarg);
1766 prewalk(1,level,ops[node+2].ival,&numarg);
1770 prewalk(1,level,ops[node+1].ival,&numarg);
1771 prewalk(1,level,ops[node+2].ival,&numarg);
1775 prewalk(1,level,ops[node+1].ival,&numarg);
1776 prewalk(1,level,ops[node+2].ival,&numarg);
1780 prewalk(1,level,ops[node+1].ival,&numarg);
1781 prewalk(1,level,ops[node+2].ival,&numarg);
1785 prewalk(1,level,ops[node+1].ival,&numarg);
1786 prewalk(1,level,ops[node+2].ival,&numarg);
1790 prewalk(1,level,ops[node+1].ival,&numarg);
1791 prewalk(1,level,ops[node+2].ival,&numarg);
1795 prewalk(1,level,ops[node+1].ival,&numarg);
1799 prewalk(1,level,ops[node+1].ival,&numarg);
1803 prewalk(1,level,ops[node+1].ival,&numarg);
1807 prewalk(1,level,ops[node+1].ival,&numarg);
1811 prewalk(1,level,ops[node+1].ival,&numarg);
1815 prewalk(1,level,ops[node+1].ival,&numarg);
1819 prewalk(0,level,ops[node+1].ival,&numarg);
1825 prewalk(0,level,ops[node+1].ival,&numarg);
1828 prewalk(0,level,ops[node+1].ival,&numarg);
1829 prewalk(1,level,ops[node+2].ival,&numarg);
1831 prewalk(1,level,ops[node+3].ival,&numarg);
1838 prewalk(0,level,ops[node+2].ival,&numarg);
1840 prewalk(0,level,ops[node+3].ival,&numarg);
1841 prewalk(0,level,ops[node+1].ival,&numarg);
1844 prewalk(0,level,ops[node+1].ival,&numarg);
1845 prewalk(0,level,ops[node+2].ival,&numarg);
1849 prewalk(0,level,ops[node+1].ival,&numarg);
1850 prewalk(0,level,ops[node+2].ival,&numarg);
1856 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1858 prewalk(0,level,ops[node+2].ival,&numarg);
1859 prewalk(0,level,ops[node+4].ival,&numarg);
1860 prewalk(0,level,ops[node+5].ival,&numarg);
1862 str_cat(tmpstr,"(");
1863 tmp2str = str_new(0);
1864 if (subretnum || numarg)
1865 str_set(tmp2str,"1");
1866 hstore(symtab,tmpstr->str_ptr,tmp2str);
1872 prewalk(0,level,ops[node+1].ival,&numarg);
1878 tmp2str = str_new(0);
1879 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1880 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1882 str_cat(tmp2str,"(");
1883 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1884 if (tmpstr && tmpstr->str_ptr)
1885 numeric |= atoi(tmpstr->str_ptr);
1886 prewalk(0,level,ops[node+2].ival,&numarg);
1892 prewalk(0,level,ops[node+3].ival,&numarg);
1893 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1894 prewalk(0,level,ops[node+1].ival,&numarg);
1898 prewalk(0,level,ops[node+1].ival,&numarg);
1902 prewalk(0,level,ops[node+1].ival,&numarg);
1908 prewalk(0,level,ops[node+1].ival,&numarg);
1914 prewalk(0,level,ops[node+2].ival,&numarg);
1918 prewalk(0,level,ops[node+1].ival,&numarg);
1921 i = ops[node+1].ival;
1922 prewalk(0,level,i,&numarg);
1935 prewalk(0,level,ops[node+1].ival,&numarg);
1936 prewalk(0,level,ops[node+2].ival,&numarg);
1937 prewalk(0,level,ops[node+3].ival,&numarg);
1942 prewalk(0,level,ops[node+1].ival,&numarg);
1943 prewalk(0,level,ops[node+2].ival,&numarg);
1947 prewalk(0,level,ops[node+1].ival,&numarg);
1949 prewalk(0,level,ops[node+2].ival,&numarg);
1954 prewalk(0,level,ops[node+1].ival,&numarg);
1958 if (len == 3) { /* output redirection */
1959 prewalk(0,level,ops[node+3].ival,&numarg);
1960 prewalk(0,level,ops[node+2].ival,&numarg);
1962 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1988 prewalk(type != OLENGTH && type != OSYSTEM,
1989 level,ops[node+1].ival,&numarg);
1997 prewalk(1,level,ops[node+1].ival,&numarg);
2005 prewalk(0,level,ops[node+1].ival,&numarg);
2006 prewalk(0,level,ops[node+2].ival,&numarg);
2008 prewalk(0,level,ops[node+3].ival,&numarg);
2012 prewalk(0,level,ops[node+1].ival,&numarg);
2013 prewalk(0,level,ops[node+2].ival,&numarg);
2016 prewalk(0,level,ops[node+1].ival,&numarg);
2017 prewalk(0,level,ops[node+2].ival,&numarg);
2018 prewalk(0,level,ops[node+3].ival,&numarg);
2019 prewalk(0,level,ops[node+4].ival,&numarg);
2022 prewalk(0,level,ops[node+2].ival,&numarg);
2023 prewalk(0,level,ops[node+1].ival,&numarg);
2027 prewalk(0,level,ops[node+2].ival,&numarg);
2030 prewalk(0,level,ops[node+1].ival,&numarg);
2037 fatal("Garbage length in prewalk");
2038 prewalk(0,level,ops[node+1].ival,&numarg);
2039 for (i = 2; i<= len; i++) {
2040 prewalk(0,level,ops[node+i].ival,&numarg);
2045 *numericptr = numeric;
2059 type = ops[node].ival;
2062 if (type == OVAR && len == 1) {
2063 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2064 tmp2str = str_make("1");
2065 hstore(symtab,tmpstr->str_ptr,tmp2str);