home *** CD-ROM | disk | FTP | other *** search
- From: lwall@netlabs.com (Larry Wall)
- Newsgroups: comp.sources.misc
- Subject: v18i027: perl - The perl programming language, Part09/36
- Message-ID: <1991Apr15.235945.22666@sparky.IMD.Sterling.COM>
- Date: 15 Apr 91 23:59:45 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: b7845ef9 09a23c7b 1cb933c8 ff1ba6f3
-
- Submitted-by: Larry Wall <lwall@netlabs.com>
- Posting-number: Volume 18, Issue 27
- Archive-name: perl/part09
-
- [There are 36 kits for perl version 4.0.]
-
- #! /bin/sh
-
- # Make a new directory for the perl sources, cd to it, and run kits 1
- # thru 36 through sh. When all 36 kits have been run, read README.
-
- echo "This is perl 4.0 kit 9 (of 36). If kit 9 is complete, the line"
- echo '"'"End of kit 9 (of 36)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- mkdir x2p 2>/dev/null
- echo Extracting x2p/walk.c
- sed >x2p/walk.c <<'!STUFFY!FUNK!' -e 's/X//'
- X/* $Header: walk.c,v 4.0 91/03/20 01:58:36 lwall Locked $
- X *
- X * Copyright (c) 1989, Larry Wall
- X *
- X * You may distribute under the terms of the GNU General Public License
- X * as specified in the README file that comes with the perl 3.0 kit.
- X *
- X * $Log: walk.c,v $
- X * Revision 4.0 91/03/20 01:58:36 lwall
- X * 4.0 baseline.
- X *
- X */
- X
- X#include "handy.h"
- X#include "EXTERN.h"
- X#include "util.h"
- X#include "a2p.h"
- X
- Xbool exitval = FALSE;
- Xbool realexit = FALSE;
- Xbool saw_getline = FALSE;
- Xbool subretnum = FALSE;
- Xbool saw_FNR = FALSE;
- Xbool saw_argv0 = FALSE;
- Xint maxtmp = 0;
- Xchar *lparen;
- Xchar *rparen;
- XSTR *subs;
- XSTR *curargs = Nullstr;
- X
- XSTR *
- Xwalk(useval,level,node,numericptr,minprec)
- Xint useval;
- Xint level;
- Xregister int node;
- Xint *numericptr;
- Xint minprec; /* minimum precedence without parens */
- X{
- X register int len;
- X register STR *str;
- X register int type;
- X register int i;
- X register STR *tmpstr;
- X STR *tmp2str;
- X STR *tmp3str;
- X char *t;
- X char *d, *s;
- X int numarg;
- X int numeric = FALSE;
- X STR *fstr;
- X int prec = P_MAX; /* assume no parens needed */
- X char *index();
- X
- X if (!node) {
- X *numericptr = 0;
- X return str_make("");
- X }
- X type = ops[node].ival;
- X len = type >> 8;
- X type &= 255;
- X switch (type) {
- X case OPROG:
- X opens = str_new(0);
- X subs = str_new(0);
- X str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X if (do_split && need_entire && !absmaxfld)
- X split_to_array = TRUE;
- X if (do_split && split_to_array)
- X set_array_base = TRUE;
- X if (set_array_base) {
- X str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
- X }
- X if (fswitch && !const_FS)
- X const_FS = fswitch;
- X if (saw_FS > 1 || saw_RS)
- X const_FS = 0;
- X if (saw_ORS && need_entire)
- X do_chop = TRUE;
- X if (fswitch) {
- X str_cat(str,"$FS = '");
- X if (index("*+?.[]()|^$\\",fswitch))
- X str_cat(str,"\\");
- X sprintf(tokenbuf,"%c",fswitch);
- X str_cat(str,tokenbuf);
- X str_cat(str,"';\t\t# field separator from -F switch\n");
- X }
- X else if (saw_FS && !const_FS) {
- X str_cat(str,"$FS = ' ';\t\t# set field separator\n");
- X }
- X if (saw_OFS) {
- X str_cat(str,"$, = ' ';\t\t# set output field separator\n");
- X }
- X if (saw_ORS) {
- X str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
- X }
- X if (saw_argv0) {
- X str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
- X }
- X if (str->str_cur > 20)
- X str_cat(str,"\n");
- X if (ops[node+2].ival) {
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,"\n\n");
- X }
- X fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
- X if (*fstr->str_ptr) {
- X if (saw_line_op)
- X str_cat(str,"line: ");
- X str_cat(str,"while (<>) {\n");
- X tab(str,++level);
- X if (saw_FS && !const_FS)
- X do_chop = TRUE;
- X if (do_chop) {
- X str_cat(str,"chop;\t# strip record separator\n");
- X tab(str,level);
- X }
- X arymax = 0;
- X if (namelist) {
- X while (isalpha(*namelist)) {
- X for (d = tokenbuf,s=namelist;
- X isalpha(*s) || isdigit(*s) || *s == '_';
- X *d++ = *s++) ;
- X *d = '\0';
- X while (*s && !isalpha(*s)) s++;
- X namelist = s;
- X nameary[++arymax] = savestr(tokenbuf);
- X }
- X }
- X if (maxfld < arymax)
- X maxfld = arymax;
- X if (do_split)
- X emit_split(str,level);
- X str_scat(str,fstr);
- X str_free(fstr);
- X fixtab(str,--level);
- X str_cat(str,"}\n");
- X if (saw_FNR)
- X str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
- X }
- X else
- X str_cat(str,"while (<>) { } # (no line actions)\n");
- X if (ops[node+4].ival) {
- X realexit = TRUE;
- X str_cat(str,"\n");
- X tab(str,level);
- X str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,"\n");
- X }
- X if (exitval)
- X str_cat(str,"exit $ExitValue;\n");
- X if (subs->str_ptr) {
- X str_cat(str,"\n");
- X str_scat(str,subs);
- X }
- X if (saw_getline) {
- X for (len = 0; len < 4; len++) {
- X if (saw_getline & (1 << len)) {
- X sprintf(tokenbuf,"\nsub Getline%d {\n",len);
- X str_cat(str, tokenbuf);
- X if (len & 2) {
- X if (do_fancy_opens)
- X str_cat(str," &Pick('',@_);\n");
- X else
- X str_cat(str," ($fh) = @_;\n");
- X }
- X else {
- X if (saw_FNR)
- X str_cat(str," $FNRbase = $. if eof;\n");
- X }
- X if (len & 1)
- X str_cat(str," local($_);\n");
- X if (len & 2)
- X str_cat(str,
- X " if ($getline_ok = (($_ = <$fh>) ne ''))");
- X else
- X str_cat(str,
- X " if ($getline_ok = (($_ = <>) ne ''))");
- X str_cat(str, " {\n");
- X level += 2;
- X tab(str,level);
- X i = 0;
- X if (do_chop) {
- X i++;
- X str_cat(str,"chop;\t# strip record separator\n");
- X tab(str,level);
- X }
- X if (do_split && !(len & 1)) {
- X i++;
- X emit_split(str,level);
- X }
- X if (!i)
- X str_cat(str,";\n");
- X fixtab(str,--level);
- X str_cat(str,"}\n $_;\n}\n");
- X --level;
- X }
- X }
- X }
- X if (do_fancy_opens) {
- X str_cat(str,"\n\
- Xsub Pick {\n\
- X local($mode,$name,$pipe) = @_;\n\
- X $fh = $opened{$name};\n\
- X if (!$fh) {\n\
- X $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
- X open($fh,$mode.$name.$pipe);\n\
- X }\n\
- X}\n\
- X");
- X }
- X break;
- X case OHUNKS:
- X str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X if (len == 3) {
- X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X else {
- X }
- X break;
- X case ORANGE:
- X prec = P_DOTDOT;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
- X str_cat(str," .. ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OPAT:
- X goto def;
- X case OREGEX:
- X str = str_new(0);
- X str_set(str,"/");
- X tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X /* translate \nnn to [\nnn] */
- X for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
- X if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
- X *d++ = '[';
- X *d++ = *s++;
- X *d++ = *s++;
- X *d++ = *s++;
- X *d++ = *s;
- X *d = ']';
- X }
- X else
- X *d = *s;
- X }
- X *d = '\0';
- X for (d=tokenbuf; *d; d++)
- X *d += 128;
- X str_cat(str,tokenbuf);
- X str_free(tmpstr);
- X str_cat(str,"/");
- X break;
- X case OHUNK:
- X if (len == 1) {
- X str = str_new(0);
- X str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
- X str_cat(str," if ");
- X str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,";");
- X }
- X else {
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X if (*tmpstr->str_ptr) {
- X str = str_new(0);
- X str_set(str,"if (");
- X str_scat(str,tmpstr);
- X str_cat(str,") {\n");
- X tab(str,++level);
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X fixtab(str,--level);
- X str_cat(str,"}\n");
- X tab(str,level);
- X }
- X else {
- X str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
- X }
- X }
- X break;
- X case OPPAREN:
- X str = str_new(0);
- X str_set(str,"(");
- X str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,")");
- X break;
- X case OPANDAND:
- X prec = P_ANDAND;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," && ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OPOROR:
- X prec = P_OROR;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," || ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OPNOT:
- X prec = P_UNARY;
- X str = str_new(0);
- X str_set(str,"!");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
- X str_free(fstr);
- X break;
- X case OCOND:
- X prec = P_COND;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," ? ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X str_cat(str," : ");
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OCPAREN:
- X str = str_new(0);
- X str_set(str,"(");
- X str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X numeric |= numarg;
- X str_cat(str,")");
- X break;
- X case OCANDAND:
- X prec = P_ANDAND;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X numeric = 1;
- X str_cat(str," && ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OCOROR:
- X prec = P_OROR;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X numeric = 1;
- X str_cat(str," || ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OCNOT:
- X prec = P_UNARY;
- X str = str_new(0);
- X str_set(str,"!");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case ORELOP:
- X prec = P_REL;
- X str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
- X numeric |= numarg;
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
- X numeric |= numarg;
- X if (!numeric ||
- X (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
- X t = tmpstr->str_ptr;
- X if (strEQ(t,"=="))
- X str_set(tmpstr,"eq");
- X else if (strEQ(t,"!="))
- X str_set(tmpstr,"ne");
- X else if (strEQ(t,"<"))
- X str_set(tmpstr,"lt");
- X else if (strEQ(t,"<="))
- X str_set(tmpstr,"le");
- X else if (strEQ(t,">"))
- X str_set(tmpstr,"gt");
- X else if (strEQ(t,">="))
- X str_set(tmpstr,"ge");
- X if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
- X !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
- X numeric |= 2;
- X }
- X if (numeric & 2) {
- X if (numeric & 1) /* numeric is very good guess */
- X str_cat(str," ");
- X else
- X str_cat(str,"\377");
- X numeric = 1;
- X }
- X else
- X str_cat(str," ");
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X str_cat(str," ");
- X str_scat(str,tmp2str);
- X str_free(tmp2str);
- X numeric = 1;
- X break;
- X case ORPAREN:
- X str = str_new(0);
- X str_set(str,"(");
- X str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X numeric |= numarg;
- X str_cat(str,")");
- X break;
- X case OMATCHOP:
- X prec = P_MATCH;
- X str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
- X str_cat(str," ");
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X if (strEQ(tmpstr->str_ptr,"~"))
- X str_cat(str,"=~");
- X else {
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X }
- X str_cat(str," ");
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OMPAREN:
- X str = str_new(0);
- X str_set(str,"(");
- X str_scat(str,
- X fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X numeric |= numarg;
- X str_cat(str,")");
- X break;
- X case OCONCAT:
- X prec = P_ADD;
- X type = ops[ops[node+1].ival].ival & 255;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
- X str_cat(str," . ");
- X type = ops[ops[node+2].ival].ival & 255;
- X str_scat(str,
- X fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
- X str_free(fstr);
- X break;
- X case OASSIGN:
- X prec = P_ASSIGN;
- X str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
- X str_cat(str," ");
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X str_scat(str,tmpstr);
- X if (str_len(tmpstr) > 1)
- X numeric = 1;
- X str_free(tmpstr);
- X str_cat(str," ");
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
- X str_free(fstr);
- X numeric |= numarg;
- X break;
- X case OADD:
- X prec = P_ADD;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," + ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OSUBTRACT:
- X prec = P_ADD;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," - ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OMULT:
- X prec = P_MUL;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," * ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case ODIV:
- X prec = P_MUL;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," / ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OPOW:
- X prec = P_POW;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
- X str_cat(str," ** ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OMOD:
- X prec = P_MUL;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str," % ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OPOSTINCR:
- X prec = P_AUTO;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
- X str_cat(str,"++");
- X numeric = 1;
- X break;
- X case OPOSTDECR:
- X prec = P_AUTO;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
- X str_cat(str,"--");
- X numeric = 1;
- X break;
- X case OPREINCR:
- X prec = P_AUTO;
- X str = str_new(0);
- X str_set(str,"++");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OPREDECR:
- X prec = P_AUTO;
- X str = str_new(0);
- X str_set(str,"--");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OUMINUS:
- X prec = P_UNARY;
- X str = str_new(0);
- X str_set(str,"-");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
- X str_free(fstr);
- X numeric = 1;
- X break;
- X case OUPLUS:
- X numeric = 1;
- X goto def;
- X case OPAREN:
- X str = str_new(0);
- X str_set(str,"(");
- X str_scat(str,
- X fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,")");
- X numeric |= numarg;
- X break;
- X case OGETLINE:
- X str = str_new(0);
- X if (useval)
- X str_cat(str,"(");
- X if (len > 0) {
- X str_cat(str,"$");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X if (!*fstr->str_ptr) {
- X str_cat(str,"_");
- X len = 2; /* a legal fiction */
- X }
- X str_free(fstr);
- X }
- X else
- X str_cat(str,"$_");
- X if (len > 1) {
- X tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
- X fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- X if (!do_fancy_opens) {
- X t = tmpstr->str_ptr;
- X if (*t == '"' || *t == '\'')
- X t = cpytill(tokenbuf,t+1,*t);
- X else
- X fatal("Internal error: OGETLINE %s", t);
- X d = savestr(t);
- X s = savestr(tokenbuf);
- X for (t = tokenbuf; *t; t++) {
- X *t &= 127;
- X if (!isalpha(*t) && !isdigit(*t))
- X *t = '_';
- X }
- X if (!index(tokenbuf,'_'))
- X strcpy(t,"_fh");
- X tmp3str = hfetch(symtab,tokenbuf);
- X if (!tmp3str) {
- X do_opens = TRUE;
- X str_cat(opens,"open(");
- X str_cat(opens,tokenbuf);
- X str_cat(opens,", ");
- X d[1] = '\0';
- X str_cat(opens,d);
- X str_cat(opens,tmpstr->str_ptr+1);
- X opens->str_cur--;
- X if (*fstr->str_ptr == '|')
- X str_cat(opens,"|");
- X str_cat(opens,d);
- X if (*fstr->str_ptr == '|')
- X str_cat(opens,") || die 'Cannot pipe from \"");
- X else
- X str_cat(opens,") || die 'Cannot open file \"");
- X if (*d == '"')
- X str_cat(opens,"'.\"");
- X str_cat(opens,s);
- X if (*d == '"')
- X str_cat(opens,"\".'");
- X str_cat(opens,"\".';\n");
- X hstore(symtab,tokenbuf,str_make("x"));
- X }
- X safefree(s);
- X safefree(d);
- X str_set(tmpstr,"'");
- X str_cat(tmpstr,tokenbuf);
- X str_cat(tmpstr,"'");
- X }
- X if (*fstr->str_ptr == '|')
- X str_cat(tmpstr,", '|'");
- X str_free(fstr);
- X }
- X else
- X tmpstr = str_make("");
- X sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
- X str_cat(str,tokenbuf);
- X str_free(tmpstr);
- X if (useval)
- X str_cat(str,",$getline_ok)");
- X saw_getline |= 1 << len;
- X break;
- X case OSPRINTF:
- X str = str_new(0);
- X str_set(str,"sprintf(");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,")");
- X break;
- X case OSUBSTR:
- X str = str_new(0);
- X str_set(str,"substr(");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X str_cat(str,", ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X str_cat(str,", ");
- X if (len == 3) {
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X }
- X else
- X str_cat(str,"999999");
- X str_cat(str,")");
- X break;
- X case OSTRING:
- X str = str_new(0);
- X str_set(str,ops[node+1].cval);
- X break;
- X case OSPLIT:
- X str = str_new(0);
- X numeric = 1;
- X tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- X if (useval)
- X str_set(str,"(@");
- X else
- X str_set(str,"@");
- X str_scat(str,tmpstr);
- X str_cat(str," = split(");
- X if (len == 3) {
- X fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
- X if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
- X i = fstr->str_ptr[1] & 127;
- X if (index("*+?.[]()|^$\\",i))
- X sprintf(tokenbuf,"/\\%c/",i);
- X else if (i == ' ')
- X sprintf(tokenbuf,"' '");
- X else
- X sprintf(tokenbuf,"/%c/",i);
- X str_cat(str,tokenbuf);
- X }
- X else
- X str_scat(str,fstr);
- X str_free(fstr);
- X }
- X else if (const_FS) {
- X sprintf(tokenbuf,"/[%c\\n]/",const_FS);
- X str_cat(str,tokenbuf);
- X }
- X else if (saw_FS)
- X str_cat(str,"$FS");
- X else
- X str_cat(str,"' '");
- X str_cat(str,", ");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X str_cat(str,", 9999)");
- X if (useval) {
- X str_cat(str,")");
- X }
- X str_free(tmpstr);
- X break;
- X case OINDEX:
- X str = str_new(0);
- X str_set(str,"index(");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X str_cat(str,", ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
- X str_free(fstr);
- X str_cat(str,")");
- X numeric = 1;
- X break;
- X case OMATCH:
- X str = str_new(0);
- X prec = P_ANDAND;
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
- X str_free(fstr);
- X str_cat(str," =~ ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
- X str_free(fstr);
- X str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
- X numeric = 1;
- X break;
- X case OUSERDEF:
- X str = str_new(0);
- X subretnum = FALSE;
- X fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
- X curargs = str_new(0);
- X str_sset(curargs,fstr);
- X str_cat(curargs,",");
- X tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
- X str_free(curargs);
- X curargs = Nullstr;
- X level--;
- X subretnum |= numarg;
- X s = Nullch;
- X t = tmp2str->str_ptr;
- X while (t = instr(t,"return "))
- X s = t++;
- X if (s) {
- X i = 0;
- X for (t = s+7; *t; t++) {
- X if (*t == ';' || *t == '}')
- X i++;
- X }
- X if (i == 1) {
- X strcpy(s,s+7);
- X tmp2str->str_cur -= 7;
- X }
- X }
- X str_set(str,"\n");
- X tab(str,level);
- X str_cat(str,"sub ");
- X str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_cat(str," {\n");
- X tab(str,++level);
- X if (fstr->str_cur) {
- X str_cat(str,"local(");
- X str_scat(str,fstr);
- X str_cat(str,") = @_;");
- X }
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
- X str_free(fstr);
- X fixtab(str,level);
- X str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
- X str_free(fstr);
- X fixtab(str,level);
- X str_scat(str,tmp2str);
- X str_free(tmp2str);
- X fixtab(str,--level);
- X str_cat(str,"}\n");
- X tab(str,level);
- X str_scat(subs,str);
- X str_set(str,"");
- X str_cat(tmpstr,"(");
- X tmp2str = str_new(0);
- X if (subretnum)
- X str_set(tmp2str,"1");
- X hstore(symtab,tmpstr->str_ptr,tmp2str);
- X str_free(tmpstr);
- X level++;
- X break;
- X case ORETURN:
- X str = str_new(0);
- X if (len > 0) {
- X str_cat(str,"return ");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
- X str_free(fstr);
- X if (numarg)
- X subretnum = TRUE;
- X }
- X else
- X str_cat(str,"return");
- X break;
- X case OUSERFUN:
- X str = str_new(0);
- X str_set(str,"&");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,"(");
- X tmpstr = hfetch(symtab,str->str_ptr+3);
- X if (tmpstr && tmpstr->str_ptr)
- X numeric |= atoi(tmpstr->str_ptr);
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,")");
- X break;
- X case OGSUB:
- X case OSUB:
- X if (type == OGSUB)
- X s = "g";
- X else
- X s = "";
- X str = str_new(0);
- X tmpstr = str_new(0);
- X i = 0;
- X if (len == 3) {
- X tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
- X if (strNE(tmpstr->str_ptr,"$_")) {
- X str_cat(tmpstr, " =~ s");
- X i++;
- X }
- X else
- X str_set(tmpstr, "s");
- X }
- X else
- X str_set(tmpstr, "s");
- X type = ops[ops[node+2].ival].ival;
- X len = type >> 8;
- X type &= 255;
- X tmp3str = str_new(0);
- X if (type == OSTR) {
- X tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
- X for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
- X if (*t == '&')
- X *d++ = '$' + 128;
- X else if (*t == '$')
- X *d++ = '\\' + 128;
- X *d = *t + 128;
- X }
- X *d = '\0';
- X str_set(tmp2str,tokenbuf);
- X }
- X else {
- X tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- X str_set(tmp3str,"($s_ = '\"'.(");
- X str_scat(tmp3str,tmp2str);
- X str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
- X str_set(tmp2str,"eval $s_");
- X s = (*s == 'g' ? "ge" : "e");
- X i++;
- X }
- X type = ops[ops[node+1].ival].ival;
- X len = type >> 8;
- X type &= 255;
- X fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
- X if (type == OREGEX) {
- X if (useval && i)
- X str_cat(str,"(");
- X str_scat(str,tmp3str);
- X str_scat(str,tmpstr);
- X str_scat(str,fstr);
- X str_scat(str,tmp2str);
- X str_cat(str,"/");
- X str_cat(str,s);
- X }
- X else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
- X if (useval && i)
- X str_cat(str,"(");
- X str_scat(str,tmp3str);
- X str_scat(str,tmpstr);
- X str_cat(str,"/");
- X str_scat(str,fstr);
- X str_cat(str,"/");
- X str_scat(str,tmp2str);
- X str_cat(str,"/");
- X str_cat(str,s);
- X }
- X else {
- X i++;
- X if (useval)
- X str_cat(str,"(");
- X str_cat(str,"$s = ");
- X str_scat(str,fstr);
- X str_cat(str,", ");
- X str_scat(str,tmp3str);
- X str_scat(str,tmpstr);
- X str_cat(str,"/$s/");
- X str_scat(str,tmp2str);
- X str_cat(str,"/");
- X str_cat(str,s);
- X }
- X if (useval && i)
- X str_cat(str,")");
- X str_free(fstr);
- X str_free(tmpstr);
- X str_free(tmp2str);
- X str_free(tmp3str);
- X numeric = 1;
- X break;
- X case ONUM:
- X str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
- X numeric = 1;
- X break;
- X case OSTR:
- X tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
- X s = "'";
- X for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
- X if (*t == '\'')
- X s = "\"";
- X else if (*t == '\\') {
- X s = "\"";
- X *d++ = *t++ + 128;
- X switch (*t) {
- X case '\\': case '"': case 'n': case 't': case '$':
- X break;
- X default: /* hide this from perl */
- X *d++ = '\\' + 128;
- X }
- X }
- X *d = *t + 128;
- X }
- X *d = '\0';
- X str = str_new(0);
- X str_set(str,s);
- X str_cat(str,tokenbuf);
- X str_free(tmpstr);
- X str_cat(str,s);
- X break;
- X case ODEFINED:
- X prec = P_UNI;
- X str = str_new(0);
- X str_set(str,"defined $");
- X goto addvar;
- X case ODELETE:
- X str = str_new(0);
- X str_set(str,"delete $");
- X goto addvar;
- X case OSTAR:
- X str = str_new(0);
- X str_set(str,"*");
- X goto addvar;
- X case OVAR:
- X str = str_new(0);
- X str_set(str,"$");
- X addvar:
- X str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X if (len == 1) {
- X tmp2str = hfetch(symtab,tmpstr->str_ptr);
- X if (tmp2str && atoi(tmp2str->str_ptr))
- X numeric = 2;
- X if (strEQ(str->str_ptr,"$FNR")) {
- X numeric = 1;
- X saw_FNR++;
- X str_set(str,"($.-$FNRbase)");
- X }
- X else if (strEQ(str->str_ptr,"$NR")) {
- X numeric = 1;
- X str_set(str,"$.");
- X }
- X else if (strEQ(str->str_ptr,"$NF")) {
- X numeric = 1;
- X str_set(str,"$#Fld");
- X }
- X else if (strEQ(str->str_ptr,"$0"))
- X str_set(str,"$_");
- X else if (strEQ(str->str_ptr,"$ARGC"))
- X str_set(str,"($#ARGV+1)");
- X }
- X else {
- X#ifdef NOTDEF
- X if (curargs) {
- X sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
- X ??? if (instr(curargs->str_ptr,tokenbuf))
- X str_cat(str,"\377"); /* can't translate yet */
- X }
- X#endif
- X str_cat(tmpstr,"[]");
- X tmp2str = hfetch(symtab,tmpstr->str_ptr);
- X if (tmp2str && atoi(tmp2str->str_ptr))
- X str_cat(str,"[");
- X else
- X str_cat(str,"{");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X if (strEQ(str->str_ptr,"$ARGV[0")) {
- X str_set(str,"$ARGV0");
- X saw_argv0++;
- X }
- X else {
- X if (tmp2str && atoi(tmp2str->str_ptr))
- X strcpy(tokenbuf,"]");
- X else
- X strcpy(tokenbuf,"}");
- X *tokenbuf += 128;
- X str_cat(str,tokenbuf);
- X }
- X }
- X str_free(tmpstr);
- X break;
- X case OFLD:
- X str = str_new(0);
- X if (split_to_array) {
- X str_set(str,"$Fld");
- X str_cat(str,"[");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,"]");
- X }
- X else {
- X i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
- X if (i <= arymax)
- X sprintf(tokenbuf,"$%s",nameary[i]);
- X else
- X sprintf(tokenbuf,"$Fld%d",i);
- X str_set(str,tokenbuf);
- X }
- X break;
- X case OVFLD:
- X str = str_new(0);
- X str_set(str,"$Fld[");
- X i = ops[node+1].ival;
- X if ((ops[i].ival & 255) == OPAREN)
- X i = ops[i+1].ival;
- X tmpstr=walk(1,level,i,&numarg,P_MIN);
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X str_cat(str,"]");
- X break;
- X case OJUNK:
- X goto def;
- X case OSNEWLINE:
- X str = str_new(2);
- X str_set(str,";\n");
- X tab(str,level);
- X break;
- X case ONEWLINE:
- X str = str_new(1);
- X str_set(str,"\n");
- X tab(str,level);
- X break;
- X case OSCOMMENT:
- X str = str_new(0);
- X str_set(str,";");
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
- X *s += 128;
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X tab(str,level);
- X break;
- X case OCOMMENT:
- X str = str_new(0);
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
- X *s += 128;
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X tab(str,level);
- X break;
- X case OCOMMA:
- X prec = P_COMMA;
- X str = walk(1,level,ops[node+1].ival,&numarg,prec);
- X str_cat(str,", ");
- X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
- X str_free(fstr);
- X break;
- X case OSEMICOLON:
- X str = str_new(1);
- X str_set(str,";\n");
- X tab(str,level);
- X break;
- X case OSTATES:
- X str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X break;
- X case OSTATE:
- X str = str_new(0);
- X if (len >= 1) {
- X str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X if (len >= 2) {
- X tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
- X if (*tmpstr->str_ptr == ';') {
- X addsemi(str);
- X str_cat(str,tmpstr->str_ptr+1);
- X }
- X str_free(tmpstr);
- X }
- X }
- X break;
- X case OCLOSE:
- X str = str_make("close(");
- X tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
- X if (!do_fancy_opens) {
- X t = tmpstr->str_ptr;
- X if (*t == '"' || *t == '\'')
- X t = cpytill(tokenbuf,t+1,*t);
- X else
- X fatal("Internal error: OCLOSE %s",t);
- X s = savestr(tokenbuf);
- X for (t = tokenbuf; *t; t++) {
- X *t &= 127;
- X if (!isalpha(*t) && !isdigit(*t))
- X *t = '_';
- X }
- X if (!index(tokenbuf,'_'))
- X strcpy(t,"_fh");
- X str_free(tmpstr);
- X safefree(s);
- X str_set(str,"close ");
- X str_cat(str,tokenbuf);
- X }
- X else {
- X sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
- X tmpstr->str_ptr);
- X str_free(tmpstr);
- X str_set(str,tokenbuf);
- X }
- X break;
- X case OPRINTF:
- X case OPRINT:
- X lparen = ""; /* set to parens if necessary */
- X rparen = "";
- X str = str_new(0);
- X if (len == 3) { /* output redirection */
- X tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
- X tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- X if (!do_fancy_opens) {
- X t = tmpstr->str_ptr;
- X if (*t == '"' || *t == '\'')
- X t = cpytill(tokenbuf,t+1,*t);
- X else
- X fatal("Internal error: OPRINT");
- X d = savestr(t);
- X s = savestr(tokenbuf);
- X for (t = tokenbuf; *t; t++) {
- X *t &= 127;
- X if (!isalpha(*t) && !isdigit(*t))
- X *t = '_';
- X }
- X if (!index(tokenbuf,'_'))
- X strcpy(t,"_fh");
- X tmp3str = hfetch(symtab,tokenbuf);
- X if (!tmp3str) {
- X str_cat(opens,"open(");
- X str_cat(opens,tokenbuf);
- X str_cat(opens,", ");
- X d[1] = '\0';
- X str_cat(opens,d);
- X str_scat(opens,tmp2str);
- X str_cat(opens,tmpstr->str_ptr+1);
- X if (*tmp2str->str_ptr == '|')
- X str_cat(opens,") || die 'Cannot pipe to \"");
- X else
- X str_cat(opens,") || die 'Cannot create file \"");
- X if (*d == '"')
- X str_cat(opens,"'.\"");
- X str_cat(opens,s);
- X if (*d == '"')
- X str_cat(opens,"\".'");
- X str_cat(opens,"\".';\n");
- X hstore(symtab,tokenbuf,str_make("x"));
- X }
- X str_free(tmpstr);
- X str_free(tmp2str);
- X safefree(s);
- X safefree(d);
- X }
- X else {
- X sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
- X tmp2str->str_ptr, tmpstr->str_ptr);
- X str_cat(str,tokenbuf);
- X tab(str,level+1);
- X strcpy(tokenbuf,"$fh");
- X str_free(tmpstr);
- X str_free(tmp2str);
- X lparen = "(";
- X rparen = ")";
- X }
- X }
- X else
- X strcpy(tokenbuf,"");
- X str_cat(str,lparen); /* may be null */
- X if (type == OPRINTF)
- X str_cat(str,"printf");
- X else
- X str_cat(str,"print");
- X if (len == 3 || do_fancy_opens) {
- X if (*tokenbuf)
- X str_cat(str," ");
- X str_cat(str,tokenbuf);
- X }
- X tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
- X if (!*tmpstr->str_ptr && lval_field) {
- X t = saw_OFS ? "$," : "' '";
- X if (split_to_array) {
- X sprintf(tokenbuf,"join(%s,@Fld)",t);
- X str_cat(tmpstr,tokenbuf);
- X }
- X else {
- X for (i = 1; i < maxfld; i++) {
- X if (i <= arymax)
- X sprintf(tokenbuf,"$%s, ",nameary[i]);
- X else
- X sprintf(tokenbuf,"$Fld%d, ",i);
- X str_cat(tmpstr,tokenbuf);
- X }
- X if (maxfld <= arymax)
- X sprintf(tokenbuf,"$%s",nameary[maxfld]);
- X else
- X sprintf(tokenbuf,"$Fld%d",maxfld);
- X str_cat(tmpstr,tokenbuf);
- X }
- X }
- X if (*tmpstr->str_ptr) {
- X str_cat(str," ");
- X str_scat(str,tmpstr);
- X }
- X else {
- X str_cat(str," $_");
- X }
- X str_cat(str,rparen); /* may be null */
- X str_free(tmpstr);
- X break;
- X case ORAND:
- X str = str_make("rand(1)");
- X break;
- X case OSRAND:
- X str = str_make("srand(");
- X goto maybe0;
- X case OATAN2:
- X str = str_make("atan2(");
- X goto maybe0;
- X case OSIN:
- X str = str_make("sin(");
- X goto maybe0;
- X case OCOS:
- X str = str_make("cos(");
- X goto maybe0;
- X case OSYSTEM:
- X str = str_make("system(");
- X goto maybe0;
- X case OLENGTH:
- X str = str_make("length(");
- X goto maybe0;
- X case OLOG:
- X str = str_make("log(");
- X goto maybe0;
- X case OEXP:
- X str = str_make("exp(");
- X goto maybe0;
- X case OSQRT:
- X str = str_make("sqrt(");
- X goto maybe0;
- X case OINT:
- X str = str_make("int(");
- X maybe0:
- X numeric = 1;
- X if (len > 0)
- X tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
- X else
- X tmpstr = str_new(0);;
- X if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
- X if (lval_field) {
- X t = saw_OFS ? "$," : "' '";
- X if (split_to_array) {
- X sprintf(tokenbuf,"join(%s,@Fld)",t);
- X str_cat(tmpstr,tokenbuf);
- X }
- X else {
- X sprintf(tokenbuf,"join(%s, ",t);
- X str_cat(tmpstr,tokenbuf);
- X for (i = 1; i < maxfld; i++) {
- X if (i <= arymax)
- X sprintf(tokenbuf,"$%s,",nameary[i]);
- X else
- X sprintf(tokenbuf,"$Fld%d,",i);
- X str_cat(tmpstr,tokenbuf);
- X }
- X if (maxfld <= arymax)
- X sprintf(tokenbuf,"$%s)",nameary[maxfld]);
- X else
- X sprintf(tokenbuf,"$Fld%d)",maxfld);
- X str_cat(tmpstr,tokenbuf);
- X }
- X }
- X else
- X str_cat(tmpstr,"$_");
- X }
- X if (strEQ(tmpstr->str_ptr,"$_")) {
- X if (type == OLENGTH && !do_chop) {
- X str = str_make("(length(");
- X str_cat(tmpstr,") - 1");
- X }
- X }
- X str_scat(str,tmpstr);
- X str_free(tmpstr);
- X str_cat(str,")");
- X break;
- X case OBREAK:
- X str = str_new(0);
- X str_set(str,"last");
- X break;
- X case ONEXT:
- X str = str_new(0);
- X str_set(str,"next line");
- X break;
- X case OEXIT:
- X str = str_new(0);
- X if (realexit) {
- X prec = P_UNI;
- X str_set(str,"exit");
- X if (len == 1) {
- X str_cat(str," ");
- X exitval = TRUE;
- X str_scat(str,
- X fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
- X str_free(fstr);
- X }
- X }
- X else {
- X if (len == 1) {
- X str_set(str,"$ExitValue = ");
- X exitval = TRUE;
- X str_scat(str,
- X fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
- X str_free(fstr);
- X str_cat(str,"; ");
- X }
- X str_cat(str,"last line");
- X }
- X break;
- X case OCONTINUE:
- X str = str_new(0);
- X str_set(str,"next");
- X break;
- X case OREDIR:
- X goto def;
- X case OIF:
- X str = str_new(0);
- X str_set(str,"if (");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,") ");
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X if (len == 3) {
- X i = ops[node+3].ival;
- X if (i) {
- X if ((ops[i].ival & 255) == OBLOCK) {
- X i = ops[i+1].ival;
- X if (i) {
- X if ((ops[i].ival & 255) != OIF)
- X i = 0;
- X }
- X }
- X else
- X i = 0;
- X }
- X if (i) {
- X str_cat(str,"els");
- X str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X else {
- X str_cat(str,"else ");
- X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X }
- X break;
- X case OWHILE:
- X str = str_new(0);
- X str_set(str,"while (");
- X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,") ");
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X break;
- X case OFOR:
- X str = str_new(0);
- X str_set(str,"for (");
- X str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X i = numarg;
- X if (i) {
- X t = s = tmpstr->str_ptr;
- X while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
- X t++;
- X i = t - s;
- X if (i < 2)
- X i = 0;
- X }
- X str_cat(str,"; ");
- X fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
- X if (i && (t = index(fstr->str_ptr,0377))) {
- X if (strnEQ(fstr->str_ptr,s,i))
- X *t = ' ';
- X }
- X str_scat(str,fstr);
- X str_free(fstr);
- X str_free(tmpstr);
- X str_cat(str,"; ");
- X str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_cat(str,") ");
- X str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
- X str_free(fstr);
- X break;
- X case OFORIN:
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X d = index(tmpstr->str_ptr,'$');
- X if (!d)
- X fatal("Illegal for loop: %s",tmpstr->str_ptr);
- X s = index(d,'{');
- X if (!s)
- X s = index(d,'[');
- X if (!s)
- X fatal("Illegal for loop: %s",d);
- X *s++ = '\0';
- X for (t = s; i = *t; t++) {
- X i &= 127;
- X if (i == '}' || i == ']')
- X break;
- X }
- X if (*t)
- X *t = '\0';
- X str = str_new(0);
- X str_set(str,d+1);
- X str_cat(str,"[]");
- X tmp2str = hfetch(symtab,str->str_ptr);
- X if (tmp2str && atoi(tmp2str->str_ptr)) {
- X sprintf(tokenbuf,
- X "foreach %s ($[ .. $#%s) ",
- X s,
- X d+1);
- X }
- X else {
- X sprintf(tokenbuf,
- X "foreach %s (keys %%%s) ",
- X s,
- X d+1);
- X }
- X str_set(str,tokenbuf);
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X str_free(tmpstr);
- X break;
- X case OBLOCK:
- X str = str_new(0);
- X str_set(str,"{");
- X if (len >= 2 && ops[node+2].ival) {
- X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X fixtab(str,++level);
- X str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
- X str_free(fstr);
- X addsemi(str);
- X fixtab(str,--level);
- X str_cat(str,"}\n");
- X tab(str,level);
- X if (len >= 3) {
- X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X break;
- X default:
- X def:
- X if (len) {
- X if (len > 5)
- X fatal("Garbage length in walk");
- X str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X for (i = 2; i<= len; i++) {
- X str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
- X str_free(fstr);
- X }
- X }
- X else {
- X str = Nullstr;
- X }
- X break;
- X }
- X if (!str)
- X str = str_new(0);
- X
- X if (useval && prec < minprec) { /* need parens? */
- X fstr = str_new(str->str_cur+2);
- X str_nset(fstr,"(",1);
- X str_scat(fstr,str);
- X str_ncat(fstr,")",1);
- X str_free(str);
- X str = fstr;
- X }
- X
- X *numericptr = numeric;
- X#ifdef DEBUGGING
- X if (debug & 4) {
- X printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
- X for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
- X if (*t == '\n')
- X printf("\\n");
- X else if (*t == '\t')
- X printf("\\t");
- X else
- X putchar(*t);
- X putchar('\n');
- X }
- X#endif
- X return str;
- X}
- X
- Xtab(str,lvl)
- Xregister STR *str;
- Xregister int lvl;
- X{
- X while (lvl > 1) {
- X str_cat(str,"\t");
- X lvl -= 2;
- X }
- X if (lvl)
- X str_cat(str," ");
- X}
- X
- Xfixtab(str,lvl)
- Xregister STR *str;
- Xregister int lvl;
- X{
- X register char *s;
- X
- X /* strip trailing white space */
- X
- X s = str->str_ptr+str->str_cur - 1;
- X while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
- X s--;
- X s[1] = '\0';
- X str->str_cur = s + 1 - str->str_ptr;
- X if (s >= str->str_ptr && *s != '\n')
- X str_cat(str,"\n");
- X
- X tab(str,lvl);
- X}
- X
- Xaddsemi(str)
- Xregister STR *str;
- X{
- X register char *s;
- X
- X s = str->str_ptr+str->str_cur - 1;
- X while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
- X s--;
- X if (s >= str->str_ptr && *s != ';' && *s != '}')
- X str_cat(str,";");
- X}
- X
- Xemit_split(str,level)
- Xregister STR *str;
- Xint level;
- X{
- X register int i;
- X
- X if (split_to_array)
- X str_cat(str,"@Fld");
- X else {
- X str_cat(str,"(");
- X for (i = 1; i < maxfld; i++) {
- X if (i <= arymax)
- X sprintf(tokenbuf,"$%s,",nameary[i]);
- X else
- X sprintf(tokenbuf,"$Fld%d,",i);
- X str_cat(str,tokenbuf);
- X }
- X if (maxfld <= arymax)
- X sprintf(tokenbuf,"$%s)",nameary[maxfld]);
- X else
- X sprintf(tokenbuf,"$Fld%d)",maxfld);
- X str_cat(str,tokenbuf);
- X }
- X if (const_FS) {
- X sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
- X str_cat(str,tokenbuf);
- X }
- X else if (saw_FS)
- X str_cat(str," = split($FS, $_, 9999);\n");
- X else
- X str_cat(str," = split(' ', $_, 9999);\n");
- X tab(str,level);
- X}
- X
- Xprewalk(numit,level,node,numericptr)
- Xint numit;
- Xint level;
- Xregister int node;
- Xint *numericptr;
- X{
- X register int len;
- X register int type;
- X register int i;
- X char *t;
- X char *d, *s;
- X int numarg;
- X int numeric = FALSE;
- X STR *tmpstr;
- X STR *tmp2str;
- X
- X if (!node) {
- X *numericptr = 0;
- X return 0;
- X }
- X type = ops[node].ival;
- X len = type >> 8;
- X type &= 255;
- X switch (type) {
- X case OPROG:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X if (ops[node+2].ival) {
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X ++level;
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X --level;
- X if (ops[node+3].ival) {
- X prewalk(0,level,ops[node+4].ival,&numarg);
- X }
- X break;
- X case OHUNKS:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X if (len == 3) {
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X }
- X break;
- X case ORANGE:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X break;
- X case OPAT:
- X goto def;
- X case OREGEX:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OHUNK:
- X if (len == 1) {
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X }
- X else {
- X i = prewalk(0,level,ops[node+1].ival,&numarg);
- X if (i) {
- X ++level;
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X --level;
- X }
- X else {
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X }
- X break;
- X case OPPAREN:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OPANDAND:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OPOROR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OPNOT:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OCPAREN:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric |= numarg;
- X break;
- X case OCANDAND:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OCOROR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OCNOT:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case ORELOP:
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X numeric |= numarg;
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X numeric |= numarg;
- X numeric = 1;
- X break;
- X case ORPAREN:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric |= numarg;
- X break;
- X case OMATCHOP:
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X numeric = 1;
- X break;
- X case OMPAREN:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric |= numarg;
- X break;
- X case OCONCAT:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OASSIGN:
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
- X numericize(ops[node+2].ival);
- X if (!numarg)
- X numericize(ops[node+3].ival);
- X }
- X numeric |= numarg;
- X break;
- X case OADD:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OSUBTRACT:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OMULT:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case ODIV:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPOW:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OMOD:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPOSTINCR:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPOSTDECR:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPREINCR:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPREDECR:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OUMINUS:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OUPLUS:
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OPAREN:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric |= numarg;
- X break;
- X case OGETLINE:
- X break;
- X case OSPRINTF:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OSUBSTR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(1,level,ops[node+2].ival,&numarg);
- X if (len == 3) {
- X prewalk(1,level,ops[node+3].ival,&numarg);
- X }
- X break;
- X case OSTRING:
- X break;
- X case OSPLIT:
- X numeric = 1;
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X if (len == 3)
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OINDEX:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OMATCH:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X numeric = 1;
- X break;
- X case OUSERDEF:
- X subretnum = FALSE;
- X --level;
- X tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
- X ++level;
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+4].ival,&numarg);
- X prewalk(0,level,ops[node+5].ival,&numarg);
- X --level;
- X str_cat(tmpstr,"(");
- X tmp2str = str_new(0);
- X if (subretnum || numarg)
- X str_set(tmp2str,"1");
- X hstore(symtab,tmpstr->str_ptr,tmp2str);
- X str_free(tmpstr);
- X level++;
- X break;
- X case ORETURN:
- X if (len > 0) {
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X if (numarg)
- X subretnum = TRUE;
- X }
- X break;
- X case OUSERFUN:
- X tmp2str = str_new(0);
- X str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
- X fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
- X str_free(tmpstr);
- X str_cat(tmp2str,"(");
- X tmpstr = hfetch(symtab,tmp2str->str_ptr);
- X if (tmpstr && tmpstr->str_ptr)
- X numeric |= atoi(tmpstr->str_ptr);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X str_free(tmp2str);
- X break;
- X case OGSUB:
- X case OSUB:
- X if (len >= 3)
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case ONUM:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X numeric = 1;
- X break;
- X case OSTR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case ODEFINED:
- X case ODELETE:
- X case OSTAR:
- X case OVAR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X if (len == 1) {
- X if (numit)
- X numericize(node);
- X }
- X else {
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X break;
- X case OFLD:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OVFLD:
- X i = ops[node+1].ival;
- X prewalk(0,level,i,&numarg);
- X break;
- X case OJUNK:
- X goto def;
- X case OSNEWLINE:
- X break;
- X case ONEWLINE:
- X break;
- X case OSCOMMENT:
- X break;
- X case OCOMMENT:
- X break;
- X case OCOMMA:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X break;
- X case OSEMICOLON:
- X break;
- X case OSTATES:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OSTATE:
- X if (len >= 1) {
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X if (len >= 2) {
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X }
- X break;
- X case OCLOSE:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OPRINTF:
- X case OPRINT:
- X if (len == 3) { /* output redirection */
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
- X break;
- X case ORAND:
- X break;
- X case OSRAND:
- X goto maybe0;
- X case OATAN2:
- X goto maybe0;
- X case OSIN:
- X goto maybe0;
- X case OCOS:
- X goto maybe0;
- X case OSYSTEM:
- X goto maybe0;
- X case OLENGTH:
- X goto maybe0;
- X case OLOG:
- X goto maybe0;
- X case OEXP:
- X goto maybe0;
- X case OSQRT:
- X goto maybe0;
- X case OINT:
- X maybe0:
- X numeric = 1;
- X if (len > 0)
- X prewalk(type != OLENGTH && type != OSYSTEM,
- X level,ops[node+1].ival,&numarg);
- X break;
- X case OBREAK:
- X break;
- X case ONEXT:
- X break;
- X case OEXIT:
- X if (len == 1) {
- X prewalk(1,level,ops[node+1].ival,&numarg);
- X }
- X break;
- X case OCONTINUE:
- X break;
- X case OREDIR:
- X goto def;
- X case OIF:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X if (len == 3) {
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X }
- X break;
- X case OWHILE:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X break;
- X case OFOR:
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+3].ival,&numarg);
- X prewalk(0,level,ops[node+4].ival,&numarg);
- X break;
- X case OFORIN:
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X break;
- X case OBLOCK:
- X if (len == 2) {
- X prewalk(0,level,ops[node+2].ival,&numarg);
- X }
- X ++level;
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X --level;
- X break;
- X default:
- X def:
- X if (len) {
- X if (len > 5)
- X fatal("Garbage length in prewalk");
- X prewalk(0,level,ops[node+1].ival,&numarg);
- X for (i = 2; i<= len; i++) {
- X prewalk(0,level,ops[node+i].ival,&numarg);
- X }
- X }
- X break;
- X }
- X *numericptr = numeric;
- X return 1;
- X}
- X
- Xnumericize(node)
- Xregister int node;
- X{
- X register int len;
- X register int type;
- X register int i;
- X STR *tmpstr;
- X STR *tmp2str;
- X int numarg;
- X
- X type = ops[node].ival;
- X len = type >> 8;
- X type &= 255;
- X if (type == OVAR && len == 1) {
- X tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
- X tmp2str = str_make("1");
- X hstore(symtab,tmpstr->str_ptr,tmp2str);
- X }
- X}
- !STUFFY!FUNK!
- echo " "
- echo "End of kit 9 (of 36)"
- cat /dev/null >kit9isdone
- run=''
- config=''
- for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36; do
- if test -f kit${iskit}isdone; then
- run="$run $iskit"
- else
- todo="$todo $iskit"
- fi
- done
- case $todo in
- '')
- echo "You have run all your kits. Please read README and then type Configure."
- for combo in *:AA; do
- if test -f "$combo"; then
- realfile=`basename $combo :AA`
- cat $realfile:[A-Z][A-Z] >$realfile
- rm -rf $realfile:[A-Z][A-Z]
- fi
- done
- rm -rf kit*isdone
- chmod 755 Configure
- ;;
- *) echo "You have run$run."
- echo "You still need to run$todo."
- ;;
- esac
- : Someone might mail this, so...
- exit
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-