1N/A/* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
1N/A *
1N/A * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999,
1N/A * 2000, 2001, 2002, by Larry Wall and others
1N/A *
1N/A * You may distribute under the terms of either the GNU General Public
1N/A * License or the Artistic License, as specified in the README file.
1N/A *
1N/A * $Log: walk.c,v $
1N/A */
1N/A
1N/A#include "EXTERN.h"
1N/A#include "a2p.h"
1N/A#include "util.h"
1N/A
1N/Abool exitval = FALSE;
1N/Abool realexit = FALSE;
1N/Abool saw_getline = FALSE;
1N/Abool subretnum = FALSE;
1N/Abool saw_FNR = FALSE;
1N/Abool saw_argv0 = FALSE;
1N/Abool saw_fh = FALSE;
1N/Aint maxtmp = 0;
1N/Achar *lparen;
1N/Achar *rparen;
1N/Achar *limit;
1N/ASTR *subs;
1N/ASTR *curargs = Nullstr;
1N/A
1N/Astatic void addsemi ( STR *str );
1N/Astatic void emit_split ( STR *str, int level );
1N/Astatic void fixtab ( STR *str, int lvl );
1N/Astatic void numericize ( int node );
1N/Astatic void tab ( STR *str, int lvl );
1N/A
1N/Aint prewalk ( int numit, int level, int node, int *numericptr );
1N/ASTR * walk ( int useval, int level, int node, int *numericptr, int minprec );
1N/A#ifdef NETWARE
1N/Achar *savestr(char *str);
1N/Achar *cpytill(register char *to, register char *from, register int delim);
1N/Achar *instr(char *big, char *little);
1N/A#endif
1N/A
1N/ASTR *
1N/Awalk(int useval, int level, register int node, int *numericptr, int minprec)
1N/A
1N/A
1N/A
1N/A
1N/A /* minimum precedence without parens */
1N/A{
1N/A register int len;
1N/A register STR *str;
1N/A register int type;
1N/A register int i;
1N/A register STR *tmpstr;
1N/A STR *tmp2str;
1N/A STR *tmp3str;
1N/A char *t;
1N/A char *d, *s;
1N/A int numarg;
1N/A int numeric = FALSE;
1N/A STR *fstr;
1N/A int prec = P_MAX; /* assume no parens needed */
1N/A
1N/A if (!node) {
1N/A *numericptr = 0;
1N/A return str_make("");
1N/A }
1N/A type = ops[node].ival;
1N/A len = type >> 8;
1N/A type &= 255;
1N/A switch (type) {
1N/A case OPROG:
1N/A arymax = 0;
1N/A if (namelist) {
1N/A while (isALPHA(*namelist)) {
1N/A for (d = tokenbuf,s=namelist;
1N/A isALPHA(*s) || isDIGIT(*s) || *s == '_';
1N/A *d++ = *s++) ;
1N/A *d = '\0';
1N/A while (*s && !isALPHA(*s)) s++;
1N/A namelist = s;
1N/A nameary[++arymax] = savestr(tokenbuf);
1N/A }
1N/A }
1N/A if (maxfld < arymax)
1N/A maxfld = arymax;
1N/A opens = str_new(0);
1N/A subs = str_new(0);
1N/A str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (do_split && need_entire && !absmaxfld)
1N/A split_to_array = TRUE;
1N/A if (do_split && split_to_array)
1N/A set_array_base = TRUE;
1N/A if (set_array_base) {
1N/A str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
1N/A }
1N/A if (fswitch && !const_FS)
1N/A const_FS = fswitch;
1N/A if (saw_FS > 1 || saw_RS)
1N/A const_FS = 0;
1N/A if (saw_ORS && need_entire)
1N/A do_chop = TRUE;
1N/A if (fswitch) {
1N/A str_cat(str,"$FS = '");
1N/A if (strchr("*+?.[]()|^$\\",fswitch))
1N/A str_cat(str,"\\");
1N/A sprintf(tokenbuf,"%c",fswitch);
1N/A str_cat(str,tokenbuf);
1N/A str_cat(str,"';\t\t# field separator from -F switch\n");
1N/A }
1N/A else if (saw_FS && !const_FS) {
1N/A str_cat(str,"$FS = ' ';\t\t# set field separator\n");
1N/A }
1N/A if (saw_OFS) {
1N/A str_cat(str,"$, = ' ';\t\t# set output field separator\n");
1N/A }
1N/A if (saw_ORS) {
1N/A str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
1N/A }
1N/A if (saw_argv0) {
1N/A str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
1N/A }
1N/A if (str->str_cur > 20)
1N/A str_cat(str,"\n");
1N/A if (ops[node+2].ival) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,"\n\n");
1N/A }
1N/A fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
1N/A if (*fstr->str_ptr) {
1N/A if (saw_line_op)
1N/A str_cat(str,"line: ");
1N/A str_cat(str,"while (<>) {\n");
1N/A tab(str,++level);
1N/A if (saw_FS && !const_FS)
1N/A do_chop = TRUE;
1N/A if (do_chop) {
1N/A str_cat(str,"chomp;\t# strip record separator\n");
1N/A tab(str,level);
1N/A }
1N/A if (do_split)
1N/A emit_split(str,level);
1N/A str_scat(str,fstr);
1N/A str_free(fstr);
1N/A fixtab(str,--level);
1N/A str_cat(str,"}\n");
1N/A if (saw_FNR)
1N/A str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
1N/A }
1N/A else if (old_awk)
1N/A str_cat(str,"while (<>) { } # (no line actions)\n");
1N/A if (ops[node+4].ival) {
1N/A realexit = TRUE;
1N/A str_cat(str,"\n");
1N/A tab(str,level);
1N/A str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,"\n");
1N/A }
1N/A if (exitval)
1N/A str_cat(str,"exit $ExitValue;\n");
1N/A if (subs->str_ptr) {
1N/A str_cat(str,"\n");
1N/A str_scat(str,subs);
1N/A }
1N/A if (saw_getline) {
1N/A for (len = 0; len < 4; len++) {
1N/A if (saw_getline & (1 << len)) {
1N/A sprintf(tokenbuf,"\nsub Getline%d {\n",len);
1N/A str_cat(str, tokenbuf);
1N/A if (len & 2) {
1N/A if (do_fancy_opens)
1N/A str_cat(str," &Pick('',@_);\n");
1N/A else
1N/A str_cat(str," ($fh) = @_;\n");
1N/A }
1N/A else {
1N/A if (saw_FNR)
1N/A str_cat(str," $FNRbase = $. if eof;\n");
1N/A }
1N/A if (len & 1)
1N/A str_cat(str," local($_);\n");
1N/A if (len & 2)
1N/A str_cat(str,
1N/A " if ($getline_ok = (($_ = <$fh>) ne ''))");
1N/A else
1N/A str_cat(str,
1N/A " if ($getline_ok = (($_ = <>) ne ''))");
1N/A str_cat(str, " {\n");
1N/A level += 2;
1N/A tab(str,level);
1N/A i = 0;
1N/A if (do_chop) {
1N/A i++;
1N/A str_cat(str,"chomp;\t# strip record separator\n");
1N/A tab(str,level);
1N/A }
1N/A if (do_split && !(len & 1)) {
1N/A i++;
1N/A emit_split(str,level);
1N/A }
1N/A if (!i)
1N/A str_cat(str,";\n");
1N/A fixtab(str,--level);
1N/A str_cat(str,"}\n $_;\n}\n");
1N/A --level;
1N/A }
1N/A }
1N/A }
1N/A if (do_fancy_opens) {
1N/A str_cat(str,"\n\
1N/Asub Pick {\n\
1N/A local($mode,$name,$pipe) = @_;\n\
1N/A $fh = $name;\n\
1N/A open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
1N/A}\n\
1N/A");
1N/A }
1N/A break;
1N/A case OHUNKS:
1N/A str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A if (len == 3) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A else {
1N/A }
1N/A break;
1N/A case ORANGE:
1N/A prec = P_DOTDOT;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
1N/A str_cat(str," .. ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OPAT:
1N/A goto def;
1N/A case OREGEX:
1N/A str = str_new(0);
1N/A str_set(str,"/");
1N/A tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A /* translate \nnn to [\nnn] */
1N/A for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
1N/A if (*s == '\\' && isDIGIT(s[1]) && isDIGIT(s[2]) && isDIGIT(s[3])){
1N/A *d++ = '[';
1N/A *d++ = *s++;
1N/A *d++ = *s++;
1N/A *d++ = *s++;
1N/A *d++ = *s;
1N/A *d = ']';
1N/A }
1N/A else
1N/A *d = *s;
1N/A }
1N/A *d = '\0';
1N/A for (d=tokenbuf; *d; d++)
1N/A *d += (char)128;
1N/A str_cat(str,tokenbuf);
1N/A str_free(tmpstr);
1N/A str_cat(str,"/");
1N/A break;
1N/A case OHUNK:
1N/A if (len == 1) {
1N/A str = str_new(0);
1N/A str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
1N/A str_cat(str," if ");
1N/A str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,";");
1N/A }
1N/A else {
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (*tmpstr->str_ptr) {
1N/A str = str_new(0);
1N/A str_set(str,"if (");
1N/A str_scat(str,tmpstr);
1N/A str_cat(str,") {\n");
1N/A tab(str,++level);
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A fixtab(str,--level);
1N/A str_cat(str,"}\n");
1N/A tab(str,level);
1N/A }
1N/A else {
1N/A str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1N/A }
1N/A }
1N/A break;
1N/A case OPPAREN:
1N/A str = str_new(0);
1N/A str_set(str,"(");
1N/A str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,")");
1N/A break;
1N/A case OPANDAND:
1N/A prec = P_ANDAND;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," && ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OPOROR:
1N/A prec = P_OROR;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," || ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OPNOT:
1N/A prec = P_UNARY;
1N/A str = str_new(0);
1N/A str_set(str,"!");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
1N/A str_free(fstr);
1N/A break;
1N/A case OCOND:
1N/A prec = P_COND;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," ? ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A str_cat(str," : ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OCPAREN:
1N/A str = str_new(0);
1N/A str_set(str,"(");
1N/A str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A numeric |= numarg;
1N/A str_cat(str,")");
1N/A break;
1N/A case OCANDAND:
1N/A prec = P_ANDAND;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A numeric = 1;
1N/A str_cat(str," && ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OCOROR:
1N/A prec = P_OROR;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A numeric = 1;
1N/A str_cat(str," || ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OCNOT:
1N/A prec = P_UNARY;
1N/A str = str_new(0);
1N/A str_set(str,"!");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case ORELOP:
1N/A prec = P_REL;
1N/A str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
1N/A numeric |= numarg;
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
1N/A numeric |= numarg;
1N/A if (!numeric ||
1N/A (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
1N/A t = tmpstr->str_ptr;
1N/A if (strEQ(t,"=="))
1N/A str_set(tmpstr,"eq");
1N/A else if (strEQ(t,"!="))
1N/A str_set(tmpstr,"ne");
1N/A else if (strEQ(t,"<"))
1N/A str_set(tmpstr,"lt");
1N/A else if (strEQ(t,"<="))
1N/A str_set(tmpstr,"le");
1N/A else if (strEQ(t,">"))
1N/A str_set(tmpstr,"gt");
1N/A else if (strEQ(t,">="))
1N/A str_set(tmpstr,"ge");
1N/A if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
1N/A !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
1N/A numeric |= 2;
1N/A }
1N/A if (numeric & 2) {
1N/A if (numeric & 1) /* numeric is very good guess */
1N/A str_cat(str," ");
1N/A else
1N/A str_cat(str,"\377");
1N/A numeric = 1;
1N/A }
1N/A else
1N/A str_cat(str," ");
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A str_cat(str," ");
1N/A str_scat(str,tmp2str);
1N/A str_free(tmp2str);
1N/A numeric = 1;
1N/A break;
1N/A case ORPAREN:
1N/A str = str_new(0);
1N/A str_set(str,"(");
1N/A str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A numeric |= numarg;
1N/A str_cat(str,")");
1N/A break;
1N/A case OMATCHOP:
1N/A prec = P_MATCH;
1N/A str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
1N/A str_cat(str," ");
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (strEQ(tmpstr->str_ptr,"~"))
1N/A str_cat(str,"=~");
1N/A else {
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A }
1N/A str_cat(str," ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OMPAREN:
1N/A str = str_new(0);
1N/A str_set(str,"(");
1N/A str_scat(str,
1N/A fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A numeric |= numarg;
1N/A str_cat(str,")");
1N/A break;
1N/A case OCONCAT:
1N/A prec = P_ADD;
1N/A type = ops[ops[node+1].ival].ival & 255;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
1N/A str_cat(str," . ");
1N/A type = ops[ops[node+2].ival].ival & 255;
1N/A str_scat(str,
1N/A fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
1N/A str_free(fstr);
1N/A break;
1N/A case OASSIGN:
1N/A prec = P_ASSIGN;
1N/A str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
1N/A str_cat(str," ");
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A str_scat(str,tmpstr);
1N/A if (str_len(tmpstr) > 1)
1N/A numeric = 1;
1N/A str_free(tmpstr);
1N/A str_cat(str," ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
1N/A str_free(fstr);
1N/A numeric |= numarg;
1N/A if (strEQ(str->str_ptr,"$/ = ''"))
1N/A str_set(str, "$/ = \"\\n\\n\"");
1N/A break;
1N/A case OADD:
1N/A prec = P_ADD;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," + ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OSUBTRACT:
1N/A prec = P_ADD;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," - ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OMULT:
1N/A prec = P_MUL;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," * ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case ODIV:
1N/A prec = P_MUL;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," / ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OPOW:
1N/A prec = P_POW;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
1N/A str_cat(str," ** ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OMOD:
1N/A prec = P_MUL;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str," % ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OPOSTINCR:
1N/A prec = P_AUTO;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
1N/A str_cat(str,"++");
1N/A numeric = 1;
1N/A break;
1N/A case OPOSTDECR:
1N/A prec = P_AUTO;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
1N/A str_cat(str,"--");
1N/A numeric = 1;
1N/A break;
1N/A case OPREINCR:
1N/A prec = P_AUTO;
1N/A str = str_new(0);
1N/A str_set(str,"++");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OPREDECR:
1N/A prec = P_AUTO;
1N/A str = str_new(0);
1N/A str_set(str,"--");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OUMINUS:
1N/A prec = P_UNARY;
1N/A str = str_new(0);
1N/A str_set(str,"-");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
1N/A str_free(fstr);
1N/A numeric = 1;
1N/A break;
1N/A case OUPLUS:
1N/A numeric = 1;
1N/A goto def;
1N/A case OPAREN:
1N/A str = str_new(0);
1N/A str_set(str,"(");
1N/A str_scat(str,
1N/A fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,")");
1N/A numeric |= numarg;
1N/A break;
1N/A case OGETLINE:
1N/A str = str_new(0);
1N/A if (useval)
1N/A str_cat(str,"(");
1N/A if (len > 0) {
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A if (!*fstr->str_ptr) {
1N/A str_cat(str,"$_");
1N/A len = 2; /* a legal fiction */
1N/A }
1N/A str_free(fstr);
1N/A }
1N/A else
1N/A str_cat(str,"$_");
1N/A if (len > 1) {
1N/A tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1N/A fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1N/A if (!do_fancy_opens) {
1N/A t = tmpstr->str_ptr;
1N/A if (*t == '"' || *t == '\'')
1N/A t = cpytill(tokenbuf,t+1,*t);
1N/A else
1N/A fatal("Internal error: OGETLINE %s", t);
1N/A d = savestr(t);
1N/A s = savestr(tokenbuf);
1N/A for (t = tokenbuf; *t; t++) {
1N/A *t &= 127;
1N/A if (isLOWER(*t))
1N/A *t = toUPPER(*t);
1N/A if (!isALPHA(*t) && !isDIGIT(*t))
1N/A *t = '_';
1N/A }
1N/A if (!strchr(tokenbuf,'_'))
1N/A strcpy(t,"_FH");
1N/A tmp3str = hfetch(symtab,tokenbuf);
1N/A if (!tmp3str) {
1N/A do_opens = TRUE;
1N/A str_cat(opens,"open(");
1N/A str_cat(opens,tokenbuf);
1N/A str_cat(opens,", ");
1N/A d[1] = '\0';
1N/A str_cat(opens,d);
1N/A str_cat(opens,tmpstr->str_ptr+1);
1N/A opens->str_cur--;
1N/A if (*fstr->str_ptr == '|')
1N/A str_cat(opens,"|");
1N/A str_cat(opens,d);
1N/A if (*fstr->str_ptr == '|')
1N/A str_cat(opens,") || die 'Cannot pipe from \"");
1N/A else
1N/A str_cat(opens,") || die 'Cannot open file \"");
1N/A if (*d == '"')
1N/A str_cat(opens,"'.\"");
1N/A str_cat(opens,s);
1N/A if (*d == '"')
1N/A str_cat(opens,"\".'");
1N/A str_cat(opens,"\".';\n");
1N/A hstore(symtab,tokenbuf,str_make("x"));
1N/A }
1N/A safefree(s);
1N/A safefree(d);
1N/A str_set(tmpstr,"'");
1N/A str_cat(tmpstr,tokenbuf);
1N/A str_cat(tmpstr,"'");
1N/A }
1N/A if (*fstr->str_ptr == '|')
1N/A str_cat(tmpstr,", '|'");
1N/A str_free(fstr);
1N/A }
1N/A else
1N/A tmpstr = str_make("");
1N/A sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
1N/A str_cat(str,tokenbuf);
1N/A str_free(tmpstr);
1N/A if (useval)
1N/A str_cat(str,",$getline_ok)");
1N/A saw_getline |= 1 << len;
1N/A break;
1N/A case OSPRINTF:
1N/A str = str_new(0);
1N/A str_set(str,"sprintf(");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,")");
1N/A break;
1N/A case OSUBSTR:
1N/A str = str_new(0);
1N/A str_set(str,"substr(");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A str_cat(str,", ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A str_cat(str,", ");
1N/A if (len == 3) {
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A }
1N/A else
1N/A str_cat(str,"999999");
1N/A str_cat(str,")");
1N/A break;
1N/A case OSTRING:
1N/A str = str_new(0);
1N/A str_set(str,ops[node+1].cval);
1N/A break;
1N/A case OSPLIT:
1N/A str = str_new(0);
1N/A limit = ", 9999)";
1N/A numeric = 1;
1N/A tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1N/A if (useval)
1N/A str_set(str,"(@");
1N/A else
1N/A str_set(str,"@");
1N/A str_scat(str,tmpstr);
1N/A str_cat(str," = split(");
1N/A if (len == 3) {
1N/A fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
1N/A if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
1N/A i = fstr->str_ptr[1] & 127;
1N/A if (strchr("*+?.[]()|^$\\",i))
1N/A sprintf(tokenbuf,"/\\%c/",i);
1N/A else if (i == ' ')
1N/A sprintf(tokenbuf,"' '");
1N/A else
1N/A sprintf(tokenbuf,"/%c/",i);
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A else
1N/A str_scat(str,fstr);
1N/A str_free(fstr);
1N/A }
1N/A else if (const_FS) {
1N/A sprintf(tokenbuf,"/[%c\\n]/",const_FS);
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A else if (saw_FS)
1N/A str_cat(str,"$FS");
1N/A else {
1N/A str_cat(str,"' '");
1N/A limit = ")";
1N/A }
1N/A str_cat(str,", ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A str_cat(str,limit);
1N/A if (useval) {
1N/A str_cat(str,")");
1N/A }
1N/A str_free(tmpstr);
1N/A break;
1N/A case OINDEX:
1N/A str = str_new(0);
1N/A str_set(str,"index(");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A str_cat(str,", ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
1N/A str_free(fstr);
1N/A str_cat(str,")");
1N/A numeric = 1;
1N/A break;
1N/A case OMATCH:
1N/A str = str_new(0);
1N/A prec = P_ANDAND;
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
1N/A str_free(fstr);
1N/A str_cat(str," =~ ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
1N/A str_free(fstr);
1N/A str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
1N/A numeric = 1;
1N/A break;
1N/A case OUSERDEF:
1N/A str = str_new(0);
1N/A subretnum = FALSE;
1N/A fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
1N/A curargs = str_new(0);
1N/A str_sset(curargs,fstr);
1N/A str_cat(curargs,",");
1N/A tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
1N/A str_free(curargs);
1N/A curargs = Nullstr;
1N/A level--;
1N/A subretnum |= numarg;
1N/A s = Nullch;
1N/A t = tmp2str->str_ptr;
1N/A while ((t = instr(t,"return ")))
1N/A s = t++;
1N/A if (s) {
1N/A i = 0;
1N/A for (t = s+7; *t; t++) {
1N/A if (*t == ';' || *t == '}')
1N/A i++;
1N/A }
1N/A if (i == 1) {
1N/A strcpy(s,s+7);
1N/A tmp2str->str_cur -= 7;
1N/A }
1N/A }
1N/A str_set(str,"\n");
1N/A tab(str,level);
1N/A str_cat(str,"sub ");
1N/A str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_cat(str," {\n");
1N/A tab(str,++level);
1N/A if (fstr->str_cur) {
1N/A str_cat(str,"local(");
1N/A str_scat(str,fstr);
1N/A str_cat(str,") = @_;");
1N/A }
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A fixtab(str,level);
1N/A str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A fixtab(str,level);
1N/A str_scat(str,tmp2str);
1N/A str_free(tmp2str);
1N/A fixtab(str,--level);
1N/A str_cat(str,"}\n");
1N/A tab(str,level);
1N/A str_scat(subs,str);
1N/A str_set(str,"");
1N/A str_cat(tmpstr,"(");
1N/A tmp2str = str_new(0);
1N/A if (subretnum)
1N/A str_set(tmp2str,"1");
1N/A hstore(symtab,tmpstr->str_ptr,tmp2str);
1N/A str_free(tmpstr);
1N/A level++;
1N/A break;
1N/A case ORETURN:
1N/A str = str_new(0);
1N/A if (len > 0) {
1N/A str_cat(str,"return ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
1N/A str_free(fstr);
1N/A if (numarg)
1N/A subretnum = TRUE;
1N/A }
1N/A else
1N/A str_cat(str,"return");
1N/A break;
1N/A case OUSERFUN:
1N/A str = str_new(0);
1N/A str_set(str,"&");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,"(");
1N/A tmpstr = hfetch(symtab,str->str_ptr+3);
1N/A if (tmpstr && tmpstr->str_ptr)
1N/A numeric |= atoi(tmpstr->str_ptr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,")");
1N/A break;
1N/A case OGSUB:
1N/A case OSUB: {
1N/A int gsub = type == OGSUB ? 1 : 0;
1N/A str = str_new(0);
1N/A tmpstr = str_new(0);
1N/A i = 0;
1N/A if (len == 3) {
1N/A tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
1N/A if (strNE(tmpstr->str_ptr,"$_")) {
1N/A str_cat(tmpstr, " =~ s");
1N/A i++;
1N/A }
1N/A else
1N/A str_set(tmpstr, "s");
1N/A }
1N/A else
1N/A str_set(tmpstr, "s");
1N/A type = ops[ops[node+2].ival].ival;
1N/A len = type >> 8;
1N/A type &= 255;
1N/A tmp3str = str_new(0);
1N/A if (type == OSTR) {
1N/A tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
1N/A for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
1N/A if (*t == '&')
1N/A *d++ = '$' + (char)128;
1N/A else if (*t == '$')
1N/A *d++ = '\\' + (char)128;
1N/A *d = *t + 128;
1N/A }
1N/A *d = '\0';
1N/A str_set(tmp2str,tokenbuf);
1N/A s = gsub ? "/g" : "/";
1N/A }
1N/A else {
1N/A tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1N/A str_set(tmp3str,"($s_ = '\"'.(");
1N/A str_scat(tmp3str,tmp2str);
1N/A str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
1N/A str_set(tmp2str,"eval $s_");
1N/A s = gsub ? "/ge" : "/e";
1N/A i++;
1N/A }
1N/A str_cat(tmp2str,s);
1N/A type = ops[ops[node+1].ival].ival;
1N/A len = type >> 8;
1N/A type &= 255;
1N/A fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (type == OREGEX) {
1N/A if (useval && i)
1N/A str_cat(str,"(");
1N/A str_scat(str,tmp3str);
1N/A str_scat(str,tmpstr);
1N/A str_scat(str,fstr);
1N/A str_scat(str,tmp2str);
1N/A }
1N/A else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
1N/A if (useval && i)
1N/A str_cat(str,"(");
1N/A str_scat(str,tmp3str);
1N/A str_scat(str,tmpstr);
1N/A str_cat(str,"/");
1N/A str_scat(str,fstr);
1N/A str_cat(str,"/");
1N/A str_scat(str,tmp2str);
1N/A }
1N/A else {
1N/A i++;
1N/A if (useval)
1N/A str_cat(str,"(");
1N/A str_cat(str,"$s = ");
1N/A str_scat(str,fstr);
1N/A str_cat(str,", ");
1N/A str_scat(str,tmp3str);
1N/A str_scat(str,tmpstr);
1N/A str_cat(str,"/$s/");
1N/A str_scat(str,tmp2str);
1N/A }
1N/A if (useval && i)
1N/A str_cat(str,")");
1N/A str_free(fstr);
1N/A str_free(tmpstr);
1N/A str_free(tmp2str);
1N/A str_free(tmp3str);
1N/A numeric = 1;
1N/A break; }
1N/A case ONUM:
1N/A str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1N/A numeric = 1;
1N/A break;
1N/A case OSTR:
1N/A tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1N/A s = "'";
1N/A for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
1N/A if (*t == '\'')
1N/A s = "\"";
1N/A else if (*t == '\\') {
1N/A s = "\"";
1N/A *d++ = *t++ + 128;
1N/A switch (*t) {
1N/A case '\\': case '"': case 'n': case 't': case '$':
1N/A break;
1N/A default: /* hide this from perl */
1N/A *d++ = '\\' + (char)128;
1N/A }
1N/A }
1N/A *d = *t + 128;
1N/A }
1N/A *d = '\0';
1N/A str = str_new(0);
1N/A str_set(str,s);
1N/A str_cat(str,tokenbuf);
1N/A str_free(tmpstr);
1N/A str_cat(str,s);
1N/A break;
1N/A case ODEFINED:
1N/A prec = P_UNI;
1N/A str = str_new(0);
1N/A str_set(str,"defined $");
1N/A goto addvar;
1N/A case ODELETE:
1N/A str = str_new(0);
1N/A str_set(str,"delete $");
1N/A goto addvar;
1N/A case OSTAR:
1N/A str = str_new(0);
1N/A str_set(str,"*");
1N/A goto addvar;
1N/A case OVAR:
1N/A str = str_new(0);
1N/A str_set(str,"$");
1N/A addvar:
1N/A str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A if (len == 1) {
1N/A tmp2str = hfetch(symtab,tmpstr->str_ptr);
1N/A if (tmp2str && atoi(tmp2str->str_ptr))
1N/A numeric = 2;
1N/A if (strEQ(str->str_ptr,"$FNR")) {
1N/A numeric = 1;
1N/A saw_FNR++;
1N/A str_set(str,"($.-$FNRbase)");
1N/A }
1N/A else if (strEQ(str->str_ptr,"$NR")) {
1N/A numeric = 1;
1N/A str_set(str,"$.");
1N/A }
1N/A else if (strEQ(str->str_ptr,"$NF")) {
1N/A numeric = 1;
1N/A str_set(str,"$#Fld");
1N/A }
1N/A else if (strEQ(str->str_ptr,"$0"))
1N/A str_set(str,"$_");
1N/A else if (strEQ(str->str_ptr,"$ARGC"))
1N/A str_set(str,"($#ARGV+1)");
1N/A }
1N/A else {
1N/A#ifdef NOTDEF
1N/A if (curargs) {
1N/A sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
1N/A ??? if (instr(curargs->str_ptr,tokenbuf))
1N/A str_cat(str,"\377"); /* can't translate yet */
1N/A }
1N/A#endif
1N/A str_cat(tmpstr,"[]");
1N/A tmp2str = hfetch(symtab,tmpstr->str_ptr);
1N/A if (tmp2str && atoi(tmp2str->str_ptr))
1N/A str_cat(str,"[");
1N/A else
1N/A str_cat(str,"{");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A if (strEQ(str->str_ptr,"$ARGV[0")) {
1N/A str_set(str,"$ARGV0");
1N/A saw_argv0++;
1N/A }
1N/A else {
1N/A if (tmp2str && atoi(tmp2str->str_ptr))
1N/A strcpy(tokenbuf,"]");
1N/A else
1N/A strcpy(tokenbuf,"}");
1N/A *tokenbuf += (char)128;
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A }
1N/A str_free(tmpstr);
1N/A break;
1N/A case OFLD:
1N/A str = str_new(0);
1N/A if (split_to_array) {
1N/A str_set(str,"$Fld");
1N/A str_cat(str,"[");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,"]");
1N/A }
1N/A else {
1N/A i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1N/A if (i <= arymax)
1N/A sprintf(tokenbuf,"$%s",nameary[i]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d",i);
1N/A str_set(str,tokenbuf);
1N/A }
1N/A break;
1N/A case OVFLD:
1N/A str = str_new(0);
1N/A str_set(str,"$Fld[");
1N/A i = ops[node+1].ival;
1N/A if ((ops[i].ival & 255) == OPAREN)
1N/A i = ops[i+1].ival;
1N/A tmpstr=walk(1,level,i,&numarg,P_MIN);
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A str_cat(str,"]");
1N/A break;
1N/A case OJUNK:
1N/A goto def;
1N/A case OSNEWLINE:
1N/A str = str_new(2);
1N/A str_set(str,";\n");
1N/A tab(str,level);
1N/A break;
1N/A case ONEWLINE:
1N/A str = str_new(1);
1N/A str_set(str,"\n");
1N/A tab(str,level);
1N/A break;
1N/A case OSCOMMENT:
1N/A str = str_new(0);
1N/A str_set(str,";");
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1N/A *s += (char)128;
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A tab(str,level);
1N/A break;
1N/A case OCOMMENT:
1N/A str = str_new(0);
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1N/A *s += (char)128;
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A tab(str,level);
1N/A break;
1N/A case OCOMMA:
1N/A prec = P_COMMA;
1N/A str = walk(1,level,ops[node+1].ival,&numarg,prec);
1N/A str_cat(str,", ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A break;
1N/A case OSEMICOLON:
1N/A str = str_new(1);
1N/A str_set(str,";\n");
1N/A tab(str,level);
1N/A break;
1N/A case OSTATES:
1N/A str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A break;
1N/A case OSTATE:
1N/A str = str_new(0);
1N/A if (len >= 1) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A if (len >= 2) {
1N/A tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1N/A if (*tmpstr->str_ptr == ';') {
1N/A addsemi(str);
1N/A str_cat(str,tmpstr->str_ptr+1);
1N/A }
1N/A str_free(tmpstr);
1N/A }
1N/A }
1N/A break;
1N/A case OCLOSE:
1N/A str = str_make("close(");
1N/A tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (!do_fancy_opens) {
1N/A t = tmpstr->str_ptr;
1N/A if (*t == '"' || *t == '\'')
1N/A t = cpytill(tokenbuf,t+1,*t);
1N/A else
1N/A fatal("Internal error: OCLOSE %s",t);
1N/A s = savestr(tokenbuf);
1N/A for (t = tokenbuf; *t; t++) {
1N/A *t &= 127;
1N/A if (isLOWER(*t))
1N/A *t = toUPPER(*t);
1N/A if (!isALPHA(*t) && !isDIGIT(*t))
1N/A *t = '_';
1N/A }
1N/A if (!strchr(tokenbuf,'_'))
1N/A strcpy(t,"_FH");
1N/A str_free(tmpstr);
1N/A safefree(s);
1N/A str_set(str,"close ");
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A else {
1N/A sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1N/A tmpstr->str_ptr, tmpstr->str_ptr);
1N/A str_free(tmpstr);
1N/A str_set(str,tokenbuf);
1N/A }
1N/A break;
1N/A case OPRINTF:
1N/A case OPRINT:
1N/A lparen = ""; /* set to parens if necessary */
1N/A rparen = "";
1N/A str = str_new(0);
1N/A if (len == 3) { /* output redirection */
1N/A tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1N/A tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1N/A if (!do_fancy_opens) {
1N/A t = tmpstr->str_ptr;
1N/A if (*t == '"' || *t == '\'')
1N/A t = cpytill(tokenbuf,t+1,*t);
1N/A else
1N/A fatal("Internal error: OPRINT");
1N/A d = savestr(t);
1N/A s = savestr(tokenbuf);
1N/A for (t = tokenbuf; *t; t++) {
1N/A *t &= 127;
1N/A if (isLOWER(*t))
1N/A *t = toUPPER(*t);
1N/A if (!isALPHA(*t) && !isDIGIT(*t))
1N/A *t = '_';
1N/A }
1N/A if (!strchr(tokenbuf,'_'))
1N/A strcpy(t,"_FH");
1N/A tmp3str = hfetch(symtab,tokenbuf);
1N/A if (!tmp3str) {
1N/A str_cat(opens,"open(");
1N/A str_cat(opens,tokenbuf);
1N/A str_cat(opens,", ");
1N/A d[1] = '\0';
1N/A str_cat(opens,d);
1N/A str_scat(opens,tmp2str);
1N/A str_cat(opens,tmpstr->str_ptr+1);
1N/A if (*tmp2str->str_ptr == '|')
1N/A str_cat(opens,") || die 'Cannot pipe to \"");
1N/A else
1N/A str_cat(opens,") || die 'Cannot create file \"");
1N/A if (*d == '"')
1N/A str_cat(opens,"'.\"");
1N/A str_cat(opens,s);
1N/A if (*d == '"')
1N/A str_cat(opens,"\".'");
1N/A str_cat(opens,"\".';\n");
1N/A hstore(symtab,tokenbuf,str_make("x"));
1N/A }
1N/A str_free(tmpstr);
1N/A str_free(tmp2str);
1N/A safefree(s);
1N/A safefree(d);
1N/A }
1N/A else {
1N/A sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1N/A tmp2str->str_ptr, tmpstr->str_ptr);
1N/A str_cat(str,tokenbuf);
1N/A tab(str,level+1);
1N/A strcpy(tokenbuf,"$fh");
1N/A str_free(tmpstr);
1N/A str_free(tmp2str);
1N/A lparen = "(";
1N/A rparen = ")";
1N/A }
1N/A }
1N/A else
1N/A strcpy(tokenbuf,"");
1N/A str_cat(str,lparen); /* may be null */
1N/A if (type == OPRINTF)
1N/A str_cat(str,"printf");
1N/A else
1N/A str_cat(str,"print");
1N/A saw_fh = 0;
1N/A if (len == 3 || do_fancy_opens) {
1N/A if (*tokenbuf) {
1N/A str_cat(str," ");
1N/A saw_fh = 1;
1N/A }
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1N/A if (!*tmpstr->str_ptr && lval_field) {
1N/A t = (char*)(saw_OFS ? "$," : "' '");
1N/A if (split_to_array) {
1N/A sprintf(tokenbuf,"join(%s,@Fld)",t);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A else {
1N/A for (i = 1; i < maxfld; i++) {
1N/A if (i <= arymax)
1N/A sprintf(tokenbuf,"$%s, ",nameary[i]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d, ",i);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A if (maxfld <= arymax)
1N/A sprintf(tokenbuf,"$%s",nameary[maxfld]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d",maxfld);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A }
1N/A if (*tmpstr->str_ptr) {
1N/A str_cat(str," ");
1N/A if (!saw_fh && *tmpstr->str_ptr == '(') {
1N/A str_cat(str,"(");
1N/A str_scat(str,tmpstr);
1N/A str_cat(str,")");
1N/A }
1N/A else
1N/A str_scat(str,tmpstr);
1N/A }
1N/A else {
1N/A str_cat(str," $_");
1N/A }
1N/A str_cat(str,rparen); /* may be null */
1N/A str_free(tmpstr);
1N/A break;
1N/A case ORAND:
1N/A str = str_make("rand(1)");
1N/A break;
1N/A case OSRAND:
1N/A str = str_make("srand(");
1N/A goto maybe0;
1N/A case OATAN2:
1N/A str = str_make("atan2(");
1N/A goto maybe0;
1N/A case OSIN:
1N/A str = str_make("sin(");
1N/A goto maybe0;
1N/A case OCOS:
1N/A str = str_make("cos(");
1N/A goto maybe0;
1N/A case OSYSTEM:
1N/A str = str_make("system(");
1N/A goto maybe0;
1N/A case OLENGTH:
1N/A str = str_make("length(");
1N/A goto maybe0;
1N/A case OLOG:
1N/A str = str_make("log(");
1N/A goto maybe0;
1N/A case OEXP:
1N/A str = str_make("exp(");
1N/A goto maybe0;
1N/A case OSQRT:
1N/A str = str_make("sqrt(");
1N/A goto maybe0;
1N/A case OINT:
1N/A str = str_make("int(");
1N/A maybe0:
1N/A numeric = 1;
1N/A if (len > 0)
1N/A tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1N/A else
1N/A tmpstr = str_new(0);
1N/A if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1N/A if (lval_field) {
1N/A t = (char*)(saw_OFS ? "$," : "' '");
1N/A if (split_to_array) {
1N/A sprintf(tokenbuf,"join(%s,@Fld)",t);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A else {
1N/A sprintf(tokenbuf,"join(%s, ",t);
1N/A str_cat(tmpstr,tokenbuf);
1N/A for (i = 1; i < maxfld; i++) {
1N/A if (i <= arymax)
1N/A sprintf(tokenbuf,"$%s,",nameary[i]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d,",i);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A if (maxfld <= arymax)
1N/A sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d)",maxfld);
1N/A str_cat(tmpstr,tokenbuf);
1N/A }
1N/A }
1N/A else
1N/A str_cat(tmpstr,"$_");
1N/A }
1N/A if (strEQ(tmpstr->str_ptr,"$_")) {
1N/A if (type == OLENGTH && !do_chop) {
1N/A str = str_make("(length(");
1N/A str_cat(tmpstr,") - 1");
1N/A }
1N/A }
1N/A str_scat(str,tmpstr);
1N/A str_free(tmpstr);
1N/A str_cat(str,")");
1N/A break;
1N/A case OBREAK:
1N/A str = str_new(0);
1N/A str_set(str,"last");
1N/A break;
1N/A case ONEXT:
1N/A str = str_new(0);
1N/A str_set(str,"next line");
1N/A break;
1N/A case OEXIT:
1N/A str = str_new(0);
1N/A if (realexit) {
1N/A prec = P_UNI;
1N/A str_set(str,"exit");
1N/A if (len == 1) {
1N/A str_cat(str," ");
1N/A exitval = TRUE;
1N/A str_scat(str,
1N/A fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1N/A str_free(fstr);
1N/A }
1N/A }
1N/A else {
1N/A if (len == 1) {
1N/A str_set(str,"$ExitValue = ");
1N/A exitval = TRUE;
1N/A str_scat(str,
1N/A fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1N/A str_free(fstr);
1N/A str_cat(str,"; ");
1N/A }
1N/A str_cat(str,"last line");
1N/A }
1N/A break;
1N/A case OCONTINUE:
1N/A str = str_new(0);
1N/A str_set(str,"next");
1N/A break;
1N/A case OREDIR:
1N/A goto def;
1N/A case OIF:
1N/A str = str_new(0);
1N/A str_set(str,"if (");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,") ");
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A if (len == 3) {
1N/A i = ops[node+3].ival;
1N/A if (i) {
1N/A if ((ops[i].ival & 255) == OBLOCK) {
1N/A i = ops[i+1].ival;
1N/A if (i) {
1N/A if ((ops[i].ival & 255) != OIF)
1N/A i = 0;
1N/A }
1N/A }
1N/A else
1N/A i = 0;
1N/A }
1N/A if (i) {
1N/A str_cat(str,"els");
1N/A str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A else {
1N/A str_cat(str,"else ");
1N/A str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A }
1N/A break;
1N/A case OWHILE:
1N/A str = str_new(0);
1N/A str_set(str,"while (");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,") ");
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A break;
1N/A case ODO:
1N/A str = str_new(0);
1N/A str_set(str,"do ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A if (str->str_ptr[str->str_cur - 1] == '\n')
1N/A --str->str_cur;
1N/A str_cat(str," while (");
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,");");
1N/A break;
1N/A case OFOR:
1N/A str = str_new(0);
1N/A str_set(str,"for (");
1N/A str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A i = numarg;
1N/A if (i) {
1N/A t = s = tmpstr->str_ptr;
1N/A while (isALPHA(*t) || isDIGIT(*t) || *t == '$' || *t == '_')
1N/A t++;
1N/A i = t - s;
1N/A if (i < 2)
1N/A i = 0;
1N/A }
1N/A str_cat(str,"; ");
1N/A fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1N/A if (i && (t = strchr(fstr->str_ptr,0377))) {
1N/A if (strnEQ(fstr->str_ptr,s,i))
1N/A *t = ' ';
1N/A }
1N/A str_scat(str,fstr);
1N/A str_free(fstr);
1N/A str_free(tmpstr);
1N/A str_cat(str,"; ");
1N/A str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_cat(str,") ");
1N/A str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A break;
1N/A case OFORIN:
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A d = strchr(tmpstr->str_ptr,'$');
1N/A if (!d)
1N/A fatal("Illegal for loop: %s",tmpstr->str_ptr);
1N/A s = strchr(d,'{');
1N/A if (!s)
1N/A s = strchr(d,'[');
1N/A if (!s)
1N/A fatal("Illegal for loop: %s",d);
1N/A *s++ = '\0';
1N/A for (t = s; (i = *t); t++) {
1N/A i &= 127;
1N/A if (i == '}' || i == ']')
1N/A break;
1N/A }
1N/A if (*t)
1N/A *t = '\0';
1N/A str = str_new(0);
1N/A str_set(str,d+1);
1N/A str_cat(str,"[]");
1N/A tmp2str = hfetch(symtab,str->str_ptr);
1N/A if (tmp2str && atoi(tmp2str->str_ptr)) {
1N/A sprintf(tokenbuf,
1N/A "foreach %s ($[ .. $#%s) ",
1N/A s,
1N/A d+1);
1N/A }
1N/A else {
1N/A sprintf(tokenbuf,
1N/A "foreach %s (keys %%%s) ",
1N/A s,
1N/A d+1);
1N/A }
1N/A str_set(str,tokenbuf);
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A str_free(tmpstr);
1N/A break;
1N/A case OBLOCK:
1N/A str = str_new(0);
1N/A str_set(str,"{");
1N/A if (len >= 2 && ops[node+2].ival) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A fixtab(str,++level);
1N/A str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A addsemi(str);
1N/A fixtab(str,--level);
1N/A str_cat(str,"}\n");
1N/A tab(str,level);
1N/A if (len >= 3) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A break;
1N/A default:
1N/A def:
1N/A if (len) {
1N/A if (len > 5)
1N/A fatal("Garbage length in walk");
1N/A str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A for (i = 2; i<= len; i++) {
1N/A str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1N/A str_free(fstr);
1N/A }
1N/A }
1N/A else {
1N/A str = Nullstr;
1N/A }
1N/A break;
1N/A }
1N/A if (!str)
1N/A str = str_new(0);
1N/A
1N/A if (useval && prec < minprec) { /* need parens? */
1N/A fstr = str_new(str->str_cur+2);
1N/A str_nset(fstr,"(",1);
1N/A str_scat(fstr,str);
1N/A str_ncat(fstr,")",1);
1N/A str_free(str);
1N/A str = fstr;
1N/A }
1N/A
1N/A *numericptr = numeric;
1N/A#ifdef DEBUGGING
1N/A if (debug & 4) {
1N/A printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1N/A for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1N/A if (*t == '\n')
1N/A printf("\\n");
1N/A else if (*t == '\t')
1N/A printf("\\t");
1N/A else
1N/A putchar(*t);
1N/A putchar('\n');
1N/A }
1N/A#endif
1N/A return str;
1N/A}
1N/A
1N/Astatic void
1N/Atab(register STR *str, register int lvl)
1N/A{
1N/A while (lvl > 1) {
1N/A str_cat(str,"\t");
1N/A lvl -= 2;
1N/A }
1N/A if (lvl)
1N/A str_cat(str," ");
1N/A}
1N/A
1N/Astatic void
1N/Afixtab(register STR *str, register int lvl)
1N/A{
1N/A register char *s;
1N/A
1N/A /* strip trailing white space */
1N/A
1N/A s = str->str_ptr+str->str_cur - 1;
1N/A while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1N/A s--;
1N/A s[1] = '\0';
1N/A str->str_cur = s + 1 - str->str_ptr;
1N/A if (s >= str->str_ptr && *s != '\n')
1N/A str_cat(str,"\n");
1N/A
1N/A tab(str,lvl);
1N/A}
1N/A
1N/Astatic void
1N/Aaddsemi(register STR *str)
1N/A{
1N/A register char *s;
1N/A
1N/A s = str->str_ptr+str->str_cur - 1;
1N/A while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1N/A s--;
1N/A if (s >= str->str_ptr && *s != ';' && *s != '}')
1N/A str_cat(str,";");
1N/A}
1N/A
1N/Astatic void
1N/Aemit_split(register STR *str, int level)
1N/A{
1N/A register int i;
1N/A
1N/A if (split_to_array)
1N/A str_cat(str,"@Fld");
1N/A else {
1N/A str_cat(str,"(");
1N/A for (i = 1; i < maxfld; i++) {
1N/A if (i <= arymax)
1N/A sprintf(tokenbuf,"$%s,",nameary[i]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d,",i);
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A if (maxfld <= arymax)
1N/A sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1N/A else
1N/A sprintf(tokenbuf,"$Fld%d)",maxfld);
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A if (const_FS) {
1N/A sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1N/A str_cat(str,tokenbuf);
1N/A }
1N/A else if (saw_FS)
1N/A str_cat(str," = split($FS, $_, 9999);\n");
1N/A else
1N/A str_cat(str," = split(' ', $_, 9999);\n");
1N/A tab(str,level);
1N/A}
1N/A
1N/Aint
1N/Aprewalk(int numit, int level, register int node, int *numericptr)
1N/A{
1N/A register int len;
1N/A register int type;
1N/A register int i;
1N/A int numarg;
1N/A int numeric = FALSE;
1N/A STR *tmpstr;
1N/A STR *tmp2str;
1N/A
1N/A if (!node) {
1N/A *numericptr = 0;
1N/A return 0;
1N/A }
1N/A type = ops[node].ival;
1N/A len = type >> 8;
1N/A type &= 255;
1N/A switch (type) {
1N/A case OPROG:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A if (ops[node+2].ival) {
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A ++level;
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A --level;
1N/A if (ops[node+3].ival) {
1N/A prewalk(0,level,ops[node+4].ival,&numarg);
1N/A }
1N/A break;
1N/A case OHUNKS:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A if (len == 3) {
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A }
1N/A break;
1N/A case ORANGE:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OPAT:
1N/A goto def;
1N/A case OREGEX:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OHUNK:
1N/A if (len == 1) {
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A }
1N/A else {
1N/A i = prewalk(0,level,ops[node+1].ival,&numarg);
1N/A if (i) {
1N/A ++level;
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A --level;
1N/A }
1N/A else {
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A }
1N/A break;
1N/A case OPPAREN:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OPANDAND:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OPOROR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OPNOT:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OCPAREN:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric |= numarg;
1N/A break;
1N/A case OCANDAND:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OCOROR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OCNOT:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case ORELOP:
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A numeric |= numarg;
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A numeric |= numarg;
1N/A numeric = 1;
1N/A break;
1N/A case ORPAREN:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric |= numarg;
1N/A break;
1N/A case OMATCHOP:
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OMPAREN:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric |= numarg;
1N/A break;
1N/A case OCONCAT:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OASSIGN:
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
1N/A numericize(ops[node+2].ival);
1N/A if (!numarg)
1N/A numericize(ops[node+3].ival);
1N/A }
1N/A numeric |= numarg;
1N/A break;
1N/A case OADD:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OSUBTRACT:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OMULT:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case ODIV:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPOW:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OMOD:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPOSTINCR:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPOSTDECR:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPREINCR:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPREDECR:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OUMINUS:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OUPLUS:
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OPAREN:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric |= numarg;
1N/A break;
1N/A case OGETLINE:
1N/A break;
1N/A case OSPRINTF:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OSUBSTR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(1,level,ops[node+2].ival,&numarg);
1N/A if (len == 3) {
1N/A prewalk(1,level,ops[node+3].ival,&numarg);
1N/A }
1N/A break;
1N/A case OSTRING:
1N/A break;
1N/A case OSPLIT:
1N/A numeric = 1;
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A if (len == 3)
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OINDEX:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OMATCH:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OUSERDEF:
1N/A subretnum = FALSE;
1N/A --level;
1N/A tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1N/A ++level;
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+4].ival,&numarg);
1N/A prewalk(0,level,ops[node+5].ival,&numarg);
1N/A --level;
1N/A str_cat(tmpstr,"(");
1N/A tmp2str = str_new(0);
1N/A if (subretnum || numarg)
1N/A str_set(tmp2str,"1");
1N/A hstore(symtab,tmpstr->str_ptr,tmp2str);
1N/A str_free(tmpstr);
1N/A level++;
1N/A break;
1N/A case ORETURN:
1N/A if (len > 0) {
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A if (numarg)
1N/A subretnum = TRUE;
1N/A }
1N/A break;
1N/A case OUSERFUN:
1N/A tmp2str = str_new(0);
1N/A str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1N/A fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1N/A str_free(tmpstr);
1N/A str_cat(tmp2str,"(");
1N/A tmpstr = hfetch(symtab,tmp2str->str_ptr);
1N/A if (tmpstr && tmpstr->str_ptr)
1N/A numeric |= atoi(tmpstr->str_ptr);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A str_free(tmp2str);
1N/A break;
1N/A case OGSUB:
1N/A case OSUB:
1N/A if (len >= 3)
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case ONUM:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A numeric = 1;
1N/A break;
1N/A case OSTR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case ODEFINED:
1N/A case ODELETE:
1N/A case OSTAR:
1N/A case OVAR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A if (len == 1) {
1N/A if (numit)
1N/A numericize(node);
1N/A }
1N/A else {
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A break;
1N/A case OFLD:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OVFLD:
1N/A i = ops[node+1].ival;
1N/A prewalk(0,level,i,&numarg);
1N/A break;
1N/A case OJUNK:
1N/A goto def;
1N/A case OSNEWLINE:
1N/A break;
1N/A case ONEWLINE:
1N/A break;
1N/A case OSCOMMENT:
1N/A break;
1N/A case OCOMMENT:
1N/A break;
1N/A case OCOMMA:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A break;
1N/A case OSEMICOLON:
1N/A break;
1N/A case OSTATES:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OSTATE:
1N/A if (len >= 1) {
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A if (len >= 2) {
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A }
1N/A break;
1N/A case OCLOSE:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OPRINTF:
1N/A case OPRINT:
1N/A if (len == 3) { /* output redirection */
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case ORAND:
1N/A break;
1N/A case OSRAND:
1N/A goto maybe0;
1N/A case OATAN2:
1N/A goto maybe0;
1N/A case OSIN:
1N/A goto maybe0;
1N/A case OCOS:
1N/A goto maybe0;
1N/A case OSYSTEM:
1N/A goto maybe0;
1N/A case OLENGTH:
1N/A goto maybe0;
1N/A case OLOG:
1N/A goto maybe0;
1N/A case OEXP:
1N/A goto maybe0;
1N/A case OSQRT:
1N/A goto maybe0;
1N/A case OINT:
1N/A maybe0:
1N/A numeric = 1;
1N/A if (len > 0)
1N/A prewalk(type != OLENGTH && type != OSYSTEM,
1N/A level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OBREAK:
1N/A break;
1N/A case ONEXT:
1N/A break;
1N/A case OEXIT:
1N/A if (len == 1) {
1N/A prewalk(1,level,ops[node+1].ival,&numarg);
1N/A }
1N/A break;
1N/A case OCONTINUE:
1N/A break;
1N/A case OREDIR:
1N/A goto def;
1N/A case OIF:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A if (len == 3) {
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A }
1N/A break;
1N/A case OWHILE:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A break;
1N/A case OFOR:
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+3].ival,&numarg);
1N/A prewalk(0,level,ops[node+4].ival,&numarg);
1N/A break;
1N/A case OFORIN:
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A break;
1N/A case OBLOCK:
1N/A if (len == 2) {
1N/A prewalk(0,level,ops[node+2].ival,&numarg);
1N/A }
1N/A ++level;
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A --level;
1N/A break;
1N/A default:
1N/A def:
1N/A if (len) {
1N/A if (len > 5)
1N/A fatal("Garbage length in prewalk");
1N/A prewalk(0,level,ops[node+1].ival,&numarg);
1N/A for (i = 2; i<= len; i++) {
1N/A prewalk(0,level,ops[node+i].ival,&numarg);
1N/A }
1N/A }
1N/A break;
1N/A }
1N/A *numericptr = numeric;
1N/A return 1;
1N/A}
1N/A
1N/Astatic void
1N/Anumericize(register int node)
1N/A{
1N/A register int len;
1N/A register int type;
1N/A STR *tmpstr;
1N/A STR *tmp2str;
1N/A int numarg;
1N/A
1N/A type = ops[node].ival;
1N/A len = type >> 8;
1N/A type &= 255;
1N/A if (type == OVAR && len == 1) {
1N/A tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
1N/A tmp2str = str_make("1");
1N/A hstore(symtab,tmpstr->str_ptr,tmp2str);
1N/A }
1N/A}