1 /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
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.1 92/08/07 18:29:31 lwall
11 * Revision 4.0.1.3 92/06/08 17:33:46 lwall
12 * patch20: in a2p, simplified the filehandle model
13 * patch20: in a2p, made RS="" translate to $/ = "\n\n"
14 * patch20: in a2p, do {...} while ... was missing some reconstruction code
15 * patch20: in a2p, getline should allow variable to be array element
17 * Revision 4.0.1.2 91/11/05 19:25:09 lwall
18 * patch11: in a2p, split on whitespace produced extra null field
20 * Revision 4.0.1.1 91/06/07 12:22:04 lwall
21 * patch4: new copyright notice
22 * patch4: a2p didn't correctly implement -n switch
24 * Revision 4.0 91/03/20 01:58:36 lwall
35 bool realexit = FALSE;
36 bool saw_getline = FALSE;
37 bool subretnum = FALSE;
39 bool saw_argv0 = FALSE;
46 STR *curargs = Nullstr;
49 walk(useval,level,node,numericptr,minprec)
54 int minprec; /* minimum precedence without parens */
68 int prec = P_MAX; /* assume no parens needed */
75 type = ops[node].ival;
82 while (isalpha(*namelist)) {
83 for (d = tokenbuf,s=namelist;
84 isalpha(*s) || isdigit(*s) || *s == '_';
87 while (*s && !isalpha(*s)) s++;
89 nameary[++arymax] = savestr(tokenbuf);
96 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
97 if (do_split && need_entire && !absmaxfld)
98 split_to_array = TRUE;
99 if (do_split && split_to_array)
100 set_array_base = TRUE;
101 if (set_array_base) {
102 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
104 if (fswitch && !const_FS)
106 if (saw_FS > 1 || saw_RS)
108 if (saw_ORS && need_entire)
111 str_cat(str,"$FS = '");
112 if (index("*+?.[]()|^$\\",fswitch))
114 sprintf(tokenbuf,"%c",fswitch);
115 str_cat(str,tokenbuf);
116 str_cat(str,"';\t\t# field separator from -F switch\n");
118 else if (saw_FS && !const_FS) {
119 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
122 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
125 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
128 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
130 if (str->str_cur > 20)
132 if (ops[node+2].ival) {
133 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
137 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
138 if (*fstr->str_ptr) {
140 str_cat(str,"line: ");
141 str_cat(str,"while (<>) {\n");
143 if (saw_FS && !const_FS)
146 str_cat(str,"chop;\t# strip record separator\n");
150 emit_split(str,level);
156 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
159 str_cat(str,"while (<>) { } # (no line actions)\n");
160 if (ops[node+4].ival) {
164 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
169 str_cat(str,"exit $ExitValue;\n");
175 for (len = 0; len < 4; len++) {
176 if (saw_getline & (1 << len)) {
177 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
178 str_cat(str, tokenbuf);
181 str_cat(str," &Pick('',@_);\n");
183 str_cat(str," ($fh) = @_;\n");
187 str_cat(str," $FNRbase = $. if eof;\n");
190 str_cat(str," local($_);\n");
193 " if ($getline_ok = (($_ = <$fh>) ne ''))");
196 " if ($getline_ok = (($_ = <>) ne ''))");
197 str_cat(str, " {\n");
203 str_cat(str,"chop;\t# strip record separator\n");
206 if (do_split && !(len & 1)) {
208 emit_split(str,level);
213 str_cat(str,"}\n $_;\n}\n");
218 if (do_fancy_opens) {
221 local($mode,$name,$pipe) = @_;\n\
223 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
229 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
230 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
233 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
241 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
243 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
251 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
252 /* translate \nnn to [\nnn] */
253 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
254 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
266 for (d=tokenbuf; *d; d++)
268 str_cat(str,tokenbuf);
275 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
277 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
282 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
283 if (*tmpstr->str_ptr) {
286 str_scat(str,tmpstr);
287 str_cat(str,") {\n");
289 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
296 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
303 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
309 str = walk(1,level,ops[node+1].ival,&numarg,prec);
311 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
313 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
318 str = walk(1,level,ops[node+1].ival,&numarg,prec);
320 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
322 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
329 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
334 str = walk(1,level,ops[node+1].ival,&numarg,prec);
336 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
339 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
345 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
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));
362 str = walk(1,level,ops[node+1].ival,&numarg,prec);
365 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
367 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
374 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
380 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
382 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
383 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
386 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
389 str_set(tmpstr,"eq");
390 else if (strEQ(t,"!="))
391 str_set(tmpstr,"ne");
392 else if (strEQ(t,"<"))
393 str_set(tmpstr,"lt");
394 else if (strEQ(t,"<="))
395 str_set(tmpstr,"le");
396 else if (strEQ(t,">"))
397 str_set(tmpstr,"gt");
398 else if (strEQ(t,">="))
399 str_set(tmpstr,"ge");
400 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
401 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
405 if (numeric & 1) /* numeric is very good guess */
413 str_scat(str,tmpstr);
416 str_scat(str,tmp2str);
423 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
430 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
432 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
433 if (strEQ(tmpstr->str_ptr,"~"))
436 str_scat(str,tmpstr);
440 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
448 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
455 type = ops[ops[node+1].ival].ival & 255;
456 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
458 type = ops[ops[node+2].ival].ival & 255;
460 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
465 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
467 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
468 str_scat(str,tmpstr);
469 if (str_len(tmpstr) > 1)
473 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
476 if (strEQ(str->str_ptr,"$/ = ''"))
477 str_set(str, "$/ = \"\\n\\n\"");
481 str = walk(1,level,ops[node+1].ival,&numarg,prec);
483 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
489 str = walk(1,level,ops[node+1].ival,&numarg,prec);
491 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
497 str = walk(1,level,ops[node+1].ival,&numarg,prec);
499 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
505 str = walk(1,level,ops[node+1].ival,&numarg,prec);
507 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
513 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
515 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
521 str = walk(1,level,ops[node+1].ival,&numarg,prec);
523 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
529 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
535 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
543 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
551 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
559 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
570 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
580 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
581 if (!*fstr->str_ptr) {
583 len = 2; /* a legal fiction */
590 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
591 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
592 if (!do_fancy_opens) {
594 if (*t == '"' || *t == '\'')
595 t = cpytill(tokenbuf,t+1,*t);
597 fatal("Internal error: OGETLINE %s", t);
599 s = savestr(tokenbuf);
600 for (t = tokenbuf; *t; t++) {
604 if (!isalpha(*t) && !isdigit(*t))
607 if (!index(tokenbuf,'_'))
609 tmp3str = hfetch(symtab,tokenbuf);
612 str_cat(opens,"open(");
613 str_cat(opens,tokenbuf);
617 str_cat(opens,tmpstr->str_ptr+1);
619 if (*fstr->str_ptr == '|')
622 if (*fstr->str_ptr == '|')
623 str_cat(opens,") || die 'Cannot pipe from \"");
625 str_cat(opens,") || die 'Cannot open file \"");
627 str_cat(opens,"'.\"");
630 str_cat(opens,"\".'");
631 str_cat(opens,"\".';\n");
632 hstore(symtab,tokenbuf,str_make("x"));
637 str_cat(tmpstr,tokenbuf);
640 if (*fstr->str_ptr == '|')
641 str_cat(tmpstr,", '|'");
645 tmpstr = str_make("");
646 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
647 str_cat(str,tokenbuf);
650 str_cat(str,",$getline_ok)");
651 saw_getline |= 1 << len;
655 str_set(str,"sprintf(");
656 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
662 str_set(str,"substr(");
663 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
666 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
670 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
674 str_cat(str,"999999");
679 str_set(str,ops[node+1].cval);
685 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
690 str_scat(str,tmpstr);
691 str_cat(str," = split(");
693 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
694 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
695 i = fstr->str_ptr[1] & 127;
696 if (index("*+?.[]()|^$\\",i))
697 sprintf(tokenbuf,"/\\%c/",i);
699 sprintf(tokenbuf,"' '");
701 sprintf(tokenbuf,"/%c/",i);
702 str_cat(str,tokenbuf);
709 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
710 str_cat(str,tokenbuf);
719 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
729 str_set(str,"index(");
730 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
733 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
741 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
744 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
746 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
752 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
753 curargs = str_new(0);
754 str_sset(curargs,fstr);
755 str_cat(curargs,",");
756 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
762 t = tmp2str->str_ptr;
763 while (t = instr(t,"return "))
767 for (t = s+7; *t; t++) {
768 if (*t == ';' || *t == '}')
773 tmp2str->str_cur -= 7;
779 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
783 str_cat(str,"local(");
785 str_cat(str,") = @_;");
788 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
791 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
794 str_scat(str,tmp2str);
802 tmp2str = str_new(0);
804 str_set(tmp2str,"1");
805 hstore(symtab,tmpstr->str_ptr,tmp2str);
812 str_cat(str,"return ");
813 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
819 str_cat(str,"return");
824 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
827 tmpstr = hfetch(symtab,str->str_ptr+3);
828 if (tmpstr && tmpstr->str_ptr)
829 numeric |= atoi(tmpstr->str_ptr);
830 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
844 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
845 if (strNE(tmpstr->str_ptr,"$_")) {
846 str_cat(tmpstr, " =~ s");
850 str_set(tmpstr, "s");
853 str_set(tmpstr, "s");
854 type = ops[ops[node+2].ival].ival;
857 tmp3str = str_new(0);
859 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
860 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
868 str_set(tmp2str,tokenbuf);
871 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
872 str_set(tmp3str,"($s_ = '\"'.(");
873 str_scat(tmp3str,tmp2str);
874 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
875 str_set(tmp2str,"eval $s_");
876 s = (*s == 'g' ? "ge" : "e");
879 type = ops[ops[node+1].ival].ival;
882 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
883 if (type == OREGEX) {
886 str_scat(str,tmp3str);
887 str_scat(str,tmpstr);
889 str_scat(str,tmp2str);
893 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
896 str_scat(str,tmp3str);
897 str_scat(str,tmpstr);
901 str_scat(str,tmp2str);
909 str_cat(str,"$s = ");
912 str_scat(str,tmp3str);
913 str_scat(str,tmpstr);
915 str_scat(str,tmp2str);
928 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
932 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
934 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
937 else if (*t == '\\') {
941 case '\\': case '"': case 'n': case 't': case '$':
943 default: /* hide this from perl */
952 str_cat(str,tokenbuf);
959 str_set(str,"defined $");
963 str_set(str,"delete $");
973 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
975 tmp2str = hfetch(symtab,tmpstr->str_ptr);
976 if (tmp2str && atoi(tmp2str->str_ptr))
978 if (strEQ(str->str_ptr,"$FNR")) {
981 str_set(str,"($.-$FNRbase)");
983 else if (strEQ(str->str_ptr,"$NR")) {
987 else if (strEQ(str->str_ptr,"$NF")) {
989 str_set(str,"$#Fld");
991 else if (strEQ(str->str_ptr,"$0"))
993 else if (strEQ(str->str_ptr,"$ARGC"))
994 str_set(str,"($#ARGV+1)");
999 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
1000 ??? if (instr(curargs->str_ptr,tokenbuf))
1001 str_cat(str,"\377"); /* can't translate yet */
1004 str_cat(tmpstr,"[]");
1005 tmp2str = hfetch(symtab,tmpstr->str_ptr);
1006 if (tmp2str && atoi(tmp2str->str_ptr))
1010 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1012 if (strEQ(str->str_ptr,"$ARGV[0")) {
1013 str_set(str,"$ARGV0");
1017 if (tmp2str && atoi(tmp2str->str_ptr))
1018 strcpy(tokenbuf,"]");
1020 strcpy(tokenbuf,"}");
1022 str_cat(str,tokenbuf);
1029 if (split_to_array) {
1030 str_set(str,"$Fld");
1032 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1037 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1039 sprintf(tokenbuf,"$%s",nameary[i]);
1041 sprintf(tokenbuf,"$Fld%d",i);
1042 str_set(str,tokenbuf);
1047 str_set(str,"$Fld[");
1048 i = ops[node+1].ival;
1049 if ((ops[i].ival & 255) == OPAREN)
1051 tmpstr=walk(1,level,i,&numarg,P_MIN);
1052 str_scat(str,tmpstr);
1071 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1072 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1074 str_scat(str,tmpstr);
1080 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1081 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1083 str_scat(str,tmpstr);
1089 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1091 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1093 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1102 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1103 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1109 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1112 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1113 if (*tmpstr->str_ptr == ';') {
1115 str_cat(str,tmpstr->str_ptr+1);
1122 str = str_make("close(");
1123 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1124 if (!do_fancy_opens) {
1125 t = tmpstr->str_ptr;
1126 if (*t == '"' || *t == '\'')
1127 t = cpytill(tokenbuf,t+1,*t);
1129 fatal("Internal error: OCLOSE %s",t);
1130 s = savestr(tokenbuf);
1131 for (t = tokenbuf; *t; t++) {
1135 if (!isalpha(*t) && !isdigit(*t))
1138 if (!index(tokenbuf,'_'))
1142 str_set(str,"close ");
1143 str_cat(str,tokenbuf);
1146 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1147 tmpstr->str_ptr, tmpstr->str_ptr);
1149 str_set(str,tokenbuf);
1154 lparen = ""; /* set to parens if necessary */
1157 if (len == 3) { /* output redirection */
1158 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1159 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1160 if (!do_fancy_opens) {
1161 t = tmpstr->str_ptr;
1162 if (*t == '"' || *t == '\'')
1163 t = cpytill(tokenbuf,t+1,*t);
1165 fatal("Internal error: OPRINT");
1167 s = savestr(tokenbuf);
1168 for (t = tokenbuf; *t; t++) {
1172 if (!isalpha(*t) && !isdigit(*t))
1175 if (!index(tokenbuf,'_'))
1177 tmp3str = hfetch(symtab,tokenbuf);
1179 str_cat(opens,"open(");
1180 str_cat(opens,tokenbuf);
1181 str_cat(opens,", ");
1184 str_scat(opens,tmp2str);
1185 str_cat(opens,tmpstr->str_ptr+1);
1186 if (*tmp2str->str_ptr == '|')
1187 str_cat(opens,") || die 'Cannot pipe to \"");
1189 str_cat(opens,") || die 'Cannot create file \"");
1191 str_cat(opens,"'.\"");
1194 str_cat(opens,"\".'");
1195 str_cat(opens,"\".';\n");
1196 hstore(symtab,tokenbuf,str_make("x"));
1204 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1205 tmp2str->str_ptr, tmpstr->str_ptr);
1206 str_cat(str,tokenbuf);
1208 strcpy(tokenbuf,"$fh");
1216 strcpy(tokenbuf,"");
1217 str_cat(str,lparen); /* may be null */
1218 if (type == OPRINTF)
1219 str_cat(str,"printf");
1221 str_cat(str,"print");
1223 if (len == 3 || do_fancy_opens) {
1228 str_cat(str,tokenbuf);
1230 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1231 if (!*tmpstr->str_ptr && lval_field) {
1232 t = saw_OFS ? "$," : "' '";
1233 if (split_to_array) {
1234 sprintf(tokenbuf,"join(%s,@Fld)",t);
1235 str_cat(tmpstr,tokenbuf);
1238 for (i = 1; i < maxfld; i++) {
1240 sprintf(tokenbuf,"$%s, ",nameary[i]);
1242 sprintf(tokenbuf,"$Fld%d, ",i);
1243 str_cat(tmpstr,tokenbuf);
1245 if (maxfld <= arymax)
1246 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1248 sprintf(tokenbuf,"$Fld%d",maxfld);
1249 str_cat(tmpstr,tokenbuf);
1252 if (*tmpstr->str_ptr) {
1254 if (!saw_fh && *tmpstr->str_ptr == '(') {
1256 str_scat(str,tmpstr);
1260 str_scat(str,tmpstr);
1265 str_cat(str,rparen); /* may be null */
1269 str = str_make("rand(1)");
1272 str = str_make("srand(");
1275 str = str_make("atan2(");
1278 str = str_make("sin(");
1281 str = str_make("cos(");
1284 str = str_make("system(");
1287 str = str_make("length(");
1290 str = str_make("log(");
1293 str = str_make("exp(");
1296 str = str_make("sqrt(");
1299 str = str_make("int(");
1303 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1305 tmpstr = str_new(0);;
1306 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1308 t = saw_OFS ? "$," : "' '";
1309 if (split_to_array) {
1310 sprintf(tokenbuf,"join(%s,@Fld)",t);
1311 str_cat(tmpstr,tokenbuf);
1314 sprintf(tokenbuf,"join(%s, ",t);
1315 str_cat(tmpstr,tokenbuf);
1316 for (i = 1; i < maxfld; i++) {
1318 sprintf(tokenbuf,"$%s,",nameary[i]);
1320 sprintf(tokenbuf,"$Fld%d,",i);
1321 str_cat(tmpstr,tokenbuf);
1323 if (maxfld <= arymax)
1324 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1326 sprintf(tokenbuf,"$Fld%d)",maxfld);
1327 str_cat(tmpstr,tokenbuf);
1331 str_cat(tmpstr,"$_");
1333 if (strEQ(tmpstr->str_ptr,"$_")) {
1334 if (type == OLENGTH && !do_chop) {
1335 str = str_make("(length(");
1336 str_cat(tmpstr,") - 1");
1339 str_scat(str,tmpstr);
1345 str_set(str,"last");
1349 str_set(str,"next line");
1355 str_set(str,"exit");
1360 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1366 str_set(str,"$ExitValue = ");
1369 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1373 str_cat(str,"last line");
1378 str_set(str,"next");
1384 str_set(str,"if (");
1385 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1388 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1391 i = ops[node+3].ival;
1393 if ((ops[i].ival & 255) == OBLOCK) {
1396 if ((ops[i].ival & 255) != OIF)
1405 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1409 str_cat(str,"else ");
1410 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1417 str_set(str,"while (");
1418 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1421 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1427 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1429 if (str->str_ptr[str->str_cur - 1] == '\n')
1431 str_cat(str," while (");
1432 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1438 str_set(str,"for (");
1439 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1442 t = s = tmpstr->str_ptr;
1443 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1450 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1451 if (i && (t = index(fstr->str_ptr,0377))) {
1452 if (strnEQ(fstr->str_ptr,s,i))
1459 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1462 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1466 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1467 d = index(tmpstr->str_ptr,'$');
1469 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1474 fatal("Illegal for loop: %s",d);
1476 for (t = s; i = *t; t++) {
1478 if (i == '}' || i == ']')
1486 tmp2str = hfetch(symtab,str->str_ptr);
1487 if (tmp2str && atoi(tmp2str->str_ptr)) {
1489 "foreach %s ($[ .. $#%s) ",
1495 "foreach %s (keys %%%s) ",
1499 str_set(str,tokenbuf);
1500 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1507 if (len >= 2 && ops[node+2].ival) {
1508 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1511 fixtab(str,++level);
1512 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1515 fixtab(str,--level);
1519 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1527 fatal("Garbage length in walk");
1528 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1529 for (i = 2; i<= len; i++) {
1530 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1542 if (useval && prec < minprec) { /* need parens? */
1543 fstr = str_new(str->str_cur+2);
1544 str_nset(fstr,"(",1);
1546 str_ncat(fstr,")",1);
1551 *numericptr = numeric;
1554 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1555 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1558 else if (*t == '\t')
1586 /* strip trailing white space */
1588 s = str->str_ptr+str->str_cur - 1;
1589 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1592 str->str_cur = s + 1 - str->str_ptr;
1593 if (s >= str->str_ptr && *s != '\n')
1604 s = str->str_ptr+str->str_cur - 1;
1605 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1607 if (s >= str->str_ptr && *s != ';' && *s != '}')
1611 emit_split(str,level)
1618 str_cat(str,"@Fld");
1621 for (i = 1; i < maxfld; i++) {
1623 sprintf(tokenbuf,"$%s,",nameary[i]);
1625 sprintf(tokenbuf,"$Fld%d,",i);
1626 str_cat(str,tokenbuf);
1628 if (maxfld <= arymax)
1629 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1631 sprintf(tokenbuf,"$Fld%d)",maxfld);
1632 str_cat(str,tokenbuf);
1635 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1636 str_cat(str,tokenbuf);
1639 str_cat(str," = split($FS, $_, 9999);\n");
1641 str_cat(str," = split(' ', $_, 9999);\n");
1645 prewalk(numit,level,node,numericptr)
1657 int numeric = FALSE;
1665 type = ops[node].ival;
1670 prewalk(0,level,ops[node+1].ival,&numarg);
1671 if (ops[node+2].ival) {
1672 prewalk(0,level,ops[node+2].ival,&numarg);
1675 prewalk(0,level,ops[node+3].ival,&numarg);
1677 if (ops[node+3].ival) {
1678 prewalk(0,level,ops[node+4].ival,&numarg);
1682 prewalk(0,level,ops[node+1].ival,&numarg);
1683 prewalk(0,level,ops[node+2].ival,&numarg);
1685 prewalk(0,level,ops[node+3].ival,&numarg);
1689 prewalk(1,level,ops[node+1].ival,&numarg);
1690 prewalk(1,level,ops[node+2].ival,&numarg);
1695 prewalk(0,level,ops[node+1].ival,&numarg);
1699 prewalk(0,level,ops[node+1].ival,&numarg);
1702 i = prewalk(0,level,ops[node+1].ival,&numarg);
1705 prewalk(0,level,ops[node+2].ival,&numarg);
1709 prewalk(0,level,ops[node+2].ival,&numarg);
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1717 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);
1722 prewalk(0,level,ops[node+2].ival,&numarg);
1725 prewalk(0,level,ops[node+1].ival,&numarg);
1728 prewalk(0,level,ops[node+1].ival,&numarg);
1732 prewalk(0,level,ops[node+1].ival,&numarg);
1734 prewalk(0,level,ops[node+2].ival,&numarg);
1737 prewalk(0,level,ops[node+1].ival,&numarg);
1739 prewalk(0,level,ops[node+2].ival,&numarg);
1742 prewalk(0,level,ops[node+1].ival,&numarg);
1746 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);
1754 prewalk(0,level,ops[node+1].ival,&numarg);
1758 prewalk(0,level,ops[node+2].ival,&numarg);
1759 prewalk(0,level,ops[node+1].ival,&numarg);
1760 prewalk(0,level,ops[node+3].ival,&numarg);
1764 prewalk(0,level,ops[node+1].ival,&numarg);
1768 prewalk(0,level,ops[node+1].ival,&numarg);
1769 prewalk(0,level,ops[node+2].ival,&numarg);
1772 prewalk(0,level,ops[node+2].ival,&numarg);
1773 prewalk(0,level,ops[node+1].ival,&numarg);
1774 prewalk(0,level,ops[node+3].ival,&numarg);
1775 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1776 numericize(ops[node+2].ival);
1778 numericize(ops[node+3].ival);
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);
1794 prewalk(1,level,ops[node+2].ival,&numarg);
1798 prewalk(1,level,ops[node+1].ival,&numarg);
1799 prewalk(1,level,ops[node+2].ival,&numarg);
1803 prewalk(1,level,ops[node+1].ival,&numarg);
1804 prewalk(1,level,ops[node+2].ival,&numarg);
1808 prewalk(1,level,ops[node+1].ival,&numarg);
1809 prewalk(1,level,ops[node+2].ival,&numarg);
1813 prewalk(1,level,ops[node+1].ival,&numarg);
1817 prewalk(1,level,ops[node+1].ival,&numarg);
1821 prewalk(1,level,ops[node+1].ival,&numarg);
1825 prewalk(1,level,ops[node+1].ival,&numarg);
1829 prewalk(1,level,ops[node+1].ival,&numarg);
1833 prewalk(1,level,ops[node+1].ival,&numarg);
1837 prewalk(0,level,ops[node+1].ival,&numarg);
1843 prewalk(0,level,ops[node+1].ival,&numarg);
1846 prewalk(0,level,ops[node+1].ival,&numarg);
1847 prewalk(1,level,ops[node+2].ival,&numarg);
1849 prewalk(1,level,ops[node+3].ival,&numarg);
1856 prewalk(0,level,ops[node+2].ival,&numarg);
1858 prewalk(0,level,ops[node+3].ival,&numarg);
1859 prewalk(0,level,ops[node+1].ival,&numarg);
1862 prewalk(0,level,ops[node+1].ival,&numarg);
1863 prewalk(0,level,ops[node+2].ival,&numarg);
1867 prewalk(0,level,ops[node+1].ival,&numarg);
1868 prewalk(0,level,ops[node+2].ival,&numarg);
1874 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1876 prewalk(0,level,ops[node+2].ival,&numarg);
1877 prewalk(0,level,ops[node+4].ival,&numarg);
1878 prewalk(0,level,ops[node+5].ival,&numarg);
1880 str_cat(tmpstr,"(");
1881 tmp2str = str_new(0);
1882 if (subretnum || numarg)
1883 str_set(tmp2str,"1");
1884 hstore(symtab,tmpstr->str_ptr,tmp2str);
1890 prewalk(0,level,ops[node+1].ival,&numarg);
1896 tmp2str = str_new(0);
1897 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1898 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1900 str_cat(tmp2str,"(");
1901 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1902 if (tmpstr && tmpstr->str_ptr)
1903 numeric |= atoi(tmpstr->str_ptr);
1904 prewalk(0,level,ops[node+2].ival,&numarg);
1910 prewalk(0,level,ops[node+3].ival,&numarg);
1911 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1912 prewalk(0,level,ops[node+1].ival,&numarg);
1916 prewalk(0,level,ops[node+1].ival,&numarg);
1920 prewalk(0,level,ops[node+1].ival,&numarg);
1926 prewalk(0,level,ops[node+1].ival,&numarg);
1932 prewalk(0,level,ops[node+2].ival,&numarg);
1936 prewalk(0,level,ops[node+1].ival,&numarg);
1939 i = ops[node+1].ival;
1940 prewalk(0,level,i,&numarg);
1953 prewalk(0,level,ops[node+1].ival,&numarg);
1954 prewalk(0,level,ops[node+2].ival,&numarg);
1955 prewalk(0,level,ops[node+3].ival,&numarg);
1960 prewalk(0,level,ops[node+1].ival,&numarg);
1961 prewalk(0,level,ops[node+2].ival,&numarg);
1965 prewalk(0,level,ops[node+1].ival,&numarg);
1967 prewalk(0,level,ops[node+2].ival,&numarg);
1972 prewalk(0,level,ops[node+1].ival,&numarg);
1976 if (len == 3) { /* output redirection */
1977 prewalk(0,level,ops[node+3].ival,&numarg);
1978 prewalk(0,level,ops[node+2].ival,&numarg);
1980 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
2006 prewalk(type != OLENGTH && type != OSYSTEM,
2007 level,ops[node+1].ival,&numarg);
2015 prewalk(1,level,ops[node+1].ival,&numarg);
2023 prewalk(0,level,ops[node+1].ival,&numarg);
2024 prewalk(0,level,ops[node+2].ival,&numarg);
2026 prewalk(0,level,ops[node+3].ival,&numarg);
2030 prewalk(0,level,ops[node+1].ival,&numarg);
2031 prewalk(0,level,ops[node+2].ival,&numarg);
2034 prewalk(0,level,ops[node+1].ival,&numarg);
2035 prewalk(0,level,ops[node+2].ival,&numarg);
2036 prewalk(0,level,ops[node+3].ival,&numarg);
2037 prewalk(0,level,ops[node+4].ival,&numarg);
2040 prewalk(0,level,ops[node+2].ival,&numarg);
2041 prewalk(0,level,ops[node+1].ival,&numarg);
2045 prewalk(0,level,ops[node+2].ival,&numarg);
2048 prewalk(0,level,ops[node+1].ival,&numarg);
2055 fatal("Garbage length in prewalk");
2056 prewalk(0,level,ops[node+1].ival,&numarg);
2057 for (i = 2; i<= len; i++) {
2058 prewalk(0,level,ops[node+i].ival,&numarg);
2063 *numericptr = numeric;
2077 type = ops[node].ival;
2080 if (type == OVAR && len == 1) {
2081 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2082 tmp2str = str_make("1");
2083 hstore(symtab,tmpstr->str_ptr,tmp2str);