1 /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
3 * Copyright (c) 1991-2002, 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.
16 bool realexit = FALSE;
17 bool saw_getline = FALSE;
18 bool subretnum = FALSE;
20 bool saw_argv0 = FALSE;
27 STR *curargs = Nullstr;
29 static void addsemi ( STR *str );
30 static void emit_split ( STR *str, int level );
31 static void fixtab ( STR *str, int lvl );
32 static void numericize ( int node );
33 static void tab ( STR *str, int lvl );
35 int prewalk ( int numit, int level, int node, int *numericptr );
36 STR * walk ( int useval, int level, int node, int *numericptr, int minprec );
40 walk(int useval, int level, register int node, int *numericptr, int minprec)
45 /* minimum precedence without parens */
59 int prec = P_MAX; /* assume no parens needed */
65 type = ops[node].ival;
72 while (isALPHA(*namelist)) {
73 for (d = tokenbuf,s=namelist;
74 isALPHA(*s) || isDIGIT(*s) || *s == '_';
77 while (*s && !isALPHA(*s)) s++;
79 nameary[++arymax] = savestr(tokenbuf);
86 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
87 if (do_split && need_entire && !absmaxfld)
88 split_to_array = TRUE;
89 if (do_split && split_to_array)
90 set_array_base = TRUE;
92 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
94 if (fswitch && !const_FS)
96 if (saw_FS > 1 || saw_RS)
98 if (saw_ORS && need_entire)
101 str_cat(str,"$FS = '");
102 if (strchr("*+?.[]()|^$\\",fswitch))
104 sprintf(tokenbuf,"%c",fswitch);
105 str_cat(str,tokenbuf);
106 str_cat(str,"';\t\t# field separator from -F switch\n");
108 else if (saw_FS && !const_FS) {
109 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
112 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
115 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
118 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
120 if (str->str_cur > 20)
122 if (ops[node+2].ival) {
123 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
127 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
128 if (*fstr->str_ptr) {
130 str_cat(str,"line: ");
131 str_cat(str,"while (<>) {\n");
133 if (saw_FS && !const_FS)
136 str_cat(str,"chomp;\t# strip record separator\n");
140 emit_split(str,level);
146 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
149 str_cat(str,"while (<>) { } # (no line actions)\n");
150 if (ops[node+4].ival) {
154 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
159 str_cat(str,"exit $ExitValue;\n");
165 for (len = 0; len < 4; len++) {
166 if (saw_getline & (1 << len)) {
167 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
168 str_cat(str, tokenbuf);
171 str_cat(str," &Pick('',@_);\n");
173 str_cat(str," ($fh) = @_;\n");
177 str_cat(str," $FNRbase = $. if eof;\n");
180 str_cat(str," local($_);\n");
183 " if ($getline_ok = (($_ = <$fh>) ne ''))");
186 " if ($getline_ok = (($_ = <>) ne ''))");
187 str_cat(str, " {\n");
193 str_cat(str,"chomp;\t# strip record separator\n");
196 if (do_split && !(len & 1)) {
198 emit_split(str,level);
203 str_cat(str,"}\n $_;\n}\n");
208 if (do_fancy_opens) {
211 local($mode,$name,$pipe) = @_;\n\
213 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
219 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
220 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
223 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
231 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
233 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
241 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
242 /* translate \nnn to [\nnn] */
243 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
244 if (*s == '\\' && isDIGIT(s[1]) && isDIGIT(s[2]) && isDIGIT(s[3])){
256 for (d=tokenbuf; *d; d++)
258 str_cat(str,tokenbuf);
265 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
267 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
272 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
273 if (*tmpstr->str_ptr) {
276 str_scat(str,tmpstr);
277 str_cat(str,") {\n");
279 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
286 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
293 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
299 str = walk(1,level,ops[node+1].ival,&numarg,prec);
301 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
303 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
308 str = walk(1,level,ops[node+1].ival,&numarg,prec);
310 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
312 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
319 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
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));
329 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
335 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
342 str = walk(1,level,ops[node+1].ival,&numarg,prec);
345 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
347 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
352 str = walk(1,level,ops[node+1].ival,&numarg,prec);
355 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
357 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
364 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
370 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
372 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
373 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
376 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
379 str_set(tmpstr,"eq");
380 else if (strEQ(t,"!="))
381 str_set(tmpstr,"ne");
382 else if (strEQ(t,"<"))
383 str_set(tmpstr,"lt");
384 else if (strEQ(t,"<="))
385 str_set(tmpstr,"le");
386 else if (strEQ(t,">"))
387 str_set(tmpstr,"gt");
388 else if (strEQ(t,">="))
389 str_set(tmpstr,"ge");
390 if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
391 !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
395 if (numeric & 1) /* numeric is very good guess */
403 str_scat(str,tmpstr);
406 str_scat(str,tmp2str);
413 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
420 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
422 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
423 if (strEQ(tmpstr->str_ptr,"~"))
426 str_scat(str,tmpstr);
430 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
438 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
445 type = ops[ops[node+1].ival].ival & 255;
446 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
448 type = ops[ops[node+2].ival].ival & 255;
450 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
455 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
457 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
458 str_scat(str,tmpstr);
459 if (str_len(tmpstr) > 1)
463 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
466 if (strEQ(str->str_ptr,"$/ = ''"))
467 str_set(str, "$/ = \"\\n\\n\"");
471 str = walk(1,level,ops[node+1].ival,&numarg,prec);
473 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
479 str = walk(1,level,ops[node+1].ival,&numarg,prec);
481 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
487 str = walk(1,level,ops[node+1].ival,&numarg,prec);
489 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
495 str = walk(1,level,ops[node+1].ival,&numarg,prec);
497 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
503 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
505 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
511 str = walk(1,level,ops[node+1].ival,&numarg,prec);
513 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
519 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
525 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
533 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
541 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
549 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
560 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
570 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
571 if (!*fstr->str_ptr) {
573 len = 2; /* a legal fiction */
580 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
581 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
582 if (!do_fancy_opens) {
584 if (*t == '"' || *t == '\'')
585 t = cpytill(tokenbuf,t+1,*t);
587 fatal("Internal error: OGETLINE %s", t);
589 s = savestr(tokenbuf);
590 for (t = tokenbuf; *t; t++) {
594 if (!isALPHA(*t) && !isDIGIT(*t))
597 if (!strchr(tokenbuf,'_'))
599 tmp3str = hfetch(symtab,tokenbuf);
602 str_cat(opens,"open(");
603 str_cat(opens,tokenbuf);
607 str_cat(opens,tmpstr->str_ptr+1);
609 if (*fstr->str_ptr == '|')
612 if (*fstr->str_ptr == '|')
613 str_cat(opens,") || die 'Cannot pipe from \"");
615 str_cat(opens,") || die 'Cannot open file \"");
617 str_cat(opens,"'.\"");
620 str_cat(opens,"\".'");
621 str_cat(opens,"\".';\n");
622 hstore(symtab,tokenbuf,str_make("x"));
627 str_cat(tmpstr,tokenbuf);
630 if (*fstr->str_ptr == '|')
631 str_cat(tmpstr,", '|'");
635 tmpstr = str_make("");
636 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
637 str_cat(str,tokenbuf);
640 str_cat(str,",$getline_ok)");
641 saw_getline |= 1 << len;
645 str_set(str,"sprintf(");
646 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
652 str_set(str,"substr(");
653 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
656 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
660 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
664 str_cat(str,"999999");
669 str_set(str,ops[node+1].cval);
675 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
680 str_scat(str,tmpstr);
681 str_cat(str," = split(");
683 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
684 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
685 i = fstr->str_ptr[1] & 127;
686 if (strchr("*+?.[]()|^$\\",i))
687 sprintf(tokenbuf,"/\\%c/",i);
689 sprintf(tokenbuf,"' '");
691 sprintf(tokenbuf,"/%c/",i);
692 str_cat(str,tokenbuf);
699 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
700 str_cat(str,tokenbuf);
709 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
719 str_set(str,"index(");
720 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
723 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
731 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
734 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
736 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
742 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
743 curargs = str_new(0);
744 str_sset(curargs,fstr);
745 str_cat(curargs,",");
746 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
752 t = tmp2str->str_ptr;
753 while ((t = instr(t,"return ")))
757 for (t = s+7; *t; t++) {
758 if (*t == ';' || *t == '}')
763 tmp2str->str_cur -= 7;
769 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
773 str_cat(str,"local(");
775 str_cat(str,") = @_;");
778 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
781 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
784 str_scat(str,tmp2str);
792 tmp2str = str_new(0);
794 str_set(tmp2str,"1");
795 hstore(symtab,tmpstr->str_ptr,tmp2str);
802 str_cat(str,"return ");
803 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
809 str_cat(str,"return");
814 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
817 tmpstr = hfetch(symtab,str->str_ptr+3);
818 if (tmpstr && tmpstr->str_ptr)
819 numeric |= atoi(tmpstr->str_ptr);
820 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
826 int gsub = type == OGSUB ? 1 : 0;
831 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
832 if (strNE(tmpstr->str_ptr,"$_")) {
833 str_cat(tmpstr, " =~ s");
837 str_set(tmpstr, "s");
840 str_set(tmpstr, "s");
841 type = ops[ops[node+2].ival].ival;
844 tmp3str = str_new(0);
846 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
847 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
849 *d++ = '$' + (char)128;
851 *d++ = '\\' + (char)128;
855 str_set(tmp2str,tokenbuf);
856 s = gsub ? "/g" : "/";
859 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
860 str_set(tmp3str,"($s_ = '\"'.(");
861 str_scat(tmp3str,tmp2str);
862 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
863 str_set(tmp2str,"eval $s_");
864 s = gsub ? "/ge" : "/e";
868 type = ops[ops[node+1].ival].ival;
871 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
872 if (type == OREGEX) {
875 str_scat(str,tmp3str);
876 str_scat(str,tmpstr);
878 str_scat(str,tmp2str);
880 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
883 str_scat(str,tmp3str);
884 str_scat(str,tmpstr);
888 str_scat(str,tmp2str);
894 str_cat(str,"$s = ");
897 str_scat(str,tmp3str);
898 str_scat(str,tmpstr);
900 str_scat(str,tmp2str);
911 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
915 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
917 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
920 else if (*t == '\\') {
924 case '\\': case '"': case 'n': case 't': case '$':
926 default: /* hide this from perl */
927 *d++ = '\\' + (char)128;
935 str_cat(str,tokenbuf);
942 str_set(str,"defined $");
946 str_set(str,"delete $");
956 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
958 tmp2str = hfetch(symtab,tmpstr->str_ptr);
959 if (tmp2str && atoi(tmp2str->str_ptr))
961 if (strEQ(str->str_ptr,"$FNR")) {
964 str_set(str,"($.-$FNRbase)");
966 else if (strEQ(str->str_ptr,"$NR")) {
970 else if (strEQ(str->str_ptr,"$NF")) {
972 str_set(str,"$#Fld");
974 else if (strEQ(str->str_ptr,"$0"))
976 else if (strEQ(str->str_ptr,"$ARGC"))
977 str_set(str,"($#ARGV+1)");
982 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
983 ??? if (instr(curargs->str_ptr,tokenbuf))
984 str_cat(str,"\377"); /* can't translate yet */
987 str_cat(tmpstr,"[]");
988 tmp2str = hfetch(symtab,tmpstr->str_ptr);
989 if (tmp2str && atoi(tmp2str->str_ptr))
993 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
995 if (strEQ(str->str_ptr,"$ARGV[0")) {
996 str_set(str,"$ARGV0");
1000 if (tmp2str && atoi(tmp2str->str_ptr))
1001 strcpy(tokenbuf,"]");
1003 strcpy(tokenbuf,"}");
1004 *tokenbuf += (char)128;
1005 str_cat(str,tokenbuf);
1012 if (split_to_array) {
1013 str_set(str,"$Fld");
1015 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1020 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1022 sprintf(tokenbuf,"$%s",nameary[i]);
1024 sprintf(tokenbuf,"$Fld%d",i);
1025 str_set(str,tokenbuf);
1030 str_set(str,"$Fld[");
1031 i = ops[node+1].ival;
1032 if ((ops[i].ival & 255) == OPAREN)
1034 tmpstr=walk(1,level,i,&numarg,P_MIN);
1035 str_scat(str,tmpstr);
1054 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1055 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1057 str_scat(str,tmpstr);
1063 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1064 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1066 str_scat(str,tmpstr);
1072 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1074 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1076 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1085 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1086 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1092 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1095 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1096 if (*tmpstr->str_ptr == ';') {
1098 str_cat(str,tmpstr->str_ptr+1);
1105 str = str_make("close(");
1106 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1107 if (!do_fancy_opens) {
1108 t = tmpstr->str_ptr;
1109 if (*t == '"' || *t == '\'')
1110 t = cpytill(tokenbuf,t+1,*t);
1112 fatal("Internal error: OCLOSE %s",t);
1113 s = savestr(tokenbuf);
1114 for (t = tokenbuf; *t; t++) {
1118 if (!isALPHA(*t) && !isDIGIT(*t))
1121 if (!strchr(tokenbuf,'_'))
1125 str_set(str,"close ");
1126 str_cat(str,tokenbuf);
1129 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1130 tmpstr->str_ptr, tmpstr->str_ptr);
1132 str_set(str,tokenbuf);
1137 lparen = ""; /* set to parens if necessary */
1140 if (len == 3) { /* output redirection */
1141 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1142 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1143 if (!do_fancy_opens) {
1144 t = tmpstr->str_ptr;
1145 if (*t == '"' || *t == '\'')
1146 t = cpytill(tokenbuf,t+1,*t);
1148 fatal("Internal error: OPRINT");
1150 s = savestr(tokenbuf);
1151 for (t = tokenbuf; *t; t++) {
1155 if (!isALPHA(*t) && !isDIGIT(*t))
1158 if (!strchr(tokenbuf,'_'))
1160 tmp3str = hfetch(symtab,tokenbuf);
1162 str_cat(opens,"open(");
1163 str_cat(opens,tokenbuf);
1164 str_cat(opens,", ");
1167 str_scat(opens,tmp2str);
1168 str_cat(opens,tmpstr->str_ptr+1);
1169 if (*tmp2str->str_ptr == '|')
1170 str_cat(opens,") || die 'Cannot pipe to \"");
1172 str_cat(opens,") || die 'Cannot create file \"");
1174 str_cat(opens,"'.\"");
1177 str_cat(opens,"\".'");
1178 str_cat(opens,"\".';\n");
1179 hstore(symtab,tokenbuf,str_make("x"));
1187 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1188 tmp2str->str_ptr, tmpstr->str_ptr);
1189 str_cat(str,tokenbuf);
1191 strcpy(tokenbuf,"$fh");
1199 strcpy(tokenbuf,"");
1200 str_cat(str,lparen); /* may be null */
1201 if (type == OPRINTF)
1202 str_cat(str,"printf");
1204 str_cat(str,"print");
1206 if (len == 3 || do_fancy_opens) {
1211 str_cat(str,tokenbuf);
1213 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1214 if (!*tmpstr->str_ptr && lval_field) {
1215 t = (char*)(saw_OFS ? "$," : "' '");
1216 if (split_to_array) {
1217 sprintf(tokenbuf,"join(%s,@Fld)",t);
1218 str_cat(tmpstr,tokenbuf);
1221 for (i = 1; i < maxfld; i++) {
1223 sprintf(tokenbuf,"$%s, ",nameary[i]);
1225 sprintf(tokenbuf,"$Fld%d, ",i);
1226 str_cat(tmpstr,tokenbuf);
1228 if (maxfld <= arymax)
1229 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1231 sprintf(tokenbuf,"$Fld%d",maxfld);
1232 str_cat(tmpstr,tokenbuf);
1235 if (*tmpstr->str_ptr) {
1237 if (!saw_fh && *tmpstr->str_ptr == '(') {
1239 str_scat(str,tmpstr);
1243 str_scat(str,tmpstr);
1248 str_cat(str,rparen); /* may be null */
1252 str = str_make("rand(1)");
1255 str = str_make("srand(");
1258 str = str_make("atan2(");
1261 str = str_make("sin(");
1264 str = str_make("cos(");
1267 str = str_make("system(");
1270 str = str_make("length(");
1273 str = str_make("log(");
1276 str = str_make("exp(");
1279 str = str_make("sqrt(");
1282 str = str_make("int(");
1286 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1288 tmpstr = str_new(0);
1289 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1291 t = (char*)(saw_OFS ? "$," : "' '");
1292 if (split_to_array) {
1293 sprintf(tokenbuf,"join(%s,@Fld)",t);
1294 str_cat(tmpstr,tokenbuf);
1297 sprintf(tokenbuf,"join(%s, ",t);
1298 str_cat(tmpstr,tokenbuf);
1299 for (i = 1; i < maxfld; i++) {
1301 sprintf(tokenbuf,"$%s,",nameary[i]);
1303 sprintf(tokenbuf,"$Fld%d,",i);
1304 str_cat(tmpstr,tokenbuf);
1306 if (maxfld <= arymax)
1307 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1309 sprintf(tokenbuf,"$Fld%d)",maxfld);
1310 str_cat(tmpstr,tokenbuf);
1314 str_cat(tmpstr,"$_");
1316 if (strEQ(tmpstr->str_ptr,"$_")) {
1317 if (type == OLENGTH && !do_chop) {
1318 str = str_make("(length(");
1319 str_cat(tmpstr,") - 1");
1322 str_scat(str,tmpstr);
1328 str_set(str,"last");
1332 str_set(str,"next line");
1338 str_set(str,"exit");
1343 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1349 str_set(str,"$ExitValue = ");
1352 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1356 str_cat(str,"last line");
1361 str_set(str,"next");
1367 str_set(str,"if (");
1368 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1371 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1374 i = ops[node+3].ival;
1376 if ((ops[i].ival & 255) == OBLOCK) {
1379 if ((ops[i].ival & 255) != OIF)
1388 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1392 str_cat(str,"else ");
1393 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1400 str_set(str,"while (");
1401 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1404 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1410 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1412 if (str->str_ptr[str->str_cur - 1] == '\n')
1414 str_cat(str," while (");
1415 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1421 str_set(str,"for (");
1422 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1425 t = s = tmpstr->str_ptr;
1426 while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
1433 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1434 if (i && (t = strchr(fstr->str_ptr,0377))) {
1435 if (strnEQ(fstr->str_ptr,s,i))
1442 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1445 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1449 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1450 d = strchr(tmpstr->str_ptr,'$');
1452 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1457 fatal("Illegal for loop: %s",d);
1459 for (t = s; (i = *t); t++) {
1461 if (i == '}' || i == ']')
1469 tmp2str = hfetch(symtab,str->str_ptr);
1470 if (tmp2str && atoi(tmp2str->str_ptr)) {
1472 "foreach %s ($[ .. $#%s) ",
1478 "foreach %s (keys %%%s) ",
1482 str_set(str,tokenbuf);
1483 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1490 if (len >= 2 && ops[node+2].ival) {
1491 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1494 fixtab(str,++level);
1495 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1498 fixtab(str,--level);
1502 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1510 fatal("Garbage length in walk");
1511 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1512 for (i = 2; i<= len; i++) {
1513 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1525 if (useval && prec < minprec) { /* need parens? */
1526 fstr = str_new(str->str_cur+2);
1527 str_nset(fstr,"(",1);
1529 str_ncat(fstr,")",1);
1534 *numericptr = numeric;
1537 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1538 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1541 else if (*t == '\t')
1552 tab(register STR *str, register int lvl)
1563 fixtab(register STR *str, register int lvl)
1567 /* strip trailing white space */
1569 s = str->str_ptr+str->str_cur - 1;
1570 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1573 str->str_cur = s + 1 - str->str_ptr;
1574 if (s >= str->str_ptr && *s != '\n')
1581 addsemi(register STR *str)
1585 s = str->str_ptr+str->str_cur - 1;
1586 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1588 if (s >= str->str_ptr && *s != ';' && *s != '}')
1593 emit_split(register STR *str, int level)
1598 str_cat(str,"@Fld");
1601 for (i = 1; i < maxfld; i++) {
1603 sprintf(tokenbuf,"$%s,",nameary[i]);
1605 sprintf(tokenbuf,"$Fld%d,",i);
1606 str_cat(str,tokenbuf);
1608 if (maxfld <= arymax)
1609 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1611 sprintf(tokenbuf,"$Fld%d)",maxfld);
1612 str_cat(str,tokenbuf);
1615 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1616 str_cat(str,tokenbuf);
1619 str_cat(str," = split($FS, $_, 9999);\n");
1621 str_cat(str," = split(' ', $_, 9999);\n");
1626 prewalk(int numit, int level, register int node, int *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) > (Size_t)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;
2043 numericize(register int node)
2051 type = ops[node].ival;
2054 if (type == OVAR && len == 1) {
2055 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2056 tmp2str = str_make("1");
2057 hstore(symtab,tmpstr->str_ptr,tmp2str);