1 /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
3 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
4 * 2000, 2001, 2002, 2005 by Larry Wall and others
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
17 bool realexit = FALSE;
18 bool saw_getline = FALSE;
19 bool subretnum = FALSE;
21 bool saw_argv0 = FALSE;
28 STR *curargs = Nullstr;
30 static void addsemi ( STR *str );
31 static void emit_split ( STR *str, int level );
32 static void fixtab ( STR *str, int lvl );
33 static void numericize ( int node );
34 static void tab ( STR *str, int lvl );
36 int prewalk ( int numit, int level, int node, int *numericptr );
37 STR * walk ( int useval, int level, int node, int *numericptr, int minprec );
39 char *savestr(char *str);
40 char *cpytill(register char *to, register char *from, register int delim);
41 char *instr(char *big, char *little);
45 walk(int useval, int level, register int node, int *numericptr, int minprec)
50 /* minimum precedence without parens */
64 int prec = P_MAX; /* assume no parens needed */
70 type = ops[node].ival;
77 while (isALPHA(*namelist)) {
78 for (d = tokenbuf,s=namelist;
79 isALPHA(*s) || isDIGIT(*s) || *s == '_';
82 while (*s && !isALPHA(*s)) s++;
84 nameary[++arymax] = savestr(tokenbuf);
91 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
92 if (do_split && need_entire && !absmaxfld)
93 split_to_array = TRUE;
94 if (do_split && split_to_array)
95 set_array_base = TRUE;
97 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
99 if (fswitch && !const_FS)
101 if (saw_FS > 1 || saw_RS)
103 if (saw_ORS && need_entire)
106 str_cat(str,"$FS = '");
107 if (strchr("*+?.[]()|^$\\",fswitch))
109 sprintf(tokenbuf,"%c",fswitch);
110 str_cat(str,tokenbuf);
111 str_cat(str,"';\t\t# field separator from -F switch\n");
113 else if (saw_FS && !const_FS) {
114 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
117 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
120 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
123 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
125 if (str->str_cur > 20)
127 if (ops[node+2].ival) {
128 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
132 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
133 if (*fstr->str_ptr) {
135 str_cat(str,"line: ");
136 str_cat(str,"while (<>) {\n");
138 if (saw_FS && !const_FS)
141 str_cat(str,"chomp;\t# strip record separator\n");
145 emit_split(str,level);
151 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
154 str_cat(str,"while (<>) { } # (no line actions)\n");
155 if (ops[node+4].ival) {
159 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
164 str_cat(str,"exit $ExitValue;\n");
170 for (len = 0; len < 4; len++) {
171 if (saw_getline & (1 << len)) {
172 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
173 str_cat(str, tokenbuf);
176 str_cat(str," &Pick('',@_);\n");
178 str_cat(str," ($fh) = @_;\n");
182 str_cat(str," $FNRbase = $. if eof;\n");
185 str_cat(str," local($_);\n");
188 " if ($getline_ok = (($_ = <$fh>) ne ''))");
191 " if ($getline_ok = (($_ = <>) ne ''))");
192 str_cat(str, " {\n");
198 str_cat(str,"chomp;\t# strip record separator\n");
201 if (do_split && !(len & 1)) {
203 emit_split(str,level);
208 str_cat(str,"}\n $_;\n}\n");
213 if (do_fancy_opens) {
216 local($mode,$name,$pipe) = @_;\n\
218 open($name,$mode.$name.$pipe) unless $opened{$name}++;\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 (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
396 !strchr(tmp2str->str_ptr,'\'') && !strchr(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));
471 if (strEQ(str->str_ptr,"$/ = ''"))
472 str_set(str, "$/ = \"\\n\\n\"");
476 str = walk(1,level,ops[node+1].ival,&numarg,prec);
478 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
484 str = walk(1,level,ops[node+1].ival,&numarg,prec);
486 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
492 str = walk(1,level,ops[node+1].ival,&numarg,prec);
494 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
500 str = walk(1,level,ops[node+1].ival,&numarg,prec);
502 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
508 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
510 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
516 str = walk(1,level,ops[node+1].ival,&numarg,prec);
518 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
524 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
530 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
538 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
546 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
554 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
565 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
575 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
576 if (!*fstr->str_ptr) {
578 len = 2; /* a legal fiction */
585 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
586 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
587 if (!do_fancy_opens) {
589 if (*t == '"' || *t == '\'')
590 t = cpytill(tokenbuf,t+1,*t);
592 fatal("Internal error: OGETLINE %s", t);
594 s = savestr(tokenbuf);
595 for (t = tokenbuf; *t; t++) {
599 if (!isALPHA(*t) && !isDIGIT(*t))
602 if (!strchr(tokenbuf,'_'))
604 tmp3str = hfetch(symtab,tokenbuf);
607 str_cat(opens,"open(");
608 str_cat(opens,tokenbuf);
612 str_cat(opens,tmpstr->str_ptr+1);
614 if (*fstr->str_ptr == '|')
617 if (*fstr->str_ptr == '|')
618 str_cat(opens,") || die 'Cannot pipe from \"");
620 str_cat(opens,") || die 'Cannot open file \"");
622 str_cat(opens,"'.\"");
625 str_cat(opens,"\".'");
626 str_cat(opens,"\".';\n");
627 hstore(symtab,tokenbuf,str_make("x"));
632 str_cat(tmpstr,tokenbuf);
635 if (*fstr->str_ptr == '|')
636 str_cat(tmpstr,", '|'");
640 tmpstr = str_make("");
641 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
642 str_cat(str,tokenbuf);
645 str_cat(str,",$getline_ok)");
646 saw_getline |= 1 << len;
650 str_set(str,"sprintf(");
651 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
657 str_set(str,"substr(");
658 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
661 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
665 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
669 str_cat(str,"999999");
674 str_set(str,ops[node+1].cval);
680 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
685 str_scat(str,tmpstr);
686 str_cat(str," = split(");
688 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
689 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
690 i = fstr->str_ptr[1] & 127;
691 if (strchr("*+?.[]()|^$\\",i))
692 sprintf(tokenbuf,"/\\%c/",i);
694 sprintf(tokenbuf,"' '");
696 sprintf(tokenbuf,"/%c/",i);
697 str_cat(str,tokenbuf);
704 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
705 str_cat(str,tokenbuf);
714 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
724 str_set(str,"index(");
725 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
728 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
736 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
739 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
741 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
747 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
748 curargs = str_new(0);
749 str_sset(curargs,fstr);
750 str_cat(curargs,",");
751 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
757 t = tmp2str->str_ptr;
758 while ((t = instr(t,"return ")))
762 for (t = s+7; *t; t++) {
763 if (*t == ';' || *t == '}')
768 tmp2str->str_cur -= 7;
774 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
778 str_cat(str,"local(");
780 str_cat(str,") = @_;");
783 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
786 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
789 str_scat(str,tmp2str);
797 tmp2str = str_new(0);
799 str_set(tmp2str,"1");
800 hstore(symtab,tmpstr->str_ptr,tmp2str);
807 str_cat(str,"return ");
808 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
814 str_cat(str,"return");
819 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
822 tmpstr = hfetch(symtab,str->str_ptr+3);
823 if (tmpstr && tmpstr->str_ptr)
824 numeric |= atoi(tmpstr->str_ptr);
825 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
831 int gsub = type == OGSUB ? 1 : 0;
836 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
837 if (strNE(tmpstr->str_ptr,"$_")) {
838 str_cat(tmpstr, " =~ s");
842 str_set(tmpstr, "s");
845 str_set(tmpstr, "s");
846 type = ops[ops[node+2].ival].ival;
849 tmp3str = str_new(0);
851 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
852 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
854 *d++ = '$' + (char)128;
856 *d++ = '\\' + (char)128;
860 str_set(tmp2str,tokenbuf);
861 s = (char *) (gsub ? "/g" : "/");
864 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
865 str_set(tmp3str,"($s_ = '\"'.(");
866 str_scat(tmp3str,tmp2str);
867 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
868 str_set(tmp2str,"eval $s_");
869 s = (char *) (gsub ? "/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);
885 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
888 str_scat(str,tmp3str);
889 str_scat(str,tmpstr);
893 str_scat(str,tmp2str);
899 str_cat(str,"$s = ");
902 str_scat(str,tmp3str);
903 str_scat(str,tmpstr);
905 str_scat(str,tmp2str);
916 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
920 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
922 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
925 else if (*t == '\\') {
929 case '\\': case '"': case 'n': case 't': case '$':
931 default: /* hide this from perl */
932 *d++ = '\\' + (char)128;
940 str_cat(str,tokenbuf);
947 str_set(str,"defined $");
951 str_set(str,"delete $");
961 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
963 tmp2str = hfetch(symtab,tmpstr->str_ptr);
964 if (tmp2str && atoi(tmp2str->str_ptr))
966 if (strEQ(str->str_ptr,"$FNR")) {
969 str_set(str,"($.-$FNRbase)");
971 else if (strEQ(str->str_ptr,"$NR")) {
975 else if (strEQ(str->str_ptr,"$NF")) {
977 str_set(str,"$#Fld");
979 else if (strEQ(str->str_ptr,"$0"))
981 else if (strEQ(str->str_ptr,"$ARGC"))
982 str_set(str,"($#ARGV+1)");
987 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
988 ??? if (instr(curargs->str_ptr,tokenbuf))
989 str_cat(str,"\377"); /* can't translate yet */
992 str_cat(tmpstr,"[]");
993 tmp2str = hfetch(symtab,tmpstr->str_ptr);
994 if (tmp2str && atoi(tmp2str->str_ptr))
998 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1000 if (strEQ(str->str_ptr,"$ARGV[0")) {
1001 str_set(str,"$ARGV0");
1005 if (tmp2str && atoi(tmp2str->str_ptr))
1006 strcpy(tokenbuf,"]");
1008 strcpy(tokenbuf,"}");
1009 *tokenbuf += (char)128;
1010 str_cat(str,tokenbuf);
1017 if (split_to_array) {
1018 str_set(str,"$Fld");
1020 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1025 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1027 sprintf(tokenbuf,"$%s",nameary[i]);
1029 sprintf(tokenbuf,"$Fld%d",i);
1030 str_set(str,tokenbuf);
1035 str_set(str,"$Fld[");
1036 i = ops[node+1].ival;
1037 if ((ops[i].ival & 255) == OPAREN)
1039 tmpstr=walk(1,level,i,&numarg,P_MIN);
1040 str_scat(str,tmpstr);
1059 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1060 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1062 str_scat(str,tmpstr);
1068 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1069 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1071 str_scat(str,tmpstr);
1077 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1079 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1081 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1090 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1091 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1097 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1100 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1101 if (*tmpstr->str_ptr == ';') {
1103 str_cat(str,tmpstr->str_ptr+1);
1110 str = str_make("close(");
1111 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1112 if (!do_fancy_opens) {
1113 t = tmpstr->str_ptr;
1114 if (*t == '"' || *t == '\'')
1115 t = cpytill(tokenbuf,t+1,*t);
1117 fatal("Internal error: OCLOSE %s",t);
1118 s = savestr(tokenbuf);
1119 for (t = tokenbuf; *t; t++) {
1123 if (!isALPHA(*t) && !isDIGIT(*t))
1126 if (!strchr(tokenbuf,'_'))
1130 str_set(str,"close ");
1131 str_cat(str,tokenbuf);
1134 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1135 tmpstr->str_ptr, tmpstr->str_ptr);
1137 str_set(str,tokenbuf);
1142 lparen = ""; /* set to parens if necessary */
1145 if (len == 3) { /* output redirection */
1146 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1147 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1148 if (!do_fancy_opens) {
1149 t = tmpstr->str_ptr;
1150 if (*t == '"' || *t == '\'')
1151 t = cpytill(tokenbuf,t+1,*t);
1153 fatal("Internal error: OPRINT");
1155 s = savestr(tokenbuf);
1156 for (t = tokenbuf; *t; t++) {
1160 if (!isALPHA(*t) && !isDIGIT(*t))
1163 if (!strchr(tokenbuf,'_'))
1165 tmp3str = hfetch(symtab,tokenbuf);
1167 str_cat(opens,"open(");
1168 str_cat(opens,tokenbuf);
1169 str_cat(opens,", ");
1172 str_scat(opens,tmp2str);
1173 str_cat(opens,tmpstr->str_ptr+1);
1174 if (*tmp2str->str_ptr == '|')
1175 str_cat(opens,") || die 'Cannot pipe to \"");
1177 str_cat(opens,") || die 'Cannot create file \"");
1179 str_cat(opens,"'.\"");
1182 str_cat(opens,"\".'");
1183 str_cat(opens,"\".';\n");
1184 hstore(symtab,tokenbuf,str_make("x"));
1192 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1193 tmp2str->str_ptr, tmpstr->str_ptr);
1194 str_cat(str,tokenbuf);
1196 strcpy(tokenbuf,"$fh");
1204 strcpy(tokenbuf,"");
1205 str_cat(str,lparen); /* may be null */
1206 if (type == OPRINTF)
1207 str_cat(str,"printf");
1209 str_cat(str,"print");
1211 if (len == 3 || do_fancy_opens) {
1216 str_cat(str,tokenbuf);
1218 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1219 if (!*tmpstr->str_ptr && lval_field) {
1220 t = (char*)(saw_OFS ? "$," : "' '");
1221 if (split_to_array) {
1222 sprintf(tokenbuf,"join(%s,@Fld)",t);
1223 str_cat(tmpstr,tokenbuf);
1226 for (i = 1; i < maxfld; i++) {
1228 sprintf(tokenbuf,"$%s, ",nameary[i]);
1230 sprintf(tokenbuf,"$Fld%d, ",i);
1231 str_cat(tmpstr,tokenbuf);
1233 if (maxfld <= arymax)
1234 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1236 sprintf(tokenbuf,"$Fld%d",maxfld);
1237 str_cat(tmpstr,tokenbuf);
1240 if (*tmpstr->str_ptr) {
1242 if (!saw_fh && *tmpstr->str_ptr == '(') {
1244 str_scat(str,tmpstr);
1248 str_scat(str,tmpstr);
1253 str_cat(str,rparen); /* may be null */
1257 str = str_make("rand(1)");
1260 str = str_make("srand(");
1263 str = str_make("atan2(");
1266 str = str_make("sin(");
1269 str = str_make("cos(");
1272 str = str_make("system(");
1275 str = str_make("length(");
1278 str = str_make("log(");
1281 str = str_make("exp(");
1284 str = str_make("sqrt(");
1287 str = str_make("int(");
1291 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1293 tmpstr = str_new(0);
1294 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1296 t = (char*)(saw_OFS ? "$," : "' '");
1297 if (split_to_array) {
1298 sprintf(tokenbuf,"join(%s,@Fld)",t);
1299 str_cat(tmpstr,tokenbuf);
1302 sprintf(tokenbuf,"join(%s, ",t);
1303 str_cat(tmpstr,tokenbuf);
1304 for (i = 1; i < maxfld; i++) {
1306 sprintf(tokenbuf,"$%s,",nameary[i]);
1308 sprintf(tokenbuf,"$Fld%d,",i);
1309 str_cat(tmpstr,tokenbuf);
1311 if (maxfld <= arymax)
1312 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1314 sprintf(tokenbuf,"$Fld%d)",maxfld);
1315 str_cat(tmpstr,tokenbuf);
1319 str_cat(tmpstr,"$_");
1321 if (strEQ(tmpstr->str_ptr,"$_")) {
1322 if (type == OLENGTH && !do_chop) {
1323 str = str_make("(length(");
1324 str_cat(tmpstr,") - 1");
1327 str_scat(str,tmpstr);
1333 str_set(str,"last");
1337 str_set(str,"next line");
1343 str_set(str,"exit");
1348 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1354 str_set(str,"$ExitValue = ");
1357 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1361 str_cat(str,"last line");
1366 str_set(str,"next");
1372 str_set(str,"if (");
1373 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1376 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1379 i = ops[node+3].ival;
1381 if ((ops[i].ival & 255) == OBLOCK) {
1384 if ((ops[i].ival & 255) != OIF)
1393 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1397 str_cat(str,"else ");
1398 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1405 str_set(str,"while (");
1406 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1409 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1415 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1417 if (str->str_ptr[str->str_cur - 1] == '\n')
1419 str_cat(str," while (");
1420 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1426 str_set(str,"for (");
1427 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1430 t = s = tmpstr->str_ptr;
1431 while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
1438 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1439 if (i && (t = strchr(fstr->str_ptr,0377))) {
1440 if (strnEQ(fstr->str_ptr,s,i))
1447 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1450 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1454 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1455 d = strchr(tmpstr->str_ptr,'$');
1457 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1462 fatal("Illegal for loop: %s",d);
1464 for (t = s; (i = *t); t++) {
1466 if (i == '}' || i == ']')
1474 tmp2str = hfetch(symtab,str->str_ptr);
1475 if (tmp2str && atoi(tmp2str->str_ptr)) {
1477 "foreach %s ($[ .. $#%s) ",
1483 "foreach %s (keys %%%s) ",
1487 str_set(str,tokenbuf);
1488 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1495 if (len >= 2 && ops[node+2].ival) {
1496 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1499 fixtab(str,++level);
1500 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1503 fixtab(str,--level);
1507 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1515 fatal("Garbage length in walk");
1516 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1517 for (i = 2; i<= len; i++) {
1518 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1530 if (useval && prec < minprec) { /* need parens? */
1531 fstr = str_new(str->str_cur+2);
1532 str_nset(fstr,"(",1);
1534 str_ncat(fstr,")",1);
1539 *numericptr = numeric;
1542 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1543 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1546 else if (*t == '\t')
1557 tab(register STR *str, register int lvl)
1568 fixtab(register STR *str, register int lvl)
1572 /* strip trailing white space */
1574 s = str->str_ptr+str->str_cur - 1;
1575 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1578 str->str_cur = s + 1 - str->str_ptr;
1579 if (s >= str->str_ptr && *s != '\n')
1586 addsemi(register STR *str)
1590 s = str->str_ptr+str->str_cur - 1;
1591 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1593 if (s >= str->str_ptr && *s != ';' && *s != '}')
1598 emit_split(register STR *str, int level)
1603 str_cat(str,"@Fld");
1606 for (i = 1; i < maxfld; i++) {
1608 sprintf(tokenbuf,"$%s,",nameary[i]);
1610 sprintf(tokenbuf,"$Fld%d,",i);
1611 str_cat(str,tokenbuf);
1613 if (maxfld <= arymax)
1614 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1616 sprintf(tokenbuf,"$Fld%d)",maxfld);
1617 str_cat(str,tokenbuf);
1620 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1621 str_cat(str,tokenbuf);
1624 str_cat(str," = split($FS, $_, 9999);\n");
1626 str_cat(str," = split(' ', $_, 9999);\n");
1631 prewalk(int numit, int level, register int node, int *numericptr)
1637 int numeric = FALSE;
1645 type = ops[node].ival;
1650 prewalk(0,level,ops[node+1].ival,&numarg);
1651 if (ops[node+2].ival) {
1652 prewalk(0,level,ops[node+2].ival,&numarg);
1655 prewalk(0,level,ops[node+3].ival,&numarg);
1657 if (ops[node+3].ival) {
1658 prewalk(0,level,ops[node+4].ival,&numarg);
1662 prewalk(0,level,ops[node+1].ival,&numarg);
1663 prewalk(0,level,ops[node+2].ival,&numarg);
1665 prewalk(0,level,ops[node+3].ival,&numarg);
1669 prewalk(1,level,ops[node+1].ival,&numarg);
1670 prewalk(1,level,ops[node+2].ival,&numarg);
1675 prewalk(0,level,ops[node+1].ival,&numarg);
1679 prewalk(0,level,ops[node+1].ival,&numarg);
1682 i = prewalk(0,level,ops[node+1].ival,&numarg);
1685 prewalk(0,level,ops[node+2].ival,&numarg);
1689 prewalk(0,level,ops[node+2].ival,&numarg);
1694 prewalk(0,level,ops[node+1].ival,&numarg);
1697 prewalk(0,level,ops[node+1].ival,&numarg);
1698 prewalk(0,level,ops[node+2].ival,&numarg);
1701 prewalk(0,level,ops[node+1].ival,&numarg);
1702 prewalk(0,level,ops[node+2].ival,&numarg);
1705 prewalk(0,level,ops[node+1].ival,&numarg);
1708 prewalk(0,level,ops[node+1].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);
1719 prewalk(0,level,ops[node+2].ival,&numarg);
1722 prewalk(0,level,ops[node+1].ival,&numarg);
1726 prewalk(0,level,ops[node+2].ival,&numarg);
1728 prewalk(0,level,ops[node+1].ival,&numarg);
1729 prewalk(0,level,ops[node+3].ival,&numarg);
1734 prewalk(0,level,ops[node+1].ival,&numarg);
1738 prewalk(0,level,ops[node+2].ival,&numarg);
1739 prewalk(0,level,ops[node+1].ival,&numarg);
1740 prewalk(0,level,ops[node+3].ival,&numarg);
1744 prewalk(0,level,ops[node+1].ival,&numarg);
1748 prewalk(0,level,ops[node+1].ival,&numarg);
1749 prewalk(0,level,ops[node+2].ival,&numarg);
1752 prewalk(0,level,ops[node+2].ival,&numarg);
1753 prewalk(0,level,ops[node+1].ival,&numarg);
1754 prewalk(0,level,ops[node+3].ival,&numarg);
1755 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
1756 numericize(ops[node+2].ival);
1758 numericize(ops[node+3].ival);
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);
1789 prewalk(1,level,ops[node+2].ival,&numarg);
1793 prewalk(1,level,ops[node+1].ival,&numarg);
1797 prewalk(1,level,ops[node+1].ival,&numarg);
1801 prewalk(1,level,ops[node+1].ival,&numarg);
1805 prewalk(1,level,ops[node+1].ival,&numarg);
1809 prewalk(1,level,ops[node+1].ival,&numarg);
1813 prewalk(1,level,ops[node+1].ival,&numarg);
1817 prewalk(0,level,ops[node+1].ival,&numarg);
1823 prewalk(0,level,ops[node+1].ival,&numarg);
1826 prewalk(0,level,ops[node+1].ival,&numarg);
1827 prewalk(1,level,ops[node+2].ival,&numarg);
1829 prewalk(1,level,ops[node+3].ival,&numarg);
1836 prewalk(0,level,ops[node+2].ival,&numarg);
1838 prewalk(0,level,ops[node+3].ival,&numarg);
1839 prewalk(0,level,ops[node+1].ival,&numarg);
1842 prewalk(0,level,ops[node+1].ival,&numarg);
1843 prewalk(0,level,ops[node+2].ival,&numarg);
1847 prewalk(0,level,ops[node+1].ival,&numarg);
1848 prewalk(0,level,ops[node+2].ival,&numarg);
1854 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1856 prewalk(0,level,ops[node+2].ival,&numarg);
1857 prewalk(0,level,ops[node+4].ival,&numarg);
1858 prewalk(0,level,ops[node+5].ival,&numarg);
1860 str_cat(tmpstr,"(");
1861 tmp2str = str_new(0);
1862 if (subretnum || numarg)
1863 str_set(tmp2str,"1");
1864 hstore(symtab,tmpstr->str_ptr,tmp2str);
1870 prewalk(0,level,ops[node+1].ival,&numarg);
1876 tmp2str = str_new(0);
1877 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1878 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1880 str_cat(tmp2str,"(");
1881 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1882 if (tmpstr && tmpstr->str_ptr)
1883 numeric |= atoi(tmpstr->str_ptr);
1884 prewalk(0,level,ops[node+2].ival,&numarg);
1890 prewalk(0,level,ops[node+3].ival,&numarg);
1891 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1892 prewalk(0,level,ops[node+1].ival,&numarg);
1896 prewalk(0,level,ops[node+1].ival,&numarg);
1900 prewalk(0,level,ops[node+1].ival,&numarg);
1906 prewalk(0,level,ops[node+1].ival,&numarg);
1912 prewalk(0,level,ops[node+2].ival,&numarg);
1916 prewalk(0,level,ops[node+1].ival,&numarg);
1919 i = ops[node+1].ival;
1920 prewalk(0,level,i,&numarg);
1933 prewalk(0,level,ops[node+1].ival,&numarg);
1934 prewalk(0,level,ops[node+2].ival,&numarg);
1935 prewalk(0,level,ops[node+3].ival,&numarg);
1940 prewalk(0,level,ops[node+1].ival,&numarg);
1941 prewalk(0,level,ops[node+2].ival,&numarg);
1945 prewalk(0,level,ops[node+1].ival,&numarg);
1947 prewalk(0,level,ops[node+2].ival,&numarg);
1952 prewalk(0,level,ops[node+1].ival,&numarg);
1956 if (len == 3) { /* output redirection */
1957 prewalk(0,level,ops[node+3].ival,&numarg);
1958 prewalk(0,level,ops[node+2].ival,&numarg);
1960 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1986 prewalk(type != OLENGTH && type != OSYSTEM,
1987 level,ops[node+1].ival,&numarg);
1995 prewalk(1,level,ops[node+1].ival,&numarg);
2003 prewalk(0,level,ops[node+1].ival,&numarg);
2004 prewalk(0,level,ops[node+2].ival,&numarg);
2006 prewalk(0,level,ops[node+3].ival,&numarg);
2010 prewalk(0,level,ops[node+1].ival,&numarg);
2011 prewalk(0,level,ops[node+2].ival,&numarg);
2014 prewalk(0,level,ops[node+1].ival,&numarg);
2015 prewalk(0,level,ops[node+2].ival,&numarg);
2016 prewalk(0,level,ops[node+3].ival,&numarg);
2017 prewalk(0,level,ops[node+4].ival,&numarg);
2020 prewalk(0,level,ops[node+2].ival,&numarg);
2021 prewalk(0,level,ops[node+1].ival,&numarg);
2025 prewalk(0,level,ops[node+2].ival,&numarg);
2028 prewalk(0,level,ops[node+1].ival,&numarg);
2035 fatal("Garbage length in prewalk");
2036 prewalk(0,level,ops[node+1].ival,&numarg);
2037 for (i = 2; i<= len; i++) {
2038 prewalk(0,level,ops[node+i].ival,&numarg);
2043 *numericptr = numeric;
2048 numericize(register int node)
2056 type = ops[node].ival;
2059 if (type == OVAR && len == 1) {
2060 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2061 tmp2str = str_make("1");
2062 hstore(symtab,tmpstr->str_ptr,tmp2str);