diff options
author | Leon Timmermans <fawaka@gmail.com> | 2014-05-21 13:56:54 +0200 |
---|---|---|
committer | Leon Timmermans <fawaka@gmail.com> | 2014-05-29 15:01:50 +0200 |
commit | e5a8a0fbd70ee31a016b7cf1c4b8c07839c6cf97 (patch) | |
tree | b76deaf20debae69504ec40cb5e3dccb759b2992 /x2p/walk.c | |
parent | c02d599bfd636e89753a6ed00b136798dc1661c3 (diff) | |
download | perl-e5a8a0fbd70ee31a016b7cf1c4b8c07839c6cf97.tar.gz |
Remove x2p
This removes find2perl, s2p and a2p from core. They have all been
released to CPAN as separate distributions.
Diffstat (limited to 'x2p/walk.c')
-rw-r--r-- | x2p/walk.c | 2055 |
1 files changed, 0 insertions, 2055 deletions
diff --git a/x2p/walk.c b/x2p/walk.c deleted file mode 100644 index d6962ede0f..0000000000 --- a/x2p/walk.c +++ /dev/null @@ -1,2055 +0,0 @@ -/* walk.c - * - * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, - * 2000, 2001, 2002, 2005 by Larry Wall and others - * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the README file. - */ - -#include "EXTERN.h" -#include "a2p.h" -#include "util.h" - -bool exitval = FALSE; -bool realexit = FALSE; -bool saw_getline = FALSE; -bool subretnum = FALSE; -bool saw_FNR = FALSE; -bool saw_argv0 = FALSE; -bool saw_fh = FALSE; -int maxtmp = 0; -const char *lparen; -const char *rparen; -const char *limit; -STR *subs; -STR *curargs = NULL; - -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 ); -#ifdef NETWARE -char *savestr(char *str); -char *cpytill(char *to, char *from, int delim); -char *instr(char *big, const char *little); -#endif - -STR * -walk(int useval, int level, int node, int *numericptr, int minprec) -{ - int len; - STR *str; - int type; - int i; - STR *tmpstr; - STR *tmp2str; - STR *tmp3str; - char *t; - char *d, *s; - int numarg; - int numeric = FALSE; - STR *fstr; - int prec = P_MAX; /* assume no parens needed */ - - if (!node) { - *numericptr = 0; - return str_make(""); - } - type = ops[node].ival; - len = type >> 8; - type &= 255; - switch (type) { - case OPROG: - arymax = 0; - if (namelist) { - while (isALPHA(*namelist)) { - for (d = tokenbuf,s=namelist; - isWORDCHAR(*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); - if (do_split && need_entire && !absmaxfld) - split_to_array = TRUE; - if (fswitch && !const_FS) - const_FS = fswitch; - if (saw_FS > 1 || saw_RS) - const_FS = 0; - if (saw_ORS && need_entire) - do_chop = TRUE; - if (fswitch) { - str_cat(str,"$FS = '"); - if (strchr("*+?.[]()|^$\\",fswitch)) - str_cat(str,"\\"); - sprintf(tokenbuf,"%c",fswitch); - str_cat(str,tokenbuf); - str_cat(str,"';\t\t# field separator from -F switch\n"); - } - else if (saw_FS && !const_FS) { - str_cat(str,"$FS = ' ';\t\t# set field separator\n"); - } - if (saw_OFS) { - str_cat(str,"$, = ' ';\t\t# set output field separator\n"); - } - if (saw_ORS) { - str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n"); - } - if (saw_argv0) { - str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n"); - } - if (str->str_cur > 20) - str_cat(str,"\n"); - if (ops[node+2].ival) { - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,"\n\n"); - } - fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN); - if (*fstr->str_ptr) { - if (saw_line_op) - str_cat(str,"line: "); - str_cat(str,"while (<>) {\n"); - tab(str,++level); - if (saw_FS && !const_FS) - do_chop = TRUE; - if (do_chop) { - str_cat(str,"chomp;\t# strip record separator\n"); - tab(str,level); - } - if (do_split) - emit_split(str,level); - str_scat(str,fstr); - str_free(fstr); - fixtab(str,--level); - str_cat(str,"}\n"); - if (saw_FNR) - str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n"); - } - else if (old_awk) - str_cat(str,"while (<>) { } # (no line actions)\n"); - if (ops[node+4].ival) { - realexit = TRUE; - str_cat(str,"\n"); - tab(str,level); - str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,"\n"); - } - if (exitval) - str_cat(str,"exit $ExitValue;\n"); - if (subs->str_ptr) { - str_cat(str,"\n"); - str_scat(str,subs); - } - if (saw_getline) { - for (len = 0; len < 4; len++) { - if (saw_getline & (1 << len)) { - sprintf(tokenbuf,"\nsub Getline%d {\n",len); - str_cat(str, tokenbuf); - if (len & 2) { - if (do_fancy_opens) - str_cat(str," &Pick('',@_);\n"); - else - str_cat(str," ($fh) = @_;\n"); - } - else { - if (saw_FNR) - str_cat(str," $FNRbase = $. if eof;\n"); - } - if (len & 1) - str_cat(str," local($_);\n"); - if (len & 2) - str_cat(str, - " if ($getline_ok = (($_ = <$fh>) ne ''))"); - else - str_cat(str, - " if ($getline_ok = (($_ = <>) ne ''))"); - str_cat(str, " {\n"); - level += 2; - tab(str,level); - i = 0; - if (do_chop) { - i++; - str_cat(str,"chomp;\t# strip record separator\n"); - tab(str,level); - } - if (do_split && !(len & 1)) { - i++; - emit_split(str,level); - } - if (!i) - str_cat(str,";\n"); - fixtab(str,--level); - str_cat(str,"}\n $_;\n}\n"); - --level; - } - } - } - if (do_fancy_opens) { - str_cat(str,"\n\ -sub Pick {\n\ - local($mode,$name,$pipe) = @_;\n\ - $fh = $name;\n\ - open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\ -}\n\ -"); - } - break; - case OHUNKS: - str = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - if (len == 3) { - str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN)); - str_free(fstr); - } - else { - } - break; - case ORANGE: - prec = P_DOTDOT; - str = walk(1,level,ops[node+1].ival,&numarg,prec+1); - str_cat(str," .. "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OPAT: - goto def; - case OREGEX: - str = str_new(0); - str_set(str,"/"); - tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN); - /* translate \nnn to [\nnn] */ - for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) { - if (*s == '\\' && isDIGIT(s[1]) && isDIGIT(s[2]) && isDIGIT(s[3])){ - *d++ = '['; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s; - *d = ']'; - } - else - *d = *s; - } - *d = '\0'; - for (d=tokenbuf; *d; d++) - *d += (char)128; - str_cat(str,tokenbuf); - str_free(tmpstr); - str_cat(str,"/"); - break; - case OHUNK: - if (len == 1) { - str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN); - str_cat(str," if "); - str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,";"); - } - else { - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - if (*tmpstr->str_ptr) { - str = str_new(0); - str_set(str,"if ("); - str_scat(str,tmpstr); - str_cat(str,") {\n"); - tab(str,++level); - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - fixtab(str,--level); - str_cat(str,"}\n"); - tab(str,level); - } - else { - str = walk(0,level,ops[node+2].ival,&numarg,P_MIN); - } - } - break; - case OPPAREN: - str = str_new(0); - str_set(str,"("); - str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,")"); - break; - case OPANDAND: - prec = P_ANDAND; - 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_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OPOROR: - prec = P_OROR; - 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_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OPNOT: - prec = P_UNARY; - str = str_new(0); - str_set(str,"!"); - 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,"("); - str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - numeric |= numarg; - str_cat(str,")"); - break; - case OCANDAND: - prec = P_ANDAND; - str = walk(1,level,ops[node+1].ival,&numarg,prec); - numeric = 1; - str_cat(str," && "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1)); - str_free(fstr); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OCOROR: - prec = P_OROR; - str = walk(1,level,ops[node+1].ival,&numarg,prec); - numeric = 1; - str_cat(str," || "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1)); - str_free(fstr); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OCNOT: - prec = P_UNARY; - str = str_new(0); - str_set(str,"!"); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec)); - str_free(fstr); - numeric = 1; - break; - case ORELOP: - prec = P_REL; - str = walk(1,level,ops[node+2].ival,&numarg,prec+1); - numeric |= numarg; - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1); - numeric |= numarg; - if (!numeric || - (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) { - t = tmpstr->str_ptr; - if (strEQ(t,"==")) - str_set(tmpstr,"eq"); - else if (strEQ(t,"!=")) - str_set(tmpstr,"ne"); - else if (strEQ(t,"<")) - str_set(tmpstr,"lt"); - else if (strEQ(t,"<=")) - str_set(tmpstr,"le"); - else if (strEQ(t,">")) - str_set(tmpstr,"gt"); - else if (strEQ(t,">=")) - str_set(tmpstr,"ge"); - if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') && - !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') ) - numeric |= 2; - } - if (numeric & 2) { - if (numeric & 1) /* numeric is very good guess */ - str_cat(str," "); - else - str_cat(str,"\377"); - numeric = 1; - } - else - str_cat(str," "); - str_scat(str,tmpstr); - str_free(tmpstr); - str_cat(str," "); - str_scat(str,tmp2str); - str_free(tmp2str); - numeric = 1; - break; - case ORPAREN: - str = str_new(0); - str_set(str,"("); - str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - numeric |= numarg; - str_cat(str,")"); - break; - case OMATCHOP: - prec = P_MATCH; - str = walk(1,level,ops[node+2].ival,&numarg,prec+1); - str_cat(str," "); - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - if (strEQ(tmpstr->str_ptr,"~")) - str_cat(str,"=~"); - else { - str_scat(str,tmpstr); - str_free(tmpstr); - } - str_cat(str," "); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - numeric = 1; - break; - case OMPAREN: - str = str_new(0); - str_set(str,"("); - str_scat(str, - fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - numeric |= numarg; - str_cat(str,")"); - break; - case OCONCAT: - prec = P_ADD; - type = ops[ops[node+1].ival].ival & 255; - str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT)); - str_cat(str," . "); - type = ops[ops[node+2].ival].ival & 255; - str_scat(str, - fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT))); - str_free(fstr); - break; - case OASSIGN: - prec = P_ASSIGN; - str = walk(0,level,ops[node+2].ival,&numarg,prec+1); - str_cat(str," "); - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - str_scat(str,tmpstr); - if (str_len(tmpstr) > 1) - numeric = 1; - str_free(tmpstr); - str_cat(str," "); - 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; - 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); - numeric = 1; - break; - case OSUBTRACT: - prec = P_ADD; - 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); - numeric = 1; - break; - case OMULT: - prec = P_MUL; - 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); - numeric = 1; - break; - case ODIV: - prec = P_MUL; - 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); - numeric = 1; - break; - case OPOW: - prec = P_POW; - str = walk(1,level,ops[node+1].ival,&numarg,prec+1); - str_cat(str," ** "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec)); - str_free(fstr); - numeric = 1; - break; - case OMOD: - prec = P_MUL; - 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); - numeric = 1; - break; - case OPOSTINCR: - prec = P_AUTO; - str = walk(1,level,ops[node+1].ival,&numarg,prec+1); - str_cat(str,"++"); - numeric = 1; - break; - case OPOSTDECR: - prec = P_AUTO; - str = walk(1,level,ops[node+1].ival,&numarg,prec+1); - str_cat(str,"--"); - numeric = 1; - break; - case OPREINCR: - prec = P_AUTO; - str = str_new(0); - str_set(str,"++"); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1)); - str_free(fstr); - numeric = 1; - break; - case OPREDECR: - prec = P_AUTO; - str = str_new(0); - str_set(str,"--"); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1)); - str_free(fstr); - numeric = 1; - break; - case OUMINUS: - prec = P_UNARY; - str = str_new(0); - str_set(str,"-"); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec)); - str_free(fstr); - numeric = 1; - break; - case OUPLUS: - numeric = 1; - goto def; - case OPAREN: - str = str_new(0); - str_set(str,"("); - str_scat(str, - fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,")"); - numeric |= numarg; - break; - case OGETLINE: - str = str_new(0); - if (useval) - str_cat(str,"("); - if (len > 0) { - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - if (!*fstr->str_ptr) { - str_cat(str,"$_"); - len = 2; /* a legal fiction */ - } - str_free(fstr); - } - else - str_cat(str,"$_"); - if (len > 1) { - tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN); - fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN); - if (!do_fancy_opens) { - t = tmpstr->str_ptr; - if (*t == '"' || *t == '\'') - t = cpytill(tokenbuf,t+1,*t); - else - fatal("Internal error: OGETLINE %s", t); - d = savestr(t); - s = savestr(tokenbuf); - for (t = tokenbuf; *t; t++) { - *t &= 127; - if (isLOWER(*t)) - *t = toUPPER(*t); - if (!isALPHANUMERIC(*t)) - *t = '_'; - } - if (!strchr(tokenbuf,'_')) - strcpy(t,"_FH"); - tmp3str = hfetch(symtab,tokenbuf); - if (!tmp3str) { - do_opens = TRUE; - str_cat(opens,"open("); - str_cat(opens,tokenbuf); - str_cat(opens,", "); - d[1] = '\0'; - str_cat(opens,d); - str_cat(opens,tmpstr->str_ptr+1); - opens->str_cur--; - if (*fstr->str_ptr == '|') - str_cat(opens,"|"); - str_cat(opens,d); - if (*fstr->str_ptr == '|') - str_cat(opens,") || die 'Cannot pipe from \""); - else - str_cat(opens,") || die 'Cannot open file \""); - if (*d == '"') - str_cat(opens,"'.\""); - str_cat(opens,s); - if (*d == '"') - str_cat(opens,"\".'"); - str_cat(opens,"\".';\n"); - hstore(symtab,tokenbuf,str_make("x")); - } - safefree(s); - safefree(d); - str_set(tmpstr,"'"); - str_cat(tmpstr,tokenbuf); - str_cat(tmpstr,"'"); - } - if (*fstr->str_ptr == '|') - str_cat(tmpstr,", '|'"); - str_free(fstr); - } - else - tmpstr = str_make(""); - sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr); - str_cat(str,tokenbuf); - str_free(tmpstr); - if (useval) - str_cat(str,",$getline_ok)"); - saw_getline |= 1 << len; - break; - case OSPRINTF: - str = str_new(0); - str_set(str,"sprintf("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,")"); - break; - case OSUBSTR: - str = str_new(0); - str_set(str,"substr("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1)); - str_free(fstr); - str_cat(str,", ("); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1)); - str_free(fstr); - str_cat(str,")-1"); - if (len == 3) { - str_cat(str,", "); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1)); - str_free(fstr); - } - str_cat(str,")"); - break; - case OSTRING: - str = str_new(0); - str_set(str,ops[node+1].cval); - break; - case OSPLIT: - str = str_new(0); - limit = ", -1)"; - numeric = 1; - tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN); - if (useval) - str_set(str,"(@"); - else - str_set(str,"@"); - str_scat(str,tmpstr); - str_cat(str," = split("); - if (len == 3) { - 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 (strchr("*+?.[]()|^$\\",i)) - sprintf(tokenbuf,"/\\%c/",i); - else if (i == ' ') - sprintf(tokenbuf,"' '"); - else - sprintf(tokenbuf,"/%c/",i); - str_cat(str,tokenbuf); - } - else - str_scat(str,fstr); - str_free(fstr); - } - else if (const_FS) { - sprintf(tokenbuf,"/[%c\\n]/",const_FS); - str_cat(str,tokenbuf); - } - else if (saw_FS) - str_cat(str,"$FS"); - 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,limit); - if (useval) { - str_cat(str,")"); - } - str_free(tmpstr); - break; - case OINDEX: - str = str_new(0); - str_set(str,"(1+index("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1)); - str_free(fstr); - str_cat(str,", "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1)); - str_free(fstr); - str_cat(str,"))"); - numeric = 1; - break; - case OMATCH: - str = str_new(0); - prec = P_ANDAND; - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1)); - str_free(fstr); - str_cat(str," =~ "); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1)); - str_free(fstr); - str_cat(str," ? scalar($RLENGTH = length($&), $RSTART = length($`)+1) : 0"); - numeric = 1; - break; - case OUSERDEF: - str = str_new(0); - subretnum = FALSE; - fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN); - curargs = str_new(0); - str_sset(curargs,fstr); - str_cat(curargs,","); - tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN); - str_free(curargs); - curargs = NULL; - level--; - subretnum |= numarg; - s = NULL; - t = tmp2str->str_ptr; - while ((t = instr(t,"return "))) - s = t++; - if (s) { - i = 0; - for (t = s+7; *t; t++) { - if (*t == ';' || *t == '}') - i++; - } - if (i == 1) { - strcpy(s,s+7); - tmp2str->str_cur -= 7; - } - } - str_set(str,"\n"); - tab(str,level); - str_cat(str,"sub "); - str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_cat(str," {\n"); - tab(str,++level); - if (fstr->str_cur) { - str_cat(str,"local("); - str_scat(str,fstr); - str_cat(str,") = @_;"); - } - str_free(fstr); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN)); - str_free(fstr); - fixtab(str,level); - str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN)); - str_free(fstr); - fixtab(str,level); - str_scat(str,tmp2str); - str_free(tmp2str); - fixtab(str,--level); - str_cat(str,"}\n"); - tab(str,level); - str_scat(subs,str); - str_set(str,""); - str_cat(tmpstr,"("); - tmp2str = str_new(0); - if (subretnum) - str_set(tmp2str,"1"); - hstore(symtab,tmpstr->str_ptr,tmp2str); - str_free(tmpstr); - level++; - break; - case ORETURN: - str = str_new(0); - if (len > 0) { - str_cat(str,"return "); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1)); - str_free(fstr); - if (numarg) - subretnum = TRUE; - } - else - str_cat(str,"return"); - break; - case OUSERFUN: - str = str_new(0); - str_set(str,"&"); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,"("); - tmpstr = hfetch(symtab,str->str_ptr+3); - if (tmpstr && tmpstr->str_ptr) - numeric |= atoi(tmpstr->str_ptr); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,")"); - break; - case OGSUB: - case OSUB: { - int gsub = type == OGSUB ? 1 : 0; - str = str_new(0); - tmpstr = str_new(0); - i = 0; - if (len == 3) { - tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1); - if (strNE(tmpstr->str_ptr,"$_")) { - str_cat(tmpstr, " =~ s"); - i++; - } - else - str_set(tmpstr, "s"); - } - else - str_set(tmpstr, "s"); - type = ops[ops[node+2].ival].ival; - len = type >> 8; - type &= 255; - tmp3str = str_new(0); - { - const char *s; - if (type == OSTR) { - tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN); - for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) { - if (*t == '&') - *d++ = '$' + (char)128; - else if (*t == '$' || *t == '/') - *d++ = '\\' + (char)128; - *d = *t + 128; - } - *d = '\0'; - str_set(tmp2str,tokenbuf); - s = (gsub ? "/g" : "/"); - } - else { - tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN); - str_set(tmp3str,"($s_ = '\"'.("); - str_scat(tmp3str,tmp2str); - str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, "); - str_set(tmp2str,"eval $s_"); - s = (gsub ? "/ge" : "/e"); - i++; - } - str_cat(tmp2str,s); - } - type = ops[ops[node+1].ival].ival; - len = type >> 8; - type &= 255; - fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN); - if (type == OREGEX) { - if (useval && i) - str_cat(str,"("); - str_scat(str,tmp3str); - str_scat(str,tmpstr); - str_scat(str,fstr); - str_scat(str,tmp2str); - } - else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) { - if (useval && i) - str_cat(str,"("); - str_scat(str,tmp3str); - str_scat(str,tmpstr); - str_cat(str,"/"); - str_scat(str,fstr); - str_cat(str,"/"); - str_scat(str,tmp2str); - } - else { - i++; - if (useval) - str_cat(str,"("); - str_cat(str,"$s = "); - str_scat(str,fstr); - str_cat(str,", "); - str_scat(str,tmp3str); - str_scat(str,tmpstr); - str_cat(str,"/$s/"); - str_scat(str,tmp2str); - } - if (useval && i) - str_cat(str,")"); - str_free(fstr); - str_free(tmpstr); - str_free(tmp2str); - str_free(tmp3str); - numeric = 1; - break; } - case ONUM: - str = walk(1,level,ops[node+1].ival,&numarg,P_MIN); - numeric = 1; - break; - case OSTR: - tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN); - { - const char *s = "'"; - for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) { - if (*t == '\'') - s = "\""; - else if (*t == '\\') { - s = "\""; - *d++ = *t++ + 128; - switch (*t) { - case '\\': case '"': case 'n': case 't': case '$': - break; - default: /* hide this from perl */ - *d++ = '\\' + (char)128; - } - } - *d = *t + 128; - } - *d = '\0'; - str = str_new(0); - str_set(str,s); - str_cat(str,tokenbuf); - str_free(tmpstr); - str_cat(str,s); - } - break; - case ODEFINED: - prec = P_UNI; - str = str_new(0); - str_set(str,"defined $"); - goto addvar; - case ODELETE: - str = str_new(0); - str_set(str,"delete $"); - goto addvar; - case OSTAR: - str = str_new(0); - str_set(str,"*"); - goto addvar; - case OVAR: - str = str_new(0); - str_set(str,"$"); - addvar: - str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - if (len == 1) { - tmp2str = hfetch(symtab,tmpstr->str_ptr); - if (tmp2str && atoi(tmp2str->str_ptr)) - numeric = 2; - if (strEQ(str->str_ptr,"$FNR")) { - numeric = 1; - saw_FNR++; - str_set(str,"($.-$FNRbase)"); - } - else if (strEQ(str->str_ptr,"$NR")) { - numeric = 1; - str_set(str,"$."); - } - else if (strEQ(str->str_ptr,"$NF")) { - numeric = 1; - str_set(str,"($#Fld+1)"); - } - else if (strEQ(str->str_ptr,"$0")) - str_set(str,"$_"); - else if (strEQ(str->str_ptr,"$ARGC")) - str_set(str,"($#ARGV+2)"); - } - else { -#ifdef NOTDEF - if (curargs) { - sprintf(tokenbuf,"$%s,",tmpstr->str_ptr); - ??? if (instr(curargs->str_ptr,tokenbuf)) - str_cat(str,"\377"); /* can't translate yet */ - } -#endif - str_cat(tmpstr,"[]"); - tmp2str = hfetch(symtab,tmpstr->str_ptr); - if (tmp2str && atoi(tmp2str->str_ptr)) - str_cat(str,"[("); - else - str_cat(str,"{"); - str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - if (strEQ(str->str_ptr,"$ARGV[0")) { - str_set(str,"$ARGV0"); - saw_argv0++; - } - else { - if (tmp2str && atoi(tmp2str->str_ptr)) - strcpy(tokenbuf,")-1]"); - else - strcpy(tokenbuf,"}"); - *tokenbuf += (char)128; - str_cat(str,tokenbuf); - } - } - str_free(tmpstr); - break; - case OFLD: - str = str_new(0); - if (split_to_array) { - str_set(str,"$Fld"); - str_cat(str,"[("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,")-1]"); - } - else { - i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr); - if (i <= arymax) - sprintf(tokenbuf,"$%s",nameary[i]); - else - sprintf(tokenbuf,"$Fld%d",i); - str_set(str,tokenbuf); - } - break; - case OVFLD: - str = str_new(0); - str_set(str,"$Fld["); - i = ops[node+1].ival; - if ((ops[i].ival & 255) == OPAREN) - i = ops[i+1].ival; - tmpstr=walk(1,level,i,&numarg,P_MIN); - str_scat(str,tmpstr); - str_free(tmpstr); - str_cat(str,"]"); - break; - case OJUNK: - goto def; - case OSNEWLINE: - str = str_new(2); - str_set(str,";\n"); - tab(str,level); - break; - case ONEWLINE: - str = str_new(1); - str_set(str,"\n"); - tab(str,level); - break; - case OSCOMMENT: - str = str_new(0); - str_set(str,";"); - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - for (s = tmpstr->str_ptr; *s && *s != '\n'; s++) - *s += (char)128; - str_scat(str,tmpstr); - str_free(tmpstr); - tab(str,level); - break; - case OCOMMENT: - str = str_new(0); - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - for (s = tmpstr->str_ptr; *s && *s != '\n'; s++) - *s += (char)128; - str_scat(str,tmpstr); - str_free(tmpstr); - tab(str,level); - break; - case OCOMMA: - prec = P_COMMA; - 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,P_MIN)); - str_free(fstr); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1)); - str_free(fstr); - break; - case OSEMICOLON: - str = str_new(1); - str_set(str,";\n"); - tab(str,level); - break; - case OSTATES: - str = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - break; - case OSTATE: - str = str_new(0); - if (len >= 1) { - str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - if (len >= 2) { - tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN); - if (*tmpstr->str_ptr == ';') { - addsemi(str); - str_cat(str,tmpstr->str_ptr+1); - } - str_free(tmpstr); - } - } - break; - case OCLOSE: - str = str_make("close("); - tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN); - if (!do_fancy_opens) { - t = tmpstr->str_ptr; - if (*t == '"' || *t == '\'') - cpytill(tokenbuf,t+1,*t); - else - fatal("Internal error: OCLOSE %s",t); - s = savestr(tokenbuf); - for (t = tokenbuf; *t; t++) { - *t &= 127; - if (isLOWER(*t)) - *t = toUPPER(*t); - if (!isALPHANUMERIC(*t)) - *t = '_'; - } - if (!strchr(tokenbuf,'_')) - strcpy(t,"_FH"); - str_free(tmpstr); - safefree(s); - str_set(str,"close "); - str_cat(str,tokenbuf); - } - else { - sprintf(tokenbuf,"delete $opened{%s} && close(%s)", - tmpstr->str_ptr, tmpstr->str_ptr); - str_free(tmpstr); - str_set(str,tokenbuf); - } - break; - case OPRINTF: - case OPRINT: - lparen = ""; /* set to parens if necessary */ - rparen = ""; - str = str_new(0); - if (len == 3) { /* output redirection */ - tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN); - tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN); - if (!do_fancy_opens) { - t = tmpstr->str_ptr; - if (*t == '"' || *t == '\'') - t = cpytill(tokenbuf,t+1,*t); - else - fatal("Internal error: OPRINT"); - d = savestr(t); - s = savestr(tokenbuf); - for (t = tokenbuf; *t; t++) { - *t &= 127; - if (isLOWER(*t)) - *t = toUPPER(*t); - if (!isALPHANUMERIC(*t)) - *t = '_'; - } - if (!strchr(tokenbuf,'_')) - strcpy(t,"_FH"); - tmp3str = hfetch(symtab,tokenbuf); - if (!tmp3str) { - str_cat(opens,"open("); - str_cat(opens,tokenbuf); - str_cat(opens,", "); - d[1] = '\0'; - str_cat(opens,d); - str_scat(opens,tmp2str); - str_cat(opens,tmpstr->str_ptr+1); - if (*tmp2str->str_ptr == '|') - str_cat(opens,") || die 'Cannot pipe to \""); - else - str_cat(opens,") || die 'Cannot create file \""); - if (*d == '"') - str_cat(opens,"'.\""); - str_cat(opens,s); - if (*d == '"') - str_cat(opens,"\".'"); - str_cat(opens,"\".';\n"); - hstore(symtab,tokenbuf,str_make("x")); - } - str_free(tmpstr); - str_free(tmp2str); - safefree(s); - safefree(d); - } - else { - sprintf(tokenbuf,"&Pick('%s', %s) &&\n", - tmp2str->str_ptr, tmpstr->str_ptr); - str_cat(str,tokenbuf); - tab(str,level+1); - strcpy(tokenbuf,"$fh"); - str_free(tmpstr); - str_free(tmp2str); - lparen = "("; - rparen = ")"; - } - } - else - strcpy(tokenbuf,""); - str_cat(str,lparen); /* may be null */ - if (type == OPRINTF) - str_cat(str,"printf"); - else - str_cat(str,"print"); - saw_fh = 0; - if (len == 3 || do_fancy_opens) { - 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); - if (!*tmpstr->str_ptr && lval_field) { - const char *t = (saw_OFS ? "$," : "' '"); - if (split_to_array) { - sprintf(tokenbuf,"join(%s,@Fld)",t); - str_cat(tmpstr,tokenbuf); - } - else { - for (i = 1; i < maxfld; i++) { - if (i <= arymax) - sprintf(tokenbuf,"$%s, ",nameary[i]); - else - sprintf(tokenbuf,"$Fld%d, ",i); - str_cat(tmpstr,tokenbuf); - } - if (maxfld <= arymax) - sprintf(tokenbuf,"$%s",nameary[maxfld]); - else - sprintf(tokenbuf,"$Fld%d",maxfld); - str_cat(tmpstr,tokenbuf); - } - } - if (*tmpstr->str_ptr) { - str_cat(str," "); - 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," $_"); - } - str_cat(str,rparen); /* may be null */ - str_free(tmpstr); - break; - case ORAND: - str = str_make("rand(1)"); - break; - case OSRAND: - str = str_make("srand("); - goto maybe0; - case OATAN2: - str = str_make("atan2("); - goto maybe0; - case OSIN: - str = str_make("sin("); - goto maybe0; - case OCOS: - str = str_make("cos("); - goto maybe0; - case OSYSTEM: - str = str_make("system("); - goto maybe0; - case OLENGTH: - str = str_make("length("); - goto maybe0; - case OLOG: - str = str_make("log("); - goto maybe0; - case OEXP: - str = str_make("exp("); - goto maybe0; - case OSQRT: - str = str_make("sqrt("); - goto maybe0; - case OINT: - str = str_make("int("); - maybe0: - numeric = 1; - if (len > 0) - tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN); - else - tmpstr = str_new(0); - if (!tmpstr->str_ptr || !*tmpstr->str_ptr) { - if (lval_field) { - const char *t = (saw_OFS ? "$," : "' '"); - if (split_to_array) { - sprintf(tokenbuf,"join(%s,@Fld)",t); - str_cat(tmpstr,tokenbuf); - } - else { - sprintf(tokenbuf,"join(%s, ",t); - str_cat(tmpstr,tokenbuf); - for (i = 1; i < maxfld; i++) { - if (i <= arymax) - sprintf(tokenbuf,"$%s,",nameary[i]); - else - sprintf(tokenbuf,"$Fld%d,",i); - str_cat(tmpstr,tokenbuf); - } - if (maxfld <= arymax) - sprintf(tokenbuf,"$%s)",nameary[maxfld]); - else - sprintf(tokenbuf,"$Fld%d)",maxfld); - str_cat(tmpstr,tokenbuf); - } - } - else - str_cat(tmpstr,"$_"); - } - if (strEQ(tmpstr->str_ptr,"$_")) { - if (type == OLENGTH && !do_chop) { - str = str_make("(length("); - str_cat(tmpstr,") - 1"); - } - } - str_scat(str,tmpstr); - str_free(tmpstr); - str_cat(str,")"); - break; - case OBREAK: - str = str_new(0); - str_set(str,"last"); - break; - case ONEXT: - str = str_new(0); - str_set(str,"next line"); - break; - case OEXIT: - str = str_new(0); - if (realexit) { - prec = P_UNI; - str_set(str,"exit"); - if (len == 1) { - str_cat(str," "); - exitval = TRUE; - str_scat(str, - fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1)); - str_free(fstr); - } - } - else { - if (len == 1) { - str_set(str,"$ExitValue = "); - exitval = TRUE; - str_scat(str, - fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN)); - str_free(fstr); - str_cat(str,"; "); - } - str_cat(str,"last line"); - } - break; - case OCONTINUE: - str = str_new(0); - str_set(str,"next"); - break; - case OREDIR: - goto def; - case OIF: - str = str_new(0); - str_set(str,"if ("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,") "); - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - if (len == 3) { - i = ops[node+3].ival; - if (i) { - if ((ops[i].ival & 255) == OBLOCK) { - i = ops[i+1].ival; - if (i) { - if ((ops[i].ival & 255) != OIF) - i = 0; - } - } - else - i = 0; - } - if (i) { - str_cat(str,"els"); - str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN)); - str_free(fstr); - } - else { - str_cat(str,"else "); - str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN)); - str_free(fstr); - } - } - break; - case OWHILE: - str = str_new(0); - str_set(str,"while ("); - str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,") "); - 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 ("); - str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN)); - i = numarg; - if (i) { - t = s = tmpstr->str_ptr; - while (isWORDCHAR(*t) || *t == '$') - t++; - i = t - s; - if (i < 2) - i = 0; - } - str_cat(str,"; "); - fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN); - if (i && (t = strchr(fstr->str_ptr,0377))) { - if (strnEQ(fstr->str_ptr,s,i)) - *t = ' '; - } - str_scat(str,fstr); - str_free(fstr); - str_free(tmpstr); - str_cat(str,"; "); - str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN)); - str_free(fstr); - str_cat(str,") "); - str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN)); - str_free(fstr); - break; - case OFORIN: - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - d = strchr(tmpstr->str_ptr,'$'); - if (!d) - fatal("Illegal for loop: %s",tmpstr->str_ptr); - s = strchr(d,'{'); - if (!s) - s = strchr(d,'['); - if (!s) - fatal("Illegal for loop: %s",d); - *s++ = '\0'; - 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); - str_cat(str,"[]"); - tmp2str = hfetch(symtab,str->str_ptr); - if (tmp2str && atoi(tmp2str->str_ptr)) { - sprintf(tokenbuf, - "foreach %s (0 .. $#%s) ", - s, - d+1); - } - else { - sprintf(tokenbuf, - "foreach %s (keys %%%s) ", - s, - d+1); - } - str_set(str,tokenbuf); - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - str_free(tmpstr); - break; - case OBLOCK: - str = str_new(0); - str_set(str,"{"); - if (len >= 2 && ops[node+2].ival) { - str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN)); - str_free(fstr); - } - fixtab(str,++level); - str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN)); - str_free(fstr); - addsemi(str); - fixtab(str,--level); - str_cat(str,"}\n"); - tab(str,level); - if (len >= 3) { - str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN)); - str_free(fstr); - } - break; - default: - def: - if (len) { - if (len > 5) - fatal("Garbage length in walk"); - str = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - for (i = 2; i<= len; i++) { - str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN)); - str_free(fstr); - } - } - else { - str = NULL; - } - break; - } - if (!str) - str = str_new(0); - - if (useval && prec < minprec) { /* need parens? */ - fstr = str_new(str->str_cur+2); - str_nset(fstr,"(",1); - str_scat(fstr,str); - str_ncat(fstr,")",1); - str_free(str); - str = fstr; - } - - *numericptr = numeric; -#ifdef DEBUGGING - if (debug & 4) { - printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur); - for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++) - if (*t == '\n') - printf("\\n"); - else if (*t == '\t') - printf("\\t"); - else - putchar(*t); - putchar('\n'); - } -#endif - return str; -} - -static void -tab(STR *str, int lvl) -{ - while (lvl > 1) { - str_cat(str,"\t"); - lvl -= 2; - } - if (lvl) - str_cat(str," "); -} - -static void -fixtab(STR *str, int lvl) -{ - char *s; - - /* strip trailing white space */ - - s = str->str_ptr+str->str_cur - 1; - while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n')) - s--; - s[1] = '\0'; - str->str_cur = s + 1 - str->str_ptr; - if (s >= str->str_ptr && *s != '\n') - str_cat(str,"\n"); - - tab(str,lvl); -} - -static void -addsemi(STR *str) -{ - char *s; - - s = str->str_ptr+str->str_cur - 1; - while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n')) - s--; - if (s >= str->str_ptr && *s != ';' && *s != '}') - str_cat(str,";"); -} - -static void -emit_split(STR *str, int level) -{ - int i; - - if (split_to_array) - str_cat(str,"@Fld"); - else { - str_cat(str,"("); - for (i = 1; i < maxfld; i++) { - if (i <= arymax) - sprintf(tokenbuf,"$%s,",nameary[i]); - else - sprintf(tokenbuf,"$Fld%d,",i); - str_cat(str,tokenbuf); - } - if (maxfld <= arymax) - sprintf(tokenbuf,"$%s)",nameary[maxfld]); - else - sprintf(tokenbuf,"$Fld%d)",maxfld); - str_cat(str,tokenbuf); - } - if (const_FS) { - sprintf(tokenbuf," = split(/[%c\\n]/, $_, -1);\n",const_FS); - str_cat(str,tokenbuf); - } - else if (saw_FS) - str_cat(str," = split($FS, $_, -1);\n"); - else - str_cat(str," = split(' ', $_, -1);\n"); - tab(str,level); -} - -int -prewalk(int numit, int level, int node, int *numericptr) -{ - int len; - int type; - int i; - int numarg; - int numeric = FALSE; - STR *tmpstr; - STR *tmp2str; - - if (!node) { - *numericptr = 0; - return 0; - } - type = ops[node].ival; - len = type >> 8; - type &= 255; - switch (type) { - case OPROG: - prewalk(0,level,ops[node+1].ival,&numarg); - if (ops[node+2].ival) { - prewalk(0,level,ops[node+2].ival,&numarg); - } - ++level; - prewalk(0,level,ops[node+3].ival,&numarg); - --level; - if (ops[node+3].ival) { - prewalk(0,level,ops[node+4].ival,&numarg); - } - break; - case OHUNKS: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - if (len == 3) { - prewalk(0,level,ops[node+3].ival,&numarg); - } - break; - case ORANGE: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - break; - case OPAT: - goto def; - case OREGEX: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OHUNK: - if (len == 1) { - prewalk(0,level,ops[node+1].ival,&numarg); - } - else { - i = prewalk(0,level,ops[node+1].ival,&numarg); - if (i) { - ++level; - prewalk(0,level,ops[node+2].ival,&numarg); - --level; - } - else { - prewalk(0,level,ops[node+2].ival,&numarg); - } - } - break; - case OPPAREN: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OPANDAND: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OPOROR: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OPNOT: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OCPAREN: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric |= numarg; - break; - case OCANDAND: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric = 1; - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OCOROR: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric = 1; - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OCNOT: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case ORELOP: - prewalk(0,level,ops[node+2].ival,&numarg); - numeric |= numarg; - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+3].ival,&numarg); - numeric |= numarg; - numeric = 1; - break; - case ORPAREN: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric |= numarg; - break; - case OMATCHOP: - prewalk(0,level,ops[node+2].ival,&numarg); - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+3].ival,&numarg); - numeric = 1; - break; - case OMPAREN: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric |= numarg; - break; - case OCONCAT: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OASSIGN: - 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) > (Size_t)1) { - numericize(ops[node+2].ival); - if (!numarg) - numericize(ops[node+3].ival); - } - numeric |= numarg; - break; - case OADD: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OSUBTRACT: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OMULT: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case ODIV: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OPOW: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OMOD: - prewalk(1,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OPOSTINCR: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OPOSTDECR: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OPREINCR: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OPREDECR: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OUMINUS: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OUPLUS: - prewalk(1,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OPAREN: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric |= numarg; - break; - case OGETLINE: - break; - case OSPRINTF: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OSUBSTR: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(1,level,ops[node+2].ival,&numarg); - if (len == 3) { - prewalk(1,level,ops[node+3].ival,&numarg); - } - break; - case OSTRING: - break; - case OSPLIT: - numeric = 1; - prewalk(0,level,ops[node+2].ival,&numarg); - if (len == 3) - prewalk(0,level,ops[node+3].ival,&numarg); - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OINDEX: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OMATCH: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - numeric = 1; - break; - case OUSERDEF: - subretnum = FALSE; - --level; - tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN); - ++level; - prewalk(0,level,ops[node+2].ival,&numarg); - prewalk(0,level,ops[node+4].ival,&numarg); - prewalk(0,level,ops[node+5].ival,&numarg); - --level; - str_cat(tmpstr,"("); - tmp2str = str_new(0); - if (subretnum || numarg) - str_set(tmp2str,"1"); - hstore(symtab,tmpstr->str_ptr,tmp2str); - str_free(tmpstr); - level++; - break; - case ORETURN: - if (len > 0) { - prewalk(0,level,ops[node+1].ival,&numarg); - if (numarg) - subretnum = TRUE; - } - break; - 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].ival,0); - str_free(tmpstr); - str_cat(tmp2str,"("); - tmpstr = hfetch(symtab,tmp2str->str_ptr); - if (tmpstr && tmpstr->str_ptr) - numeric |= atoi(tmpstr->str_ptr); - prewalk(0,level,ops[node+2].ival,&numarg); - str_free(tmp2str); - break; - case OGSUB: - case OSUB: - if (len >= 3) - prewalk(0,level,ops[node+3].ival,&numarg); - prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg); - prewalk(0,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case ONUM: - prewalk(0,level,ops[node+1].ival,&numarg); - numeric = 1; - break; - case OSTR: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case ODEFINED: - case ODELETE: - case OSTAR: - case OVAR: - prewalk(0,level,ops[node+1].ival,&numarg); - if (len == 1) { - if (numit) - numericize(node); - } - else { - prewalk(0,level,ops[node+2].ival,&numarg); - } - break; - case OFLD: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OVFLD: - i = ops[node+1].ival; - prewalk(0,level,i,&numarg); - break; - case OJUNK: - goto def; - case OSNEWLINE: - break; - case ONEWLINE: - break; - case OSCOMMENT: - break; - case OCOMMENT: - break; - case OCOMMA: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - prewalk(0,level,ops[node+3].ival,&numarg); - break; - case OSEMICOLON: - break; - case OSTATES: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OSTATE: - if (len >= 1) { - prewalk(0,level,ops[node+1].ival,&numarg); - if (len >= 2) { - prewalk(0,level,ops[node+2].ival,&numarg); - } - } - break; - case OCLOSE: - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OPRINTF: - case OPRINT: - if (len == 3) { /* output redirection */ - prewalk(0,level,ops[node+3].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - } - prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg); - break; - case ORAND: - break; - case OSRAND: - goto maybe0; - case OATAN2: - goto maybe0; - case OSIN: - goto maybe0; - case OCOS: - goto maybe0; - case OSYSTEM: - goto maybe0; - case OLENGTH: - goto maybe0; - case OLOG: - goto maybe0; - case OEXP: - goto maybe0; - case OSQRT: - goto maybe0; - case OINT: - maybe0: - numeric = 1; - if (len > 0) - prewalk(type != OLENGTH && type != OSYSTEM, - level,ops[node+1].ival,&numarg); - break; - case OBREAK: - break; - case ONEXT: - break; - case OEXIT: - if (len == 1) { - prewalk(1,level,ops[node+1].ival,&numarg); - } - break; - case OCONTINUE: - break; - case OREDIR: - goto def; - case OIF: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - if (len == 3) { - prewalk(0,level,ops[node+3].ival,&numarg); - } - break; - case OWHILE: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - break; - case OFOR: - prewalk(0,level,ops[node+1].ival,&numarg); - prewalk(0,level,ops[node+2].ival,&numarg); - prewalk(0,level,ops[node+3].ival,&numarg); - prewalk(0,level,ops[node+4].ival,&numarg); - break; - case OFORIN: - prewalk(0,level,ops[node+2].ival,&numarg); - prewalk(0,level,ops[node+1].ival,&numarg); - break; - case OBLOCK: - if (len == 2) { - prewalk(0,level,ops[node+2].ival,&numarg); - } - ++level; - prewalk(0,level,ops[node+1].ival,&numarg); - --level; - break; - default: - def: - if (len) { - if (len > 5) - fatal("Garbage length in prewalk"); - prewalk(0,level,ops[node+1].ival,&numarg); - for (i = 2; i<= len; i++) { - prewalk(0,level,ops[node+i].ival,&numarg); - } - } - break; - } - *numericptr = numeric; - return 1; -} - -static void -numericize(int node) -{ - int len; - int type; - STR *tmpstr; - STR *tmp2str; - int numarg; - - type = ops[node].ival; - len = type >> 8; - type &= 255; - if (type == OVAR && len == 1) { - tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN); - tmp2str = str_make("1"); - hstore(symtab,tmpstr->str_ptr,tmp2str); - } -} |