X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=x2p%2Fwalk.c;h=403d686e391855eed42848679fd4b6c90b14f7ab;hb=9c7d862108a3f02f3db65204f8154cdfe689040e;hp=d0ea34112cc5102c12ff034d62a17336bd4af516;hpb=ae98613044a1084886d80b8283b25bad38cfd171;p=p5sagit%2Fp5-mst-13.2.git diff --git a/x2p/walk.c b/x2p/walk.c index d0ea341..403d686 100644 --- a/x2p/walk.c +++ b/x2p/walk.c @@ -1,23 +1,16 @@ -/* $Header: walk.c,v 3.0.1.1 89/11/11 05:09:33 lwall Locked $ +/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $ * - * Copyright (c) 1989, Larry Wall + * Copyright (c) 1991, Larry Wall * - * You may distribute under the terms of the GNU General Public License - * as specified in the README file that comes with the perl 3.0 kit. + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. * * $Log: walk.c,v $ - * Revision 3.0.1.1 89/11/11 05:09:33 lwall - * patch2: in a2p, awk script with no line actions still needs main loop - * - * Revision 3.0 89/10/18 15:35:48 lwall - * 3.0 baseline - * */ -#include "handy.h" #include "EXTERN.h" -#include "util.h" #include "a2p.h" +#include "util.h" bool exitval = FALSE; bool realexit = FALSE; @@ -25,12 +18,24 @@ bool saw_getline = FALSE; bool subretnum = FALSE; bool saw_FNR = FALSE; bool saw_argv0 = FALSE; +bool saw_fh = FALSE; int maxtmp = 0; char *lparen; char *rparen; +char *limit; STR *subs; STR *curargs = Nullstr; +static void addsemi _(( STR *str )); +static void emit_split _(( STR *str, int level )); +static void fixtab _(( STR *str, int lvl )); +static void numericize _(( int node )); +static void tab _(( STR *str, int lvl )); + +int prewalk _(( int numit, int level, int node, int *numericptr )); +STR * walk _(( int useval, int level, int node, int *numericptr, int minprec )); + + STR * walk(useval,level,node,numericptr,minprec) int useval; @@ -52,7 +57,6 @@ int minprec; /* minimum precedence without parens */ int numeric = FALSE; STR *fstr; int prec = P_MAX; /* assume no parens needed */ - char *index(); if (!node) { *numericptr = 0; @@ -63,6 +67,20 @@ int minprec; /* minimum precedence without parens */ type &= 255; switch (type) { case OPROG: + arymax = 0; + if (namelist) { + while (isalpha(*namelist)) { + for (d = tokenbuf,s=namelist; + isalpha(*s) || isdigit(*s) || *s == '_'; + *d++ = *s++) ; + *d = '\0'; + while (*s && !isalpha(*s)) s++; + namelist = s; + nameary[++arymax] = savestr(tokenbuf); + } + } + if (maxfld < arymax) + maxfld = arymax; opens = str_new(0); subs = str_new(0); str = walk(0,level,ops[node+1].ival,&numarg,P_MIN); @@ -81,7 +99,7 @@ int minprec; /* minimum precedence without parens */ do_chop = TRUE; if (fswitch) { str_cat(str,"$FS = '"); - if (index("*+?.[]()|^$\\",fswitch)) + if (strchr("*+?.[]()|^$\\",fswitch)) str_cat(str,"\\"); sprintf(tokenbuf,"%c",fswitch); str_cat(str,tokenbuf); @@ -118,20 +136,6 @@ int minprec; /* minimum precedence without parens */ str_cat(str,"chop;\t# strip record separator\n"); tab(str,level); } - arymax = 0; - if (namelist) { - while (isalpha(*namelist)) { - for (d = tokenbuf,s=namelist; - isalpha(*s) || isdigit(*s) || *s == '_'; - *d++ = *s++) ; - *d = '\0'; - while (*s && !isalpha(*s)) s++; - namelist = s; - nameary[++arymax] = savestr(tokenbuf); - } - } - if (maxfld < arymax) - maxfld = arymax; if (do_split) emit_split(str,level); str_scat(str,fstr); @@ -152,7 +156,7 @@ int minprec; /* minimum precedence without parens */ str_cat(str,"\n"); } if (exitval) - str_cat(str,"exit ExitValue;\n"); + str_cat(str,"exit $ExitValue;\n"); if (subs->str_ptr) { str_cat(str,"\n"); str_scat(str,subs); @@ -173,7 +177,7 @@ int minprec; /* minimum precedence without parens */ str_cat(str," $FNRbase = $. if eof;\n"); } if (len & 1) - str_cat(str," local($_)\n"); + str_cat(str," local($_);\n"); if (len & 2) str_cat(str, " if ($getline_ok = (($_ = <$fh>) ne ''))"); @@ -205,11 +209,8 @@ int minprec; /* minimum precedence without parens */ str_cat(str,"\n\ sub Pick {\n\ local($mode,$name,$pipe) = @_;\n\ - $fh = $opened{$name};\n\ - if (!$fh) {\n\ - $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\ - open($fh,$mode.$name.$pipe);\n\ - }\n\ + $fh = $name;\n\ + open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\ }\n\ "); } @@ -318,6 +319,16 @@ sub Pick {\n\ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec)); str_free(fstr); break; + case OCOND: + prec = P_COND; + str = walk(1,level,ops[node+1].ival,&numarg,prec); + str_cat(str," ? "); + str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1)); + str_free(fstr); + str_cat(str," : "); + str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); + str_free(fstr); + break; case OCPAREN: str = str_new(0); str_set(str,"("); @@ -376,8 +387,8 @@ sub Pick {\n\ str_set(tmpstr,"gt"); else if (strEQ(t,">=")) str_set(tmpstr,"ge"); - if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') && - !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') ) + if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') && + !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') ) numeric |= 2; } if (numeric & 2) { @@ -452,6 +463,8 @@ sub Pick {\n\ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec)); str_free(fstr); numeric |= numarg; + if (strEQ(str->str_ptr,"$/ = ''")) + str_set(str, "$/ = \"\\n\\n\""); break; case OADD: prec = P_ADD; @@ -554,10 +567,9 @@ sub Pick {\n\ if (useval) str_cat(str,"("); if (len > 0) { - str_cat(str,"$"); str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); if (!*fstr->str_ptr) { - str_cat(str,"_"); + str_cat(str,"$_"); len = 2; /* a legal fiction */ } str_free(fstr); @@ -577,11 +589,13 @@ sub Pick {\n\ s = savestr(tokenbuf); for (t = tokenbuf; *t; t++) { *t &= 127; + if (islower(*t)) + *t = toupper(*t); if (!isalpha(*t) && !isdigit(*t)) *t = '_'; } - if (!index(tokenbuf,'_')) - strcpy(t,"_fh"); + if (!strchr(tokenbuf,'_')) + strcpy(t,"_FH"); tmp3str = hfetch(symtab,tokenbuf); if (!tmp3str) { do_opens = TRUE; @@ -656,6 +670,7 @@ sub Pick {\n\ break; case OSPLIT: str = str_new(0); + limit = ", 9999)"; numeric = 1; tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN); if (useval) @@ -668,8 +683,10 @@ sub Pick {\n\ fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1); if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') { i = fstr->str_ptr[1] & 127; - if (index("*+?.[]()|^$\\",i)) + if (strchr("*+?.[]()|^$\\",i)) sprintf(tokenbuf,"/\\%c/",i); + else if (i == ' ') + sprintf(tokenbuf,"' '"); else sprintf(tokenbuf,"/%c/",i); str_cat(str,tokenbuf); @@ -684,12 +701,14 @@ sub Pick {\n\ } else if (saw_FS) str_cat(str,"$FS"); - else + else { str_cat(str,"' '"); + limit = ")"; + } str_cat(str,", "); str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1)); str_free(fstr); - str_cat(str,", 999)"); + str_cat(str,limit); if (useval) { str_cat(str,")"); } @@ -909,7 +928,7 @@ sub Pick {\n\ s = "\""; *d++ = *t++ + 128; switch (*t) { - case '\\': case '"': case 'n': case 't': + case '\\': case '"': case 'n': case 't': case '$': break; default: /* hide this from perl */ *d++ = '\\' + 128; @@ -1101,19 +1120,21 @@ sub Pick {\n\ s = savestr(tokenbuf); for (t = tokenbuf; *t; t++) { *t &= 127; + if (islower(*t)) + *t = toupper(*t); if (!isalpha(*t) && !isdigit(*t)) *t = '_'; } - if (!index(tokenbuf,'_')) - strcpy(t,"_fh"); + if (!strchr(tokenbuf,'_')) + strcpy(t,"_FH"); str_free(tmpstr); safefree(s); str_set(str,"close "); str_cat(str,tokenbuf); } else { - sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)", - tmpstr->str_ptr); + sprintf(tokenbuf,"delete $opened{%s} && close(%s)", + tmpstr->str_ptr, tmpstr->str_ptr); str_free(tmpstr); str_set(str,tokenbuf); } @@ -1136,11 +1157,13 @@ sub Pick {\n\ s = savestr(tokenbuf); for (t = tokenbuf; *t; t++) { *t &= 127; + if (islower(*t)) + *t = toupper(*t); if (!isalpha(*t) && !isdigit(*t)) *t = '_'; } - if (!index(tokenbuf,'_')) - strcpy(t,"_fh"); + if (!strchr(tokenbuf,'_')) + strcpy(t,"_FH"); tmp3str = hfetch(symtab,tokenbuf); if (!tmp3str) { str_cat(opens,"open("); @@ -1186,9 +1209,12 @@ sub Pick {\n\ str_cat(str,"printf"); else str_cat(str,"print"); + saw_fh = 0; if (len == 3 || do_fancy_opens) { - if (*tokenbuf) + if (*tokenbuf) { str_cat(str," "); + saw_fh = 1; + } str_cat(str,tokenbuf); } tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN); @@ -1215,7 +1241,13 @@ sub Pick {\n\ } if (*tmpstr->str_ptr) { str_cat(str," "); - str_scat(str,tmpstr); + if (!saw_fh && *tmpstr->str_ptr == '(') { + str_cat(str,"("); + str_scat(str,tmpstr); + str_cat(str,")"); + } + else + str_scat(str,tmpstr); } else { str_cat(str," $_"); @@ -1261,7 +1293,7 @@ sub Pick {\n\ tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN); else tmpstr = str_new(0);; - if (!*tmpstr->str_ptr) { + if (!tmpstr->str_ptr || !*tmpstr->str_ptr) { if (lval_field) { t = saw_OFS ? "$," : "' '"; if (split_to_array) { @@ -1321,7 +1353,7 @@ sub Pick {\n\ } else { if (len == 1) { - str_set(str,"ExitValue = "); + str_set(str,"$ExitValue = "); exitval = TRUE; str_scat(str, fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN)); @@ -1379,6 +1411,18 @@ sub Pick {\n\ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); str_free(fstr); break; + case ODO: + str = str_new(0); + str_set(str,"do "); + str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); + str_free(fstr); + if (str->str_ptr[str->str_cur - 1] == '\n') + --str->str_cur;; + str_cat(str," while ("); + str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); + str_free(fstr); + str_cat(str,");"); + break; case OFOR: str = str_new(0); str_set(str,"for ("); @@ -1394,7 +1438,7 @@ sub Pick {\n\ } str_cat(str,"; "); fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN); - if (i && (t = index(fstr->str_ptr,0377))) { + if (i && (t = strchr(fstr->str_ptr,0377))) { if (strnEQ(fstr->str_ptr,s,i)) *t = ' '; } @@ -1410,19 +1454,21 @@ sub Pick {\n\ break; case OFORIN: tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - d = index(tmpstr->str_ptr,'$'); + d = strchr(tmpstr->str_ptr,'$'); if (!d) fatal("Illegal for loop: %s",tmpstr->str_ptr); - s = index(d,'{'); + s = strchr(d,'{'); if (!s) - s = index(d,'['); + s = strchr(d,'['); if (!s) fatal("Illegal for loop: %s",d); *s++ = '\0'; - t = index(s,'}' + 128); - if (!t) - t = index(s,']' + 128); - if (t) + for (t = s; i = *t; t++) { + i &= 127; + if (i == '}' || i == ']') + break; + } + if (*t) *t = '\0'; str = str_new(0); str_set(str,d+1); @@ -1430,7 +1476,7 @@ sub Pick {\n\ tmp2str = hfetch(symtab,str->str_ptr); if (tmp2str && atoi(tmp2str->str_ptr)) { sprintf(tokenbuf, - "foreach %s (@%s) ", + "foreach %s ($[ .. $#%s) ", s, d+1); } @@ -1509,6 +1555,7 @@ sub Pick {\n\ return str; } +static void tab(str,lvl) register STR *str; register int lvl; @@ -1521,6 +1568,7 @@ register int lvl; str_cat(str," "); } +static void fixtab(str,lvl) register STR *str; register int lvl; @@ -1540,6 +1588,7 @@ register int lvl; tab(str,lvl); } +static void addsemi(str) register STR *str; { @@ -1552,6 +1601,7 @@ register STR *str; str_cat(str,";"); } +static void emit_split(str,level) register STR *str; int level; @@ -1576,16 +1626,17 @@ int level; str_cat(str,tokenbuf); } if (const_FS) { - sprintf(tokenbuf," = split(/[%c\\n]/, $_, 999);\n",const_FS); + sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS); str_cat(str,tokenbuf); } else if (saw_FS) - str_cat(str," = split($FS, $_, 999);\n"); + str_cat(str," = split($FS, $_, 9999);\n"); else - str_cat(str," = split(' ', $_, 999);\n"); + str_cat(str," = split(' ', $_, 9999);\n"); tab(str,level); } +int prewalk(numit,level,node,numericptr) int numit; int level; @@ -1595,8 +1646,6 @@ int *numericptr; register int len; register int type; register int i; - char *t; - char *d, *s; int numarg; int numeric = FALSE; STR *tmpstr; @@ -1716,7 +1765,7 @@ int *numericptr; prewalk(0,level,ops[node+2].ival,&numarg); prewalk(0,level,ops[node+1].ival,&numarg); prewalk(0,level,ops[node+3].ival,&numarg); - if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) { + if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) { numericize(ops[node+2].ival); if (!numarg) numericize(ops[node+3].ival); @@ -1839,7 +1888,7 @@ int *numericptr; case OUSERFUN: tmp2str = str_new(0); str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - fixrargs(tmpstr->str_ptr,ops[node+2],0); + fixrargs(tmpstr->str_ptr,ops[node+2].ival,0); str_free(tmpstr); str_cat(tmp2str,"("); tmpstr = hfetch(symtab,tmp2str->str_ptr); @@ -2008,12 +2057,12 @@ int *numericptr; return 1; } +static void numericize(node) register int node; { register int len; register int type; - register int i; STR *tmpstr; STR *tmp2str; int numarg;