1 /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
3 * Copyright (c) 1991-2003, 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 );
38 char *savestr(char *str);
39 char *cpytill(register char *to, register char *from, register int delim);
40 char *instr(char *big, char *little);
44 walk(int useval, int level, register int node, int *numericptr, int minprec)
49 /* minimum precedence without parens */
63 int prec = P_MAX; /* assume no parens needed */
69 type = ops[node].ival;
76 while (isALPHA(*namelist)) {
77 for (d = tokenbuf,s=namelist;
78 isALPHA(*s) || isDIGIT(*s) || *s == '_';
81 while (*s && !isALPHA(*s)) s++;
83 nameary[++arymax] = savestr(tokenbuf);
90 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
91 if (do_split && need_entire && !absmaxfld)
92 split_to_array = TRUE;
93 if (do_split && split_to_array)
94 set_array_base = TRUE;
96 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
98 if (fswitch && !const_FS)
100 if (saw_FS > 1 || saw_RS)
102 if (saw_ORS && need_entire)
105 str_cat(str,"$FS = '");
106 if (strchr("*+?.[]()|^$\\",fswitch))
108 sprintf(tokenbuf,"%c",fswitch);
109 str_cat(str,tokenbuf);
110 str_cat(str,"';\t\t# field separator from -F switch\n");
112 else if (saw_FS && !const_FS) {
113 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
116 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
119 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
122 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
124 if (str->str_cur > 20)
126 if (ops[node+2].ival) {
127 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
131 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
132 if (*fstr->str_ptr) {
134 str_cat(str,"line: ");
135 str_cat(str,"while (<>) {\n");
137 if (saw_FS && !const_FS)
140 str_cat(str,"chomp;\t# strip record separator\n");
144 emit_split(str,level);
150 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
153 str_cat(str,"while (<>) { } # (no line actions)\n");
154 if (ops[node+4].ival) {
158 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
163 str_cat(str,"exit $ExitValue;\n");
169 for (len = 0; len < 4; len++) {
170 if (saw_getline & (1 << len)) {
171 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
172 str_cat(str, tokenbuf);
175 str_cat(str," &Pick('',@_);\n");
177 str_cat(str," ($fh) = @_;\n");
181 str_cat(str," $FNRbase = $. if eof;\n");
184 str_cat(str," local($_);\n");
187 " if ($getline_ok = (($_ = <$fh>) ne ''))");
190 " if ($getline_ok = (($_ = <>) ne ''))");
191 str_cat(str, " {\n");
197 str_cat(str,"chomp;\t# strip record separator\n");
200 if (do_split && !(len & 1)) {
202 emit_split(str,level);
207 str_cat(str,"}\n $_;\n}\n");
212 if (do_fancy_opens) {
215 local($mode,$name,$pipe) = @_;\n\
217 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
223 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
224 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
227 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
235 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
237 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
245 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
246 /* translate \nnn to [\nnn] */
247 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
248 if (*s == '\\' && isDIGIT(s[1]) && isDIGIT(s[2]) && isDIGIT(s[3])){
260 for (d=tokenbuf; *d; d++)
262 str_cat(str,tokenbuf);
269 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
271 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
276 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
277 if (*tmpstr->str_ptr) {
280 str_scat(str,tmpstr);
281 str_cat(str,") {\n");
283 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
290 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
297 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
303 str = walk(1,level,ops[node+1].ival,&numarg,prec);
305 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
307 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
312 str = walk(1,level,ops[node+1].ival,&numarg,prec);
314 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
316 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
323 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
328 str = walk(1,level,ops[node+1].ival,&numarg,prec);
330 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
333 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
339 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
346 str = walk(1,level,ops[node+1].ival,&numarg,prec);
349 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
351 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
356 str = walk(1,level,ops[node+1].ival,&numarg,prec);
359 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
361 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
368 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
374 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
376 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
377 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
380 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
383 str_set(tmpstr,"eq");
384 else if (strEQ(t,"!="))
385 str_set(tmpstr,"ne");
386 else if (strEQ(t,"<"))
387 str_set(tmpstr,"lt");
388 else if (strEQ(t,"<="))
389 str_set(tmpstr,"le");
390 else if (strEQ(t,">"))
391 str_set(tmpstr,"gt");
392 else if (strEQ(t,">="))
393 str_set(tmpstr,"ge");
394 if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
395 !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
399 if (numeric & 1) /* numeric is very good guess */
407 str_scat(str,tmpstr);
410 str_scat(str,tmp2str);
417 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
424 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
426 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
427 if (strEQ(tmpstr->str_ptr,"~"))
430 str_scat(str,tmpstr);
434 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
442 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
449 type = ops[ops[node+1].ival].ival & 255;
450 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
452 type = ops[ops[node+2].ival].ival & 255;
454 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
459 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
461 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
462 str_scat(str,tmpstr);
463 if (str_len(tmpstr) > 1)
467 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
470 if (strEQ(str->str_ptr,"$/ = ''"))
471 str_set(str, "$/ = \"\\n\\n\"");
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);
501 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
507 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
509 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
515 str = walk(1,level,ops[node+1].ival,&numarg,prec);
517 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
523 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
529 str = 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+1));
553 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
564 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 (!strchr(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 (strchr("*+?.[]()|^$\\",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));
830 int gsub = type == OGSUB ? 1 : 0;
835 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
836 if (strNE(tmpstr->str_ptr,"$_")) {
837 str_cat(tmpstr, " =~ s");
841 str_set(tmpstr, "s");
844 str_set(tmpstr, "s");
845 type = ops[ops[node+2].ival].ival;
848 tmp3str = str_new(0);
850 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
851 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
853 *d++ = '$' + (char)128;
855 *d++ = '\\' + (char)128;
859 str_set(tmp2str,tokenbuf);
860 s = gsub ? "/g" : "/";
863 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
864 str_set(tmp3str,"($s_ = '\"'.(");
865 str_scat(tmp3str,tmp2str);
866 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
867 str_set(tmp2str,"eval $s_");
868 s = gsub ? "/ge" : "/e";
872 type = ops[ops[node+1].ival].ival;
875 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
876 if (type == OREGEX) {
879 str_scat(str,tmp3str);
880 str_scat(str,tmpstr);
882 str_scat(str,tmp2str);
884 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
887 str_scat(str,tmp3str);
888 str_scat(str,tmpstr);
892 str_scat(str,tmp2str);
898 str_cat(str,"$s = ");
901 str_scat(str,tmp3str);
902 str_scat(str,tmpstr);
904 str_scat(str,tmp2str);
915 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
919 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
921 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
924 else if (*t == '\\') {
928 case '\\': case '"': case 'n': case 't': case '$':
930 default: /* hide this from perl */
931 *d++ = '\\' + (char)128;
939 str_cat(str,tokenbuf);
946 str_set(str,"defined $");
950 str_set(str,"delete $");
960 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
962 tmp2str = hfetch(symtab,tmpstr->str_ptr);
963 if (tmp2str && atoi(tmp2str->str_ptr))
965 if (strEQ(str->str_ptr,"$FNR")) {
968 str_set(str,"($.-$FNRbase)");
970 else if (strEQ(str->str_ptr,"$NR")) {
974 else if (strEQ(str->str_ptr,"$NF")) {
976 str_set(str,"$#Fld");
978 else if (strEQ(str->str_ptr,"$0"))
980 else if (strEQ(str->str_ptr,"$ARGC"))
981 str_set(str,"($#ARGV+1)");
986 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
987 ??? if (instr(curargs->str_ptr,tokenbuf))
988 str_cat(str,"\377"); /* can't translate yet */
991 str_cat(tmpstr,"[]");
992 tmp2str = hfetch(symtab,tmpstr->str_ptr);
993 if (tmp2str && atoi(tmp2str->str_ptr))
997 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
999 if (strEQ(str->str_ptr,"$ARGV[0")) {
1000 str_set(str,"$ARGV0");
1004 if (tmp2str && atoi(tmp2str->str_ptr))
1005 strcpy(tokenbuf,"]");
1007 strcpy(tokenbuf,"}");
1008 *tokenbuf += (char)128;
1009 str_cat(str,tokenbuf);
1016 if (split_to_array) {
1017 str_set(str,"$Fld");
1019 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1024 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1026 sprintf(tokenbuf,"$%s",nameary[i]);
1028 sprintf(tokenbuf,"$Fld%d",i);
1029 str_set(str,tokenbuf);
1034 str_set(str,"$Fld[");
1035 i = ops[node+1].ival;
1036 if ((ops[i].ival & 255) == OPAREN)
1038 tmpstr=walk(1,level,i,&numarg,P_MIN);
1039 str_scat(str,tmpstr);
1058 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1059 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1061 str_scat(str,tmpstr);
1067 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1068 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1070 str_scat(str,tmpstr);
1076 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1078 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1080 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1089 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1090 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1096 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1099 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1100 if (*tmpstr->str_ptr == ';') {
1102 str_cat(str,tmpstr->str_ptr+1);
1109 str = str_make("close(");
1110 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1111 if (!do_fancy_opens) {
1112 t = tmpstr->str_ptr;
1113 if (*t == '"' || *t == '\'')
1114 t = cpytill(tokenbuf,t+1,*t);
1116 fatal("Internal error: OCLOSE %s",t);
1117 s = savestr(tokenbuf);
1118 for (t = tokenbuf; *t; t++) {
1122 if (!isALPHA(*t) && !isDIGIT(*t))
1125 if (!strchr(tokenbuf,'_'))
1129 str_set(str,"close ");
1130 str_cat(str,tokenbuf);
1133 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1134 tmpstr->str_ptr, tmpstr->str_ptr);
1136 str_set(str,tokenbuf);
1141 lparen = ""; /* set to parens if necessary */
1144 if (len == 3) { /* output redirection */
1145 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1146 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1147 if (!do_fancy_opens) {
1148 t = tmpstr->str_ptr;
1149 if (*t == '"' || *t == '\'')
1150 t = cpytill(tokenbuf,t+1,*t);
1152 fatal("Internal error: OPRINT");
1154 s = savestr(tokenbuf);
1155 for (t = tokenbuf; *t; t++) {
1159 if (!isALPHA(*t) && !isDIGIT(*t))
1162 if (!strchr(tokenbuf,'_'))
1164 tmp3str = hfetch(symtab,tokenbuf);
1166 str_cat(opens,"open(");
1167 str_cat(opens,tokenbuf);
1168 str_cat(opens,", ");
1171 str_scat(opens,tmp2str);
1172 str_cat(opens,tmpstr->str_ptr+1);
1173 if (*tmp2str->str_ptr == '|')
1174 str_cat(opens,") || die 'Cannot pipe to \"");
1176 str_cat(opens,") || die 'Cannot create file \"");
1178 str_cat(opens,"'.\"");
1181 str_cat(opens,"\".'");
1182 str_cat(opens,"\".';\n");
1183 hstore(symtab,tokenbuf,str_make("x"));
1191 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1192 tmp2str->str_ptr, tmpstr->str_ptr);
1193 str_cat(str,tokenbuf);
1195 strcpy(tokenbuf,"$fh");
1203 strcpy(tokenbuf,"");
1204 str_cat(str,lparen); /* may be null */
1205 if (type == OPRINTF)
1206 str_cat(str,"printf");
1208 str_cat(str,"print");
1210 if (len == 3 || do_fancy_opens) {
1215 str_cat(str,tokenbuf);
1217 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1218 if (!*tmpstr->str_ptr && lval_field) {
1219 t = (char*)(saw_OFS ? "$," : "' '");
1220 if (split_to_array) {
1221 sprintf(tokenbuf,"join(%s,@Fld)",t);
1222 str_cat(tmpstr,tokenbuf);
1225 for (i = 1; i < maxfld; i++) {
1227 sprintf(tokenbuf,"$%s, ",nameary[i]);
1229 sprintf(tokenbuf,"$Fld%d, ",i);
1230 str_cat(tmpstr,tokenbuf);
1232 if (maxfld <= arymax)
1233 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1235 sprintf(tokenbuf,"$Fld%d",maxfld);
1236 str_cat(tmpstr,tokenbuf);
1239 if (*tmpstr->str_ptr) {
1241 if (!saw_fh && *tmpstr->str_ptr == '(') {
1243 str_scat(str,tmpstr);
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 || !*tmpstr->str_ptr) {
1295 t = (char*)(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));
1414 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1416 if (str->str_ptr[str->str_cur - 1] == '\n')
1418 str_cat(str," while (");
1419 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1425 str_set(str,"for (");
1426 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1429 t = s = tmpstr->str_ptr;
1430 while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
1437 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1438 if (i && (t = strchr(fstr->str_ptr,0377))) {
1439 if (strnEQ(fstr->str_ptr,s,i))
1446 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1449 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1453 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1454 d = strchr(tmpstr->str_ptr,'$');
1456 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1461 fatal("Illegal for loop: %s",d);
1463 for (t = s; (i = *t); t++) {
1465 if (i == '}' || i == ']')
1473 tmp2str = hfetch(symtab,str->str_ptr);
1474 if (tmp2str && atoi(tmp2str->str_ptr)) {
1476 "foreach %s ($[ .. $#%s) ",
1482 "foreach %s (keys %%%s) ",
1486 str_set(str,tokenbuf);
1487 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1494 if (len >= 2 && ops[node+2].ival) {
1495 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1498 fixtab(str,++level);
1499 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1502 fixtab(str,--level);
1506 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1514 fatal("Garbage length in walk");
1515 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1516 for (i = 2; i<= len; i++) {
1517 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1529 if (useval && prec < minprec) { /* need parens? */
1530 fstr = str_new(str->str_cur+2);
1531 str_nset(fstr,"(",1);
1533 str_ncat(fstr,")",1);
1538 *numericptr = numeric;
1541 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1542 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1545 else if (*t == '\t')
1556 tab(register STR *str, register int lvl)
1567 fixtab(register STR *str, register int lvl)
1571 /* strip trailing white space */
1573 s = str->str_ptr+str->str_cur - 1;
1574 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1577 str->str_cur = s + 1 - str->str_ptr;
1578 if (s >= str->str_ptr && *s != '\n')
1585 addsemi(register STR *str)
1589 s = str->str_ptr+str->str_cur - 1;
1590 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1592 if (s >= str->str_ptr && *s != ';' && *s != '}')
1597 emit_split(register STR *str, int level)
1602 str_cat(str,"@Fld");
1605 for (i = 1; i < maxfld; i++) {
1607 sprintf(tokenbuf,"$%s,",nameary[i]);
1609 sprintf(tokenbuf,"$Fld%d,",i);
1610 str_cat(str,tokenbuf);
1612 if (maxfld <= arymax)
1613 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1615 sprintf(tokenbuf,"$Fld%d)",maxfld);
1616 str_cat(str,tokenbuf);
1619 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1620 str_cat(str,tokenbuf);
1623 str_cat(str," = split($FS, $_, 9999);\n");
1625 str_cat(str," = split(' ', $_, 9999);\n");
1630 prewalk(int numit, int level, register int node, int *numericptr)
1636 int numeric = FALSE;
1644 type = ops[node].ival;
1649 prewalk(0,level,ops[node+1].ival,&numarg);
1650 if (ops[node+2].ival) {
1651 prewalk(0,level,ops[node+2].ival,&numarg);
1654 prewalk(0,level,ops[node+3].ival,&numarg);
1656 if (ops[node+3].ival) {
1657 prewalk(0,level,ops[node+4].ival,&numarg);
1661 prewalk(0,level,ops[node+1].ival,&numarg);
1662 prewalk(0,level,ops[node+2].ival,&numarg);
1664 prewalk(0,level,ops[node+3].ival,&numarg);
1668 prewalk(1,level,ops[node+1].ival,&numarg);
1669 prewalk(1,level,ops[node+2].ival,&numarg);
1674 prewalk(0,level,ops[node+1].ival,&numarg);
1678 prewalk(0,level,ops[node+1].ival,&numarg);
1681 i = prewalk(0,level,ops[node+1].ival,&numarg);
1684 prewalk(0,level,ops[node+2].ival,&numarg);
1688 prewalk(0,level,ops[node+2].ival,&numarg);
1693 prewalk(0,level,ops[node+1].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);
1701 prewalk(0,level,ops[node+2].ival,&numarg);
1704 prewalk(0,level,ops[node+1].ival,&numarg);
1707 prewalk(0,level,ops[node+1].ival,&numarg);
1711 prewalk(0,level,ops[node+1].ival,&numarg);
1713 prewalk(0,level,ops[node+2].ival,&numarg);
1716 prewalk(0,level,ops[node+1].ival,&numarg);
1718 prewalk(0,level,ops[node+2].ival,&numarg);
1721 prewalk(0,level,ops[node+1].ival,&numarg);
1725 prewalk(0,level,ops[node+2].ival,&numarg);
1727 prewalk(0,level,ops[node+1].ival,&numarg);
1728 prewalk(0,level,ops[node+3].ival,&numarg);
1733 prewalk(0,level,ops[node+1].ival,&numarg);
1737 prewalk(0,level,ops[node+2].ival,&numarg);
1738 prewalk(0,level,ops[node+1].ival,&numarg);
1739 prewalk(0,level,ops[node+3].ival,&numarg);
1743 prewalk(0,level,ops[node+1].ival,&numarg);
1747 prewalk(0,level,ops[node+1].ival,&numarg);
1748 prewalk(0,level,ops[node+2].ival,&numarg);
1751 prewalk(0,level,ops[node+2].ival,&numarg);
1752 prewalk(0,level,ops[node+1].ival,&numarg);
1753 prewalk(0,level,ops[node+3].ival,&numarg);
1754 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
1755 numericize(ops[node+2].ival);
1757 numericize(ops[node+3].ival);
1762 prewalk(1,level,ops[node+1].ival,&numarg);
1763 prewalk(1,level,ops[node+2].ival,&numarg);
1767 prewalk(1,level,ops[node+1].ival,&numarg);
1768 prewalk(1,level,ops[node+2].ival,&numarg);
1772 prewalk(1,level,ops[node+1].ival,&numarg);
1773 prewalk(1,level,ops[node+2].ival,&numarg);
1777 prewalk(1,level,ops[node+1].ival,&numarg);
1778 prewalk(1,level,ops[node+2].ival,&numarg);
1782 prewalk(1,level,ops[node+1].ival,&numarg);
1783 prewalk(1,level,ops[node+2].ival,&numarg);
1787 prewalk(1,level,ops[node+1].ival,&numarg);
1788 prewalk(1,level,ops[node+2].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(1,level,ops[node+1].ival,&numarg);
1816 prewalk(0,level,ops[node+1].ival,&numarg);
1822 prewalk(0,level,ops[node+1].ival,&numarg);
1825 prewalk(0,level,ops[node+1].ival,&numarg);
1826 prewalk(1,level,ops[node+2].ival,&numarg);
1828 prewalk(1,level,ops[node+3].ival,&numarg);
1835 prewalk(0,level,ops[node+2].ival,&numarg);
1837 prewalk(0,level,ops[node+3].ival,&numarg);
1838 prewalk(0,level,ops[node+1].ival,&numarg);
1841 prewalk(0,level,ops[node+1].ival,&numarg);
1842 prewalk(0,level,ops[node+2].ival,&numarg);
1846 prewalk(0,level,ops[node+1].ival,&numarg);
1847 prewalk(0,level,ops[node+2].ival,&numarg);
1853 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1855 prewalk(0,level,ops[node+2].ival,&numarg);
1856 prewalk(0,level,ops[node+4].ival,&numarg);
1857 prewalk(0,level,ops[node+5].ival,&numarg);
1859 str_cat(tmpstr,"(");
1860 tmp2str = str_new(0);
1861 if (subretnum || numarg)
1862 str_set(tmp2str,"1");
1863 hstore(symtab,tmpstr->str_ptr,tmp2str);
1869 prewalk(0,level,ops[node+1].ival,&numarg);
1875 tmp2str = str_new(0);
1876 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1877 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1879 str_cat(tmp2str,"(");
1880 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1881 if (tmpstr && tmpstr->str_ptr)
1882 numeric |= atoi(tmpstr->str_ptr);
1883 prewalk(0,level,ops[node+2].ival,&numarg);
1889 prewalk(0,level,ops[node+3].ival,&numarg);
1890 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1891 prewalk(0,level,ops[node+1].ival,&numarg);
1895 prewalk(0,level,ops[node+1].ival,&numarg);
1899 prewalk(0,level,ops[node+1].ival,&numarg);
1905 prewalk(0,level,ops[node+1].ival,&numarg);
1911 prewalk(0,level,ops[node+2].ival,&numarg);
1915 prewalk(0,level,ops[node+1].ival,&numarg);
1918 i = ops[node+1].ival;
1919 prewalk(0,level,i,&numarg);
1932 prewalk(0,level,ops[node+1].ival,&numarg);
1933 prewalk(0,level,ops[node+2].ival,&numarg);
1934 prewalk(0,level,ops[node+3].ival,&numarg);
1939 prewalk(0,level,ops[node+1].ival,&numarg);
1940 prewalk(0,level,ops[node+2].ival,&numarg);
1944 prewalk(0,level,ops[node+1].ival,&numarg);
1946 prewalk(0,level,ops[node+2].ival,&numarg);
1951 prewalk(0,level,ops[node+1].ival,&numarg);
1955 if (len == 3) { /* output redirection */
1956 prewalk(0,level,ops[node+3].ival,&numarg);
1957 prewalk(0,level,ops[node+2].ival,&numarg);
1959 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1985 prewalk(type != OLENGTH && type != OSYSTEM,
1986 level,ops[node+1].ival,&numarg);
1994 prewalk(1,level,ops[node+1].ival,&numarg);
2002 prewalk(0,level,ops[node+1].ival,&numarg);
2003 prewalk(0,level,ops[node+2].ival,&numarg);
2005 prewalk(0,level,ops[node+3].ival,&numarg);
2009 prewalk(0,level,ops[node+1].ival,&numarg);
2010 prewalk(0,level,ops[node+2].ival,&numarg);
2013 prewalk(0,level,ops[node+1].ival,&numarg);
2014 prewalk(0,level,ops[node+2].ival,&numarg);
2015 prewalk(0,level,ops[node+3].ival,&numarg);
2016 prewalk(0,level,ops[node+4].ival,&numarg);
2019 prewalk(0,level,ops[node+2].ival,&numarg);
2020 prewalk(0,level,ops[node+1].ival,&numarg);
2024 prewalk(0,level,ops[node+2].ival,&numarg);
2027 prewalk(0,level,ops[node+1].ival,&numarg);
2034 fatal("Garbage length in prewalk");
2035 prewalk(0,level,ops[node+1].ival,&numarg);
2036 for (i = 2; i<= len; i++) {
2037 prewalk(0,level,ops[node+i].ival,&numarg);
2042 *numericptr = numeric;
2047 numericize(register int node)
2055 type = ops[node].ival;
2058 if (type == OVAR && len == 1) {
2059 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2060 tmp2str = str_make("1");
2061 hstore(symtab,tmpstr->str_ptr,tmp2str);