From @uunet.uu.net:root@jpl-devvax.jpl.nasa.gov Sun Jun 5 04:26:05 1988 Received: from BBN.COM by pineapple.bbn.com id AA14491; Sun, 5 Jun 88 04:25:21 EDT Received: from uunet.uu.net by BBN.COM id aa22017; 5 Jun 88 4:25 EDT Received: from elroy.jpl.nasa.gov by uunet.UU.NET (5.54/1.14) id AA17222; Sun, 5 Jun 88 04:21:36 EDT Received: from devvax.Jpl.Nasa.Gov (jpl-devvax.jpl.nasa.gov) by elroy.Jpl.Nasa.Gov (4.0/SMI-3.2+DXR) id AA12968; Sun, 5 Jun 88 01:12:47 PDT Received: by devvax.Jpl.Nasa.Gov (5.51/4.7) id AA08257; Sun, 5 Jun 88 01:11:31 PDT Date: Sun, 5 Jun 88 01:11:31 PDT From: The Superuser Message-Id: <8806050811.AA08257@devvax.Jpl.Nasa.Gov> Apparently-To: rsalz@uunet.uu.net Status: R #! /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 9 (of 15). If kit 9 is complete, the line" echo '"'"End of kit 9 (of 15)"'" will echo at the end.' echo "" export PATH || (echo "You didn't use sh, you clunch." ; kill $$) mkdir x2p 2>/dev/null echo Extracting toke.c sed >toke.c <<'!STUFFY!FUNK!' -e 's/X//' X/* $Header: toke.c,v 2.0 88/06/05 00:11:16 root Exp $ X * X * $Log: toke.c,v $ X * Revision 2.0 88/06/05 00:11:16 root X * Baseline version 2.0. X * X */ X X#include "EXTERN.h" X#include "perl.h" X#include "perly.h" X X#define CLINE (cmdline = (line < cmdline ? line : cmdline)) X X#define RETURN(retval) return (bufptr = s,(int)retval) X#define OPERATOR(retval) return (expectterm = TRUE,bufptr = s,(int)retval) X#define TERM(retval) return (CLINE, expectterm = FALSE,bufptr = s,(int)retval) X#define LOOPX(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)LOOPEX) X#define UNI(f) return(yylval.ival = f,expectterm = TRUE,bufptr = s,(int)UNIOP) X#define FTST(f) return(yylval.ival=f,expectterm = TRUE,bufptr = s,(int)FILETEST) X#define FUN0(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC0) X#define FUN1(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC1) X#define FUN2(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC2) X#define FUN3(f) return(yylval.ival = f,expectterm = FALSE,bufptr = s,(int)FUNC3) X#define SFUN(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)STABFUN) X#define LFUN(f) return(yylval.ival=f,expectterm = FALSE,bufptr = s,(int)LVALFUN) X Xyylex() X{ X register char *s = bufptr; X register char *d; X register int tmp; X static bool in_format = FALSE; X static bool firstline = TRUE; X X retry: X#ifdef YYDEBUG X if (yydebug) X if (index(s,'\n')) X fprintf(stderr,"Tokener at %s",s); X else X fprintf(stderr,"Tokener at %s\n",s); X#endif X switch (*s) { X default: X fprintf(stderr, X "Unrecognized character %c in file %s line %ld--ignoring.\n", X *s++,filename,(long)line); X goto retry; X case 0: X s = str_get(linestr); X *s = '\0'; X if (firstline && (minus_n || minus_p)) { X firstline = FALSE; X str_set(linestr,"line: while (<>) {"); X if (minus_a) X str_cat(linestr,"@F=split(' ');"); X s = str_get(linestr); X goto retry; X } X if (!rsfp) X RETURN(0); X if (in_format) { X yylval.formval = load_format(); /* leaves . in buffer */ X in_format = FALSE; X s = str_get(linestr); X TERM(FORMLIST); X } X line++; X if ((s = str_gets(linestr, rsfp)) == Nullch) { X if (preprocess) X pclose(rsfp); X else if (rsfp != stdin) X fclose(rsfp); X rsfp = Nullfp; X if (minus_n || minus_p) { X str_set(linestr,minus_p ? "}continue{print;" : ""); X str_cat(linestr,"}"); X s = str_get(linestr); X goto retry; X } X s = str_get(linestr); X RETURN(0); X } X#ifdef DEBUG X else if (firstline) { X char *showinput(); X s = showinput(); X } X#endif X firstline = FALSE; X goto retry; X case ' ': case '\t': case '\f': X s++; X goto retry; X case '\n': X case '#': X if (preprocess && s == str_get(linestr) && X s[1] == ' ' && isdigit(s[2])) { X line = atoi(s+2)-1; X for (s += 2; isdigit(*s); s++) ; X while (*s && isspace(*s)) s++; X if (filename) X safefree(filename); X s[strlen(s)-1] = '\0'; /* wipe out newline */ X if (*s == '"') { X s++; X s[strlen(s)-1] = '\0'; /* wipe out trailing quote */ X } X if (*s) X filename = savestr(s); X else X filename = savestr(origfilename); X s = str_get(linestr); X } X if (in_eval) { X while (*s && *s != '\n') X s++; X if (*s) X s++; X line++; X } X else X *s = '\0'; X if (lex_newlines) X RETURN('\n'); X goto retry; X case '-': X if (s[1] && isalpha(s[1]) && !isalpha(s[2])) { X s++; X switch (*s++) { X case 'r': FTST(O_FTEREAD); X case 'w': FTST(O_FTEWRITE); X case 'x': FTST(O_FTEEXEC); X case 'o': FTST(O_FTEOWNED); X case 'R': FTST(O_FTRREAD); X case 'W': FTST(O_FTRWRITE); X case 'X': FTST(O_FTREXEC); X case 'O': FTST(O_FTROWNED); X case 'e': FTST(O_FTIS); X case 'z': FTST(O_FTZERO); X case 's': FTST(O_FTSIZE); X case 'f': FTST(O_FTFILE); X case 'd': FTST(O_FTDIR); X case 'l': FTST(O_FTLINK); X case 'p': FTST(O_FTPIPE); X case 'S': FTST(O_FTSOCK); X case 'u': FTST(O_FTSUID); X case 'g': FTST(O_FTSGID); X case 'k': FTST(O_FTSVTX); X case 'b': FTST(O_FTBLK); X case 'c': FTST(O_FTCHR); X case 't': FTST(O_FTTTY); X case 'T': FTST(O_FTTEXT); X case 'B': FTST(O_FTBINARY); X default: X s -= 2; X break; X } X } X /*FALL THROUGH*/ X case '+': X if (s[1] == *s) { X s++; X if (*s++ == '+') X RETURN(INC); X else X RETURN(DEC); X } X /* FALL THROUGH */ X case '*': X case '%': X case '^': X case '~': X case '(': X case ',': X case ':': X case '[': X tmp = *s++; X OPERATOR(tmp); X case '{': X tmp = *s++; X if (isspace(*s) || *s == '#') X cmdline = NOLINE; /* invalidate current command line number */ X OPERATOR(tmp); X case ';': X if (line < cmdline) X cmdline = line; X tmp = *s++; X OPERATOR(tmp); X case ')': X case ']': X tmp = *s++; X TERM(tmp); X case '}': X tmp = *s++; X for (d = s; *d == ' ' || *d == '\t'; d++) ; X if (*d == '\n' || *d == '#') X OPERATOR(tmp); /* block end */ X else X TERM(tmp); /* associative array end */ X case '&': X s++; X tmp = *s++; X if (tmp == '&') X OPERATOR(ANDAND); X s--; X OPERATOR('&'); X case '|': X s++; X tmp = *s++; X if (tmp == '|') X OPERATOR(OROR); X s--; X OPERATOR('|'); X case '=': X s++; X tmp = *s++; X if (tmp == '=') X OPERATOR(EQ); X if (tmp == '~') X OPERATOR(MATCH); X s--; X OPERATOR('='); X case '!': X s++; X tmp = *s++; X if (tmp == '=') X OPERATOR(NE); X if (tmp == '~') X OPERATOR(NMATCH); X s--; X OPERATOR('!'); X case '<': X if (expectterm) { X s = scanstr(s); X TERM(RSTRING); X } X s++; X tmp = *s++; X if (tmp == '<') X OPERATOR(LS); X if (tmp == '=') X OPERATOR(LE); X s--; X OPERATOR('<'); X case '>': X s++; X tmp = *s++; X if (tmp == '>') X OPERATOR(RS); X if (tmp == '=') X OPERATOR(GE); X s--; X OPERATOR('>'); X X#define SNARFWORD \ X d = tokenbuf; \ X while (isalpha(*s) || isdigit(*s) || *s == '_') \ X *d++ = *s++; \ X *d = '\0'; \ X d = tokenbuf; X X case '$': X if (s[1] == '#' && (isalpha(s[2]) || s[2] == '_')) { X s++; X s = scanreg(s,tokenbuf); X yylval.stabval = aadd(stabent(tokenbuf,TRUE)); X TERM(ARYLEN); X } X s = scanreg(s,tokenbuf); X yylval.stabval = stabent(tokenbuf,TRUE); X TERM(REG); X X case '@': X s = scanreg(s,tokenbuf); X yylval.stabval = aadd(stabent(tokenbuf,TRUE)); X TERM(ARY); X X case '/': /* may either be division or pattern */ X case '?': /* may either be conditional or pattern */ X if (expectterm) { X s = scanpat(s); X TERM(PATTERN); X } X tmp = *s++; X OPERATOR(tmp); X X case '.': X if (!expectterm || !isdigit(s[1])) { X s++; X tmp = *s++; X if (tmp == '.') X OPERATOR(DOTDOT); X s--; X OPERATOR('.'); X } X /* FALL THROUGH */ X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X case '\'': case '"': case '`': X s = scanstr(s); X TERM(RSTRING); X X case '_': X SNARFWORD; X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'a': case 'A': X SNARFWORD; X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'b': case 'B': X SNARFWORD; X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'c': case 'C': X SNARFWORD; X if (strEQ(d,"continue")) X OPERATOR(CONTINUE); X if (strEQ(d,"chdir")) X UNI(O_CHDIR); X if (strEQ(d,"close")) X OPERATOR(CLOSE); X if (strEQ(d,"crypt")) X FUN2(O_CRYPT); X if (strEQ(d,"chop")) X LFUN(O_CHOP); X if (strEQ(d,"chmod")) { X yylval.ival = O_CHMOD; X OPERATOR(LISTOP); X } X if (strEQ(d,"chown")) { X yylval.ival = O_CHOWN; X OPERATOR(LISTOP); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'd': case 'D': X SNARFWORD; X if (strEQ(d,"do")) X OPERATOR(DO); X if (strEQ(d,"die")) X UNI(O_DIE); X if (strEQ(d,"delete")) X OPERATOR(DELETE); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'e': case 'E': X SNARFWORD; X if (strEQ(d,"else")) X OPERATOR(ELSE); X if (strEQ(d,"elsif")) { X yylval.ival = line; X OPERATOR(ELSIF); X } X if (strEQ(d,"eq") || strEQ(d,"EQ")) X OPERATOR(SEQ); X if (strEQ(d,"exit")) X UNI(O_EXIT); X if (strEQ(d,"eval")) { X allstabs = TRUE; /* must initialize everything since */ X UNI(O_EVAL); /* we don't know what will be used */ X } X if (strEQ(d,"eof")) X TERM(FEOF); X if (strEQ(d,"exp")) X FUN1(O_EXP); X if (strEQ(d,"each")) X SFUN(O_EACH); X if (strEQ(d,"exec")) { X yylval.ival = O_EXEC; X OPERATOR(LISTOP); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'f': case 'F': X SNARFWORD; X if (strEQ(d,"for")) X OPERATOR(FOR); X if (strEQ(d,"foreach")) X OPERATOR(FOR); X if (strEQ(d,"format")) { X in_format = TRUE; X OPERATOR(FORMAT); X } X if (strEQ(d,"fork")) X FUN0(O_FORK); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'g': case 'G': X SNARFWORD; X if (strEQ(d,"gt") || strEQ(d,"GT")) X OPERATOR(SGT); X if (strEQ(d,"ge") || strEQ(d,"GE")) X OPERATOR(SGE); X if (strEQ(d,"goto")) X LOOPX(O_GOTO); X if (strEQ(d,"gmtime")) X FUN1(O_GMTIME); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'h': case 'H': X SNARFWORD; X if (strEQ(d,"hex")) X FUN1(O_HEX); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'i': case 'I': X SNARFWORD; X if (strEQ(d,"if")) { X yylval.ival = line; X OPERATOR(IF); X } X if (strEQ(d,"index")) X FUN2(O_INDEX); X if (strEQ(d,"int")) X FUN1(O_INT); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'j': case 'J': X SNARFWORD; X if (strEQ(d,"join")) X OPERATOR(JOIN); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'k': case 'K': X SNARFWORD; X if (strEQ(d,"keys")) X SFUN(O_KEYS); X if (strEQ(d,"kill")) { X yylval.ival = O_KILL; X OPERATOR(LISTOP); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'l': case 'L': X SNARFWORD; X if (strEQ(d,"last")) X LOOPX(O_LAST); X if (strEQ(d,"local")) X OPERATOR(LOCAL); X if (strEQ(d,"length")) X FUN1(O_LENGTH); X if (strEQ(d,"lt") || strEQ(d,"LT")) X OPERATOR(SLT); X if (strEQ(d,"le") || strEQ(d,"LE")) X OPERATOR(SLE); X if (strEQ(d,"localtime")) X FUN1(O_LOCALTIME); X if (strEQ(d,"log")) X FUN1(O_LOG); X if (strEQ(d,"link")) X FUN2(O_LINK); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'm': case 'M': X SNARFWORD; X if (strEQ(d,"m")) { X s = scanpat(s-1); X TERM(PATTERN); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'n': case 'N': X SNARFWORD; X if (strEQ(d,"next")) X LOOPX(O_NEXT); X if (strEQ(d,"ne") || strEQ(d,"NE")) X OPERATOR(SNE); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'o': case 'O': X SNARFWORD; X if (strEQ(d,"open")) X OPERATOR(OPEN); X if (strEQ(d,"ord")) X FUN1(O_ORD); X if (strEQ(d,"oct")) X FUN1(O_OCT); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'p': case 'P': X SNARFWORD; X if (strEQ(d,"print")) { X yylval.ival = O_PRINT; X OPERATOR(LISTOP); X } X if (strEQ(d,"printf")) { X yylval.ival = O_PRTF; X OPERATOR(LISTOP); X } X if (strEQ(d,"push")) { X yylval.ival = O_PUSH; X OPERATOR(PUSH); X } X if (strEQ(d,"pop")) X OPERATOR(POP); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'q': case 'Q': X SNARFWORD; X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'r': case 'R': X SNARFWORD; X if (strEQ(d,"reset")) X UNI(O_RESET); X if (strEQ(d,"redo")) X LOOPX(O_REDO); X if (strEQ(d,"rename")) X FUN2(O_RENAME); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 's': case 'S': X SNARFWORD; X if (strEQ(d,"s")) { X s = scansubst(s); X TERM(SUBST); X } X if (strEQ(d,"shift")) X TERM(SHIFT); X if (strEQ(d,"split")) X TERM(SPLIT); X if (strEQ(d,"substr")) X FUN3(O_SUBSTR); X if (strEQ(d,"sprintf")) X OPERATOR(SPRINTF); X if (strEQ(d,"sub")) X OPERATOR(SUB); X if (strEQ(d,"select")) X OPERATOR(SELECT); X if (strEQ(d,"seek")) X OPERATOR(SEEK); X if (strEQ(d,"stat")) X OPERATOR(STAT); X if (strEQ(d,"study")) { X sawstudy++; X LFUN(O_STUDY); X } X if (strEQ(d,"sqrt")) X FUN1(O_SQRT); X if (strEQ(d,"sleep")) X UNI(O_SLEEP); X if (strEQ(d,"system")) { X yylval.ival = O_SYSTEM; X OPERATOR(LISTOP); X } X if (strEQ(d,"symlink")) X FUN2(O_SYMLINK); X if (strEQ(d,"sort")) { X yylval.ival = O_SORT; X OPERATOR(LISTOP); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 't': case 'T': X SNARFWORD; X if (strEQ(d,"tr")) { X s = scantrans(s); X TERM(TRANS); X } X if (strEQ(d,"tell")) X TERM(TELL); X if (strEQ(d,"time")) X FUN0(O_TIME); X if (strEQ(d,"times")) X FUN0(O_TMS); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'u': case 'U': X SNARFWORD; X if (strEQ(d,"using")) X OPERATOR(USING); X if (strEQ(d,"until")) { X yylval.ival = line; X OPERATOR(UNTIL); X } X if (strEQ(d,"unless")) { X yylval.ival = line; X OPERATOR(UNLESS); X } X if (strEQ(d,"umask")) X FUN1(O_UMASK); X if (strEQ(d,"unshift")) { X yylval.ival = O_UNSHIFT; X OPERATOR(PUSH); X } X if (strEQ(d,"unlink")) { X yylval.ival = O_UNLINK; X OPERATOR(LISTOP); X } X if (strEQ(d,"utime")) { X yylval.ival = O_UTIME; X OPERATOR(LISTOP); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'v': case 'V': X SNARFWORD; X if (strEQ(d,"values")) X SFUN(O_VALUES); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'w': case 'W': X SNARFWORD; X if (strEQ(d,"write")) X TERM(WRITE); X if (strEQ(d,"while")) { X yylval.ival = line; X OPERATOR(WHILE); X } X if (strEQ(d,"wait")) X FUN0(O_WAIT); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'x': case 'X': X SNARFWORD; X if (!expectterm && strEQ(d,"x")) X OPERATOR('x'); X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'y': case 'Y': X SNARFWORD; X if (strEQ(d,"y")) { X s = scantrans(s); X TERM(TRANS); X } X yylval.cval = savestr(d); X OPERATOR(WORD); X case 'z': case 'Z': X SNARFWORD; X yylval.cval = savestr(d); X OPERATOR(WORD); X } X} X Xchar * Xscanreg(s,dest) Xregister char *s; Xchar *dest; X{ X register char *d; X X s++; X d = dest; X if (isdigit(*s)) { X while (isdigit(*s) || *s == '_') X *d++ = *s++; X } X else { X while (isalpha(*s) || isdigit(*s) || *s == '_') X *d++ = *s++; X } X *d = '\0'; X d = dest; X if (!*d) { X *d = *s++; X if (*d == '{') { X d = dest; X while (*s && *s != '}') X *d++ = *s++; X *d = '\0'; X d = dest; X if (*s) X s++; X } X else X d[1] = '\0'; X } X if (*d == '^' && !isspace(*s)) X *d = *s++ & 31; X return s; X} X XSTR * Xscanconst(string) Xchar *string; X{ X register STR *retstr; X register char *t; X register char *d; X X if (index(string,'|')) { X return Nullstr; X } X retstr = str_make(string); X t = str_get(retstr); X *(long*)&retstr->str_nval = 100; X for (d=t; *d; ) { X switch (*d) { X case '.': case '[': case '$': case '(': case ')': case '|': X *d = '\0'; X break; X case '\\': X if (index("wWbB0123456789sSdD",d[1])) { X *d = '\0'; X break; X } X strcpy(d,d+1); X switch(*d) { X case 'n': X *d = '\n'; X break; X case 't': X *d = '\t'; X break; X case 'f': X *d = '\f'; X break; X case 'r': X *d = '\r'; X break; X } X /* FALL THROUGH */ X default: X if (d[1] == '*' || d[1] == '+' || d[1] == '?') { X *d = '\0'; X break; X } X d++; X } X } X if (!*t) { X str_free(retstr); X return Nullstr; X } X retstr->str_cur = strlen(retstr->str_ptr); X return retstr; X} X Xchar * Xscanpat(s) Xregister char *s; X{ X register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT)); X register char *d; X X bzero((char *)spat, sizeof(SPAT)); X spat->spat_next = spat_root; /* link into spat list */ X spat_root = spat; X X switch (*s++) { X case 'm': X s++; X break; X case '/': X break; X case '?': X spat->spat_flags |= SPAT_ONCE; X break; X default: X fatal("panic: scanpat"); X } X s = cpytill(tokenbuf,s,s[-1]); X if (!*s) X fatal("Search pattern not terminated"); X s++; X if (*s == 'i') { X s++; X spat->spat_flags |= SPAT_FOLD; X } X for (d=tokenbuf; *d; d++) { X if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') { X register ARG *arg; X X spat->spat_runtime = arg = op_new(1); X arg->arg_type = O_ITEM; X arg[1].arg_type = A_DOUBLE; X arg[1].arg_ptr.arg_str = str_make(tokenbuf); X goto got_pat; /* skip compiling for now */ X } X } X if (!(spat->spat_flags & SPAT_FOLD)) { X if (*tokenbuf == '^') { X spat->spat_short = scanconst(tokenbuf+1); X if (spat->spat_short) { X spat->spat_slen = strlen(spat->spat_short->str_ptr); X if (spat->spat_slen == strlen(tokenbuf+1)) X spat->spat_flags |= SPAT_ALL; X } X } X else { X spat->spat_flags |= SPAT_SCANFIRST; X spat->spat_short = scanconst(tokenbuf); X if (spat->spat_short) { X spat->spat_slen = strlen(spat->spat_short->str_ptr); X if (spat->spat_slen == strlen(tokenbuf)) X spat->spat_flags |= SPAT_ALL; X } X } X } X spat->spat_regexp = regcomp(tokenbuf,spat->spat_flags & SPAT_FOLD,1); X hoistmust(spat); X got_pat: X yylval.arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat); X return s; X} X Xchar * Xscansubst(s) Xregister char *s; X{ X register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT)); X register char *d; X X bzero((char *)spat, sizeof(SPAT)); X spat->spat_next = spat_root; /* link into spat list */ X spat_root = spat; X X s = cpytill(tokenbuf,s+1,*s); X if (!*s) X fatal("Substitution pattern not terminated"); X for (d=tokenbuf; *d; d++) { X if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') { X register ARG *arg; X X spat->spat_runtime = arg = op_new(1); X arg->arg_type = O_ITEM; X arg[1].arg_type = A_DOUBLE; X arg[1].arg_ptr.arg_str = str_make(tokenbuf); X goto get_repl; /* skip compiling for now */ X } X } X if (*tokenbuf == '^') { X spat->spat_short = scanconst(tokenbuf+1); X if (spat->spat_short) X spat->spat_slen = strlen(spat->spat_short->str_ptr); X } X else { X spat->spat_flags |= SPAT_SCANFIRST; X spat->spat_short = scanconst(tokenbuf); X if (spat->spat_short) X spat->spat_slen = strlen(spat->spat_short->str_ptr); X } X d = savestr(tokenbuf); Xget_repl: X s = scanstr(s); X if (!*s) X fatal("Substitution replacement not terminated"); X spat->spat_repl = yylval.arg; X spat->spat_flags |= SPAT_ONCE; X while (*s == 'g' || *s == 'i') { X if (*s == 'g') { X s++; X spat->spat_flags &= ~SPAT_ONCE; X } X if (*s == 'i') { X s++; X spat->spat_flags |= SPAT_FOLD; X } X } X if (!spat->spat_runtime) { X spat->spat_regexp = regcomp(d, spat->spat_flags & SPAT_FOLD,1); X hoistmust(spat); X safefree(d); X } X if (spat->spat_flags & SPAT_FOLD) { /* Oops, disable optimization */ X str_free(spat->spat_short); X spat->spat_short = Nullstr; X spat->spat_slen = 0; X } X yylval.arg = make_match(O_SUBST,stab2arg(A_STAB,defstab),spat); X return s; X} X Xhoistmust(spat) Xregister SPAT *spat; X{ X if (spat->spat_regexp->regmust) { /* is there a better short-circuit? */ X if (spat->spat_short && X strEQ(spat->spat_short->str_ptr,spat->spat_regexp->regmust->str_ptr)){ X if (spat->spat_flags & SPAT_SCANFIRST) { X str_free(spat->spat_short); X spat->spat_short = Nullstr; X } X else { X str_free(spat->spat_regexp->regmust); X spat->spat_regexp->regmust = Nullstr; X return; X } X } X if (!spat->spat_short || /* promote the better string */ X ((spat->spat_flags & SPAT_SCANFIRST) && X (spat->spat_short->str_cur < spat->spat_regexp->regmust->str_cur) )){ X str_free(spat->spat_short); /* ok if null */ X spat->spat_short = spat->spat_regexp->regmust; X spat->spat_regexp->regmust = Nullstr; X spat->spat_flags |= SPAT_SCANFIRST; X } X } X} X Xchar * Xexpand_charset(s) Xregister char *s; X{ X char t[512]; X register char *d = t; X register int i; X X while (*s) { X if (s[1] == '-' && s[2]) { X for (i = s[0]; i <= s[2]; i++) X *d++ = i; X s += 3; X } X else X *d++ = *s++; X } X *d = '\0'; X return savestr(t); X} X Xchar * Xscantrans(s) Xregister char *s; X{ X ARG *arg = X l(make_op(O_TRANS,2,stab2arg(A_STAB,defstab),Nullarg,Nullarg,0)); X register char *t; X register char *r; X register char *tbl = safemalloc(256); X register int i; X X arg[2].arg_type = A_NULL; X arg[2].arg_ptr.arg_cval = tbl; X for (i=0; i<256; i++) X tbl[i] = 0; X s = scanstr(s); X if (!*s) X fatal("Translation pattern not terminated"); X t = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str)); X free_arg(yylval.arg); X s = scanstr(s-1); X if (!*s) X fatal("Translation replacement not terminated"); X r = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str)); X free_arg(yylval.arg); X yylval.arg = arg; X if (!*r) { X safefree(r); X r = t; X } X for (i = 0; t[i]; i++) { X if (!r[i]) X r[i] = r[i-1]; X tbl[t[i] & 0377] = r[i]; X } X if (r != t) X safefree(r); X safefree(t); X return s; X} X Xchar * Xscanstr(s) Xregister char *s; X{ X register char term; X register char *d; X register ARG *arg; X register bool makesingle = FALSE; X register STAB *stab; X char *leave = "\\$nrtfb0123456789"; /* which backslash sequences to keep */ X X arg = op_new(1); X yylval.arg = arg; X arg->arg_type = O_ITEM; X X switch (*s) { X default: /* a substitution replacement */ X arg[1].arg_type = A_DOUBLE; X makesingle = TRUE; /* maybe disable runtime scanning */ X term = *s; X if (term == '\'') X leave = Nullch; X goto snarf_it; X case '0': X { X long i; X int shift; X X arg[1].arg_type = A_SINGLE; X if (s[1] == 'x') { X shift = 4; X s += 2; X } X else if (s[1] == '.') X goto decimal; X else X shift = 3; X i = 0; X for (;;) { X switch (*s) { X default: X goto out; X case '8': case '9': X if (shift != 4) X fatal("Illegal octal digit"); X /* FALL THROUGH */ X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': X i <<= shift; X i += *s++ & 15; X break; X case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': X case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': X if (shift != 4) X goto out; X i <<= 4; X i += (*s++ & 7) + 9; X break; X } X } X out: X sprintf(tokenbuf,"%ld",i); X arg[1].arg_ptr.arg_str = str_make(tokenbuf); X } X break; X case '1': case '2': case '3': case '4': case '5': X case '6': case '7': case '8': case '9': case '.': X decimal: X arg[1].arg_type = A_SINGLE; X d = tokenbuf; X while (isdigit(*s) || *s == '_') { X if (*s == '_') X s++; X else X *d++ = *s++; X } X if (*s == '.' && index("0123456789eE",s[1])) { X *d++ = *s++; X while (isdigit(*s) || *s == '_') { X if (*s == '_') X s++; X else X *d++ = *s++; X } X } X if (index("eE",*s) && index("+-0123456789",s[1])) { X *d++ = *s++; X if (*s == '+' || *s == '-') X *d++ = *s++; X while (isdigit(*s)) X *d++ = *s++; X } X *d = '\0'; X arg[1].arg_ptr.arg_str = str_make(tokenbuf); X break; X case '\'': X arg[1].arg_type = A_SINGLE; X term = *s; X leave = Nullch; X goto snarf_it; X X case '<': X d = tokenbuf; X s = cpytill(d,s+1,'>'); X if (*s) X s++; X if (*d == '$') d++; X while (*d && (isalpha(*d) || isdigit(*d) || *d == '_')) d++; X if (*d) { X d = tokenbuf; X arg[1].arg_type = A_GLOB; X d = savestr(d); X arg[1].arg_ptr.arg_stab = stab = genstab(); X stab->stab_io = stio_new(); X stab->stab_val = str_make(d); X } X else { X d = tokenbuf; X if (!*d) X strcpy(d,"ARGV"); X if (*d == '$') { X arg[1].arg_type = A_INDREAD; X arg[1].arg_ptr.arg_stab = stabent(d+1,TRUE); X } X else { X arg[1].arg_type = A_READ; X if (rsfp == stdin && strEQ(d,"stdin")) X fatal("Can't get both program and data from "); X arg[1].arg_ptr.arg_stab = stabent(d,TRUE); X arg[1].arg_ptr.arg_stab->stab_io = stio_new(); X if (strEQ(d,"ARGV")) { X aadd(arg[1].arg_ptr.arg_stab); X arg[1].arg_ptr.arg_stab->stab_io->flags |= X IOF_ARGV|IOF_START; X } X } X } X break; X case '"': X arg[1].arg_type = A_DOUBLE; X makesingle = TRUE; /* maybe disable runtime scanning */ X term = *s; X goto snarf_it; X case '`': X arg[1].arg_type = A_BACKTICK; X term = *s; X snarf_it: X { X STR *tmpstr; X int sqstart = line; X char *tmps; X X tmpstr = str_new(strlen(s)); X s = str_append_till(tmpstr,s+1,term,leave); X while (!*s) { /* multiple line string? */ X s = str_gets(linestr, rsfp); X if (!s) { X line = sqstart; X fatal("EOF in string"); X } X line++; X s = str_append_till(tmpstr,s,term,leave); X } X s++; X if (term == '\'') { X arg[1].arg_ptr.arg_str = tmpstr; X break; X } X tmps = s; X s = tmpstr->str_ptr; X while (*s) { /* see if we can make SINGLE */ X if (*s == '\\' && s[1] && isdigit(s[1]) && !isdigit(s[2]) && X !index("`\"",term) ) X *s = '$'; /* grandfather \digit in subst */ X if (*s == '$' && s[1] && s[1] != ')' && s[1] != '|') { X makesingle = FALSE; /* force interpretation */ X } X else if (*s == '\\' && s[1]) { X s++; X } X s++; X } X s = d = tmpstr->str_ptr; /* assuming shrinkage only */ X while (*s) { X if (*s == '$' && s[1] && s[1] != ')' && s[1] != '|') { X int len; X X len = scanreg(s,tokenbuf) - s; X stabent(tokenbuf,TRUE); /* make sure it's created */ X while (len--) X *d++ = *s++; X continue; X } X else if (*s == '\\' && s[1]) { X s++; X switch (*s) { X default: X if (!makesingle && (!leave || index(leave,*s))) X *d++ = '\\'; X *d++ = *s++; X continue; X case '0': case '1': case '2': case '3': X case '4': case '5': case '6': case '7': X *d = *s++ - '0'; X if (index("01234567",*s)) { X *d <<= 3; X *d += *s++ - '0'; X } X if (index("01234567",*s)) { X *d <<= 3; X *d += *s++ - '0'; X } X d++; X continue; X case 'b': X *d++ = '\b'; X break; X case 'n': X *d++ = '\n'; X break; X case 'r': X *d++ = '\r'; X break; X case 'f': X *d++ = '\f'; X break; X case 't': X *d++ = '\t'; X break; X } X s++; X continue; X } X *d++ = *s++; X } X *d = '\0'; X X if (arg[1].arg_type == A_DOUBLE && makesingle) X arg[1].arg_type = A_SINGLE; /* now we can optimize on it */ X X tmpstr->str_cur = d - tmpstr->str_ptr; /* XXX cheat */ X arg[1].arg_ptr.arg_str = tmpstr; X s = tmps; X break; X } X } X return s; X} X XFCMD * Xload_format() X{ X FCMD froot; X FCMD *flinebeg; X register FCMD *fprev = &froot; X register FCMD *fcmd; X register char *s; X register char *t; X register char tmpchar; X bool noblank; X X while ((s = str_gets(linestr,rsfp)) != Nullch) { X line++; X if (strEQ(s,".\n")) { X bufptr = s; X return froot.f_next; X } X if (*s == '#') X continue; X flinebeg = Nullfcmd; X noblank = FALSE; X while (*s) { X fcmd = (FCMD *)safemalloc(sizeof (FCMD)); X bzero((char*)fcmd, sizeof (FCMD)); X fprev->f_next = fcmd; X fprev = fcmd; X for (t=s; *t && *t != '@' && *t != '^'; t++) { X if (*t == '~') { X noblank = TRUE; X *t = ' '; X } X } X tmpchar = *t; X *t = '\0'; X fcmd->f_pre = savestr(s); X fcmd->f_presize = strlen(s); X *t = tmpchar; X s = t; X if (!*s) { X if (noblank) X fcmd->f_flags |= FC_NOBLANK; X break; X } X if (!flinebeg) X flinebeg = fcmd; /* start values here */ X if (*s++ == '^') X fcmd->f_flags |= FC_CHOP; /* for doing text filling */ X switch (*s) { X case '*': X fcmd->f_type = F_LINES; X *s = '\0'; X break; X case '<': X fcmd->f_type = F_LEFT; X while (*s == '<') X s++; X break; X case '>': X fcmd->f_type = F_RIGHT; X while (*s == '>') X s++; X break; X case '|': X fcmd->f_type = F_CENTER; X while (*s == '|') X s++; X break; X default: X fcmd->f_type = F_LEFT; X break; X } X if (fcmd->f_flags & FC_CHOP && *s == '.') { X fcmd->f_flags |= FC_MORE; X while (*s == '.') X s++; X } X fcmd->f_size = s-t; X } X if (flinebeg) { X again: X if ((bufptr = str_gets(linestr ,rsfp)) == Nullch) X goto badform; X line++; X if (strEQ(bufptr,".\n")) { X yyerror("Missing values line"); X return froot.f_next; X } X if (*bufptr == '#') X goto again; X lex_newlines = TRUE; X while (flinebeg || *bufptr) { X switch(yylex()) { X default: X yyerror("Bad value in format"); X *bufptr = '\0'; X break; X case '\n': X if (flinebeg) X yyerror("Missing value in format"); X *bufptr = '\0'; X break; X case REG: X yylval.arg = stab2arg(A_LVAL,yylval.stabval); X /* FALL THROUGH */ X case RSTRING: X if (!flinebeg) X yyerror("Extra value in format"); X else { X flinebeg->f_expr = yylval.arg; X do { X flinebeg = flinebeg->f_next; X } while (flinebeg && flinebeg->f_size == 0); X } X break; X case ',': case ';': X continue; X } X } X lex_newlines = FALSE; X } X } X badform: X bufptr = str_get(linestr); X yyerror("Format not terminated"); X return froot.f_next; X} !STUFFY!FUNK! echo Extracting x2p/a2py.c sed >x2p/a2py.c <<'!STUFFY!FUNK!' -e 's/X//' X/* $Header: a2py.c,v 2.0 88/06/05 00:15:41 root Exp $ X * X * $Log: a2py.c,v $ X * Revision 2.0 88/06/05 00:15:41 root X * Baseline version 2.0. X * X */ X X#include "util.h" Xchar *index(); X Xchar *filename; X Xint checkers = 0; X Xmain(argc,argv,env) Xregister int argc; Xregister char **argv; Xregister char **env; X{ X register STR *str; X register char *s; X int i; X STR *walk(); X STR *tmpstr; X X linestr = str_new(80); X str = str_new(0); /* first used for -I flags */ X for (argc--,argv++; argc; argc--,argv++) { X if (argv[0][0] != '-' || !argv[0][1]) X break; X reswitch: X switch (argv[0][1]) { X#ifdef DEBUGGING X case 'D': X debug = atoi(argv[0]+2); X#ifdef YYDEBUG X yydebug = (debug & 1); X#endif X break; X#endif X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X maxfld = atoi(argv[0]+1); X absmaxfld = TRUE; X break; X case 'F': X fswitch = argv[0][2]; X break; X case 'n': X namelist = savestr(argv[0]+2); X break; X case '-': X argc--,argv++; X goto switch_end; X case 0: X break; X default: X fatal("Unrecognized switch: %s\n",argv[0]); X } X } X switch_end: X X /* open script */ X X if (argv[0] == Nullch) X argv[0] = "-"; X filename = savestr(argv[0]); X if (strEQ(filename,"-")) X argv[0] = ""; X if (!*argv[0]) X rsfp = stdin; X else X rsfp = fopen(argv[0],"r"); X if (rsfp == Nullfp) X fatal("Awk script \"%s\" doesn't seem to exist.\n",filename); X X /* init tokener */ X X bufptr = str_get(linestr); X symtab = hnew(); X X /* now parse the report spec */ X X if (yyparse()) X fatal("Translation aborted due to syntax errors.\n"); X X#ifdef DEBUGGING X if (debug & 2) { X int type, len; X X for (i=1; i> 8; X type &= 255; X printf("%d\t%d\t%d\t%-10s",i++,type,len,opname[type]); X if (type == OSTRING) X printf("\t\"%s\"\n",ops[i].cval),i++; X else { X while (len--) { X printf("\t%d",ops[i].ival),i++; X } X putchar('\n'); X } X } X } X if (debug & 8) X dump(root); X#endif X X /* first pass to look for numeric variables */ X X prewalk(0,0,root,&i); X X /* second pass to produce new program */ X X tmpstr = walk(0,0,root,&i); X str = str_make("#!/usr/bin/perl\neval \"exec /usr/bin/perl -S $0 $*\"\n\ X if $running_under_some_shell;\n\ X # this emulates #! processing on NIH machines.\n\ X # (remove #! line above if indigestible)\n\n"); X str_cat(str, X "eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_]+=)(.*)/ && shift;\n"); X str_cat(str, X " # process any FOO=bar switches\n\n"); X if (do_opens && opens) { X str_scat(str,opens); X str_free(opens); X str_cat(str,"\n"); X } X str_scat(str,tmpstr); X str_free(tmpstr); X#ifdef DEBUGGING X if (!(debug & 16)) X#endif X fixup(str); X putlines(str); X if (checkers) { X fprintf(stderr, X "Please check my work on the %d line%s I've marked with \"#???\".\n", X checkers, checkers == 1 ? "" : "s" ); X fprintf(stderr, X "The operation I've selected may be wrong for the operand types.\n"); X } X exit(0); X} X X#define RETURN(retval) return (bufptr = s,retval) X#define XTERM(retval) return (expectterm = TRUE,bufptr = s,retval) X#define XOP(retval) return (expectterm = FALSE,bufptr = s,retval) X#define ID(x) return (yylval=string(x,0),expectterm = FALSE,bufptr = s,VAR) X Xyylex() X{ X register char *s = bufptr; X register char *d; X register int tmp; X X retry: X#ifdef YYDEBUG X if (yydebug) X if (index(s,'\n')) X fprintf(stderr,"Tokener at %s",s); X else X fprintf(stderr,"Tokener at %s\n",s); X#endif X switch (*s) { X default: X fprintf(stderr, X "Unrecognized character %c in file %s line %d--ignoring.\n", X *s++,filename,line); X goto retry; X case '\\': X case 0: X s = str_get(linestr); X *s = '\0'; X if (!rsfp) X RETURN(0); X line++; X if ((s = str_gets(linestr, rsfp)) == Nullch) { X if (rsfp != stdin) X fclose(rsfp); X rsfp = Nullfp; X s = str_get(linestr); X RETURN(0); X } X goto retry; X case ' ': case '\t': X s++; X goto retry; X case '\n': X *s = '\0'; X XTERM(NEWLINE); X case '#': X yylval = string(s,0); X *s = '\0'; X XTERM(COMMENT); X case ';': X tmp = *s++; X if (*s == '\n') { X s++; X XTERM(SEMINEW); X } X XTERM(tmp); X case '(': X case '{': X case '[': X case ')': X case ']': X tmp = *s++; X XOP(tmp); X case 127: X s++; X XTERM('}'); X case '}': X for (d = s + 1; isspace(*d); d++) ; X if (!*d) X s = d - 1; X *s = 127; X XTERM(';'); X case ',': X tmp = *s++; X XTERM(tmp); X case '~': X s++; X yylval = string("~",1); X XTERM(MATCHOP); X case '+': X case '-': X if (s[1] == *s) { X s++; X if (*s++ == '+') X XTERM(INCR); X else X XTERM(DECR); X } X /* FALL THROUGH */ X case '*': X case '%': X tmp = *s++; X if (*s == '=') { X yylval = string(s-1,2); X s++; X XTERM(ASGNOP); X } X XTERM(tmp); X case '&': X s++; X tmp = *s++; X if (tmp == '&') X XTERM(ANDAND); X s--; X XTERM('&'); X case '|': X s++; X tmp = *s++; X if (tmp == '|') X XTERM(OROR); X s--; X XTERM('|'); X case '=': X s++; X tmp = *s++; X if (tmp == '=') { X yylval = string("==",2); X XTERM(RELOP); X } X s--; X yylval = string("=",1); X XTERM(ASGNOP); X case '!': X s++; X tmp = *s++; X if (tmp == '=') { X yylval = string("!=",2); X XTERM(RELOP); X } X if (tmp == '~') { X yylval = string("!~",2); X XTERM(MATCHOP); X } X s--; X XTERM(NOT); X case '<': X s++; X tmp = *s++; X if (tmp == '=') { X yylval = string("<=",2); X XTERM(RELOP); X } X s--; X yylval = string("<",1); X XTERM(RELOP); X case '>': X s++; X tmp = *s++; X if (tmp == '>') { X yylval = string(">>",2); X XTERM(GRGR); X } X if (tmp == '=') { X yylval = string(">=",2); X XTERM(RELOP); X } X s--; X yylval = string(">",1); X XTERM(RELOP); X X#define SNARFWORD \ X d = tokenbuf; \ X while (isalpha(*s) || isdigit(*s) || *s == '_') \ X *d++ = *s++; \ X *d = '\0'; \ X d = tokenbuf; X X case '$': X s++; X if (*s == '0') { X s++; X do_chop = TRUE; X need_entire = TRUE; X ID("0"); X } X do_split = TRUE; X if (isdigit(*s)) { X for (d = s; isdigit(*s); s++) ; X yylval = string(d,s-d); X tmp = atoi(d); X if (tmp > maxfld) X maxfld = tmp; X XOP(FIELD); X } X split_to_array = set_array_base = TRUE; X XOP(VFIELD); X X case '/': /* may either be division or pattern */ X if (expectterm) { X s = scanpat(s); X XTERM(REGEX); X } X tmp = *s++; X if (*s == '=') { X yylval = string("/=",2); X s++; X XTERM(ASGNOP); X } X XTERM(tmp); X X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X s = scannum(s); X XOP(NUMBER); X case '"': X s++; X s = cpy2(tokenbuf,s,s[-1]); X if (!*s) X fatal("String not terminated:\n%s",str_get(linestr)); X s++; X yylval = string(tokenbuf,0); X XOP(STRING); X X case 'a': case 'A': X SNARFWORD; X ID(d); X case 'b': case 'B': X SNARFWORD; X if (strEQ(d,"break")) X XTERM(BREAK); X if (strEQ(d,"BEGIN")) X XTERM(BEGIN); X ID(d); X case 'c': case 'C': X SNARFWORD; X if (strEQ(d,"continue")) X XTERM(CONTINUE); X ID(d); X case 'd': case 'D': X SNARFWORD; X ID(d); X case 'e': case 'E': X SNARFWORD; X if (strEQ(d,"END")) X XTERM(END); X if (strEQ(d,"else")) X XTERM(ELSE); X if (strEQ(d,"exit")) { X saw_line_op = TRUE; X XTERM(EXIT); X } X if (strEQ(d,"exp")) { X yylval = OEXP; X XTERM(FUN1); X } X ID(d); X case 'f': case 'F': X SNARFWORD; X if (strEQ(d,"FS")) { X saw_FS++; X if (saw_FS == 1 && in_begin) { X for (d = s; *d && isspace(*d); d++) ; X if (*d == '=') { X for (d++; *d && isspace(*d); d++) ; X if (*d == '"' && d[2] == '"') X const_FS = d[1]; X } X } X ID(tokenbuf); X } X if (strEQ(d,"FILENAME")) X d = "ARGV"; X if (strEQ(d,"for")) X XTERM(FOR); X ID(d); X case 'g': case 'G': X SNARFWORD; X if (strEQ(d,"getline")) X XTERM(GETLINE); X ID(d); X case 'h': case 'H': X SNARFWORD; X ID(d); X case 'i': case 'I': X SNARFWORD; X if (strEQ(d,"if")) X XTERM(IF); X if (strEQ(d,"in")) X XTERM(IN); X if (strEQ(d,"index")) { X set_array_base = TRUE; X XTERM(INDEX); X } X if (strEQ(d,"int")) { X yylval = OINT; X XTERM(FUN1); X } X ID(d); X case 'j': case 'J': X SNARFWORD; X ID(d); X case 'k': case 'K': X SNARFWORD; X ID(d); X case 'l': case 'L': X SNARFWORD; X if (strEQ(d,"length")) { X yylval = OLENGTH; X XTERM(FUN1); X } X if (strEQ(d,"log")) { X yylval = OLOG; X XTERM(FUN1); X } X ID(d); X case 'm': case 'M': X SNARFWORD; X ID(d); X case 'n': case 'N': X SNARFWORD; X if (strEQ(d,"NF")) X do_split = split_to_array = set_array_base = TRUE; X if (strEQ(d,"next")) { X saw_line_op = TRUE; X XTERM(NEXT); X } X ID(d); X case 'o': case 'O': X SNARFWORD; X if (strEQ(d,"ORS")) { X saw_ORS = TRUE; X d = "$\\"; X } X if (strEQ(d,"OFS")) { X saw_OFS = TRUE; X d = "$,"; X } X if (strEQ(d,"OFMT")) { X d = "$#"; X } X ID(d); X case 'p': case 'P': X SNARFWORD; X if (strEQ(d,"print")) { X XTERM(PRINT); X } X if (strEQ(d,"printf")) { X XTERM(PRINTF); X } X ID(d); X case 'q': case 'Q': X SNARFWORD; X ID(d); X case 'r': case 'R': X SNARFWORD; X if (strEQ(d,"RS")) { X d = "$/"; X saw_RS = TRUE; X } X ID(d); X case 's': case 'S': X SNARFWORD; X if (strEQ(d,"split")) { X set_array_base = TRUE; X XOP(SPLIT); X } X if (strEQ(d,"substr")) { X set_array_base = TRUE; X XTERM(SUBSTR); X } X if (strEQ(d,"sprintf")) X XTERM(SPRINTF); X if (strEQ(d,"sqrt")) { X yylval = OSQRT; X XTERM(FUN1); X } X ID(d); X case 't': case 'T': X SNARFWORD; X ID(d); X case 'u': case 'U': X SNARFWORD; X ID(d); X case 'v': case 'V': X SNARFWORD; X ID(d); X case 'w': case 'W': X SNARFWORD; X if (strEQ(d,"while")) X XTERM(WHILE); X ID(d); X case 'x': case 'X': X SNARFWORD; X ID(d); X case 'y': case 'Y': X SNARFWORD; X ID(d); X case 'z': case 'Z': X SNARFWORD; X ID(d); X } X} X Xchar * Xscanpat(s) Xregister char *s; X{ X register char *d; X X switch (*s++) { X case '/': X break; X default: X fatal("Search pattern not found:\n%s",str_get(linestr)); X } X X d = tokenbuf; X for (; *s; s++,d++) { X if (*s == '\\') { X if (s[1] == '/') X *d++ = *s++; X else if (s[1] == '\\') X *d++ = *s++; X } X else if (*s == '[') { X *d++ = *s++; X do { X if (*s == '\\' && s[1]) X *d++ = *s++; X if (*s == '/' || (*s == '-' && s[1] == ']')) X *d++ = '\\'; X *d++ = *s++; X } while (*s && *s != ']'); X } X else if (*s == '/') X break; X *d = *s; X } X *d = '\0'; X X if (!*s) X fatal("Search pattern not terminated:\n%s",str_get(linestr)); X s++; X yylval = string(tokenbuf,0); X return s; X} X Xyyerror(s) Xchar *s; X{ X fprintf(stderr,"%s in file %s at line %d\n", X s,filename,line); X} X Xchar * Xscannum(s) Xregister char *s; X{ X register char *d; X X switch (*s) { X case '1': case '2': case '3': case '4': case '5': X case '6': case '7': case '8': case '9': case '0' : case '.': X d = tokenbuf; X while (isdigit(*s)) { X *d++ = *s++; X } X if (*s == '.' && index("0123456789eE",s[1])) { X *d++ = *s++; X while (isdigit(*s)) { X *d++ = *s++; X } X } X if (index("eE",*s) && index("+-0123456789",s[1])) { X *d++ = *s++; X if (*s == '+' || *s == '-') X *d++ = *s++; X while (isdigit(*s)) X *d++ = *s++; X } X *d = '\0'; X yylval = string(tokenbuf,0); X break; X } X return s; X} X Xstring(ptr,len) Xchar *ptr; X{ X int retval = mop; X X ops[mop++].ival = OSTRING + (1<<8); X if (!len) X len = strlen(ptr); X ops[mop].cval = safemalloc(len+1); X strncpy(ops[mop].cval,ptr,len); X ops[mop++].cval[len] = '\0'; X return retval; X} X Xoper0(type) Xint type; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type; X return retval; X} X Xoper1(type,arg1) Xint type; Xint arg1; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type + (1<<8); X ops[mop++].ival = arg1; X return retval; X} X Xoper2(type,arg1,arg2) Xint type; Xint arg1; Xint arg2; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type + (2<<8); X ops[mop++].ival = arg1; X ops[mop++].ival = arg2; X return retval; X} X Xoper3(type,arg1,arg2,arg3) Xint type; Xint arg1; Xint arg2; Xint arg3; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type + (3<<8); X ops[mop++].ival = arg1; X ops[mop++].ival = arg2; X ops[mop++].ival = arg3; X return retval; X} X Xoper4(type,arg1,arg2,arg3,arg4) Xint type; Xint arg1; Xint arg2; Xint arg3; Xint arg4; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type + (4<<8); X ops[mop++].ival = arg1; X ops[mop++].ival = arg2; X ops[mop++].ival = arg3; X ops[mop++].ival = arg4; X return retval; X} X Xoper5(type,arg1,arg2,arg3,arg4,arg5) Xint type; Xint arg1; Xint arg2; Xint arg3; Xint arg4; Xint arg5; X{ X int retval = mop; X X if (type > 255) X fatal("type > 255 (%d)\n",type); X ops[mop++].ival = type + (5<<8); X ops[mop++].ival = arg1; X ops[mop++].ival = arg2; X ops[mop++].ival = arg3; X ops[mop++].ival = arg4; X ops[mop++].ival = arg5; X return retval; X} X Xint depth = 0; X Xdump(branch) Xint branch; X{ X register int type; X register int len; X register int i; X X type = ops[branch].ival; X len = type >> 8; X type &= 255; X for (i=depth; i; i--) X printf(" "); X if (type == OSTRING) { X printf("%-5d\"%s\"\n",branch,ops[branch+1].cval); X } X else { X printf("(%-5d%s %d\n",branch,opname[type],len); X depth++; X for (i=1; i<=len; i++) X dump(ops[branch+i].ival); X depth--; X for (i=depth; i; i--) X printf(" "); X printf(")\n"); X } X} X Xbl(arg,maybe) Xint arg; Xint maybe; X{ X if (!arg) X return 0; X else if ((ops[arg].ival & 255) != OBLOCK) X return oper2(OBLOCK,arg,maybe); X else if ((ops[arg].ival >> 8) < 2) X return oper2(OBLOCK,ops[arg+1].ival,maybe); X else X return arg; X} X Xfixup(str) XSTR *str; X{ X register char *s; X register char *t; X X for (s = str->str_ptr; *s; s++) { X if (*s == ';' && s[1] == ' ' && s[2] == '\n') { X strcpy(s+1,s+2); X s++; X } X else if (*s == '\n') { X for (t = s+1; isspace(*t & 127); t++) ; X t--; X while (isspace(*t & 127) && *t != '\n') t--; X if (*t == '\n' && t-s > 1) { X if (s[-1] == '{') X s--; X strcpy(s+1,t); X } X s++; X } X } X} X Xputlines(str) XSTR *str; X{ X register char *d, *s, *t, *e; X register int pos, newpos; X X d = tokenbuf; X pos = 0; X for (s = str->str_ptr; *s; s++) { X *d++ = *s; X pos++; X if (*s == '\n') { X *d = '\0'; X d = tokenbuf; X pos = 0; X putone(); X } X else if (*s == '\t') X pos += 7; X if (pos > 78) { /* split a long line? */ X *d-- = '\0'; X newpos = 0; X for (t = tokenbuf; isspace(*t & 127); t++) { X if (*t == '\t') X newpos += 8; X else X newpos += 1; X } X e = d; X while (d > tokenbuf && (*d != ' ' || d[-1] != ';')) X d--; X if (d < t+10) { X d = e; X while (d > tokenbuf && X (*d != ' ' || d[-1] != '|' || d[-2] != '|') ) X d--; X } X if (d < t+10) { X d = e; X while (d > tokenbuf && X (*d != ' ' || d[-1] != '&' || d[-2] != '&') ) X d--; X } X if (d < t+10) { X d = e; X while (d > tokenbuf && (*d != ' ' || d[-1] != ',')) X d--; X } X if (d < t+10) { X d = e; X while (d > tokenbuf && *d != ' ') X d--; X } X if (d > t+3) { X *d = '\0'; X putone(); X putchar('\n'); X if (d[-1] != ';' && !(newpos % 4)) { X *t++ = ' '; X *t++ = ' '; X newpos += 2; X } X strcpy(t,d+1); X newpos += strlen(t); X d = t + strlen(t); X pos = newpos; X } X else X d = e + 1; X } X } X} X Xputone() X{ X register char *t; X X for (t = tokenbuf; *t; t++) { X *t &= 127; X if (*t == 127) { X *t = ' '; X strcpy(t+strlen(t)-1, "\t#???\n"); X checkers++; X } X } X t = tokenbuf; X if (*t == '#') { X if (strnEQ(t,"#!/bin/awk",10) || strnEQ(t,"#! /bin/awk",11)) X return; X if (strnEQ(t,"#!/usr/bin/awk",14) || strnEQ(t,"#! /usr/bin/awk",15)) X return; X } X fputs(tokenbuf,stdout); X} X Xnumary(arg) Xint arg; X{ X STR *key; X int dummy; X X key = walk(0,0,arg,&dummy); X str_cat(key,"[]"); X hstore(symtab,key->str_ptr,str_make("1")); X str_free(key); X set_array_base = TRUE; X return arg; X} !STUFFY!FUNK! echo Extracting x2p/s2p.man sed >x2p/s2p.man <<'!STUFFY!FUNK!' -e 's/X//' X.rn '' }` X''' $Header: s2p.man,v 2.0 88/06/05 00:15:59 root Exp $ X''' X''' $Log: s2p.man,v $ X''' Revision 2.0 88/06/05 00:15:59 root X''' Baseline version 2.0. X''' X''' X.de Sh X.br X.ne 5 X.PP X\fB\\$1\fR X.PP X.. X.de Sp X.if t .sp .5v X.if n .sp X.. X.de Ip X.br X.ie \\n.$>=3 .ne \\$3 X.el .ne 3 X.IP "\\$1" \\$2 X.. X''' X''' Set up \*(-- to give an unbreakable dash; X''' string Tr holds user defined translation string. X''' Bell System Logo is used as a dummy character. X''' X.tr \(*W-|\(bv\*(Tr X.ie n \{\ X.ds -- \(*W- X.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch X.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch X.ds L" "" X.ds R" "" X.ds L' ' X.ds R' ' X'br\} X.el\{\ X.ds -- \(em\| X.tr \*(Tr X.ds L" `` X.ds R" '' X.ds L' ` X.ds R' ' X'br\} X.TH S2P 1 NEW X.SH NAME Xs2p - Sed to Perl translator X.SH SYNOPSIS X.B s2p [options] filename X.SH DESCRIPTION X.I S2p Xtakes a sed script specified on the command line (or from standard input) Xand produces a comparable X.I perl Xscript on the standard output. X.Sh "Options" XOptions include: X.TP 5 X.B \-D Xsets debugging flags. X.TP 5 X.B \-n Xspecifies that this sed script was always invoked with a sed -n. XOtherwise a switch parser is prepended to the front of the script. X.TP 5 X.B \-p Xspecifies that this sed script was never invoked with a sed -n. XOtherwise a switch parser is prepended to the front of the script. X.Sh "Considerations" XThe perl script produced looks very sed-ish, and there may very well be Xbetter ways to express what you want to do in perl. XFor instance, s2p does not make any use of the split operator, but you might Xwant to. X.PP XThe perl script you end up with may be either faster or slower than the original Xsed script. XIf you're only interested in speed you'll just have to try it both ways. XOf course, if you want to do something sed doesn't do, you have no choice. X.SH ENVIRONMENT XS2p uses no environment variables. X.SH AUTHOR XLarry Wall X.SH FILES X.SH SEE ALSO Xperl The perl compiler/interpreter X.br Xa2p awk to perl translator X.SH DIAGNOSTICS X.SH BUGS X.rn }` '' !STUFFY!FUNK! echo "" echo "End of kit 9 (of 15)" cat /dev/null >kit9isdone 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