REPOST v15i096: Perl, release 2, Part07/15
Rich Salz
rsalz at uunet.uu.net
Thu Jul 14 22:26:45 AEST 1988
Submitted-by: Larry Wall <lwall at jpl-devvax.jpl.nasa.gov>
Posting-number: Volume 15, Issue 96
Archive-name: perl2/part07
#! /bin/sh
# Make a new directory for the perl sources, cd to it, and run kits 1
# thru 15 through sh. When all 15 kits have been run, read README.
echo "This is perl 2.0 kit 7 (of 15). If kit 7 is complete, the line"
echo '"'"End of kit 7 (of 15)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
mkdir t x2p 2>/dev/null
echo Extracting x2p/walk.c
sed >x2p/walk.c <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: walk.c,v 2.0 88/06/05 00:16:12 root Exp $
X *
X * $Log: walk.c,v $
X * Revision 2.0 88/06/05 00:16:12 root
X * Baseline version 2.0.
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;
Xint maxtmp = 0;
Xchar *lparen;
Xchar *rparen;
X
XSTR *
Xwalk(useval,level,node,numericptr)
Xint useval;
Xint level;
Xregister int node;
Xint *numericptr;
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 char *t;
X char *d, *s;
X int numarg;
X int numeric = FALSE;
X STR *fstr;
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 str = walk(0,level,ops[node+1].ival,&numarg);
X opens = str_new(0);
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 (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));
X str_free(fstr);
X str_cat(str,"\n\n");
X }
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=walk(0,level,ops[node+3].ival,&numarg));
X str_free(fstr);
X fixtab(str,--level);
X str_cat(str,"}\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));
X str_free(fstr);
X str_cat(str,"\n");
X }
X if (exitval)
X str_cat(str,"exit ExitValue;\n");
X if (saw_getline) {
X str_cat(str,"\nsub Getline {\n $_ = <>;\n");
X tab(str,++level);
X if (do_chop) {
X str_cat(str,"chop;\t# strip record separator\n");
X tab(str,level);
X }
X if (do_split)
X emit_split(str,level);
X fixtab(str,--level);
X str_cat(str,"}\n");
X }
X if (do_fancy_opens) {
X str_cat(str,"\n\
Xsub Pick {\n\
X ($name) = @_;\n\
X $fh = $opened{$name};\n\
X if (!$fh) {\n\
X $nextfh == 0 && open(fh_0,$name);\n\
X $nextfh == 1 && open(fh_1,$name);\n\
X $nextfh == 2 && open(fh_2,$name);\n\
X $nextfh == 3 && open(fh_3,$name);\n\
X $nextfh == 4 && open(fh_4,$name);\n\
X $nextfh == 5 && open(fh_5,$name);\n\
X $nextfh == 6 && open(fh_6,$name);\n\
X $nextfh == 7 && open(fh_7,$name);\n\
X $nextfh == 8 && open(fh_8,$name);\n\
X $nextfh == 9 && open(fh_9,$name);\n\
X $fh = $opened{$name} = 'fh_' . $nextfh++;\n\
X }\n\
X select($fh);\n\
X}\n\
X");
X }
X break;
X case OHUNKS:
X str = walk(0,level,ops[node+1].ival,&numarg);
X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X if (len == 3) {
X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
X str_free(fstr);
X }
X else {
X }
X break;
X case ORANGE:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," .. ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
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);
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);
X str_cat(str," if ");
X str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X str_cat(str,";");
X }
X else {
X tmpstr = walk(0,level,ops[node+1].ival,&numarg);
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));
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);
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));
X str_free(fstr);
X str_cat(str,")");
X break;
X case OPANDAND:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," && ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OPOROR:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," || ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OPNOT:
X str = str_new(0);
X str_set(str,"!");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
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));
X str_free(fstr);
X numeric |= numarg;
X str_cat(str,")");
X break;
X case OCANDAND:
X str = walk(1,level,ops[node+1].ival,&numarg);
X numeric = 1;
X str_cat(str," && ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OCOROR:
X str = walk(1,level,ops[node+1].ival,&numarg);
X numeric = 1;
X str_cat(str," || ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OCNOT:
X str = str_new(0);
X str_set(str,"!");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case ORELOP:
X str = walk(1,level,ops[node+2].ival,&numarg);
X numeric |= numarg;
X tmpstr = walk(0,level,ops[node+1].ival,&numarg);
X tmp2str = walk(1,level,ops[node+3].ival,&numarg);
X numeric |= numarg;
X if (!numeric) {
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));
X str_free(fstr);
X numeric |= numarg;
X str_cat(str,")");
X break;
X case OMATCHOP:
X str = walk(1,level,ops[node+2].ival,&numarg);
X str_cat(str," ");
X tmpstr = walk(0,level,ops[node+1].ival,&numarg);
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));
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,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X numeric |= numarg;
X str_cat(str,")");
X break;
X case OCONCAT:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," . ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OASSIGN:
X str = walk(0,level,ops[node+2].ival,&numarg);
X str_cat(str," ");
X tmpstr = walk(0,level,ops[node+1].ival,&numarg);
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));
X str_free(fstr);
X numeric |= numarg;
X break;
X case OADD:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," + ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OSUB:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," - ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OMULT:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," * ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case ODIV:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," / ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OMOD:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str," % ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OPOSTINCR:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str,"++");
X numeric = 1;
X break;
X case OPOSTDECR:
X str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str,"--");
X numeric = 1;
X break;
X case OPREINCR:
X str = str_new(0);
X str_set(str,"++");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OPREDECR:
X str = str_new(0);
X str_set(str,"--");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X numeric = 1;
X break;
X case OUMINUS:
X str = str_new(0);
X str_set(str,"-");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
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,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X str_cat(str,")");
X numeric |= numarg;
X break;
X case OGETLINE:
X str = str_new(0);
X str_set(str,"do Getline()");
X saw_getline = TRUE;
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));
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));
X str_free(fstr);
X str_cat(str,", ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
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));
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);
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);
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
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));
X str_free(fstr);
X str_cat(str,")");
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));
X str_free(fstr);
X str_cat(str,", ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X str_cat(str,")");
X numeric = 1;
X break;
X case ONUM:
X str = walk(1,level,ops[node+1].ival,&numarg);
X numeric = 1;
X break;
X case OSTR:
X tmpstr = walk(1,level,ops[node+1].ival,&numarg);
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':
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 OVAR:
X str = str_new(0);
X str_set(str,"$");
X str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
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,"$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 }
X else {
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));
X str_free(fstr);
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 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));
X str_free(fstr);
X str_cat(str,"]");
X }
X else {
X i = atoi(walk(1,level,ops[node+1].ival,&numarg)->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);
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);
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);
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 str = walk(1,level,ops[node+1].ival,&numarg);
X str_cat(str,", ");
X str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
X str_free(fstr);
X break;
X case OSEMICOLON:
X str = str_new(1);
X str_set(str,"; ");
X break;
X case OSTATES:
X str = walk(0,level,ops[node+1].ival,&numarg);
X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
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));
X str_free(fstr);
X if (len >= 2) {
X tmpstr = walk(0,level,ops[node+2].ival,&numarg);
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 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);
X tmp2str = walk(1,level,ops[node+2].ival,&numarg);
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 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 str_free(tmpstr);
X str_free(tmp2str);
X safefree(s);
X safefree(d);
X }
X else {
X sprintf(tokenbuf,"do Pick('%s' . (%s)) &&\n",
X tmp2str->str_ptr, tmpstr->str_ptr);
X str_cat(str,tokenbuf);
X tab(str,level+1);
X *tokenbuf = '\0';
X str_free(tmpstr);
X str_free(tmp2str);
X lparen = "(";
X rparen = ")";
X }
X }
X else
X strcpy(tokenbuf,"stdout");
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);
X if (!*tmpstr->str_ptr && lval_field) {
X t = saw_OFS ? "$," : "' '";
X if (split_to_array) {
X sprintf(tokenbuf,"join(%s, at 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 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);
X else
X tmpstr = str_new(0);;
X if (!*tmpstr->str_ptr) {
X if (lval_field) {
X t = saw_OFS ? "$," : "' '";
X if (split_to_array) {
X sprintf(tokenbuf,"join(%s, at 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 str_set(str,"exit");
X if (len == 1) {
X str_cat(str," ");
X exitval = TRUE;
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X }
X }
X else {
X if (len == 1) {
X str_set(str,"ExitValue = ");
X exitval = TRUE;
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
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));
X str_free(fstr);
X str_cat(str,") ");
X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
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));
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));
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));
X str_free(fstr);
X str_cat(str,") ");
X str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
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));
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);
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));
X str_free(fstr);
X str_cat(str,") ");
X str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
X str_free(fstr);
X break;
X case OFORIN:
X tmpstr=walk(0,level,ops[node+2].ival,&numarg);
X str = str_new(0);
X str_sset(str,tmpstr);
X str_cat(str,"[]");
X tmp2str = hfetch(symtab,str->str_ptr);
X if (tmp2str && atoi(tmp2str->str_ptr)) {
X fstr=walk(1,level,ops[node+1].ival,&numarg);
X sprintf(tokenbuf,
X "foreach $%s (@%s) ",
X fstr->str_ptr,
X tmpstr->str_ptr);
X str_set(str,tokenbuf);
X str_free(fstr);
X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
X str_free(fstr);
X }
X else {
X str_set(str,"while (($");
X str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
X str_free(fstr);
X str_cat(str,",$junkval) = each(");
X str_scat(str,tmpstr);
X str_cat(str,")) ");
X str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
X str_free(fstr);
X }
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));
X str_free(fstr);
X }
X fixtab(str,++level);
X str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
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));
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);
X for (i = 2; i<= len; i++) {
X str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg));
X str_free(fstr);
X }
X }
X else {
X str = Nullstr;
X }
X break;
X }
X if (!str)
X str = str_new(0);
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'))
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]/);\n",const_FS);
X str_cat(str,tokenbuf);
X }
X else if (saw_FS)
X str_cat(str," = split($FS);\n");
X else
X str_cat(str," = split(' ');\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
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 OSUB:
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 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 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 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 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 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 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,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 prewalk(0,level,ops[node+3].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);
X tmp2str = str_make("1");
X hstore(symtab,tmpstr->str_ptr,tmp2str);
X }
X}
!STUFFY!FUNK!
echo Extracting str.c
sed >str.c <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: str.c,v 2.0 88/06/05 00:11:07 root Exp $
X *
X * $Log: str.c,v $
X * Revision 2.0 88/06/05 00:11:07 root
X * Baseline version 2.0.
X *
X */
X
X#include "EXTERN.h"
X#include "perl.h"
X
Xstr_reset(s)
Xregister char *s;
X{
X register STAB *stab;
X register STR *str;
X register int i;
X register int max;
X register SPAT *spat;
X
X if (!*s) { /* reset ?? searches */
X for (spat = spat_root; spat != Nullspat; spat = spat->spat_next) {
X spat->spat_flags &= ~SPAT_USED;
X }
X return;
X }
X
X /* reset variables */
X
X while (*s) {
X i = *s;
X if (s[1] == '-') {
X s += 2;
X }
X max = *s++;
X for ( ; i <= max; i++) {
X for (stab = stab_index[i]; stab; stab = stab->stab_next) {
X str = stab->stab_val;
X str->str_cur = 0;
X str->str_nok = 0;
X if (str->str_ptr != Nullch)
X str->str_ptr[0] = '\0';
X if (stab->stab_array) {
X aclear(stab->stab_array);
X }
X if (stab->stab_hash) {
X hclear(stab->stab_hash);
X }
X }
X }
X }
X}
X
Xstr_numset(str,num)
Xregister STR *str;
Xdouble num;
X{
X str->str_nval = num;
X str->str_pok = 0; /* invalidate pointer */
X str->str_nok = 1; /* validate number */
X}
X
Xextern int errno;
X
Xchar *
Xstr_2ptr(str)
Xregister STR *str;
X{
X register char *s;
X int olderrno;
X
X if (!str)
X return "";
X GROWSTR(&(str->str_ptr), &(str->str_len), 24);
X s = str->str_ptr;
X if (str->str_nok) {
X olderrno = errno; /* some Xenix systems wipe out errno here */
X#if defined(scs) && defined(ns32000)
X gcvt(str->str_nval,20,s);
X#else
X#ifdef apollo
X if (str->str_nval == 0.0)
X strcpy(s,"0");
X else
X#endif /*apollo*/
X sprintf(s,"%.20g",str->str_nval);
X#endif /*scs*/
X errno = olderrno;
X while (*s) s++;
X }
X else if (dowarn)
X warn("Use of uninitialized variable");
X *s = '\0';
X str->str_cur = s - str->str_ptr;
X str->str_pok = 1;
X#ifdef DEBUGGING
X if (debug & 32)
X fprintf(stderr,"0x%lx ptr(%s)\n",str,str->str_ptr);
X#endif
X return str->str_ptr;
X}
X
Xdouble
Xstr_2num(str)
Xregister STR *str;
X{
X if (!str)
X return 0.0;
X if (str->str_len && str->str_pok)
X str->str_nval = atof(str->str_ptr);
X else {
X if (dowarn)
X fprintf(stderr,"Use of uninitialized variable in %s line %ld.\n",
X filename,(long)line);
X str->str_nval = 0.0;
X }
X str->str_nok = 1;
X#ifdef DEBUGGING
X if (debug & 32)
X fprintf(stderr,"0x%lx num(%g)\n",str,str->str_nval);
X#endif
X return str->str_nval;
X}
X
Xstr_sset(dstr,sstr)
XSTR *dstr;
Xregister STR *sstr;
X{
X if (!sstr)
X str_nset(dstr,No,0);
X else if (sstr->str_nok)
X str_numset(dstr,sstr->str_nval);
X else if (sstr->str_pok)
X str_nset(dstr,sstr->str_ptr,sstr->str_cur);
X else
X str_nset(dstr,"",0);
X}
X
Xstr_nset(str,ptr,len)
Xregister STR *str;
Xregister char *ptr;
Xregister int len;
X{
X GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
X bcopy(ptr,str->str_ptr,len);
X str->str_cur = len;
X *(str->str_ptr+str->str_cur) = '\0';
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X}
X
Xstr_set(str,ptr)
Xregister STR *str;
Xregister char *ptr;
X{
X register int len;
X
X if (!ptr)
X ptr = "";
X len = strlen(ptr);
X GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
X bcopy(ptr,str->str_ptr,len+1);
X str->str_cur = len;
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X}
X
Xstr_chop(str,ptr) /* like set but assuming ptr is in str */
Xregister STR *str;
Xregister char *ptr;
X{
X if (!(str->str_pok))
X str_2ptr(str);
X str->str_cur -= (ptr - str->str_ptr);
X bcopy(ptr,str->str_ptr, str->str_cur + 1);
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X}
X
Xstr_ncat(str,ptr,len)
Xregister STR *str;
Xregister char *ptr;
Xregister int len;
X{
X if (!(str->str_pok))
X str_2ptr(str);
X GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
X bcopy(ptr,str->str_ptr+str->str_cur,len);
X str->str_cur += len;
X *(str->str_ptr+str->str_cur) = '\0';
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X}
X
Xstr_scat(dstr,sstr)
XSTR *dstr;
Xregister STR *sstr;
X{
X if (!sstr)
X return;
X if (!(sstr->str_pok))
X str_2ptr(sstr);
X if (sstr)
X str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
X}
X
Xstr_cat(str,ptr)
Xregister STR *str;
Xregister char *ptr;
X{
X register int len;
X
X if (!ptr)
X return;
X if (!(str->str_pok))
X str_2ptr(str);
X len = strlen(ptr);
X GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
X bcopy(ptr,str->str_ptr+str->str_cur,len+1);
X str->str_cur += len;
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X}
X
Xchar *
Xstr_append_till(str,from,delim,keeplist)
Xregister STR *str;
Xregister char *from;
Xregister int delim;
Xchar *keeplist;
X{
X register char *to;
X register int len;
X
X if (!from)
X return Nullch;
X len = strlen(from);
X GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X to = str->str_ptr+str->str_cur;
X for (; *from; from++,to++) {
X if (*from == '\\' && from[1] && delim != '\\') {
X if (!keeplist) {
X if (from[1] == delim || from[1] == '\\')
X from++;
X else
X *to++ = *from++;
X }
X else if (index(keeplist,from[1]))
X *to++ = *from++;
X else
X from++;
X }
X else if (*from == delim)
X break;
X *to = *from;
X }
X *to = '\0';
X str->str_cur = to - str->str_ptr;
X return from;
X}
X
XSTR *
Xstr_new(len)
Xint len;
X{
X register STR *str;
X
X if (freestrroot) {
X str = freestrroot;
X freestrroot = str->str_link.str_next;
X str->str_link.str_magic = Nullstab;
X }
X else {
X str = (STR *) safemalloc(sizeof(STR));
X bzero((char*)str,sizeof(STR));
X }
X if (len)
X GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
X return str;
X}
X
Xvoid
Xstr_grow(str,len)
Xregister STR *str;
Xint len;
X{
X if (len && str)
X GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
X}
X
X/* make str point to what nstr did */
X
Xvoid
Xstr_replace(str,nstr)
Xregister STR *str;
Xregister STR *nstr;
X{
X safefree(str->str_ptr);
X str->str_ptr = nstr->str_ptr;
X str->str_len = nstr->str_len;
X str->str_cur = nstr->str_cur;
X str->str_pok = nstr->str_pok;
X if (str->str_nok = nstr->str_nok)
X str->str_nval = nstr->str_nval;
X safefree((char*)nstr);
X}
X
Xvoid
Xstr_free(str)
Xregister STR *str;
X{
X if (!str)
X return;
X if (str->str_len)
X str->str_ptr[0] = '\0';
X str->str_cur = 0;
X str->str_nok = 0;
X str->str_pok = 0;
X str->str_link.str_next = freestrroot;
X freestrroot = str;
X}
X
Xstr_len(str)
Xregister STR *str;
X{
X if (!str)
X return 0;
X if (!(str->str_pok))
X str_2ptr(str);
X if (str->str_len)
X return str->str_cur;
X else
X return 0;
X}
X
Xchar *
Xstr_gets(str,fp)
Xregister STR *str;
Xregister FILE *fp;
X{
X#ifdef STDSTDIO /* Here is some breathtakingly efficient cheating */
X
X register char *bp; /* we're going to steal some values */
X register int cnt; /* from the stdio struct and put EVERYTHING */
X register STDCHAR *ptr; /* in the innermost loop into registers */
X register char newline = record_separator;/* (assuming >= 6 registers) */
X int i;
X int bpx;
X int obpx;
X register int get_paragraph;
X register char *oldbp;
X
X if (get_paragraph = !newline) { /* yes, that's an assignment */
X newline = '\n';
X oldbp = Nullch; /* remember last \n position (none) */
X }
X cnt = fp->_cnt; /* get count into register */
X str->str_nok = 0; /* invalidate number */
X str->str_pok = 1; /* validate pointer */
X if (str->str_len <= cnt) /* make sure we have the room */
X GROWSTR(&(str->str_ptr), &(str->str_len), cnt+1);
X bp = str->str_ptr; /* move these two too to registers */
X ptr = fp->_ptr;
X for (;;) {
X screamer:
X while (--cnt >= 0) { /* this */ /* eat */
X if ((*bp++ = *ptr++) == newline) /* really */ /* dust */
X goto thats_all_folks; /* screams */ /* sed :-) */
X }
X
X fp->_cnt = cnt; /* deregisterize cnt and ptr */
X fp->_ptr = ptr;
X i = _filbuf(fp); /* get more characters */
X cnt = fp->_cnt;
X ptr = fp->_ptr; /* reregisterize cnt and ptr */
X
X bpx = bp - str->str_ptr; /* prepare for possible relocation */
X if (get_paragraph && oldbp)
X obpx = oldbp - str->str_ptr;
X GROWSTR(&(str->str_ptr), &(str->str_len), bpx + cnt + 2);
X bp = str->str_ptr + bpx; /* reconstitute our pointer */
X if (get_paragraph && oldbp)
X oldbp = str->str_ptr + obpx;
X
X if (i == newline) { /* all done for now? */
X *bp++ = i;
X goto thats_all_folks;
X }
X else if (i == EOF) /* all done for ever? */
X goto thats_really_all_folks;
X *bp++ = i; /* now go back to screaming loop */
X }
X
Xthats_all_folks:
X if (get_paragraph && bp - 1 != oldbp) {
X oldbp = bp; /* remember where this newline was */
X goto screamer; /* and go back to the fray */
X }
Xthats_really_all_folks:
X fp->_cnt = cnt; /* put these back or we're in trouble */
X fp->_ptr = ptr;
X *bp = '\0';
X str->str_cur = bp - str->str_ptr; /* set length */
X
X#else /* !STDSTDIO */ /* The big, slow, and stupid way */
X
X static char buf[4192];
X
X if (fgets(buf, sizeof buf, fp) != Nullch)
X str_set(str, buf);
X else
X str_set(str, No);
X
X#endif /* STDSTDIO */
X
X return str->str_cur ? str->str_ptr : Nullch;
X}
X
X
XSTR *
Xinterp(str,s)
Xregister STR *str;
Xregister char *s;
X{
X register char *t = s;
X char *envsave = envname;
X envname = Nullch;
X
X str_set(str,"");
X while (*s) {
X if (*s == '\\' && s[1] == '\\') {
X str_ncat(str, t, s++ - t);
X t = s++;
X }
X else if (*s == '\\' && s[1] == '$') {
X str_ncat(str, t, s++ - t);
X t = s++;
X }
X else if (*s == '$' && s[1] && s[1] != '|') {
X str_ncat(str,t,s-t);
X s = scanreg(s,tokenbuf);
X str_cat(str,reg_get(tokenbuf));
X t = s;
X }
X else
X s++;
X }
X envname = envsave;
X str_ncat(str,t,s-t);
X return str;
X}
X
Xvoid
Xstr_inc(str)
Xregister STR *str;
X{
X register char *d;
X
X if (!str)
X return;
X if (str->str_nok) {
X str->str_nval += 1.0;
X str->str_pok = 0;
X return;
X }
X if (!str->str_pok || !*str->str_ptr) {
X str->str_nval = 1.0;
X str->str_nok = 1;
X return;
X }
X d = str->str_ptr;
X while (isalpha(*d)) d++;
X while (isdigit(*d)) d++;
X if (*d) {
X str_numset(str,atof(str->str_ptr) + 1.0); /* punt */
X return;
X }
X d--;
X while (d >= str->str_ptr) {
X if (isdigit(*d)) {
X if (++*d <= '9')
X return;
X *(d--) = '0';
X }
X else {
X ++*d;
X if (isalpha(*d))
X return;
X *(d--) -= 'z' - 'a' + 1;
X }
X }
X /* oh,oh, the number grew */
X GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + 2);
X str->str_cur++;
X for (d = str->str_ptr + str->str_cur; d > str->str_ptr; d--)
X *d = d[-1];
X if (isdigit(d[1]))
X *d = '1';
X else
X *d = d[1];
X}
X
Xvoid
Xstr_dec(str)
Xregister STR *str;
X{
X if (!str)
X return;
X if (str->str_nok) {
X str->str_nval -= 1.0;
X str->str_pok = 0;
X return;
X }
X if (!str->str_pok) {
X str->str_nval = -1.0;
X str->str_nok = 1;
X return;
X }
X str_numset(str,atof(str->str_ptr) - 1.0);
X}
X
X/* make a string that will exist for the duration of the expression eval */
X
XSTR *
Xstr_static(oldstr)
XSTR *oldstr;
X{
X register STR *str = str_new(0);
X static long tmps_size = -1;
X
X str_sset(str,oldstr);
X if (++tmps_max > tmps_size) {
X tmps_size = tmps_max;
X if (!(tmps_size & 127)) {
X if (tmps_size)
X tmps_list = (STR**)saferealloc((char*)tmps_list,
X (MEM_SIZE)((tmps_size + 128) * sizeof(STR*)) );
X else
X tmps_list = (STR**)safemalloc(128 * sizeof(char*));
X }
X }
X tmps_list[tmps_max] = str;
X return str;
X}
X
XSTR *
Xstr_make(s)
Xchar *s;
X{
X register STR *str = str_new(0);
X
X str_set(str,s);
X return str;
X}
X
XSTR *
Xstr_nmake(n)
Xdouble n;
X{
X register STR *str = str_new(0);
X
X str_numset(str,n);
X return str;
X}
!STUFFY!FUNK!
echo Extracting t/op.split
sed >t/op.split <<'!STUFFY!FUNK!' -e 's/X//'
X#!./perl
X
X# $Header: op.split,v 2.0 88/06/05 00:14:37 root Exp $
X
Xprint "1..7\n";
X
X$FS = ':';
X
X$_ = 'a:b:c';
X
X($a,$b,$c) = split($FS,$_);
X
Xif (join(';',$a,$b,$c) eq 'a;b;c') {print "ok 1\n";} else {print "not ok 1\n";}
X
X at ary = split(/:b:/);
Xif (join("$_", at ary) eq 'aa:b:cc') {print "ok 2\n";} else {print "not ok 2\n";}
X
X$_ = "abc\n";
X at ary = split(//);
Xif (join(".", at ary) eq "a.b.c.\n") {print "ok 3\n";} else {print "not ok 3\n";}
X
X$_ = "a:b:c::::";
X at ary = split(/:/);
Xif (join(".", at ary) eq "a.b.c") {print "ok 4\n";} else {print "not ok 4\n";}
X
X$_ = join(':',split(' '," a b\tc \t d "));
Xif ($_ eq 'a:b:c:d') {print "ok 5\n";} else {print "not ok 5 #$_#\n";}
X
X$_ = join(':',split(/ */,"foo bar bie\tdoll"));
Xif ($_ eq "f:o:o:b:a:r:b:i:e:\t:d:o:l:l")
X {print "ok 6\n";} else {print "not ok 6\n";}
X
X$_ = join(':', 'foo', split(/ /,'a b c'), 'bar');
Xif ($_ eq "foo:a:b::c:bar") {print "ok 7\n";} else {print "not ok 7 $_\n";}
X
!STUFFY!FUNK!
echo ""
echo "End of kit 7 (of 15)"
cat /dev/null >kit7isdone
run=''
config=''
for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; 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."
chmod 755 Configure
;;
*) echo "You have run$run."
echo "You still need to run$todo."
;;
esac
: Someone might mail this, so...
exit
More information about the Comp.sources.unix
mailing list