mkdir regress.d # To unbundle, sh this file echo main.c 1>&2 sed 's/.//' >main.c <<'//GO.SYSIN DD main.c' -#define MAIN 1 -#include <ctype.h> -#include "re.h" -#include "lre.h" -#include "hdr.h" - -/* handle void* which didn't exist prior to ANSI C and C++ */ -#if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -# define VOID void -#else -# define VOID char -#endif - -static enum { gre, grep, egrep, fgrep } whoami = gre; -static char fullopts[] = "e:f:1bcEFGhilLnsvx"; -static char *opts = fullopts+4; /* start in after last : */ - -static void -usage(void) -{ - EPR "usage: %s [ -%s ] [ -e pattern ] [ -f file ] [ pattern ] [ file ] ...\n", progname, opts); - exit(2); -} - -#ifdef PROFILING -short profb[50000]; -#endif - -main(int argc, char **argv) -{ - register c; - int errflg = 0; - char *input = 0, *finput = 0; - int k, sval; - unsigned char map[256]; - int foundsome = 0; - PROCFN procfn; - RDFN rdfn; - MATCHFN matchfn; - VOID *pat; - -#ifdef PROFILING - { extern etext(); monitor((int (*)())2, etext, profb, ((int)etext) - 2+12+2400, 300); } -#endif - -/*re_debug=20;/**/ - /* - determine if we are to be restricted to compatability mode - */ - if(progname = strrchr(argv[0], '/')) - progname++; - else - progname = argv[0]; -#ifdef PLAN9 - if(strcmp(progname, "ogrep") == 0) -#else - if(strcmp(progname, "grep") == 0) -#endif - whoami = grep; - else if(strcmp(progname, "egrep") == 0) - whoami = egrep; - else if(strcmp(progname, "fgrep") == 0) - whoami = fgrep; - offsetunit = (whoami == gre)? 1 : 1024; /* test before -[FGE] */ - /* - read the options; decide legality after we know what we are doing. - the options are split so we can maintain the usage line - in one place. note the only option we have to be wary of - is -f (not grep) - */ - while((c = getopt(argc, argv, fullopts)) != -1) - switch(c) - { - case '1': oneflag = 1; break; - case 'b': bflag = 1; break; - case 'c': cflag = 1; break; - case 'e': if(input){ - EPR "%s: only one -e arg allowed\n", progname); - errflg = 1; - } - input = optarg; break; - case 'E': whoami = egrep; break; - case 'f': if(input){ - EPR "%s: only one -f arg allowed\n", progname); - errflg = 1; - } - finput = optarg; break; - case 'F': whoami = fgrep; break; - case 'G': whoami = grep; break; - case 'h': hflag = 1; break; - case 'i': iflag = 1; break; - case 'l': lflag = 1; break; - case 'L': Lflag = 1; break; - case 'n': nflag = 1; break; - case 's': sflag = 1; break; - case 'v': vflag = 1; break; - case 'x': xflag = 1; break; - case '?': errflg = 1; break; - } - if(errflg) - usage(); - argv += optind; - /* - check for bad flag combinations - */ - if(finput && (whoami == grep)){ - EPR "%s: cannot use -f with grep\n", progname); - exit(2); - } - if(finput && input){ - EPR "%s: cannot use -f with -e\n", progname); - exit(2); - } - if(!input && !finput){ - input = *argv++; - if(input == 0) - usage(); - } - /* - character mapping ? - */ - for(k = 0; k < 256; k++) - map[k] = k; - if(iflag) - for(k = 'A'; k <= 'Z'; k++) - map[k] = tolower(k); - /* - in the interests of readability, fob off grep-type specific - handling to separate functions. setting bmfn means using - bmfind; similiarly cwfn means use cwfind - - rules: - lnum needs be maintained only if nflag. - nbytes needs be maintained only if bflag. - for -[s1lL], do a longjmp(env). - for -c, increment nmatch. - */ - switch(whoami) - { - case gre: dogre(greparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break; - case grep: dogre(grepparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break; - case fgrep: dofgrep(input, finput, map, &procfn, &pat, &rdfn, &matchfn); break; - case egrep: dogre(egrepparse, input, finput, map, &procfn, &pat, &rdfn, &matchfn); break; - } - /* - do generic flag handling - */ - prname = !hflag && *argv && argv[1]; - /* - do file arguments now! for uniformity, no args = '-' - */ - if(!*argv) - *--argv = "-"; - for(; curfile = *argv++; close(ifd)){ - if(strcmp(curfile, "-") == 0) - ifd = 0; - else if((ifd = open(curfile, 0)) < 0){ - EPR "%s: ", progname); - perror(curfile); - errflg = 2; - continue; - } - if(sflag && foundsome) - continue; /* don't need to scan */ - lnum = nmatch = nbytes = 0; - longlinewarned = 0; - if((sval = setjmp(env)) == 0) - if((*procfn)(pat, rdfn, matchfn) < 0){ - EPR "%s: ", progname); - perror(curfile); - errflg = 2; - continue; - } - if((lflag && sval) || (Lflag && !sval)) - PR "%s\n", curfile); - if(cflag){ - if(prname) - PR "%s:", curfile); - PR "%ld\n", nmatch); - } - if(nmatch) - foundsome = 1; - } - exit(errflg? errflg : (foundsome == 0)); - /*NOTREACHED*/ -} - -void -re_error(char *s) -{ - EPR "%s: %s\n", progname, s); - exit(2); -} //GO.SYSIN DD main.c echo dofgrep.c 1>&2 sed 's/.//' >dofgrep.c <<'//GO.SYSIN DD dofgrep.c' -#include <ctype.h> -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static int addwords(char*, re_cw*, unsigned char**, unsigned char**); - -void -dofgrep(char *input, char *finput, unsigned char *map, PROCFN *pprocfn, void **pat, RDFN *prdfn, MATCHFN *pmatchfn) -{ - unsigned char *lb, *le; - int nwords, k; - re_cw *cw; - - *pat = (void *)(cw = re_cwinit(map)); - if(finput){ - nwords = addwords(finput, cw, &lb, &le); - } else { - register unsigned char *s, *e; - - nwords = 0; - s = (unsigned char *)input; - while(*s){ - char ch; - - for(e = s; *e && (*e != '\n'); e++) - ; - ch = *e; - if(xflag){ - s[-1] = '\n'; - *e = '\n'; - re_cwadd(cw, (lb = s)-1, (le = e)+1); - *e = ch; - } else - re_cwadd(cw, lb = s, le = e); - s = *e? (e+1):e; - nwords++; - } - if(nwords == 1){ - s = (unsigned char *)malloc(1 + (k = le-lb)); - if (!s){ - re_error("malloc failure"); - cw->seenerror = 1; - return; - } - memmove((char *)s, (char *)lb, k); - lb = s; - le = s+k; - if(xflag) - *le++ = '\n'; - } - } - if(nwords == 1){ - *pat = (void *)re_bmcomp((char *)lb, (char *)le, map); - *pprocfn = re_bmexec; - *prdfn = greprd; - *pmatchfn = xflag ? bmxmatch : grepmatch; - } else { - re_cwcomp(cw); - *pprocfn = re_cwexec; - *prdfn = xflag? cwxrd : greprd; - *pmatchfn = xflag ? cwxmatch : grepmatch; - } - if(sflag || lflag || Lflag || oneflag){ - if(vflag == 0) - succfn = oneshot, failfn = count_m; - else - succfn = count, failfn = oneshot; - } else if(cflag){ - if(vflag == 0) - succfn = inc, failfn = null; - else - succfn = null, failfn = inc_m; - } else if(vflag){ - if(bflag||nflag) - succfn = count; - else - succfn = null; - failfn = pr_m; - } else { - succfn = pr; - if(bflag||nflag) - failfn = count_m; - else - failfn = null; - } -} - -static -addwords(char *file, re_cw *pat, unsigned char **b, unsigned char **e) -{ - unsigned char rbuf[MAXLINE+2]; - unsigned char *buf = rbuf+1; - int fd; - int nwords = 0, eof, k; - register unsigned char *nl, *nn, *end; - - if((fd = open(file, 0)) < 0){ - perror(file); - exit(2); - } - rbuf[0] = '\n'; - nl = end = buf+1; - eof = 0; - for(;;){ - if((nn = (unsigned char *)memchr((char *)nl, '\n', end-nl)) == 0){ - if(nl == buf){ - EPR "line too long in %s\n", file); - exit(2); - } - memmove((char *)buf, (char *)nl, end-nl); - end -= nl-buf; - nl = buf; - k = read(fd, (char *)end, &buf[MAXLINE]-end); - if(k > 0){ - end += k; - continue; - } else if(k == 0){ - if(nl == end) /* clean read to end of file */ - break; - eof = 1; - *end++ = '\n'; - continue; - } else { - perror(file); - exit(2); - } - } - if(xflag) - re_cwadd(pat, nl-1, nn+1); - else - re_cwadd(pat, nl, nn); - nl = nn+1; - nwords++; - if(eof) - break; - } - close(fd); - if(nwords == 1){ - k = strlen((char *)buf)-1; - *b = (unsigned char *)malloc(k+1); - if (!*b){ - re_error("malloc failed"); - pat->seenerror = 1; - return 0; - } - memmove((char *)*b, (char *)buf, k); - if(xflag) - (*b)[k++] = '\n'; - *e = *b + k; - } - return(nwords); -} //GO.SYSIN DD dofgrep.c echo dogre.c 1>&2 sed 's/.//' >dogre.c <<'//GO.SYSIN DD dogre.c' -#include <ctype.h> -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static void gresucc(char*, char*); /* does reg exp match after bm */ -static int reader(void*, RDFN, MATCHFN);/* plain analog of bmfind, cwfind */ -static void readin(char*, char*, unsigned char**, unsigned char**); - -void -dogre(Parsetype parser, char *input, char *finput, unsigned char *map, PROCFN *pprocfn, void **pat, RDFN *prdfn, MATCHFN *pmatchfn) -{ - unsigned char *lb, *le; - - readin(input, finput, &lb, &le); - *pat = 0; - globre = egprep(parser, lb, le, map, 1); - *prdfn = greprd; - *pmatchfn = grepmatch; - if(sflag || lflag || Lflag || oneflag){ - if(vflag == 0) - succ2fn = oneshot, failfn = count_m; - else - succ2fn = count, failfn = oneshot; - } else if(cflag){ - if(vflag == 0) - succ2fn = inc, failfn = null; - else - succ2fn = null, failfn = inc_m; - } else if(vflag){ - if(bflag||nflag) - succ2fn = count; - else - succ2fn = null; - failfn = pr_m; - } else { - succ2fn = pr; - if(bflag||nflag) - failfn = count_m; - else - failfn = null; - } - if(re_lit(globre, &lb, &le)){ - *pat = (void *)re_bmcomp((char *)lb, (char *)le, map); - *pprocfn = re_bmexec; - succfn = gresucc; - } else { - if(*pat = (void *)re_recw(globre, map)) - *pprocfn = re_cwexec; - else - *pprocfn = reader; - succfn = succ2fn; - } -} - -static -reader(void *UNUSED, RDFN rdfn, MATCHFN matchfn) -{ - unsigned char *b, *e; - unsigned char *nl; - int k; -#pragma ref UNUSED - - b = 0; - while((k = (*rdfn)((char**)&b, (char**)&e)) > 0){ - while(nl = (unsigned char *)memchr((char *)b, '\n', e-b)){ - if(eg_match(globre, b, nl, (unsigned char **)0, (unsigned char **)0)){ - e = nl; - if((k = (*matchfn)((char**)&b, (char**)&e)) <= 0) - return(k); - } else - b = nl+1; - } - } - return(k); -} - -static void -readin(char *in, char *fin, unsigned char **beg, unsigned char **end) -{ - int size, n, fd, left; - char *base, *p; - - if(in){ - if(xflag){ - size = 4+strlen(in)+1; - *beg = (unsigned char *)malloc(size); - if (!*beg){ - EPR "%s: can't malloc %d bytes for -x\n", progname, size); - exit(2); - } - p = (char *)*beg; - *p++ = '^'; - *p++ = '('; - memmove(p, in, n = strlen(in)); - p += n; - *p++ = ')'; - *p++ = '$'; - *end = (unsigned char *)p; - } else { - *beg = (unsigned char *)in; - *end = *beg + strlen(in); - } - return; - } - /* we know fin is nonzero */ - if((fd = open(fin, 0)) < 0){ - perror(fin); - exit(2); - } - /* - i object to calling stat; the following crap is not painful - and at worst involves copying twice the number of bytes. - */ - size = 128; - if((base = malloc(size)) == 0){ - EPR "%s: can't malloc %d bytes for -f %s\n", progname, size, fin); - exit(2); - } - left = size; - p = base; - if(xflag){ - *p++ = '^'; - left--; - } - for(; (n = read(fd, p, left)) > 0;){ - p += n; - left -= n; - if(left == 0){ - size *= 2; - if((base = realloc(base, size+2)) == 0){ - EPR "%s: can't malloc %d bytes for -f %s\n", progname, size, fin); - exit(2); - } - p = base+size/2; - left = size/2; - } - } - if(n < 0){ - perror(fin); - exit(2); - } - close(fd); - if(xflag){ - *p++ = '$'; - } - *beg = (unsigned char *)base; - *end = (unsigned char *)p; -} - -static void -gresucc(char *b, char *e) -{ - if(eg_match(globre, (unsigned char*)b, (unsigned char*)(e-1), (unsigned char **)0, (unsigned char **)0)) - (*succ2fn)(b, e); - else - (*failfn)(b, e); -} //GO.SYSIN DD dogre.c echo fns.c 1>&2 sed 's/.//' >fns.c <<'//GO.SYSIN DD fns.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -void -pr(char *b, char *e) -{ - nmatch++; - if(prname) - PR "%s:", curfile); - if(bflag){ - PR "%ld:", nbytes/offsetunit); - nbytes += (e-b) + noverflow; - noverflow = 0; - } - if(nflag) - PR "%ld:", ++lnum); - WR(b, e-b); -} - -void -pr_m(char *b, char *e) -{ - register char *nl; - - while(nl = (char*)memchr(b, '\n', e-b)){ - nmatch++; - nl++; - if(prname) - PR "%s:", curfile); - if(bflag){ - PR "%ld:", nbytes/offsetunit); - nbytes += (nl-b) + noverflow; - noverflow = 0; - } - if(nflag) - PR "%ld:", ++lnum); - WR(b, nl-b); - if((b = nl) >= e) - break; - } -} - -/* ARGSUSED */ -void -inc(char *UNUSED, char *UNUSED2) -{ -#pragma ref UNUSED -#pragma ref UNUSED2 - nmatch++; -} - -void -inc_m(register char *b, register char *e) -{ - register char *nl; - - while(nl = (char*)memchr(b, '\n', e-b)){ - nmatch++; - if((b = nl+1) >= e) - break; - } -} - -void -null(char *UNUSED, char *UNUSED2) -#pragma ref UNUSED -#pragma ref UNUSED2 -{ -} - -void -count(register char *b, register char *e) -{ - nbytes += (e-b) + noverflow; - noverflow = 0; - lnum++; -} - -void -count_m(register char *b, register char *e) -{ - register char *nl; - - nbytes += (e-b) + noverflow; - noverflow = 0; - while(nl = (char*)memchr(b, '\n', e-b)){ - lnum++; - if((b = nl+1) >= e) - break; - } -} - -void -oneshot(char *b, char *e) -{ - register char *nl; - - nmatch++; - nl = (char*)memchr(b, '\n', e-b)+1; - if(oneflag) - pr(b, nl); - longjmp(env, 1); -} //GO.SYSIN DD fns.c echo buffer.c 1>&2 sed 's/.//' >buffer.c <<'//GO.SYSIN DD buffer.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -/*#define DEBUG /**/ - -/* the following ifdef aids testing of the buffering code */ -#ifndef BUFSIZE -#define BUFSIZE 50000 -#endif - -#define OVERFLOW (BUFSIZE/10) -/* - lines less than BUFSIZE are preserved. larger lines have at least - BUFSIZE-OVERFLOW preserved -*/ - -static char rbuf[BUFSIZE+1] = "\n"; -static char *buf = rbuf+1; -static char *next, *proc; -/* invariants: - valid text in buffer: buf <= text < next - text to be processed: proc <= text < next - buf, proc always point at beginning of lines -*/ - -greprd(register char **b, register char **e) -{ - int n; - int keepingsome; - register char *p; - - if(*b == 0) /* set up invariants */ - *b = *e = next = proc = buf; - keepingsome = *b != *e; -again: /* this is only used for overflowing input lines */ -#ifdef DEBUG - fprint(2, "%d <> %d; keep=%d (%d'%.10s'..%d) proc=%d\n", next, &buf[BUFSIZE], keepingsome, *b, *b?*b:"", *e, proc); -#endif - if(next < &buf[BUFSIZE]){ - /* - next is fine but *b may not be set - */ - if(!keepingsome) - *b = proc; - } else { - /* - find a \n so we can shift the buffer - */ - if(keepingsome){ - for(p = *b-1; p >= buf; p--) - if(*p == '\n') break; - p++; - /* the best new buffer start is p */ - if(p == buf){ /* progressing? */ - longline: - if(!longlinewarned){ - EPR "%s: %s: warning: ", progname, curfile); - if(bflag) - EPR "%ld: ", nbytes/offsetunit); - if(nflag) - EPR "%ld: ", lnum); - EPR "line too long (> %d chars); text skipped\n", BUFSIZE); - longlinewarned = 1; - } - next -= OVERFLOW; - noverflow += OVERFLOW; - goto again; - } - } else { - /* not keeping any; we only have to look at unprocessed */ - for(p = next-1; p >= proc; p--) - if(*p == '\n') break; - p++; - if(p == buf) - goto longline; - *b = p; - } - /* process any we haven't */ - if(proc < p){ - (*failfn)(proc, p); - proc = p; - } - /* move it! */ - n = p-buf; - memcpy(buf, p, next-p); - proc -= n; - next -= n; - *b -= n; - } - /* - *b points to start of returned (saved) text - next points to first available text for reading - */ - FLUSH; - if((n = read(ifd, next, &buf[BUFSIZE] - next)) <= 0){ - if(proc < next){ - (*failfn)(proc, next); - } - proc = next; - return(n); - } - next += n; - *e = next; -#ifdef DEBUG -fprint(2, "greprd returns %d .. %d\n", *b, *e); -#endif - return(1); -} - -grepmatch(register char **b, register char **e) -{ - char *s, *f; - int eoffset, n, ret = 1; -#ifdef DEBUG -fprint(2, "match! *b=%d@%d='%.100s' *e=%d@%d\n", **b, *b, *b, **e, *e);/**/ -#endif - for(s = *b; s >= proc; s--) - if(*s == '\n') - break; - if(s != *b) - s++; - if(proc < s){ - (*failfn)(proc, s); - proc = s; - } - f = *e; - for(;;){ - for(; f < next; f++) - if(*f == '\n') - goto done; - eoffset = f-s; - if((n = greprd(&s, &f)) <= 0){ - ret = n; - goto done; - } - f = s+eoffset; - } -done: - f++; - if(s > f) - abort(); - (*succfn)(s, f); - proc = *b = f; - *e = next; -#ifdef DEBUG -fprint(2, "match at '%.20s'; resuming at '%.20s'@%d\n", s, f, f);/**/ -#endif - return(ret); -} - -cwxrd(register char **b, register char **e) -{ - int n; - - n = greprd(b, e); - if(n > 0){ - (*b)--; -#ifdef DEBUG - fprint(2, "grepxrd returns %d .. %d\n", *b, *e); -#endif - } - return(n); -} - -cwxmatch(register char **b, register char **e) -{ - char *s, *f; - int eoffset, n, ret = 1; - -#ifdef DEBUG -fprint(2, "cwxmatch! *b=%d@%d='%.100s' *e=%d@%d\n", **b, *b, *b, **e, *e);/**/ -#endif - for(s = *b; s >= proc; s--) - if(*s == '\n') - break; - s++; - if(proc < s){ -/* -fprint(2, "cwxfail! *b=%d@%d='%.50s' *e=%d@%d\n", **b, *b, *b, **e, *e); -fprint(2, "s=%d, proc=%d, dbg.b=%d dbg.e=%d dbg.resume=%d\n", s, proc,dbg.b, dbg.e, dbg.resume); -*/ - (*failfn)(proc, s); - proc = s; - } - f = *e - 1; - for(;;){ - for(; f < next; f++) - if(*f == '\n') - goto done; - eoffset = f-s; - if((n = greprd(&s, &f)) <= 0){ - ret = n; - goto done; - } - f = s+eoffset; - } -done: - f++; - if(s > f) - abort(); - (*succfn)(s, f); - proc = *b = f; - *e = next; - (*b)--; -#ifdef DEBUG -fprint(2, "cwxmatch at '%.20s'; resuming at '%.20s'@%d\n", s, f, f);/**/ -#endif - return(ret); -} - -bmxmatch(register char **b, register char **e) -{ - char *s, *f; - int eoffset, n, ret = 1; - -#ifdef DEBUG -fprint(2, "bmxmatch! *b=%d@%d='%.100s' *e=%d@%d\n", **b, *b, *b, **e, *e);/**/ -#endif - for(s = *b; s >= proc; s--) - if(*s == '\n') - break; - s++; - if(proc < s){ - (*failfn)(proc, s); - proc = s; - } - f = *e - 1; - for(;;){ - for(; f < next; f++) - if(*f == '\n') - goto done; - eoffset = f-s; - if((n = greprd(&s, &f)) <= 0){ - ret = n; - goto done; - } - f = s+eoffset; - } -done: - f++; - if(s > f) - abort(); - (*((*b == s)? succfn:failfn))(s, f); - proc = *b = f; - *e = next; -#ifdef DEBUG -fprint(2, "bmxmatch at '%.20s'; resuming at '%.20s'\n", s, f);/**/ -#endif - return(ret); -} //GO.SYSIN DD buffer.c echo cw.c 1>&2 sed 's/.//' >cw.c <<'//GO.SYSIN DD cw.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -typedef struct Link -{ - unsigned char l; - struct Node *node; - struct Link *next; -} Link; -static Link *froot; - -#define NEW(N) (froot?(t = froot, froot = froot->next, t->next = 0, t->node = N, t): newlink(c, 0, N)) -#define ADD(N) if(qtail) qtail = qtail->next = NEW(N);\ - else qtail = qhead = NEW(N) -#define DEL() { Link *tmp = qhead;if((qhead = qhead->next) == 0)\ - qtail = 0; tmp->next = froot; froot = tmp;} - -typedef struct Node -{ - short out; - short d; - short shift1; - short shift2; - long id; - struct Node **tab; - Link *alts; - struct Node *fail; -} Node; - -static Link *newlink(re_cw*, int, Node*); -static Node *newnode(re_cw*, int); -static void zeroroot(Node*, Node*); -static void shifttab(Node*); -static void shiftprop(re_cw*,Node*); -#ifdef DEBUG -static void cwpr(register Node *n); -#endif - -re_cw * -re_cwinit(unsigned char *cmap) -{ - register i; - register re_cw *c; - - if((c = (re_cw *)egmalloc(sizeof *c, "malloc failed in re_cwinit")) == 0) - return((re_cw *)0); - c->nodeid = 0; - c->maxdepth = 0; - c->mindepth = 10000; - c->seenerror = 0; - c->root = newnode(c, 0); - if(cmap) - memmove((char *)c->map, (char *)cmap, sizeof c->map); - else - for(i = 0; i < sizeof c->map; i++) - c->map[i] = i; - return(c); -} - -void -re_cwadd(register re_cw *c, register unsigned char *s, register unsigned char *e) -{ - register Node *p, *state; - register Link *l; - int depth; - - for(state = c->root; s <= --e;){ - for(l = state->alts; l; l = l->next) - if(l->l == c->map[*e]) break; - if(l == 0) - break; - else - state = l->node; - } - if(s <= e){ - depth = state->d+1; - l = newlink(c, *e--, p = newnode(c, depth++)); - if((l == 0) || (p == 0)){ - c->seenerror = 1; - return; - } - l->next = state->alts; - state->alts = l; - state = p; - while(s <= e){ - state->alts = newlink(c, *e--, p = newnode(c, depth++)); - if((state->alts == 0) || (p == 0)){ - c->seenerror = 1; - return; - } - state = p; - } - } - if(c->mindepth > state->d) - c->mindepth = state->d; - state->out = 1; -} - -#ifdef DEBUG -static void -cwpr(register Node *n) -{ - register Link *l; - - Fprint(1, "%d[%d,%d]: ", n->id, n->shift1, n->shift2); - for(l = n->alts; l; l = l->next){ - Fprint(1, "edge from \"%d\" to \"%d\" label {\"%c\"};", - n->id, l->node->id, l->l); - if(l->node->out) Fprint(1, " draw \"%d\" as Doublecircle;", l->node->id); - if(l->node->fail) - Fprint(1, " edge from \"%d\" to \"%d\" dashed;", l->node->id, l->node->fail->id); - Fprint(1, "\n"); - cwpr(l->node); - } -} -#endif - -static void -fail(re_cw *c, Node *root) -{ - Link *qhead = 0, *qtail = 0; - register Link *l, *ll; - register Link *t; - register Node *state, *r, *s; - int a; - - for(l = root->alts; l; l = l->next){ - ADD(l->node); - l->node->fail = root; - } - while(qhead){ - r = qhead->node; - DEL(); - for(l = r->alts; l; l = l->next){ - s = l->node; - a = l->l; - ADD(s); - for(state = r->fail; state;){ - for(ll = state->alts; ll; ll = ll->next) - if(ll->l == a) - break; - if(ll || (state == root)){ - if(ll) - state = ll->node; - /* - do it here as only other exit is - state 0 - */ - if(state->out){ - s->out = 1; - } - break; - } else - state = state->fail; - } - s->fail = state; - } - } - zeroroot(root, root); -} - -static void -zeroroot(register Node *root, register Node *n) -{ - register Link *l; - - if(n->fail == root) - n->fail = 0; - for(l = n->alts; l; l = l->next) - zeroroot(root, l->node); -} - -static void -shift(re_cw *c) -{ - Link *qhead = 0, *qtail = 0; - register Link *l; - register Link *t; - register Node *state, *r, *s; - int k; - - for(k = 0; k < 256; k++) - c->step[k] = c->mindepth+1; - c->root->shift1 = 1; - c->root->shift2 = c->mindepth; - for(l = c->root->alts; l; l = l->next){ -/* l->node->shift2 = c->root->shift2;/**/ - ADD(l->node); - l->node->fail = 0; - } - while(qhead){ - r = qhead->node; - DEL(); - r->shift1 = c->mindepth; - r->shift2 = c->mindepth; - if(state = r->fail){ - do { - k = r->d - state->d; - if(k < state->shift1){ - state->shift1 = k; - } - if(r->out && (k < state->shift2)){ - state->shift2 = k; - } - } while(state = state->fail); - } - for(l = r->alts; l; l = l->next){ - s = l->node; - ADD(s); - } - } - shiftprop(c, c->root); - shifttab(c->root); - c->step[0] = 1; -} - -static void -shifttab(register Node *n) -{ - register Link *l; - register Node **nn; - - n->tab = nn = (Node **)calloc(256, sizeof(Node *)); - for(l = n->alts; l; l = l->next) - nn[l->l] = l->node; -} - -static void -shiftprop(register re_cw *c, register Node *n) -{ - register Link *l; - register Node *nn; - - for(l = n->alts; l; l = l->next){ - if(c->step[l->l] > l->node->d) - c->step[l->l] = l->node->d; - nn = l->node; - if(n->shift2 < nn->shift2) - nn->shift2 = n->shift2; - shiftprop(c, nn); - } -} - -void -re_cwcomp(re_cw *c) -{ - if(c->seenerror) - return; - fail(c, c->root); - shift(c); -#ifdef DEBUG - cwpr(c->root); -#endif -} - -re_cwexec(void *re_c, RDFN rdfn, MATCHFN matchfn) -{ - re_cw *c = (re_cw*)re_c; - register Node *state; - register Link *l; - register unsigned char *sp; - register unsigned char *e, *s; - register Node *ostate; - register k; - unsigned char *rs, *re; - unsigned char fake[1]; - unsigned char mappedsp; - - if(c->seenerror) - return(-1); - fake[0] = 0; - state = c->root; - for(rs = 0; (k = (*rdfn)((char**)&rs,(char**) &re)) > 0;){ -doneline: - s = rs+c->mindepth-1; - e = re; - while(s < e){ - /* scan */ - for(sp = s; ostate = state;){ - if(state->tab){ - if((state = state->tab[c->map[*sp]]) == 0) - goto nomatch; - } else { - mappedsp = c->map[*sp]; - for(l = state->alts; ; l = l->next){ - if(l == 0) - goto nomatch; - if(l->l == mappedsp){ - state = l->node; - break; - } - } - } -#ifdef DEBUG -print("state %d -0x%x-> state %d (out=%d)\n", ostate->id, *sp&0xFF, state->id, state->out); -#endif - if(state->out){ - unsigned char *bm = sp, *em = s+1; - if((k = (*matchfn)((char**)&bm, (char**)&em)) <= 0) - return(k); - rs = bm; - re = em; - state = c->root; - goto doneline; - } - if(--sp < rs){ - sp = fake; - break; - } - } - nomatch: - k = c->step[c->map[*sp]]-ostate->d-1; - if(k < ostate->shift1) - k = ostate->shift1; - if(k > ostate->shift2) - k = ostate->shift2; - s += k; - state = c->root; - } -#ifdef DEBUG -print("end of s<e loop: s=%d e=%d, rs=%d, re=%d\n", s, e, rs, re); -#endif - rs = re; /* we have analysed evrything up to here */ - } - return(k? -1:0); -} - -static void -freenode(Node *n) -{ - register Link *l, *ll; - - if(n->tab) - free((char *)n->tab); - for(l = n->alts; l; l = ll){ - ll = l->next; - freenode(l->node); - } - free((char *)n); -} - -void -re_cwfree(re_cw *cw) -{ - register Link *l; - - while(froot){ - l = froot->next; - free((char *)froot); - froot = l; - } - freenode(cw->root); - free((char *)cw); -} - -static Node * -newnode(re_cw *c, int d) -{ - static Node *next = 0, *lim = 0; - static incr = 1000; - - if(next == lim){ - next = (Node *)malloc(incr*sizeof(Node)); - if(next == 0){ - re_error("node malloc fail"); - return 0; - } - lim = next+incr; - } - next->d = d; - if(d > c->maxdepth) c->maxdepth = d; - next->id = c->nodeid++; - next->alts = 0; - next->tab = 0; - next->out = 0; - return(next++); -} - -static Link * -newlink(re_cw *c, int l, Node *n) -{ - static Link *next = 0, *lim = 0; - static incr = 1000; - - if(next == lim){ - next = (Link *)malloc(incr*sizeof(Node)); - if(next == 0){ - re_error("link malloc fail"); - return 0; - } - lim = next+incr; - } - next->l = c->map[l]; - next->node = n; - next->next = 0; - return(next++); -} //GO.SYSIN DD cw.c echo bm.c 1>&2 sed 's/.//' >bm.c <<'//GO.SYSIN DD bm.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -/* - this next one is dirty but i can't think of a good way out now. - essentially, LARGE has to be a bit bigger than the biggest buffer - we are ever given by rdfn -*/ -#define LARGE (100000000+2) - -static int bb(re_bm *, unsigned char*, unsigned char*); - -re_bm * -re_bmcomp(char *ppb, char *ppe, unsigned char *map) -{ - register unsigned char *pb = (unsigned char *)ppb; - register unsigned char *pe = (unsigned char *)ppe; - register int j; - int delta[256]; - register re_bm *b; - - b = (re_bm *)malloc(sizeof *b); - if(b == 0){ - re_error("b malloc fail"); - return 0; - } - b->patlen = pe-pb; - memmove((char *)b->cmap, (char *)map, sizeof b->cmap); - b->bmpat = malloc(b->patlen); - if(b->bmpat == 0){ - re_error("bmpat malloc fail"); - free((char*)b); - return 0; - } - if (bb(b, pb, pe) == 0){ - free((char*)b->bmpat); - free((char*)b); - return 0; - } - for(j = 0; pb+j < pe; j++) - b->bmpat[j] = b->cmap[pb[j]]; - for(j = 0; j < 256; j++) - delta[j] = b->patlen; - for(pe--; pb < pe; pb++) - delta[b->cmap[*pb]] = pe-pb; - delta[b->cmap[*pb]] = LARGE; - for(j = 0; j < 256; j++) - b->delta0[j] = delta[b->cmap[j]]; - return(b); -} - -static int -bb(register re_bm *b, register unsigned char *pb, register unsigned char *pe) -{ - int *f; - register m = pe-pb; - register i, k, j; - - f = (int *)malloc(sizeof(int)*(m+1)); - if(f == 0){ - re_error("delta2 f malloc"); - return 0; - } - pb--; - b->delta2 = (int *)malloc(sizeof(int)*(b->patlen+1)); - if(b->delta2 == 0){ - re_error("delta2 malloc"); - free((char*)f); - return 0; - } - for(i = 1; i <= m; i++) - b->delta2[i] = 2*m-i; - j = m; - k = m+1; - while(j > 0){ - f[j] = k; - while((k <= m) && (pb[j] != pb[k])){ - if(m-j < b->delta2[k]) - b->delta2[k] = m-j; - k = f[k]; - } - j--; - k--; - } - for(i = 1; i <= k; i++){ - if(b->delta2[i] > m+k-i) - b->delta2[i] = m+k-i; - } - free((char *)f); - return 1; -} - -re_bmexec(void *re_b, RDFN rdfn, MATCHFN matchfn) -{ - register re_bm *b = (re_bm*)re_b; - register unsigned char *sp; - register unsigned char *e, *s; - unsigned char *re, *rs; - register k; - - for(rs = 0; (k = (*rdfn)((char**)&rs, (char**)&re)) > 0; rs = s, re = e){ - e = re; - s = rs; - while(s < e){ - while((s += b->delta0[*s]) < e) - ; - if(s < e+b->patlen){ /* no match */ - s = e; - break; - } - s -= LARGE; - for(k = b->patlen-2, sp = s-1; k >= 0; k--) - if(b->cmap[*sp--] != b->bmpat[k]) - break; -/*print("k=%d s=%d sp=%d\n", k, s, sp);/**/ - if(k < 0){ - unsigned char *bm = ++sp, *em = s+1; - if((k = (*matchfn)((char**)&bm, (char**)&em)) <= 0) - return(k); - s = bm; - e = em; - } else { - /*j = b->delta2[k+1]; - k = b->delta0[cmap[*++sp]]; - if((j > k) || (k == LARGE)) - k = j; - s = sp+k;*/s++; - } - } - } - return(k); -} - -void -re_bmfree(re_bm *pat) -{ - free((char *)pat->delta2); - free(pat->bmpat); - free((char *)pat); -} //GO.SYSIN DD bm.c echo re.c 1>&2 sed 's/.//' >re.c <<'//GO.SYSIN DD re.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -re_re * -re_recomp(char *b, char *e, unsigned char *map) -{ - return(egprep(greparse, (unsigned char *)b, (unsigned char *)e, map, 1)); -} - -re_reexec(re_re *pat, char *b, char *e, char *match[10][2]) -{ - unsigned char *mb[10], *me[10], **rb, **re; - int n, i; - - if(match) - rb = mb, re = me; - else - rb = re = 0; - n = eg_match(pat, (unsigned char *)b, (unsigned char *)e, rb, re); - if(match) - for(i = 0; i < 10; i++){ - match[i][0] = (char *)mb[i]; - match[i][1] = (char *)me[i]; - } - return(n); -} - -static void -freeexpr(register Expr *e) -{ - switch(e->type) - { - case Literal: - case Dot: - case Carat: - case Dollar: - if(e->follow) - free((char *)e->follow); - break; - case Compcharclass: - case Charclass: - free((char *)e->r); - break; - case Cat: - case Alternate: - freeexpr(e->l); - freeexpr(e->r); - break; - case Star: - case Plus: - case Quest: - case Group: - case EOP: - freeexpr(e->l); - break; - case Backref: - default: - break; - } -} - -void -re_refree(re_re *re) -{ - if(re == 0) - return; - if(re->posbase) - free((char *)re->posbase); - if(re->root) - freeexpr(re->root); - if(re->ptr) - free((char *)re->ptr); - if(re->states) - free((char *)re->states); - /* leave br alone for now; it is hard to get right */ - free((char *)re); -} //GO.SYSIN DD re.c echo eg.c 1>&2 sed 's/.//' >eg.c <<'//GO.SYSIN DD eg.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -int re_debug = 0; - -#define RESET(r, ps) COPY(r, ps, begin) -#define SET(r, ps, n) {if(r->ps.base[n] == 0) r->ps.count++, r->ps.base[n] = r->ps.last, r->ps.last = n; } -#define GET(ps, n) for(n = ps.last; n > 0; n = ps.base[n]) -#define COPY(r, to, from) memmove((char *)r->to.base, (char *)r->from.base, r->maxid*sizeof(int)), r->to.count = r->from.count, r->to.last = r->from.last - -static State *addstate(re_re *r, Positionset *ps); -static int first(re_re *, Expr *); -static int match(re_re *, Expr *, int); -static State *nextstate(re_re *, State *, int); -#ifdef DEBUG -static void ppr(Positionset *, char *); -#endif - -typedef enum { NORMAL, ACCEPT, ACCEPT_EOP, FAIL } Out; - -static void -eptr(register re_re *r, register Expr *e) -{ - if((e->id < 0) || (e->id >= r->maxid)){ - EPR "eptr abort: r=%ld[maxid=%d] e=%ld[id=%d]\n", r, r->maxid, e, e->id); - abort(); - } - r->ptr[e->id] = e; - if((e->type != Charclass) && (e->type != Compcharclass)){ - if(e->l) - eptr(r, e->l); - if(e->r) - eptr(r, e->r); - } -} - -re_re * -egprep(enum Parsetype parser, unsigned char *b, unsigned char *e, unsigned char *map, int dotstar) -{ - register re_re *r; - Expr *ecomp; - int i; - - r = (re_re *)egmalloc(sizeof (re_re), "allocating re_re"); - if(r == 0) - return 0; - memset((char *)r, 0, sizeof (re_re)); - eg_lexinit((char *)b, (char *)e); - if(map) - memmove(r->mymap, (char *)map, 256); - else - for(i = 0; i < 256; i++) - r->mymap[i] = i; - eg_lex(); - if(dotstar){ - ecomp = eg_newexpr(Star, 0, eg_newexpr(Dot, '.', (Expr *)0, (Expr *)0), (Expr *)0); - ecomp = eg_newexpr(Cat, 0, ecomp, eg_eall(parser, r->mymap)); - } else - ecomp = eg_eall(parser, r->mymap); - r->root = eg_newexpr(EOP, '#', ecomp, (Expr *)0); - egpost(r); - r->carat = 0; - if(r->backref || r->parens) - egbr(r); - else - eginit(r, dotstar); - return(r); -} - -void -eginit(register re_re *r, int dotstar) -{ - int n; - -#ifdef DEBUG - if(TRACE(6)) - PR "eginit(r=%d, dotstar=%d)\n", r, dotstar); -#endif -#ifdef DEBUG - if(TRACE(10)){ - char buf[EPRINTSIZE]; - eg_epr(r->root, buf, 0); - PR "eginit: r=%d expr='%s'\n", r, buf); - } -#endif - r->ptr = (Expr **)egmalloc(r->maxid*sizeof(Expr *), "ptr"); - if (!r->ptr) - return; - eptr(r, r->root); - r->firstpos.base = (int *)egmalloc(n = r->maxid*sizeof(int), "first base"); - if (!r->firstpos.base){ - free((char*)r->ptr); - return; - } - r->begin.base = (int *)egmalloc(n, "begin base"); - if (!r->begin.base){ - free((char*)r->firstpos.base); - free((char*)r->ptr); - return; - } - r->tmp.base = (int *)egmalloc(n, "tmp base"); - if (!r->tmp.base){ - free((char*)r->begin.base); - free((char*)r->firstpos.base); - free((char*)r->ptr); - return; - } - memset((char *)r->begin.base, 0, n); - r->begin.count = 0; - r->begin.last = -1; - r->carat = dotstar; - RESET(r, firstpos); - if(first(r, r->root->l) == 0){ - /* - nullable, so include me - */ - SET(r, firstpos, r->root->id) - } - if(dotstar) - COPY(r, begin, firstpos); - eg_stateinit(r); - eg_clrstates(r); - eg_posinit(r); - (void)addstate(r, &r->firstpos); - eg_savestate(r, dotstar? nextstate(r, r->states, RE_CARAT):r->states); - eg_posset(r); -} - -unsigned char * -eg_quickmatch(register re_re *r, register unsigned char *b, register unsigned char *e, int endpts) -{ - register State *s, *t; - -#ifdef DEBUG - if(TRACE(10)){ - char buf[EPRINTSIZE]; - eg_epr(r->root, buf, 0); - PR "qm: r=%d expr='%s' endpts=%d\n", r, buf, endpts); - } -#endif - s = eg_startstate(r); - if(endpts&RE_BEG){ - if(!r->carat){ - if(t = s->tab[RE_CARAT]) - s = t; - else - s = nextstate(r, s, RE_CARAT); - if(s->out == FAIL) - s = eg_startstate(r); - } - if(s->out){ -#ifdef DEBUG - if(TRACE(6)) - PR "match at ^: '%s' out=%d\n", b, s->out); -#endif - return((s->out == FAIL)? 0:b); - } - } - while(b < e){ -#ifdef DEBUG - if(TRACE(4)) - PR "state %d@%d[%d pos]: char '%c'\n", s-r->states, (int)s, s->npos, *b); -#endif - if(t = s->tab[*(unsigned char *)b]) - s = t; - else - s = nextstate(r, s, *(unsigned char *)b); - if(s->out){ -#ifdef DEBUG - if(TRACE(6)) - PR "match at input '%s' out=%d\n", b, s->out); -#endif - return((s->out == FAIL)? 0:b); - } - b++; - } - if(endpts&RE_END){ - if(t = s->tab[RE_DOLLAR]) - s = t; - else - s = nextstate(r, s, RE_DOLLAR); - } - if(s->out){ -#ifdef DEBUG - if(TRACE(6)) - PR "match at $ '%s' out=%d\n", b, s->out); -#endif - return((s->out == FAIL)? 0:b); - } -#ifdef DEBUG - if(TRACE(3)){ - char buf[EPRINTSIZE]; - - eg_epr(r->root, buf, 1); - PR "pat = %s\n", buf); - } -#endif - return(0); -} - -unsigned char * -eg_lquickmatch(register re_re *r, register unsigned char *b, register unsigned char *e, int endpts) -{ - register State *s, *t; - int outedness = 0; - -#ifdef DEBUG - if(TRACE(10)){ - char buf[EPRINTSIZE]; - eg_epr(r->root, buf, 0); - PR "lqm: r=%d carat=%d expr='%s' endpts=%d\n", r, r->carat, buf, endpts); - } -#endif - s = eg_startstate(r); - if(endpts&RE_BEG){ - if(!r->carat){ - if(t = s->tab[RE_CARAT]) - s = t; - else - s = nextstate(r, s, RE_CARAT); - if(s->out == FAIL) - s = eg_startstate(r); - } - if(s->out){ -#ifdef DEBUG - if(TRACE(6)) - PR "match at ^: '%s' out=%d\n", b, s->out); -#endif - if(s->out == ACCEPT_EOP) - return(b); - else if(s->out == FAIL) - return(0); - outedness = 1; - } - } - /* - look for first match - */ - if(outedness == 0) - for(; b < e; b++){ -#ifdef DEBUG - if(TRACE(4)) - PR "state %d@%d[%d pos]: char '%c'\n", s-r->states, (int)s, s->npos, *b); -#endif - if(t = s->tab[*(unsigned char *)b]) - s = t; - else - s = nextstate(r, s, *(unsigned char *)b); - if(s->out){ -#ifdef DEBUG - if(TRACE(4)) - PR " out=%d, state %d@%d\n", s->out, - s-r->states, (int)s); -#endif - b++; - if((s->out == ACCEPT_EOP) || (s->out == FAIL)) - goto finish; - outedness = 1; - break; - } - } - /* - in the following loop, we have seen a match already - because only way outedness is zero is if b>=e - */ - for(; b < e; b++){ -#ifdef DEBUG - if(TRACE(4)) - PR "statex %d@%d[%d pos]: char '%c'\n", s-r->states, (int)s, s->npos, *b); -#endif - if(t = s->tab[*(unsigned char *)b]) - s = t; - else - s = nextstate(r, s, *(unsigned char *)b); - if(s->out == ACCEPT) - continue; - if((s->out == NORMAL) || (s->out == FAIL)){ -#ifdef DEBUG - if(TRACE(6)) - PR "unmatch at input '%s' out=%d\n", b, s->out); -#endif - return(b); - } - } - if(endpts&RE_END){ - if(t = s->tab[RE_DOLLAR]) - s = t; - else - s = nextstate(r, s, RE_DOLLAR); - } -finish: - if((s->out && (s->out != FAIL)) || outedness){ -#ifdef DEBUG - if(TRACE(6)) - PR "match at $ '%s' out=%d\n", b, s->out); -#endif - return(b); - } -#ifdef DEBUG - if(TRACE(3)){ - char buf[EPRINTSIZE]; - - eg_epr(r->root, buf, 1); - PR "lqm('%s') failed; out=%d, s->out=%d \n", buf, outedness, s->out); - } -#endif - return(0); -} - -static -match(register re_re *r, register Expr *e, int a) -{ - switch(e->type) - { - case Dollar: return(a == RE_DOLLAR); - case Carat: return(a == RE_CARAT); - case Dot: return(a < 256); - case Literal: return(r->mymap[a] == r->mymap[e->lit]); - case Charclass: if(a >= 256) return(0); - return(memchr((char *)e->r, r->mymap[a], (int)e->l) != 0); - case Compcharclass: - if(a >= 256) return(0); - return(memchr((char *)e->r, r->mymap[a], (int)e->l) == 0); - } - return(0); -} - - /* - generates the followset for a node in firstpos - */ - -static void -follow(register re_re *r, register Expr *e) -{ - register Expr *p; - - if(e->type == EOP) - return; - else - p = e->parent; - switch(p->type) - { - case EOP: - SET(r, firstpos, p->id) - break; - case Plus: - case Star: - (void)first(r, e); - follow(r, p); - break; - case Quest: - case Alternate: - follow(r, p); - break; - case Cat: - if(e == p->l){ - if(first(r, p->r) == 0){ - follow(r, p); - break; - } - } else - follow(r, p); - break; - case Group: - follow(r, p); - break; - } -} - - /* - first returns 0 if e is nullable and in the process, - sets up firstpos. - */ - -static -first(register re_re *r, register Expr *e) -{ - int k; - - switch(e->type) - { - case Carat: - case Dollar: - case Literal: - case Dot: - case Charclass: - case Compcharclass: - SET(r, firstpos, e->id) - return(1); - case EOP: - case Star: - case Quest: - (void)first(r, e->l); - return(0); - case Group: - case Plus: - return(first(r, e->l)); - case Cat: - return(first(r, e->l) || first(r, e->r)); - case Alternate: - k = first(r, e->r); - return(first(r, e->l) && k); - default: - EPR "bad type %d\n", e->type); - abort(); - return(0); - } -} - -static void -efollow(register re_re *r, register Expr *e) -{ - register i, *p; - - RESET(r, firstpos); - follow(r, e); - e->flen = r->firstpos.count; - e->follow = (int *)malloc((unsigned)(e->flen*sizeof(int))); - if(e->follow == 0){ - char buf[100]; - SPR buf, "efollow malloc fail(%ld)\n", e->flen); - re_error(buf); - return; - } - p = e->follow; - GET(r->firstpos, i) - *p++ = i; - if(p != e->follow+e->flen){ - char buf[100]; - SPR buf, "efollow length error: %d %ld\n", p-e->follow, e->flen); - re_error(buf); - return; - } -} - -static State * -addstate(register re_re *r, register Positionset *ps) -{ - register *p, j; - register State *s; - - s = r->states + eg_getstate(r); - memset((char *)s->tab, 0, sizeof(s->tab)); - s->pos = eg_posalloc(r, (int)ps->count); - s->npos = ps->count; - p = r->posbase+s->pos; - GET((*ps), j) - *p++ = j; - if(s->out = (ps->base[r->root->id] != 0)){ - if((ps->base[r->root->id] <= 0) && (ps->last == r->root->id)) - s->out = ACCEPT_EOP; /* marker for only the EOP marker */ - else - s->out = ACCEPT; - } - if(s->npos == 0) - s->out = FAIL; -#ifdef DEBUG - if(TRACE(3)){ - char buf[2000]; - eg_spr(s->npos, s->pos+r->posbase, buf); - PR "new state[%d]@%d %s,pos=%d out=%d\n", s-r->states, s, buf, s->pos, s->out); - } -#endif - return(s); -} - -static State * -nextstate(register re_re *r, register State *s, int a) -{ - register int p, *q, *eq; - register long i; - State *news; - Expr *e; - - RESET(r, tmp); -#ifdef DEBUG - if(TRACE(5)){ - char buf[2000]; - ppr(&r->tmp, buf); - PR "nextstate: reset: %s\n", buf); - } -#endif - for(i = s->npos, p = s->pos; i > 0; i--){ - e = r->ptr[r->posbase[p++]]; -#ifdef DEBUG - if(TRACE(11)){ - PR "i=%d e->type=%d\n", i, e->type); - } -#endif - if(e->type == EOP) continue; - if(match(r, e, a)){ -#ifdef DEBUG - if(TRACE(11)){PR "matched %c\n", a);} -#endif - if(e->follow == 0) - efollow(r, e); - for(q = e->follow, eq = q+e->flen; q < eq; q++){ - SET(r, tmp, *q) - } - } - } -#ifdef DEBUG - if(TRACE(5)){ - char buf[2000]; - ppr(&r->tmp, buf); - PR "nextstate(%d, '%c'): found %s\n", s-r->states, a, buf); - } -#endif - if(news = eg_stateof(r, &r->tmp)){ - if(a <= RE_DOLLAR) - s->tab[a] = news; - } else - news = addstate(r, &r->tmp); -#ifdef DEBUG - if(TRACE(5)){ - PR "nextstate(%d, '%c'): returning %ld %d out=%d\n", s-r->states, a, - (long)news, news-r->states, news->out); - } -#endif - return(news); -} - -void * -egmalloc(int n, char *s) -{ - char *x; - char buf[256]; - - if((x = malloc(n)) == 0){ - SPR buf, "malloc fail(%d): %s", n, s); - re_error(buf); - return 0; - } - return((void *)x); -} - -void * -egrealloc(char *p, int n, char *s) -{ - char *x; - char buf[256]; - - if((x = realloc(p, n)) == 0){ - SPR buf, "realloc fail(%d): %s", n, s); - re_error(buf); - return 0; - } - return((void *)x); -} - -#ifdef DEBUG -static void -ppr(register Positionset *ps, register char *p) -{ - register n; - - if(ps->count < 1){ - SPR p, "{}"); - return; - } - *p++ = '{'; - GET((*ps), n){ - SPR p, "%d[=%d],", n, ps->base[n]); - p = strchr(p, 0); - } - p[-1] = '}'; -} -#endif //GO.SYSIN DD eg.c echo egcomp.c 1>&2 sed 's/.//' >egcomp.c <<'//GO.SYSIN DD egcomp.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static Exprtype toktype; -static int toklit; -static char *beg, *end; -static int maxid; -static Expr *e0(void); -static Expr *d0(void); -static Expr *r18(void); -static void err(char*); -static int parno; -static jmp_buf gohome; -static unsigned char *mymap; - -void -egpost(re_re *r) -{ - r->maxid = maxid; - r->backref = r->root->backref; - r->parens = r->root->parens; -} - -Expr * -eg_newexpr(Exprtype t, int l, Expr *left, Expr *right) -{ - register Expr *e = (Expr *)egmalloc(sizeof(Expr), "eg_newexpr"); - - if (!e) - return 0; - e->type = t; - e->parent = 0; - e->lit = l; - if(e->lit) - e->id = maxid++; - else - e->id = 0; - e->backref = 0; - e->parens = 0; - if(e->l = left){ - left->parent = e; - if(left->backref) e->backref = 1; - if(left->parens) e->parens = 1; - } - if(e->r = right){ - right->parent = e; - if(right->backref) e->backref = 1; - if(right->parens) e->parens = 1; - } - e->follow = 0; - e->flen = 0; - e->reallit = 0; - return(e); -} - -void -eg_lexinit(char *b, char *e) -{ - beg = b; - end = e; - maxid = 1; - parno = 1; -} - -void -eg_lex(void) -{ - if(beg == end){ - toktype = EOP; - toklit = -1; - } else switch(toklit = *beg++) - { - case '.': toktype = Dot; break; - case '*': toktype = Star; break; - case '+': toktype = Plus; break; - case '?': toktype = Quest; break; - case '^': toktype = Carat; break; - case '$': toktype = Dollar; break; - case '[': toktype = Charclass; break; - case '\n': - case '|': toktype = Alternate; break; - case '(': toktype = Lpar; break; - case ')': toktype = Rpar; break; - case '\\': toktype = Backslash; - if(beg == end) - err("bad \\"); - else - toklit = *beg++; - break; - default: toktype = Literal; break; - } -} - -void -eg_epr(register Expr *e, char *res, int doset) -{ - char r1[EPRINTSIZE], r2[EPRINTSIZE], rid[EPRINTSIZE]; - int ids = 0; /* sort of a debugging flag */ - - if(e == 0){ - SPR res, "!0!"); - return; - } - r1[0] = 0; - if(ids) - SPR rid, "%d:", e->id); - else - rid[0] = 0; - switch(e->type) - { - case Literal: - if(doset) - eg_spr(e->flen, e->follow, r1); - SPR res, "%s'%c'%s", rid, e->lit, r1); - break; - case Dot: - case Carat: - case Dollar: - if(doset) - eg_spr(e->flen, e->follow, r1); - SPR res, "%s%c%s", rid, e->lit, r1); - break; - case Compcharclass: - case Charclass: - *res++ = '['; - if(e->type == Compcharclass) - *res++ = '^'; - memmove(res, (char *)e->r, (int)e->l); - res += (int)e->l; - *res++ = ']'; - *res = 0; - break; - case Cat: - eg_epr(e->l, r1, doset); - eg_epr(e->r, r2, doset); - SPR res, "%s%s%s", rid, r1, r2); - break; - case Alternate: - eg_epr(e->l, r1, doset); - eg_epr(e->r, r2, doset); - SPR res, "%s(%s|%s)", rid, r1, r2); - break; - case Star: - eg_epr(e->l, r1, doset); - SPR res, "%s(%s)*", rid, r1); - break; - case Plus: - eg_epr(e->l, r1, doset); - SPR res, "%s(%s)+", rid, r1); - break; - case Quest: - eg_epr(e->l, r1, doset); - SPR res, "%s(%s)?", rid, r1); - break; - case Group: - eg_epr(e->l, r1, doset); - SPR res, "%sG<%s>", rid, r1); - break; - case EOP: - eg_epr(e->l, r1, doset); - SPR res, "%s%s<EOP>", rid, r1); - break; - case Backref: - SPR res, "%s\\%d", rid, e->lit); - break; - default: - SPR res, "<undef type %d>", e->type); - err(res); - break; - } -} - -static void -ccl(int *count, char **str, int oldrange) -{ - register n; - int cnt; - char tab[256], *s; - int range, lastc, i; - -#define TSET(b) {if(tab[n = mymap[(b)]] == 0){ tab[n] = 1; cnt++; } } - - cnt = 0; - memset(tab, 0, sizeof tab); - lastc = -1; - range = 0; - /* scan for chars */ - for(; (beg < end); beg++){ - toklit = *beg; - if(*beg == ']'){ - if(!oldrange) - break; - if(lastc >= 0) - break; - } - if(*beg == '-'){ - if(lastc < 0){ - TSET('-') - lastc = *(unsigned char *)beg; - } else - range = 1; - continue; - } - if(*beg == '\\'){ - if(++beg >= end){ - err("unexpected eop after \\ in char class"); - beg--; - } - } - if(range){ - for(i = *(unsigned char *)beg; i >= lastc; i--) - TSET(i) - range = 0; - } else - TSET(*(unsigned char *)beg) - lastc = *(unsigned char *)beg; - } - if(range){ - if(oldrange) - TSET('-') - else - err("unterminated range in []"); - } - if(beg < end) - beg++; - else - err("eop during ccl"); - if(cnt == 0) - err("empty charclass"); - eg_lex(); - *count = cnt; - *str = s = (char *)egmalloc(cnt, "charclass defn"); - if (!s) - return; - for(n = 0; n < 256; n++) - if(tab[n]) - *s++ = n; -} - -/* - gre patterns: - - e0: e1 { '|' e1 }* - e1: e2 { e2 }* - e2: e3 { '*' | '?' | '+' | \{ m,n \} }* - e3: lit | '.' | '^' | '$' | '(' e0 ')' -*/ - -static Expr * -e3(void) -{ - Expr *e; - Exprtype t; - int cnt; - char *s; - - switch(toktype) - { - case Backslash: - if((toklit >= '1') && (toklit <= '9')){ - e = eg_newexpr(Backref, toklit-'0', (Expr *)0, (Expr *)0); - e->backref = 1; - } else - e = eg_newexpr(Literal, toklit, (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Literal: - e = eg_newexpr(Literal, toklit, (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Dot: - e = eg_newexpr(Dot, '.', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Carat: - e = eg_newexpr(Carat, '^', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Dollar: - e = eg_newexpr(Dollar, '$', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Charclass: - t = toktype; - if(*beg == '^'){ - t = Compcharclass; - beg++; - } - ccl(&cnt, &s, 0); - e = eg_newexpr(t, '[', (Expr *)0, (Expr *)0); - e->l = (Expr *)cnt; /* num of chars */ - e->r = (Expr *)s; /* chars */ - break; - case Lpar: - eg_lex(); - cnt = parno++; - e = e0(); - if(toktype == Rpar) - eg_lex(); - else - err("expected a ')'"); - e = eg_newexpr(Group, cnt, e, (Expr *)0); - e->parens = 1; - return(e); - case EOP: - default: - err("expected a lit or '('"); - e = 0; - } - return(e); -} - -static int -integer(void) -{ - int n; - - n = 0; - while((toktype == Literal) && (toklit >= '0') && (toklit <= '9')){ - n = 10*n + toklit-'0'; - eg_lex(); - } - return(n); -} - -static Expr * -ecopy(Expr *e) -{ - Expr *ee; - char res[256]; - - if(e == 0) - return(e); - switch(e->type) - { - case Literal: - case Dot: - case Carat: - case Dollar: - case Backref: - return(eg_newexpr(e->type, e->lit, (Expr *)0, (Expr *)0)); - case Compcharclass: - case Charclass: - ee = eg_newexpr(e->type, e->lit, (Expr *)0, (Expr *)0); - ee->r = (Expr *)egmalloc((int)e->l, "expr copy"); - if (!ee->r) - return 0; - ee->l = e->l; - memmove((char *)ee->r, (char *)e->r, (int)e->l); - return(ee); - case Cat: - case Alternate: - return(eg_newexpr(e->type, e->lit, ecopy(e->l), ecopy(e->r))); - case Star: - case Plus: - case Quest: - case Group: - case EOP: - return(eg_newexpr(e->type, e->lit, ecopy(e->l), (Expr *)0)); - default: - SPR res, "<undef type %d>", e->type); - err(res); - return((Expr *)0); - } -} - -static Expr * -edup(Expr *expr, int n, int opt) -{ - if(n == 1){ - expr = ecopy(expr); - if(opt) - expr = eg_newexpr(Quest, 0, expr, (Expr *)0); - return(expr); - } - return(eg_newexpr(Cat, 0, edup(expr, n-n/2, opt), edup(expr, n/2, opt))); -} - -static Expr * -range(Expr *expr) -{ - int beg, end; - Expr *e, *e1; - - if((toktype == Literal) && (toklit >= '0') && (toklit <= '9')) - beg = integer(); - else - err("expected a number in range"); - if((toktype == Literal) && (toklit == ',')){ - end = -1; - eg_lex(); - } else - end = -2; - if((toktype == Literal) && (toklit >= '0') && (toklit <= '9')) - end = integer(); - if((toktype == Backslash) && (toklit == '}')) - eg_lex(); - else - err("expected \\} in range"); - e1 = edup(expr, beg, 0); - if(end == -2) - e = e1; - else if(end == -1) - e = eg_newexpr(Cat, 0, e1, eg_newexpr(Star, 0, expr, (Expr *)0)); - else { - if(end < beg) - err("bad range specification"); - e = (end > beg)? eg_newexpr(Cat, 0, e1, edup(expr, end-beg, 1)) : e1; - } - return(e); -} - -static Expr * -e2(void) -{ - Expr *e; - Exprtype t; - - e = e3(); - while((toktype == Star) || (toktype == Plus) || (toktype == Quest) - || ((toktype == Backslash) && (toklit == '{'))){ - if((toktype == Backslash) && (toklit == '{')){ - eg_lex(); - e = range(e); - } else { - t = toktype; - eg_lex(); - e = eg_newexpr(t, 0, e, (Expr *)0); - } - } - return(e); -} - -static Expr * -e1(void) -{ - Expr *e, *f; - - e = e2(); - while((toktype == Literal) || (toktype == Dot) || (toktype == Lpar) - || (toktype == Backslash) || (toktype == Dollar) - || (toktype == Carat) || (toktype == Charclass)){ - f = e2(); - e = eg_newexpr(Cat, 0, e, f); - } - return(e); -} - -static Expr * -e0(void) -{ - Expr *e, *f; - - e = e1(); - while(toktype == Alternate){ - eg_lex(); - if(toktype == EOP) - continue; - f = e1(); - e = eg_newexpr(Alternate, 0, e, f); - } - return(e); -} - -/* - egrep patterns: - - d0: d1 { '|' d1 }* - d1: d2 { d2 }* - d2: d3 { '*' | '?' | '+' } - d3: lit | '.' | '^' | '$' | '(' d0 ')' -*/ - -static Expr * -d3(void) -{ - Expr *e; - Exprtype t; - int cnt; - char *s; - - switch(toktype) - { - case Backslash: - case Literal: - e = eg_newexpr(Literal, toklit, (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Dot: - e = eg_newexpr(Dot, '.', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Carat: - e = eg_newexpr(Carat, '^', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Dollar: - e = eg_newexpr(Dollar, '$', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Charclass: - t = toktype; - if(*beg == '^'){ - t = Compcharclass; - beg++; - } - ccl(&cnt, &s, 1); - e = eg_newexpr(t, '[', (Expr *)0, (Expr *)0); - e->l = (Expr *)cnt; /* num of chars */ - e->r = (Expr *)s; /* chars */ - break; - case Lpar: - eg_lex(); - e = d0(); - if(toktype == Rpar) - eg_lex(); - else - err("expected a ')'"); - return(e); - default: - err("expected a lit or '('"); - e = 0; - } - return(e); -} - -static Expr * -d2(void) -{ - Expr *e; - Exprtype t; - - e = d3(); - while((toktype == Star) || (toktype == Plus) || (toktype == Quest)){ - t = toktype; - eg_lex(); - e = eg_newexpr(t, 0, e, (Expr *)0); - } - return(e); -} - -static Expr * -d1(void) -{ - Expr *e, *f; - - e = d2(); - while((toktype == Literal) || (toktype == Dot) || (toktype == Lpar) - || (toktype == Dollar) || (toktype == Backslash) - || (toktype == Carat) || (toktype == Charclass)){ - f = d2(); - e = eg_newexpr(Cat, 0, e, f); - } - return(e); -} - -static Expr * -d0(void) -{ - Expr *e, *f; - - e = d1(); - while(toktype == Alternate){ - eg_lex(); - if(toktype == EOP) - continue; - f = d1(); - e = eg_newexpr(Alternate, 0, e, f); - } - return(e); -} - -/* - grep patterns: - - r0: r18 | '^' r18 | '^' r18 '$' | r18 '$' - r18: r17 { r17 }* - r17: r14 | r14 '*' | '\(' r18 '\)' - r14: lit | '.' | '*' | '\' d -*/ - -static Expr * -r14(void) -{ - Expr *e; - Exprtype t; - int cnt; - char *s; - - switch(toktype) - { - case Alternate: - case Plus: - case Quest: - case Star: - case Lpar: - case Rpar: - case Dollar: - case Carat: - case Literal: - e = eg_newexpr(Literal, toklit, (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Backslash: - if((toklit >= '1') && (toklit <= '9')){ - e = eg_newexpr(Backref, toklit-'0', (Expr *)0, (Expr *)0); - e->backref = 1; - } else { - e = eg_newexpr(Literal, toklit, (Expr *)0, (Expr *)0); - e->reallit = 1; - } - eg_lex(); - break; - case Dot: - e = eg_newexpr(Dot, '.', (Expr *)0, (Expr *)0); - eg_lex(); - break; - case Charclass: - t = toktype; - if(*beg == '^'){ - t = Compcharclass; - beg++; - } - ccl(&cnt, &s, 1); - e = eg_newexpr(t, '[', (Expr *)0, (Expr *)0); - e->l = (Expr *)cnt; /* num of chars */ - e->r = (Expr *)s; /* chars */ - break; - default: - err("expected a one-char RE"); - eg_lex(); /* make sure we don't loop */ - e = 0; - } - return(e); -} - -static Expr * -r17(void) -{ - Expr *e; - int cnt; - - if((toktype == Backslash) && (toklit == '(')){ - eg_lex(); - cnt = parno++; - e = r18(); - if((toktype == Backslash) && (toklit == ')')) - eg_lex(); - else - err("expected a closing \\)"); - e = eg_newexpr(Group, cnt, e, (Expr *)0); - e->parens = 1; - } else { - e = r14(); - if(toktype == Star){ - e = eg_newexpr(Star, 0, e, (Expr *)0); - eg_lex(); - } - } - return(e); -} - -static Expr * -r18(void) -{ - Expr *e, *f; - - e = r17(); - while(toktype != EOP){ - if((toktype == Backslash) && (toklit == ')')) - break; - f = r17(); - e = eg_newexpr(Cat, 0, e, f); - } - return(e); -} - -static Expr * -r0(void) -{ - Expr *e, *e1; - - if(toktype == Carat){ - e1 = eg_newexpr(Carat, '^', (Expr *)0, (Expr *)0); - eg_lex(); - } else - e1 = 0; - if(toktype == EOP) - e = e1; - else { - e = r18(); - /* did we see a dollar that is not a literal? */ - if(e && (toktype == EOP)){ - /* singleton dollar */ - if((e->type == Literal) && (e->lit == '$')) - e->type = Dollar; - /* any other dollar */ - if((e->type == Cat) && !e->r->reallit && (e->r->type == Literal) - && (e->r->lit == '$')) - e->r->type = Dollar; - } - if(e1){ - if(e) - e = eg_newexpr(Cat, 0, e1, e); - else - e = e1; - } - } - if(toktype == Dollar){ - if(e) - e = eg_newexpr(Cat, 0, e, eg_newexpr(Dollar, '$', (Expr *)0, (Expr *)0)); - else - e = eg_newexpr(Dollar, '$', (Expr *)0, (Expr *)0); - eg_lex(); - } - return(e); -} - -Expr * -eg_eall(enum Parsetype type, unsigned char *map) -{ - Expr *e; - - mymap = map; - if(setjmp(gohome) == 0){ - if(type == egrepparse) - while(toktype == Alternate) /* bogus but user-friendly */ - eg_lex(); - switch(type) - { - case greparse: e = e0(); break; - case grepparse: e = r0(); break; - case egrepparse: e = d0(); break; - } - if(type == egrepparse) - while(toktype == Alternate) /* bogus but user-friendly */ - eg_lex(); - if(toktype != EOP) - err("expected end of pattern"); - } else - e = 0; -/*{char buf1[4096]; e, buf1, 0); print("e='%s'\n", buf1);}/**/ - return(e); -} - -void -eg_spr(long c, int *p, register char *buf) -{ - if(c > 0){ - *buf++ = '{'; - *buf = 0; - while(--c > 0){ - SPR buf, "%d,", *p++); - buf = strchr(buf, 0); - } - SPR buf, "%d}", *p); - } else - SPR buf, "{}"); -} - -static void -err(char *s) -{ - char buf[4096]; - - if(toklit < 0) - SPR buf, "expression error: %s but got end of expression", s); - else - SPR buf, "expression error: %s near '%c'", s, toklit); - re_error(buf); - longjmp(gohome, 1); -} //GO.SYSIN DD egcomp.c echo eglit.c 1>&2 sed 's/.//' >eglit.c <<'//GO.SYSIN DD eglit.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static void traverse(Expr *); - -#define MAXLIT 256 /* is plenty big enough */ -static unsigned char tmp[MAXLIT], best[MAXLIT]; -static unsigned char *p; -static int bestlen; -#define START { p = tmp ; } -#define ADD(c) { if(p >= &tmp[MAXLIT]) p--; *p++ = c; } -#define FINISH { ADD(0) if((p-tmp) > bestlen) memmove((char *)best, (char *)tmp, bestlen = p-tmp); } - -re_lit(re_re *r, unsigned char **b, unsigned char **e) -{ - bestlen = 0; - START - traverse(r->root); - FINISH - if(bestlen < 3) - return(0); - *b = best; - *e = best+bestlen-1; - return(1); -} - -static void -traverse(register Expr *e) -{ - switch(e->type) - { - case Literal: - ADD(e->lit) - break; - case Charclass: - if((int)e->l == 1) - ADD(*(char *)e->r) - else { - FINISH - START - } - break; - case Cat: - traverse(e->l); - traverse(e->r); - break; - case Plus: - traverse(e->l); - FINISH /* can't go on past a + */ - START /* but we can start with one! */ - traverse(e->l); - break; - case EOP: - FINISH - START - traverse(e->l); - break; - default: - FINISH - START - break; - } -} //GO.SYSIN DD eglit.c echo egpos.c 1>&2 sed 's/.//' >egpos.c <<'//GO.SYSIN DD egpos.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#ifndef POSSTEP -#define POSSTEP (8*1024) -#endif - -void -eg_posinit(re_re *r) -{ - if(r->nposalloc <= 0) - r->nposalloc = POSSTEP; - r->posbase = (int *)egmalloc(r->nposalloc*sizeof(int), "posbase"); - if (!r->posbase) - return; - r->posnext = 0; -} - -void -eg_posset(re_re *r) -{ - r->posreset = r->posnext; -} - -eg_posalloc(re_re *r, int n) -{ - register j; - - if(n < 0){ - r->posnext = r->posreset; - return(-1); - } - j = r->posnext; - r->posnext += n; - if(r->posnext >= r->nposalloc){ - while((r->nposalloc < r->posnext) && (r->nposalloc < 256*1024)) - r->nposalloc *= 2; - if(r->nposalloc < r->posnext){ - r->nposalloc = (r->posnext+POSSTEP-1)/POSSTEP; - r->nposalloc *= POSSTEP; - } - r->posbase = (int *)egrealloc((char *)r->posbase, r->nposalloc*sizeof(int), "posbase"); - if (!r->posbase) - return(-1); - } - return(j); -} //GO.SYSIN DD egpos.c echo egstate.c 1>&2 sed 's/.//' >egstate.c <<'//GO.SYSIN DD egstate.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#ifndef MINSTATE -#define MINSTATE 32 -#endif - -void -eg_stateinit(re_re *r) -{ - r->statelim = MINSTATE; - r->states = 0; - r->threshhold = 2; -} - -void -eg_clrstates(re_re *r) -{ - r->nstates = 0; - if(r->states == 0){ - r->states = (State *)egmalloc(r->statelim*sizeof(State), "states"); - if (!r->states) - return; - } -} - -void -eg_savestate(re_re *r, State *s) -{ - r->initialstate = s-r->states; - r->istate = r->states[r->initialstate]; /* save for reset */ - r->istate.init = 1; - r->flushed = 0; -} - -State * -eg_startstate(re_re *r) -{ - register i; - - if(r->flushed > r->threshhold){ - int slim = r->statelim*2; - if(slim > 512) - slim = 512; - if(slim > r->statelim){ - for(i = 0; i < r->statelim; i++) - memset((char *)r->states[i].tab, 0, sizeof r->states[i].tab); - r->states = (State *)egrealloc((char *)r->states, - (r->statelim = slim)*sizeof(State), "states"); - if (!r->states) - return 0; - } - r->flushed = 0; - r->threshhold++; - r->states[r->initialstate] = r->istate; - r->nstates = r->initialstate+1; - } - return(r->states+r->initialstate); -} - -eg_getstate(register re_re *r) -{ - if(r->nstates >= r->statelim){ - r->nstates = r->initialstate+1; - r->states[r->initialstate] = r->istate; - (void)eg_posalloc(r, -1); - r->flushed++; - } - r->states[r->nstates].init = 0; - return(r->nstates++); -} - -State * -eg_stateof(re_re *r, register Positionset *ps) -{ - register State *s; - register i; - register *p, *e; - - for(i = 0, s = r->states; i < r->nstates; i++, s++){ - if(s->npos == ps->count){ - for(p = s->pos+r->posbase, e = p+s->npos; p < e;) - if(ps->base[*p++] == 0){ - goto next; - } - return(s); - } - next:; - } - return(0); -} //GO.SYSIN DD egstate.c echo egcw.c 1>&2 sed 's/.//' >egcw.c <<'//GO.SYSIN DD egcw.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static altlist(Expr*, unsigned char *); -static word(Expr*, unsigned char*); -static re_cw *pat; - -re_cw * -re_recw(re_re *r, unsigned char *map) -{ - unsigned char buf[20000]; - register Expr *e, *root = r->root; - - if(root->type != EOP) - return(0); - if(root->l->type != Cat) - return(0); - if(root->l->l->type != Star) - return(0); - if(root->l->l->l->type != Dot) - return(0); - e = root->l->r; - pat = re_cwinit(map); - if(altlist(e, buf) == 0) - return(0); - re_cwcomp(pat); - return(pat); -} - -static -altlist(Expr *e, unsigned char *buf) -{ - if(e->type == Alternate) - return(altlist(e->l, buf) && altlist(e->r, buf)); - return(word(e, buf)); -} - -static unsigned char *p; - -static -word(Expr *e, unsigned char *buf) -{ - if(buf) - p = buf; - if(e->type == Cat){ - if(word(e->l, (unsigned char *)0) == 0) - return(0); - if(word(e->r, (unsigned char *)0) == 0) - return(0); - } else if(e->type == Literal) - *p++ = e->lit; - else - return(0); - if(buf) - re_cwadd(pat, buf, p); - return(1); -} - //GO.SYSIN DD egcw.c echo egbr.c 1>&2 sed 's/.//' >egbr.c <<'//GO.SYSIN DD egbr.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#define DEBUG - -static Br *seq(Expr *); -static Br *spew(Br_type, Expr*, int); - -static Expr *eop; - -static char tabs[] = { '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', - '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0 -}; -#define SPACE(d) (&tabs[sizeof tabs - (d) - 1]) - -static void -init1(register Br *br, re_re *r) -{ - switch(br->type) - { - case br_re: - br->r = (re_re *)egmalloc(sizeof(re_re), "egbr"); -#ifdef DEBUG - if(TRACE(3)) - PR "b@%ld->r = %ld\n", br, br->r); -#endif - if(!br->r) - return; - memcpy((char *)br->r, (char *)r, sizeof(*r)); - if(br->e->type != EOP) - br->e = eg_newexpr(EOP, '#', br->e, (Expr *)0); - br->r->root = br->e; - br->e->id = eop->id; - br->r->br = br; - br->r->backref = br->r->root->backref; - br->r->parens = br->r->root->parens; - eginit(br->r, br == r->br); - break; - case br_star: - case br_plus: - case br_quest: - case br_group: - init1(br->lb, r); - break; - case br_cat: - case br_alt: - init1(br->lb, r); - init1(br->rb, r); - break; - } -} - -void -egbr(re_re *r) -{ - eop = 0; -/* -#ifdef DEBUG - if(1||TRACE(3)){ - char buf[EPRINTSIZE]; - - eg_epr(r->root, buf, 0); - PR "egbr(%s) ->\n", buf); - eg_brpr(seq(r->root)); - } -#endif -/**/ - egcanon(r->root); - r->br = seq(r->root); -#ifdef DEBUG - if(TRACE(3)){ - char buf[EPRINTSIZE]; - - eg_epr(r->root, buf, 0); - PR "egbr(%s) ->\n", buf); - eg_brpr(r->br); - } -#endif - init1(r->br, r); -} - -#ifdef DEBUG -static void -brpr1(Br *b, int depth) -{ - char buf[EPRINTSIZE]; - - PR "%s%d@", SPACE(depth), (int)b); - switch(b->type) - { - case br_br: - PR "BR %d\n", b->group); - break; - case br_re: - eg_epr((Expr *)b->e, buf, 0); - if(((Expr *)b->e)->backref) PR "X"); - if(((Expr *)b->e)->parens) PR "()"); - PR "RE/%s/%d\n", buf, (int)b->r); - break; - case br_group: - PR "GROUP %d\n", b->group); - brpr1(b->lb, depth+1); - break; - case br_quest: - PR "BR?"); - brpr1(b->lb, depth+1); - break; - case br_plus: - PR "BR+\n"); - brpr1(b->lb, depth+1); - break; - case br_star: - PR "BR*\n"); - brpr1(b->lb, depth+1); - break; - case br_cat: - PR "BR CAT\n"); - brpr1(b->lb, depth+1); - brpr1(b->rb, depth+1); - break; - case br_alt: - PR "BR |\n"); - brpr1(b->lb, depth+1); - brpr1(b->rb, depth+1); - break; - default: - PR "BADTYPE/%d/\n", b->type); - break; - } -} - -void -eg_brpr(Br *br) -{ - brpr1(br, 0); -} -#endif - -static Br * -seq(Expr *e) -{ - Br *br; - - if(e->type == EOP) - eop = e; - if(!e->backref && !e->parens) - return(spew(br_re, e, -1)); - switch(e->type) - { - case Cat: - br = spew(br_cat, (Expr *)0, -1); - br->lb = seq(e->l); - br->rb = seq(e->r); - return(br); - case Alternate: - br = spew(br_alt, (Expr *)0, -1); - br->lb = seq(e->l); - br->rb = seq(e->r); - return(br); - case Star: - br = spew(br_star, (Expr *)0, -1); - br->lb = seq(e->l); - return(br); - case Plus: - br = spew(br_plus, (Expr *)0, -1); - br->lb = seq(e->l); - return(br); - case Quest: - br = spew(br_quest, (Expr *)0, -1); - br->lb = seq(e->l); - return(br); - case Group: - br = spew(br_group, (Expr *)0, e->lit); - br->lb = seq(e->l); - return(br); - case Backref: - return(spew(br_br, e->l, e->lit)); - case EOP: - return(seq(e->l)); - default: - return(spew(br_re, e, -1)); - } -} - -static Br * -spew(Br_type t, Expr *d, int g) -{ - Br *b; - - b = (Br *)egmalloc(sizeof(Br), "back ref malloc"); - if(!b) - return(0); - b->type = t; - b->e = d; - b->group = g; - b->r = 0; - b->rb = b->lb = 0; - return(b); -} //GO.SYSIN DD egbr.c echo egerror.c 1>&2 sed 's/.//' >egerror.c <<'//GO.SYSIN DD egerror.c' -#include <stdio.h> -#include "re.h" - -void -re_error(char *s) -{ - fprintf(stderr, "pattern error: %s\n", s); - exit(1); - /* NOTREACHED */ -} //GO.SYSIN DD egerror.c echo refile.c 1>&2 sed 's/.//' >refile.c <<'//GO.SYSIN DD refile.c' -#include <string.h> -#include <stdio.h> -#if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -#include <stdlib.h> -#endif -#include "re.h" - -#ifdef MAIN - -main(argc, argv) - char **argv; -{ - Expr *re; - re_re *r; - char *pat; - FILE *tmp; - char *tmpn; - extern char *tmpnam(); - char e1[4096], e2[4096]; - unsigned char map[256]; - int n; - - if(argc != 2){ - fprintf(stderr, "Usage: efile pattern\n"); - exit(1); - } - pat = argv[1]; - for(n = 0; n < 256; n++) - map[n] = n; - r = re_recomp(pat, pat+strlen(pat), map); - if(r == 0) - exit(1); - re = r->root; - tmpn = tmpnam((char *)0); - if((tmp = fopen(tmpn, "w+r")) == NULL){ - perror(tmpn); - exit(1); - } - eg_epr(re, e1, 0); - re_refile(r, tmp); - rewind(tmp); - r = re_filere(tmp); - eg_epr(r->root, e2, 0); - if(strcmp(e1, e2)) - printf("MISMATCH!!\nbefore:\n%s\nafter:\n%s\n", e1, e2); - else - printf("ok\n"); - re_refree(r); - exit(0); -} -#else - -#include "lre.h" - -#if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -static void etofile(Expr *, FILE *); -static Expr *filetoe(FILE *); -#else -static void etofile(); -static Expr *filetoe(); -#endif - -#define REVERSION 2 - -void -re_refile(re_re *re, FILE *fp) -{ - if(re == 0) - return; - if(putc(REVERSION, fp) != REVERSION){ - re_error("couldn't write version"); - return; - } - if(fwrite(re->mymap, 256, 1, fp) != 1){ - re_error("couldn't write char map"); - return; - } - putw(re->carat, fp); - etofile(re->root, fp); -} - -static void -etofile(Expr *e, FILE *fp) -{ - Expr ee; - - if(e == 0){ - e = ⅇ - e->type = Null; - } - putw(e->type, fp); - putw(e->lit, fp); - putc(e->backref, fp); - putc(e->parens, fp); - switch(e->type) - { - case Null: - case Literal: - case Dot: - case Carat: - case Dollar: - case Backref: - break; - case Compcharclass: - case Charclass: - putw((int)e->l, fp); - fwrite((char *)e->r, (int)e->l, 1, fp); - break; - case Cat: - case Alternate: - etofile(e->l, fp); - etofile(e->r, fp); - break; - case Star: - case Plus: - case Quest: - case Group: - case EOP: - etofile(e->l, fp); - break; - } -} - -re_re * -re_filere(FILE *fp) -{ - register re_re *r; - - r = (re_re *)egmalloc(sizeof (re_re), "allocating re_re"); - if(r == 0) - return(0); - memset((char *)r, 0, sizeof (re_re)); - if(getc(fp) != REVERSION){ - re_error("read bad version number"); - goto err; - } - if(fread(r->mymap, 256, 1, fp) != 1){ - re_error("couldn't read char map"); - goto err; - } - r->carat = getw(fp); - eg_lexinit((char *)0, (char *)0); - if((r->root = filetoe(fp)) == 0){ -err: - free((char *)r); - return(0); - } - egpost(r); - if(r->backref || r->parens) - egbr(r); - else - eginit(r, r->carat); - return(r); -} - -static Expr * -filetoe(FILE *fp) -{ - Expr *ee, *er, *el, *ret; - int t, l; - Exprtype et; - char res[256]; - int br, parens; - - t = getw(fp); - if((t == EOF) && feof(fp)) - return(0); - et = (Exprtype)t; - l = getw(fp); - br = getc(fp); - parens = getc(fp); - switch(et) - { - case Null: - return(0); - case Literal: - case Dot: - case Carat: - case Dollar: - case Backref: - ret = eg_newexpr(et, l, (Expr *)0, (Expr *)0); - break; - case Compcharclass: - case Charclass: - ee = eg_newexpr(et, l, (Expr *)0, (Expr *)0); - l = getw(fp); - ee->r = (Expr *)egmalloc(l, "filetoe copy"); - if (!ee->r) - return 0; - ee->l = (Expr *)l; - fread((char *)ee->r, l, 1, fp); - ret = ee; - break; - case Cat: - case Alternate: - el = filetoe(fp); - er = filetoe(fp); - ret = eg_newexpr(et, l, el, er); - break; - case Star: - case Plus: - case Quest: - case Group: - case EOP: - el = filetoe(fp); - ret = eg_newexpr(et, l, el, (Expr *)0); - break; - default: - SPR res, "<reading expr undef type %d lit=%d>", t, l); - re_error(res); - return((Expr *)0); - } - ret->backref = br; - ret->parens = parens; - return(ret); -} -#endif //GO.SYSIN DD refile.c echo egparen.c 1>&2 sed 's/.//' >egparen.c <<'//GO.SYSIN DD egparen.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -static int egparen(Expr *e); - -int -re_paren(re_re *re) -{ - return egparen(re->root); -} - -static int -egparen(Expr *e) -{ - if(e == 0) - return(0); - switch(e->type) - { - case Null: - case Literal: - case Dot: - case Carat: - case Dollar: - case Backref: - case Compcharclass: - case Charclass: - break; - case Cat: - case Alternate: - return(egparen(e->l)+egparen(e->r)); - case Star: - case Plus: - case Quest: - case EOP: - return(egparen(e->l)); - case Group: - return(1+egparen(e->l)); - } - return(0); -} //GO.SYSIN DD egparen.c echo egmatch.c 1>&2 sed 's/.//' >egmatch.c <<'//GO.SYSIN DD egmatch.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#define DEBUG - -static unsigned char *eg_slowmatch(Br *, unsigned char *, unsigned char *, int); -static unsigned char *wholeb, *wholee; -static unsigned char *start[10]; -static int len[10]; -static void undobr(Br *); /* undo group assignements */ - -eg_match(register re_re *r, register unsigned char *b, register unsigned char *e, unsigned char **rb, unsigned char **re) -{ - int i, ret; - -#ifdef DEBUG - if(TRACE(2)){ - PR "eg_match(%d->%d, %d, %d)\n", (int)r, (int)r->br, (int)b, (int)e); - if(r->br) - eg_brpr(r->br); - } -#endif - if((rb == 0) != (re == 0)){ - re_error("must supply both or none of group pointers"); - return(0); - } - if(r->backref || r->parens || rb){ - wholeb = e; - for(i = 1; i < 10; i++) - start[i] = 0; - if(r->br == 0) - egbr(r); - ret = (wholee = eg_slowmatch(r->br, b, e, RE_BEG|RE_END)) != 0; - if(rb && ret){ - rb[0] = wholeb; - re[0] = wholee; - for(i = 1; i < 10; i++){ - rb[i] = start[i]; - re[i] = rb[i]+len[i]; - } -#ifdef DEBUG - if(TRACE(1)){ - PR "eg_match groups:"); - for(i = 0; i < 10; i++) - if(rb[i])PR " %d: %d@%d", i, rb[i], re[i]-rb[i]); - PR "\n"); - } -#endif - } -#ifdef DEBUG - else { - if(TRACE(1)){ - PR "eg_match groups: [%d - %d]\n", wholeb, wholee); - for(i = 1; i < 10; i++) - if(start[i])PR " %d: %d@%d", i, start[i], len[i]); - PR "\n"); - } - } -#endif - } else - ret = eg_quickmatch(r, b, e, RE_BEG|RE_END) != 0; - return(ret); -} - -static unsigned char * -eg_slowmatch(Br *br, unsigned char *b, unsigned char *e, int endpts) -{ - int i; - unsigned char *me, *end; - unsigned char *beg, *lbeg, *llbeg, *rbeg, *rend, *lm, *rm; -#ifdef DEBUG - char buf[EPRINTSIZE]; - static id = 1; - int myid = id++; -#endif - -#define BOFF(x) ((x)? (endpts&~RE_BEG):endpts) -#define EOFF(x) ((x)? (endpts&~RE_END):endpts) - - if(br == 0) /* nothing to match - we won! */ - return(b); -#ifdef DEBUG - if(TRACE(3)) - PR "slowmatch(br=%d, [b,e]=%d,%d id=%d, endpt=%d)\n", br, b, e, myid, endpts); -#endif - switch(br->type) - { - case br_br: - i = br->group; -#ifdef DEBUG - if(TRACE(3)) - PR "br[%d]: %d,%d b=%d,e=%d\n", i, (int)start[i], len[i], b, e); -#endif - if(start[i] == 0) - return(0); - if((len[i] > e-b) || memcmp((char *)b, (char *)start[i], len[i])) - return(0); - if(wholeb > b) wholeb = b; -#ifdef DEBUG - if(TRACE(3)) - PR "br[%d]: matched\n", i); -#endif - return(b+len[i]); - - case br_re: -#ifdef DEBUG - if(TRACE(3)){ - eg_epr(br->e, buf, 0); - PR "matching RE(%s)@%d against '", buf, br->r); - WR((char *)b, e-b); - PR "' id=%d\n", myid); - } -#endif - if((me = eg_lquickmatch(br->r, b, e, endpts)) == 0) - return(0); -#ifdef DEBUG - if(TRACE(3)){ - PR "--%s matched '", buf); - WR((char *)b, me-b); - PR "'[%d %d] id=%d\n", (int)b, (int)me, myid); - } -#endif - if(wholeb > b) - wholeb = b; - return(me); - - case br_group: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching GROUP%d against '", br->group); - WR((char *)b, e-b); - PR "' id=%d\n", myid); - } -#endif - if((me = eg_slowmatch(br->lb, b, e, endpts)) == 0){ - undobr(br->lb); - return(0); - } -#ifdef DEBUG - if(TRACE(3)){ - PR "--G%d matched '", br->group); - WR((char *)b, me-b); - PR "'[%d %d]\n", (int)b, (int)me); - } -#endif - if(wholeb > b) - wholeb = b; - start[br->group] = b; - len[br->group] = me-b; - return(me); - - case br_quest: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching BR? against '", buf); - WR((char *)b, e-b); - PR "'\n"); - } -#endif - if(lbeg = eg_slowmatch(br->lb, b, e, endpts)){ - return(lbeg); - } - undobr(br->lb); - return(b); - - case br_plus: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching BR+ against '", buf); - WR((char *)b, e-b); - PR "' id=%d\n", myid); - } -#endif - if((lbeg = eg_slowmatch(br->lb, b, e, endpts)) == 0){ - undobr(br->lb); - return(0); - } - llbeg = b; - while(beg = eg_slowmatch(br->lb, lbeg, e, BOFF(lbeg != b))){ - llbeg = lbeg, lbeg = beg; - } -#ifdef DEBUG - if(TRACE(3)){ - PR "--+ matched [%d %d]'", (int)llbeg, (int)lbeg); - WR((char *)llbeg, lbeg-llbeg); - PR "' id=%d\n", myid); - } -#endif - return(eg_slowmatch(br->lb, llbeg, e, BOFF(llbeg != b))); - - case br_star: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching BR* against '", buf); - WR((char *)b, e-b); - PR "'\n"); - } -#endif - llbeg = lbeg = b; - while(beg = eg_slowmatch(br->lb, lbeg, e, BOFF(lbeg != b))) - llbeg = lbeg, lbeg = beg; -#ifdef DEBUG - if(TRACE(3)){ - PR "--* matched '"); - WR((char *)lbeg, lbeg-llbeg); - PR "'[%d %d]\n", (int)llbeg, (int)lbeg); - } -#endif - if(beg = eg_slowmatch(br->lb, llbeg, e, BOFF(llbeg != b))) - return(beg); - undobr(br->lb); - return(b); - - case br_cat: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching BRcat against '", buf); - WR((char *)b, e-b); - PR "' id=%d\n", myid); - } -#endif - /* - this is not so hard. - we try all possible matches of the left half, - and record the match that gave the longest - valid match on the right half - */ - rend = 0; - for(end = e; b <= e; e = beg-1){ - if((beg = eg_slowmatch(br->lb, b, e, EOFF(e != end))) == 0){ - break; - } -#ifdef DEBUG - if(TRACE(3)){ - PR "--cat matched '"); - WR((char *)b, beg-b); - PR "'[%d %d] id=%d\n", (int)b, (int)beg, myid); - } -#endif - if((me = eg_slowmatch(br->rb, beg, end, BOFF(beg != b))) == 0){ - continue; /* no match of right half */ - } -#ifdef DEBUG - if(TRACE(3)){ - PR "----cat matched '"); - WR((char *)b, beg-b); - PR "'[%d %d] id=%d\n", (int)b, (int)beg, myid); - } -#endif - if(me > rend){ - rend = me; - rbeg = beg; -#ifdef DEBUG - if(TRACE(3)){ - PR "--++-- cat new max rb=%d re=%d\n", (int)rbeg, (int)rend); - } -#endif - } - } - if(rend == 0){ - undobr(br->lb); - undobr(br->rb); - return(0); - } - (void)eg_slowmatch(br->lb, b, rbeg, EOFF(rbeg != end)); - return(eg_slowmatch(br->rb, rbeg, end, BOFF(rbeg != b))); - - case br_alt: -#ifdef DEBUG - if(TRACE(3)){ - PR "matching BR| against '", buf); - WR((char *)b, e-b); - PR "'\n"); - } -#endif - if(lm = eg_slowmatch(br->lb, b, e, endpts)){ -#ifdef DEBUG - if(TRACE(3)){ - PR "--|L matched '"); - WR((char *)b, lm-b); - PR "'[%d %d]\n", (int)b, (int)lm); - } -#endif - } - if(rm = eg_slowmatch(br->rb, b, e, endpts)){ -#ifdef DEBUG - if(TRACE(3)){ - PR "--|R matched '"); - WR((char *)b, rm-b); - PR "'[%d %d]\n", (int)b, (int)rm); - } -#endif - } - if(lm > rm){ - undobr(br->rb); - return(eg_slowmatch(br->lb, b, e, endpts)); - } else { - if(rm == 0){ - undobr(br->lb); - undobr(br->rb); - return(0); - } else { - undobr(br->lb); - return(beg); - } - } - } - abort(); - return(0); -} - -static void -undobr(register Br *br) -{ - switch(br->type) - { - case br_group: - start[br->group] = 0; - undobr(br->lb); - break; - case br_star: - case br_plus: - case br_quest: - undobr(br->lb); - break; - case br_cat: - case br_alt: - undobr(br->lb); - undobr(br->rb); - break; - } -} //GO.SYSIN DD egmatch.c echo egcanon.c 1>&2 sed 's/.//' >egcanon.c <<'//GO.SYSIN DD egcanon.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#define DEBUG - -static Expr **proot; - -#define PURE(e) (!(e)->backref && !(e)->parens) -#define PROC(kid) if(ee = proc(kid)){ ee->parent = (kid)->parent; free((char *)kid); kid = ee; } - -static Expr * -proc(Expr *e) -{ - Expr *ee; - - if(e->type == Cat){ - if(PURE(e->l)){ - if(proot){ - *proot = eg_newexpr(Cat, 0, *proot, e->l); - return((ee = proc(e->r))? ee:e->r); - } else - proot = &e->l; - } else { - PROC(e->l) - } - if(PURE(e->r)){ - if(proot){ - *proot = eg_newexpr(Cat, 0, *proot, e->r); - return(e->l); - } else - proot = &e->r; - } else { - PROC(e->r) - } - return(0); - } - proot = 0; - switch(e->type) - { - case Alternate: - PROC(e->l) - proot = 0; - PROC(e->r) - break; - case Star: - case Plus: - case Quest: - case EOP: - case Group: - PROC(e->l) - break; - } - proot = 0; - return(0); -} - -void -egcanon(Expr *e) -{ -#ifdef DEBUG - char before[EPRINTSIZE], after[EPRINTSIZE]; -#endif - -#ifdef DEBUG - eg_epr(e, before, 0); - if(TRACE(3)){ - PR "egcanon(%s):\n", before); - } -#endif - proot = 0; - if(!PURE(e)) - proc(e); -#ifdef DEBUG - eg_epr(e, after, 0); - if(TRACE(3)){ - PR "egcanon returns %s\n", after); - } - if(strcmp(before, after)){ - EPR "URK! egcanon did not preserve!\nbefore=%s\n after=%s\n", before, after); - exit(1); - } -#endif -} //GO.SYSIN DD egcanon.c echo hdr.h 1>&2 sed 's/.//' >hdr.h <<'//GO.SYSIN DD hdr.h' -#ifdef MAIN -#define EXTERN -#else -#define EXTERN extern -#endif - -#include "io.h" -#include <setjmp.h> - -EXTERN int ifd; - -EXTERN long lnum; -EXTERN long nbytes; -EXTERN long noverflow; -EXTERN int bflag; -EXTERN int cflag; -EXTERN int hflag; -EXTERN int iflag; -EXTERN int lflag; -EXTERN int Lflag; -EXTERN int nflag; -EXTERN int oneflag; -EXTERN int sflag; -EXTERN int vflag; -EXTERN int xflag; -EXTERN long nmatch; -EXTERN char *progname; -EXTERN char *curfile; -EXTERN int prname; -EXTERN int offsetunit; -EXTERN jmp_buf env; -EXTERN int longlinewarned; - -extern char *optarg; -extern int optind; -extern int getopt(int, char**, char*); -extern void *memcpy(void*, const void*, int); -#ifndef MEMMOVE -#define memmove(to, from, n) memcpy(to, from, n) -#else -extern void *memmove(void*, const void*, int); -#endif -extern void *memchr(void*, int, int); -extern char *memset(void*, int, int); -extern int memcmp(void*, void*, int); -extern int strlen(char *); -extern int strcmp(char *, char *); -extern char *strchr(char *, int); -extern char *strrchr(char *, int); -extern void *calloc(int, int); -extern void free(void*); -extern void *malloc(int); -extern void *realloc(void*, int); -extern int open(char *, int, ...); -extern int read(int, char*, unsigned); -extern int close(int); -extern int tolower(int); -extern void abort(void); -extern void perror(char*); -extern void exit(int); - -typedef void (*SUCCFN)(char*,char*); -extern void count(char *, char *); /* updates lnum,nbytes */ -extern void count_m(char *, char *); /* updates lnum,nbytes */ -extern int cwxrd(char**,char**); -extern int cwxmatch(char**,char**); -extern int bmxmatch(char**,char**); /* variants for -x for cw/bm */ -extern void dogre(Parsetype, char*, char*, unsigned char*, PROCFN*, void**, RDFN*, MATCHFN*); -extern void dofgrep(char*, char*, unsigned char*, PROCFN*, void**, RDFN*, MATCHFN*); -extern re_re *egprep(enum Parsetype, unsigned char*, unsigned char*, unsigned char*, int); -extern int greprd(char**, char**); -extern int grepmatch(char**, char**); /* normal arguments to *find */ -extern void inc(char*, char*); -extern void inc_m(char*, char*); /* increments nmatch */ -extern void null(char*, char*); /* does nothing */ -extern void oneshot(char*, char*); /* increments nmatch, does the longjmp */ -extern void pr(char*, char*); -extern void pr_m(char*, char*); -extern int re_lit(re_re*, unsigned char**, unsigned char**); - -EXTERN SUCCFN succfn, failfn, succ2fn; -EXTERN re_re *globre; /* the current re */ - -#define MAXLINE 65536 - -#ifdef c_plusplus -#define UNUSED -#define UNUSED2 -#else -#ifdef __cplusplus -#define UNUSED -#define UNUSED2 -#else -#define UNUSED unused -#define UNUSED2 unused2 -#endif -#endif //GO.SYSIN DD hdr.h echo io.h 1>&2 sed 's/.//' >io.h <<'//GO.SYSIN DD io.h' -#ifndef EPR - -#ifdef USE_STDIO -#define PR printf( -#define EPR fprintf(stderr, -#define SPR sprintf( -#define WR(b,n) fwrite(b, 1, n, stdout) -#define FLUSH fflush(stdout) -#else -#include <fio.h> -extern int fprint(int, char*, ...); -extern int sprint(char*, char*, ...); - -#define PR fprint(1, -#define EPR fprint(2, -#define SPR sprint( -#define WR(b,n) write(1, b, (long)(n)) -#define FLUSH Fflush(1) -#endif - -#endif //GO.SYSIN DD io.h echo re.h 1>&2 sed 's/.//' >re.h <<'//GO.SYSIN DD re.h' -#ifndef RE_H -#define RE_H - -# if defined(__cplusplus) -extern "C" { /* C++ 2.0 */ -# endif - -typedef struct re_bm -{ - int delta0[256], *delta2; - unsigned char cmap[256]; - char *bmpat; - int patlen; -} re_bm; - -typedef struct re_cw -{ - int maxdepth, mindepth; - char seenerror; /* set if we called re_error */ - long nodeid; - int step[256]; - unsigned char map[256]; - struct Node *root; -} re_cw; - -typedef enum -{ - Literal, Dot, Carat, Dollar, Charclass, Compcharclass, /* 0-5 */ - Cat, Alternate, Star, Plus, Quest, Backref, Group, EOP, /* 6-13 */ - /* not in grammar, just helping */ - Lpar, Rpar, Backslash, Null -} Exprtype; - -typedef struct Expr -{ - Exprtype type; - char reallit; /* just for dollar and -G, dammit! */ - char backref; /* backref used here or below */ - char parens; /* parens used here or below */ - char seenerror; /* set if we called re_error */ - int id; - unsigned int lit; - long flen; - int *follow; - struct Expr *l, *r, *parent; -} Expr; -typedef enum Parsetype { greparse, grepparse, egrepparse } Parsetype; - -#define RE_DOLLAR 256 -#define RE_CARAT 257 -#define RE_HIGH 258 /* always 1+last constant */ - -typedef struct State -{ - struct State *tab[RE_HIGH]; - char out; /* matched */ - char init; /* inital state */ - long npos; - int pos; /* index into posbase */ -} State; - -typedef struct Positionset -{ - long count; - int last; - int *base; -} Positionset; - -typedef enum { - br_re, br_group, br_br, br_cat, br_alt, br_star, br_plus, br_quest -} Br_type; - -typedef struct Br -{ - Br_type type; - Expr *e; - int group; - struct re_re *r; - struct Br *lb, *rb; -} Br; - -typedef struct re_re -{ - int *posbase; - int nposalloc, posnext, posreset; - int maxid; - Expr *root; - Expr **ptr; - unsigned char mymap[256]; - Positionset firstpos, begin, tmp; - int nstates, statelim; - State *states; - State istate; - int initialstate; - int carat; - int flushed; - int threshhold; /* resize cache every threshhold flushes */ - int backref; - int parens; - Br *br; -} re_re; - -/* - matching routine endpoint markers -*/ -#define RE_BEG 1 /* beginning matches ^ */ -#define RE_END 2 /* end matches $ */ - -# ifdef USE_STDIO -# include <stdio.h> -# if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -extern void re_refile(re_re*, FILE*); -extern re_re *re_filere(FILE*); -# else -extern void re_refile(); -extern re_re *re_filere(); -# endif -# endif /* USE_STDIO */ - -# if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -# define VOID void -typedef int (*RDFN)(char**, char**); -typedef int (*MATCHFN)(char**,char**); -typedef int (*PROCFN)(VOID*, RDFN, MATCHFN); -extern re_bm *re_bmcomp(char*, char*, unsigned char*); -extern int re_bmexec(VOID*, RDFN, MATCHFN); -extern void re_bmfree(re_bm*); -extern void re_cwadd(re_cw*, unsigned char*, unsigned char*); -extern void re_cwcomp(re_cw*); -extern int re_cwexec(VOID*, RDFN, MATCHFN); -extern void re_cwfree(re_cw*); -extern re_cw *re_cwinit(unsigned char*); -extern void re_error(char*); -extern int re_paren(re_re *e); -extern re_re *re_recomp(char*, char*, unsigned char*); -extern re_cw *re_recw(re_re*, unsigned char*); -extern int re_reexec(re_re*, char*, char*, char*[10][2]); -extern void re_refree(re_re*); -#else -# define VOID char -typedef int (*RDFN)(); -typedef int (*MATCHFN)(); -typedef int (*PROCFN)(); -extern re_bm *re_bmcomp(); -extern int re_bmexec(); -extern void re_bmfree(); -extern void re_cwadd(); -extern void re_cwcomp(); -extern int re_cwexec(); -extern void re_cwfree(); -extern re_cw *re_cwinit(); -extern void re_error(); -extern int re_paren(); -extern re_re *re_recomp(); -extern re_cw *re_recw(); -extern int re_reexec(); -extern void re_refree(); -# endif - -# if defined(__cplusplus) -} /* C++ 2.0 */ -# endif -#endif //GO.SYSIN DD re.h echo lre.h 1>&2 sed 's/.//' >lre.h <<'//GO.SYSIN DD lre.h' -#ifndef LRE_H -#define LRE_H - -# if defined(__cplusplus) -extern "C" { /* C++ 2.0 */ -# endif - -#include "io.h" - -#ifndef MEMMOVE -#define memmove(to, from, n) memcpy(to, from, n) -#endif - -#define TRACE(n) (n < re_debug) -#define EPRINTSIZE 32767 -extern int re_debug; - -# if defined(__STDC__) || defined(c_plusplus) || defined(__cplusplus) -extern void eg_clrstates(re_re*); -extern Expr *eg_eall(enum Parsetype, unsigned char*); -extern void egbr(re_re*); -extern int egdfabr(re_re*, unsigned char*, unsigned char*, unsigned char**, unsigned char**); -extern int eg_match(re_re*, unsigned char*, unsigned char*, unsigned char**, unsigned char**); -extern void eginit(re_re*, int); -extern void *egmalloc(int, char*); -extern void egpost(re_re*); -extern void egcanon(Expr *); -extern re_re *egprep(enum Parsetype, unsigned char*, unsigned char*, unsigned char*, int); -extern void *egrealloc(char*, int, char*); -extern void eg_epr(Expr*, char*, int); -extern void eg_brpr(Br *); -extern int eg_getstate(re_re*); -extern void eg_lexinit(char*, char*); -extern void eg_lex(void); -extern Expr *eg_newexpr(Exprtype, int, Expr*, Expr*); -extern int eg_posalloc(re_re*, int); -extern void eg_posinit(re_re*); -extern void eg_posset(re_re*); -State *eg_startstate(re_re*); -State *eg_stateof(re_re*, Positionset*); -extern void eg_savestate(re_re*, State*); -extern void eg_spr(long, int*, char*); -extern void eg_stateinit(re_re*); -extern unsigned char *eg_quickmatch(re_re *, unsigned char *, unsigned char *, int); -extern unsigned char *eg_lquickmatch(re_re *, unsigned char *, unsigned char *, int); -#else -extern void clrstates(); -extern Expr *eg_eall(); -extern void egbr(); -extern int egdfabr(); -extern int eg_match(); -extern void eginit(); -extern char *egmalloc(); -extern void egpost(); -extern void egcanon(); -extern re_re *egprep(); -extern char *egrealloc(); -extern void eg_epr(); -extern void eg_brpr(); -extern int eg_getstate(); -extern void eg_lex(); -extern void eg_lexinit(); -extern Expr *eg_newexpr(); -extern int eg_posalloc(); -extern void eg_posinit(); -extern void eg_posset(); -extern void eg_savestate(); -extern void eg_spr(); -extern State *eg_startstate(); -extern void eg_stateinit(); -extern State *eg_stateof(); -extern unsigned char *eg_quickmatch(); -extern unsigned char *eg_lquickmatch(); -# endif - -# if defined(__cplusplus) -} /* C++ 2.0 */ -# endif -#endif //GO.SYSIN DD lre.h echo libc.h 1>&2 sed 's/.//' >libc.h <<'//GO.SYSIN DD libc.h' -/* system calls */ -extern unsigned alarm(); -extern void nap(), pause(); -extern char *sbrk(); -extern void exit(), _exit(); -extern long lseek(); -extern void nice(); -extern void profil(); -extern unsigned long settod(); -extern void sync(); -extern long time(); - -/* libc et al */ -extern long lcm(); -extern double atof(), strtod(); -extern long atol(); -extern char *crypt(); -extern char *ctime(); -extern char *ecvt(), *fcvt(), *gcvt(); -extern char *galloc(); -extern char *getenv(); -extern char *getlogin(); -extern char *getpass(); -extern char *getwd(), *getcwd(); -extern char *malloc(), *realloc(), *calloc(); -extern char *memcpy(), *memchr(), *memccpy(), *memset(), *memmove(); -extern char *mktemp(); -extern double frand(); -extern char *setfields(); -extern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strchr(), *strrchr(); -extern char *strpbrk(), *strtok(), *strdup(); -extern int atoi(); -extern char *tgetstr(), tgoto(); -extern char *ttyname(), *cttyname(); - -#define NONEXIT 33 //GO.SYSIN DD libc.h echo getopt.c 1>&2 sed 's/.//' >getopt.c <<'//GO.SYSIN DD getopt.c' -#include "re.h" -#include "lre.h" -#include "hdr.h" - -#define ERR(str, chr) if(opterr){fprint(2, "%s%s%c\n", argv[0], str, chr);} -#define EOF -1 -#define NULL 0 -int opterr = 1; -int optind = 1; -int optopt; -char *optarg; - -int -getopt(int argc, char **argv, char *opts) -{ - static int sp = 1; - register c; - register char *cp; - - if (sp == 1) - if (optind >= argc || - argv[optind][0] != '-' || argv[optind][1] == '\0') - return EOF; - else if (strcmp(argv[optind], "--") == NULL) { - optind++; - return EOF; - } - optopt = c = argv[optind][sp]; - if (c == ':' || (cp=strchr(opts, c)) == NULL) { - ERR (": illegal option -- ", c); - if (argv[optind][++sp] == '\0') { - optind++; - sp = 1; - } - return '?'; - } - if (*++cp == ':') { - if (argv[optind][sp+1] != '\0') - optarg = &argv[optind++][sp+1]; - else if (++optind >= argc) { - ERR (": option requires an argument -- ", c); - sp = 1; - return '?'; - } else - optarg = argv[optind++]; - sp = 1; - } else { - if (argv[optind][++sp] == '\0') { - sp = 1; - optind++; - } - optarg = NULL; - } - return c; -} //GO.SYSIN DD getopt.c echo regress.d/complex 1>&2 sed 's/.//' >regress.d/complex <<'//GO.SYSIN DD regress.d/complex' -did=verified -for i in `ls t*.sh | sed -e 's/.sh$//' | sort +0.1n` -do - sh $i.sh > temp - if cmp -s temp $i.out - then - : - else - echo "test $i failed" - fi - rm temp - did="$did $i" -done -echo "$did" //GO.SYSIN DD regress.d/complex echo regress.d/lt0.c 1>&2 sed 's/.//' >regress.d/lt0.c <<'//GO.SYSIN DD regress.d/lt0.c' -/* -From pegasus.ATT.COM!hansen Tue Oct 9 00:34 EDT 1990 -Received: by pyxis; Tue Oct 9 00:34 EDT 1990 -FROM: hansen@pegasus.ATT.COM (t.l.hansen) -TO: research!andrew -DATE: 9 Oct 1990 0:27 EDT -SUBJECT: bug in re_reexec()! - -Compile and link the following program. The expected output is: - -parens = 2 -matched -0: 0x80881430 - 0x80881445 -"!nosuchsystem!testing" -1: 0x80886334 - 0xc0020c1c -"nosuchsystem" -2: 0xc0020a78 - 0x80883924 -"testing" - -Instead, I get this. (Note the strings after 1: and 2:.) - -parens = 2 -matched -0: 0x80881430 - 0x80881445 -"!nosuchsystem!testing" -1: 0x80886334 - 0xc0020c1c -"" -2: 0xc0020a78 - 0x80883924 -"" - -Can you please look into this soon? If not, let me know so that I can hunt -for it. I probably won't be able to find it as quickly as you, though. This -showed up within mail and I have an MR haunting me. Thanks. - - Tony - ----------------------------------------------------------------- -*/ -#include <stdio.h> -#include <ctype.h> -#include "re.h" -#include "lre.h" - -void prc(c) -unsigned char c; -{ - if (c >= 0200) - { - (void) printf("M-"); - c -= 0200; - } - if (isprint(c)) putchar(c); - else - { - putchar('^'); - putchar(c ^ 0100); - } -} - -void pr(i, mb, me) -int i; -char *mb; -char *me; -{ - (void) printf("%d: %#x - %#x\n", i, mb, me); - putchar('"'); - for (; mb < me; mb++) - { - if (!*mb) - break; - prc(*mb); - } - putchar('"'); - putchar('\n'); -} - -main() -{ - re_re *regex; - int i; - unsigned char re_map[256]; - static char lname[] = "!nosuchsystem!testing"; - static char pat[] = "!([^!]+)!(.+)"; - char *match[10][2]; - int parens; - - for (i = 0; i < 256; i++) - re_map[i] = i; - regex = re_recomp(pat, pat+strlen(pat), re_map); - parens = re_paren(regex); - (void) printf("parens = %d\n", parens); - if (parens != 2) - return 0; - if (!re_reexec(regex, lname, lname+strlen(lname), match)) - { - (void) printf("no match\n"); - return 0; - } - - (void) printf("matched\n"); - for (i = 0; i <= parens; i++) - pr(i, match[i][0], match[i][1]); - return 0; -} //GO.SYSIN DD regress.d/lt0.c echo regress.d/makefile 1>&2 sed 's/.//' >regress.d/makefile <<'//GO.SYSIN DD regress.d/makefile' -GRE=gre - -all: - @echo "checking $(GRE):" - @GRE=$(GRE) sh simple - @GRE=$(GRE) sh complex //GO.SYSIN DD regress.d/makefile echo regress.d/simple 1>&2 sed 's/.//' >regress.d/simple <<'//GO.SYSIN DD regress.d/simple' -awk ' -BEGIN { - sq = "'"'"'" - FS = "\t" - gre = "'"$GRE"'" -} -NF == 0 { - next -} -$1 != "" { # new test - re = $1 - if($4 == ""){ - nopts = 1; opts[0] = "" - } else if(substr($4, 1, 1) == "-"){ - nopts = 1; opts[0] = " " $4 - } else { - for(nopts = 0; nopts < length($4); nopts++){ - x = substr($4, nopts, 1) - if(x == "~") opts[nopts] = "" - else opts[nopts] = " -" x - } - } -} -$2 != "" { # either ~ or !~ - op = $2 - if (op == "~") - neg = 0 - else if (op == "!~") - neg = 1 -} -$3 != "" { # new test string - str = $3 -} -$3 == "\"\"" { # explicit empty line - $3 = "" -} -NF > 2 { # generate a test - input = $3 - for(i = 0; i < nopts; i++){ - ntests++; - if(neg){ - printf("if echo %s | %s -s %s; then echo %s%d fails %s %s %s %s%s ;else :; fi\n", sq input sq, gre opts[i], sq re sq, sq, NR, opts[i], re, op, input, sq) - } else { - printf("if echo %s | %s -s %s; then :; else echo %s%d fails %s %s %s %s%s ; fi\n", sq input sq, gre opts[i], sq re sq, sq, NR, opts[i], re, op, input, sq) - } - } -} -END { print "echo " sq ntests " simple tests" sq } -' > regress.i <<\!!! -a ~ a - ba - bab - !~ "" - x - xxxxx -. ~ x - xxx - !~ "" -.a ~ xa - xxa - xax - !~ a - ab - "" -$ ~ x - "" -.$ ~ x - !~ "" -a$ ~ a - ba - bbba - !~ ab - x - "" -^ ~ x - "" - ^ -^a$ ~ a - !~ xa - ax - xax - "" -^a.$ ~ ax - aa - !~ xa - aaa - axy - "" -^$ ~ "" - !~ x - ^ -^.a ~ xa - xaa - !~ a - "" -^.*a ~ a - xa - xxxxxxa - !~ "" -^.+a ~ xa - xxxxxxa - !~ "" - a - ax -a* ~ "" - a - aaaa - xa - xxxx -aa* ~ a - aaa - xa - !~ xxxx - "" -\$ ~ x$ - $ - $x - !~ "" - x -\. ~ . - !~ x - "" -.^$ ~ a^ -G - !~ "" - a^$ -^x$ ~ x -G - !~ yx - xy -a\$ ~ a$ -G - !~ a -\(ab\)$ ~ cab -G - ab - !~ ab$ -xr+y ~ xry ~E - xrry - xrrrrrry - !~ ry - xy -xr?y ~ xy ~E - xry - !~ xrry -a(bc|def)g ~ abcg ~E - adefg - !~ abc - abg - adef - adeg -[0-9] ~ 1 - 567 - x0y - !~ abc - "" -[^0-9] !~ 1 - 567 - "" - ~ abc - x0y -x[0-9]+y ~ x0y ~E - x23y - x12345y - !~ 0y - xy -x[0-9]?y ~ xy ~E - x1y - !~ x23y -X ~ x -i -read ~ read -x - !~ xy read - x read y - xread - readx -read ~ read -xF - !~ xy read - x read y - xread - readx -read ~ read -F - xy read - x read y - xread - readx -[.]de.. ~ .dexx - .deyyy - !~ .de - .dex -^|s ~ |sec -G - !~ sec -..B ~ CDAB -G - !~ ABCD -$.*tt.*\$ ~ $tt$ -G -^([a-z]+)\1$ ~ vivi - !~ vivify -([a-z]+)\1 ~ vivi - vivify - revivi - !~ vovify - viv -\(....\).*\1 ~ beriberi -G -(....).*\1 ~ beriberi -^$ ~ -^$ ~ -G -[ab]\{2\}k ~ abk - xyaak - zabak - !~ zad - bq - abq -[ab]\{2,\}d ~ abd - abababad - !~ ad - ababaq -q[ab]\{2,4\}d ~ qabd - qababd - qaaad - !~ qad - qababad -a[]]b ~ a]b -E -a[]]b ~ a]b -G -a[^]b]c ~ adc -E -a[^]b]c ~ adc -G -angel[^e] ~ angelo -i - ~ ANGELH - !~ angel - ANGEL - angele - ANGELE -^[^-].*> ~ abc> -G - !~ -a> -^[A-Z] ~ abc -i - ABC -^[^A-Z] !~ abc -i - ABC - ~ 123 -|abc ~ |abc -G - !~ abc -\(ac*\)c*d[ac]*\1 ~ acdacaaa -G -(ac*)c*d[ac]*\1 ~ acdacaaa -ram|am ~ am -.|.. !~ abc -x -[a-za-za-za-za-za-za-za-za-za-z] ~ for this line -E -[a-za-za-za-za-za-za-za-za-za-z] ~ for this line -[a-za-za-za-za-za-za-za-za-z] ~ but watch out -E -[a-za-za-za-za-za-za-za-za-z] ~ but watch out -!!! -cp regress.i ../temp -sh < regress.i && rm regress.i -echo "verified simple" //GO.SYSIN DD regress.d/simple echo regress.d/t1.i 1>&2 sed 's/.//' >regress.d/t1.i <<'//GO.SYSIN DD regress.d/t1.i' -.xxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //GO.SYSIN DD regress.d/t1.i echo regress.d/t1.out 1>&2 sed 's/.//' >regress.d/t1.out <<'//GO.SYSIN DD regress.d/t1.out' //GO.SYSIN DD regress.d/t1.out echo regress.d/t1.sh 1>&2 sed 's/.//' >regress.d/t1.sh <<'//GO.SYSIN DD regress.d/t1.sh' -cat t1.i | $GRE -v '^\.x' //GO.SYSIN DD regress.d/t1.sh echo regress.d/t10.i 1>&2 sed 's/.//' >regress.d/t10.i <<'//GO.SYSIN DD regress.d/t10.i' -at -hematic //GO.SYSIN DD regress.d/t10.i echo regress.d/t10.out 1>&2 sed 's/.//' >regress.d/t10.out <<'//GO.SYSIN DD regress.d/t10.out' //GO.SYSIN DD regress.d/t10.out echo regress.d/t10.sh 1>&2 sed 's/.//' >regress.d/t10.sh <<'//GO.SYSIN DD regress.d/t10.sh' -$GRE -xvFf t10.i t10.i //GO.SYSIN DD regress.d/t10.sh echo regress.d/t11.i 1>&2 sed 's/.//' >regress.d/t11.i <<'//GO.SYSIN DD regress.d/t11.i' -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxyz -abc //GO.SYSIN DD regress.d/t11.i echo regress.d/t11.out 1>&2 sed 's/.//' >regress.d/t11.out <<'//GO.SYSIN DD regress.d/t11.out' -gre: t11.i: warning: line too long (> 500 chars); text skipped -abc //GO.SYSIN DD regress.d/t11.out echo regress.d/t11.sh 1>&2 sed 's/.//' >regress.d/t11.sh <<'//GO.SYSIN DD regress.d/t11.sh' -$GRE abc t11.i 2>&1 //GO.SYSIN DD regress.d/t11.sh echo regress.d/t12.i 1>&2 sed 's/.//' >regress.d/t12.i <<'//GO.SYSIN DD regress.d/t12.i' -AAA n -AAAS n -Aaron n -AAU n -AAUP d -AAUW d -ABA n -Ababa pc -aback d -abacus n -abaft d -abalone n -abandon v,er,va -abase v,er,va -abash v,er,va -abate v,er,va -abattoir n -abbe n -abbess n -abbey n -abbot n -Abbott n -abbreviate v,ion -abc n -abdicate v,ion,va -abdomen n -abdominal a -abduct v,ion -Abe pc -abeam d -abed d -Abel pc -Abelian pc -Abelson n -Aberdeen pc -Abernathy n -aberrant n,a -aberrate v,ion -abet v,va,ms -abettor n -abeyant a -abhor v,er,ms -abhorrent a -abide v,er -Abidjan pc -Abigail pc -abject a,ion -abjuration n -abjure v,er -ablate v,ion -ablaut n -ablaze d -able v,a,comp,va -abloom d -ablution n -ABM n -abnegate v,ion -Abner pc -abnormal n,a -aboard d -abode n -abolish v,er,va -abolition n,na -abolitionary n -abominable a -abominate v,ion -aboriginal n,a -aborigine n -aborning d -abort v,er,ion -abortifacient n -abound vi -about d,nopref -above d -aboveboard d -aboveground d -abovementioned d -abracadabra n -abrade v,er,va -Abraham n -Abram n -Abramson n -abrasion n,na -abreact v,ion -abreast d -abridge v,er,va -abridgment n -abroad d -abrogate v,ion -abrupt a,ion -abscess n,v -abscissa n -abscissae d -abscission n -abscond v,er -absent v,a -absentee n -absenteeism n -absentia n -absentminded a -absinthe n -absolute n,a,na -absolution n -absolve v,er -absorb v,er,va -absorbent a -absorption n,na -abstain v,er -abstemious a -abstention n -abstinent a -abstract n,v,a,er,ion -abstruse a -absurd a,na -abuilding d -abundant a -abuse n,v,er,va -abusive a -abut v,er,va,ms -abysmal a -abyss n -abyssal a -Abyssinia pc -AC d -acacia n -academe pc,na -academia pc -academic n,na -academician n -academy n -Acadia pc -acanthus n -Acapulco pc -accede v -accelerando d -accelerate v,ion -accelerometer n -accent n,v,na -accentual a -accentuate v,ion -accept v,er,va -acceptant a -acceptor n -access n,v -accessible a,in -accession n,v,na -accessory n,na -accident n,a -accidental a -accipiter n -acclaim n,v,er -acclamation n -acclimate n,v,ion -acclimatize v,er,ion -accolade n -accommodate v,ion -accompaniment n -accompanist n -accompany v,na -accompli d -accomplice n -accomplish v,er,va -accord n,v -accordant a -accordion n,na -accost v -account n,v,va -accountant n,a,na -Accra pc -accredit v,va -accreditation n -accrete v -accretion n,na -accretionary n -accrual a -accrue v,va -acculturate v,ion -accumulate v,ion -accuracy n,in -accurate a,in -accursed a -accusation n,na -accusatory d -accuse v,er -accustom v -ace n,v,nopref -acentric d -acerb a -acerbic a -acetaldehyde n -acetate n -acetic d -acetone n -acetyl n,na -acetylene n -ache n,v,er -achieve v,er,va -Achilles pc -aching a -achondrite n,na -achromatic a -acid n,a -acidic d -acidify v,er,ion -acidimeter n,na -acidulous a -Ackerman n -Ackley n -acknowledge v,va -acknowledgeable d -ACLU pc -ACM pc -acme pc -acne n -acolyte n -acorn n -acoustic n,a -acoustician n -acoustoelectric a,na -acoustooptic n,a,na -acquaint v -acquaintance n,na -acquiesce v -acquiescent a -acquire v,va -acquisition n,na -acquit v,ms -acquittal n -acre n -acreage pc -acrid a -acrimonious a -acrimony n -acrobat n -acrobatic n,na -acrolein n -acronym n -acrophobia n -acropolis n -across d -acrostic a -acrylate n -acrylic n -ACS pc -act n,v,ion,va -Actaeon pc -actinic na -actinide n -actinium n -actinometer n,na -activate v,ion,in -activism pc -Acton n -actress n -actual a,na -actuarial a -actuary n -actuate v,ion -acuity n -acumen n -acupuncture n -acute a -acyclic a -acyl n -ad n -Ada pc -adage n -adagio n -Adair pc -Adam pc -adamant a -adamantine a -Adams n -Adamson n -adapt v,er,ion,va -adaptation n,na -adaptive a -adaptor n -add v,er,va -addend n -addenda pc -addendum pc -addict n,v,ion -Addis pc -Addison n -addition n,na -addle v -address n,v,er,na,va -addressee n -Addressograph pc -adduce v,er,va -Adelaide pc -Adele pc -Adelia pc -Aden pc -adenoid n,na -adenoma n -adenosine n -adept n,a -adequacy n,in -adequate a,in -adhere v -adherent n,a -adhesion n,na -adiabatic n -adieu n -adipose a -Adirondack n -adjacent a -adjectival a -adjective n,a -adjoin v -adjoint n -adjourn v,va -adjudge v -adjudicate v,ion -adjunct n,a,ion -adjuration n -adjure v -adjust v,er,va -adjutant n,a -Adkins n -Adler n -administer v -administrable d -administrate v,ion -administratrix d -admiral n -admiralty n -admiration n -admire v,er,va -admissible a,in -admission n,na -admit v,er,ms -admittance n -admix v -admixture n -admonish v,er,va -admonition n -admonitory a -ado d,nopref -adobe n,er -adolescent n,a -Adolph pc -Adolphus pc -Adonis pc -adopt v,er,ion,va -adoration n -adore v,er,va -adorn v,er,va -adrenal n,a -adrenaline n -Adrian pc -Adriatic pc -Adrienne pc -adrift d -adroit a,comp -adsorb v,va -adsorbate n -adsorbent n -adsorption n,na -adulate v,ion -adult n,a -adulterant n -adulterate v,ion -adulterer n -adulteress n -adulterous a -adultery n -adumbrate v,ion -advance v,er,va -advantage n,v -advantageous a -advection n,na -advent n,na -adventitial a -adventitious a -adventure n,v,er,na -adventuresome a -adventuress n -adventurous a -adverb n -adverbial a -adversary n,a -adverse a -advert n,v -advertent a,in -advertise v,er,va -advice pc -advise v,er,va -advisee n -advisor n,y -advocacy n -advocate v,ion -adz n -adze n -Aegean pc -aegis n -Aeneas pc -Aeneid pc -aeolian d -Aeolus pc -aerate v,a,ion,va -aerial n,a,na -aerie n -Aerobacter pc -aerobatic n -aerobic n,na -aerodynamic n,na -aeronautic n,na -aerosol n,na -aerospace n -Aeschylus pc -aesthete n -aesthetic n,na -afar d -affable a,va -affair n -affect n,v,ion,va -affectation n -affectionate a -afferent a -affiance n,v -affidavit n -affiliate n,v,ion -affine n,ed,a -affinity n -affirm v,va -affirmation n,na -affix v,va -affixation n -afflatus n -afflict v,er,ion -affluent n,a -afford v,va -afforest v -afforestation n -affray n,v -affright n,v -affront n,v -afghan n -Afghanistan pc -aficionado n -afield d -afire d -AFL d -aflame d -afloat d -aflutter d -afoot d -aforementioned d -aforesaid d -aforethought d -afoul d -afraid d -afresh d -Africa pc -Afrikaner pc -afro n -aft er -afterbirth n -afterburner n -afterdeck n -aftereffect n -afterglow n -afterimage n -afterlife n -aftermath pc -aftermost pc -afternoon n -aftershock n -aftertaste n -afterthought n -afterward n -afterworld n -again d,nopref -against d,nopref -Agamemnon pc -agamic a -agape d -agar n,nopref -agate n,nopref -Agatha pc -agave n -age n,v -Agee n -agelong d -agenda pc,na -agendum pc -agent n,a -agglomerate v,ion -agglutinate v,ion -agglutinin n -aggrade v -aggravate v,ion -aggregate n,v,a,ion -aggression n,na -aggressor n -aggrieve v -aghast d -agile a -agitate v,ion -agitprop pc -agleam d -agley d -aglitter d -aglow d -Agnes pc -Agnew n -agnomen n -agnostic n,na -ago d,nopref -agog d -agon n -agone na -agony n -agora n -agoraphobia n -agouti n -agrarian n,na -agree v,va -agreeable a -agreeing d -agribusiness n -Agricola pc -agricultural a,na -agriculture n,na -agrimony n -agronomist n -agronomy n,na -aground d -ague n -Agway pc -ah n,nopref -Ahab pc -ahead d -ahem d -Ahmadabad pc -ahoy d -aid n,v,er,nopref -Aida pc -aide n,nopref -Aiken pc -ail n,v,nopref -ailanthus pc -Aileen pc -aileron n -ailment n -aim n,v -ain't d -Ainu n -air n,v,man,y -airborne d -airbrush n,v -Airbus n -aircraft n -airdrop n,v,va -Aires pc -airfare n -airfield n -airflow n -airfoil n -airframe n -airhead n -airlift n,v -airline n,er -airlock n -airmail n,v -airmass n -airpark n -airport n -airscrew n -airsick a -airspace n -airspeed n //GO.SYSIN DD regress.d/t12.i echo regress.d/t12.out 1>&2 sed 's/.//' >regress.d/t12.out <<'//GO.SYSIN DD regress.d/t12.out' //GO.SYSIN DD regress.d/t12.out echo regress.d/t12.sh 1>&2 sed 's/.//' >regress.d/t12.sh <<'//GO.SYSIN DD regress.d/t12.sh' -$GRE -Fxvf t12.i t12.i 2>&1 //GO.SYSIN DD regress.d/t12.sh echo regress.d/t13.i 1>&2 sed 's/.//' >regress.d/t13.i <<'//GO.SYSIN DD regress.d/t13.i' -/p1/usr/bin/pmxpc: - pm.sl 2.94 - xdhu.sl 1.8 - /lib/crt1.o.sl 1.1 4.0 01/15/86 12744 AT&T-SF - /usr/include/stdio.h.sl 1.1 4.0 01/15/86 4140 AT&T-SF - /usr/include/ctype.h.sl 1.1 4.0 01/15/86 45671 AT&T-SF - /usr/include/string.h.sl 1.1 4.0 01/15/86 51235 AT&T-SF - /usr/include/signal.h.sl 1.1 4.0 01/15/86 34302 AT&T-SF - /usr/include/sys/signal.h.sl 1.5 3.2 09/02/87 33640 AT&T-SF - /usr/include/sys/types.h.sl 1.3 3.1 06/02/86 48113 AT&T-SF - /usr/include/sys/stat.h.sl 1.3 3.0 12/19/85 41824 - /usr/include/termio.h.sl 1.1 4.0 01/15/86 29141 AT&T-SF //GO.SYSIN DD regress.d/t13.i echo regress.d/t13.out 1>&2 sed 's/.//' >regress.d/t13.out <<'//GO.SYSIN DD regress.d/t13.out' -/p1/usr/bin/pmxpc: - pm.sl 2.94 - xdhu.sl 1.8 //GO.SYSIN DD regress.d/t13.out echo regress.d/t13.sh 1>&2 sed 's/.//' >regress.d/t13.sh <<'//GO.SYSIN DD regress.d/t13.sh' -$GRE 'pm|xdhu' < t13.i 2>&1 //GO.SYSIN DD regress.d/t13.sh echo regress.d/t2.out 1>&2 sed 's/.//' >regress.d/t2.out <<'//GO.SYSIN DD regress.d/t2.out' //GO.SYSIN DD regress.d/t2.out echo regress.d/t2.sh 1>&2 sed 's/.//' >regress.d/t2.sh <<'//GO.SYSIN DD regress.d/t2.sh' -$GRE -v '^\.x' t1.i //GO.SYSIN DD regress.d/t2.sh echo regress.d/t3.i 1>&2 sed 's/.//' >regress.d/t3.i <<'//GO.SYSIN DD regress.d/t3.i' -x -abcd -abcde -eabcd -defg -xdefg -defgx -abcd defg //GO.SYSIN DD regress.d/t3.i echo regress.d/t3.out 1>&2 sed 's/.//' >regress.d/t3.out <<'//GO.SYSIN DD regress.d/t3.out' -abcd -defg //GO.SYSIN DD regress.d/t3.out echo regress.d/t3.sh 1>&2 sed 's/.//' >regress.d/t3.sh <<'//GO.SYSIN DD regress.d/t3.sh' -$GRE -xF 'defg -abcd' t3.i //GO.SYSIN DD regress.d/t3.sh echo regress.d/t4.i 1>&2 sed 's/.//' >regress.d/t4.i <<'//GO.SYSIN DD regress.d/t4.i' - 1 ZIPPORI, Israel - /usr/spool/ap/88/07/15/a0471: Israel-MonaLisa - 1 ZERIFIN, Israel - /usr/spool/ap/88/05/17/a0823: Israel-Baez - 1 ZEPHYRHILLS, Fla. - /usr/spool/ap/88/04/27/a0963: HelicopterEscape - 1 ZENICA, Yugoslavia - /usr/spool/ap/88/07/13/a0814: Yugoslavia - 1 ZAP, N.D. - /usr/spool/ap/88/03/13/a0776: CoalStrike - 1 ZAMBRANO, Honduras - /usr/spool/ap/88/03/24/a0512: Honduras-Soldiers - 1 ZACHARY, La. - /usr/spool/ap/88/04/05/a0745: Brites - 1 YUCCA VALLEY, Calif. - /usr/spool/ap/88/08/26/a0624: BRF--SoCalQuake - 1 YORKVILLE, Ill. - /usr/spool/ap/88/08/31/a0687: ReformedStudent - 1 YORK, Maine - /usr/spool/ap/88/10/09/a0772: SeaSearches - 1 YENAN, China - /usr/spool/ap/88/02/24/a0419: China-Yenan - 1 YELOWSTONE NATIONAL PARK, Wyo. - /usr/spool/ap/88/09/15/a0792: Dukakis - 1 YEADON, Pa. - /usr/spool/ap/88/05/14/a0689: Brites - 1 YATTA, Occupied West Bank - /usr/spool/ap/88/10/29/a0417: Israel-Undercover - 1 YASSIHOYUK, Turkey - /usr/spool/ap/88/09/09/a0423: MidasTomb - 1 YAPHANK, N.Y. - /usr/spool/ap/88/05/10/a0686: Brites - 1 YAMOUSSOUKRO, Ivory Coast - /usr/spool/ap/88/09/25/a0635: Africa-UN //GO.SYSIN DD regress.d/t4.i echo regress.d/t4.out 1>&2 sed 's/.//' >regress.d/t4.out <<'//GO.SYSIN DD regress.d/t4.out' - 1 ZIPPORI, Israel - 1 ZERIFIN, Israel - 1 ZEPHYRHILLS, Fla. - 1 ZENICA, Yugoslavia - 1 ZAP, N.D. - 1 ZAMBRANO, Honduras - 1 ZACHARY, La. - 1 YUCCA VALLEY, Calif. - 1 YORKVILLE, Ill. - 1 YORK, Maine - 1 YENAN, China - 1 YELOWSTONE NATIONAL PARK, Wyo. - 1 YEADON, Pa. - 1 YATTA, Occupied West Bank - 1 YASSIHOYUK, Turkey - 1 YAPHANK, N.Y. - 1 YAMOUSSOUKRO, Ivory Coast //GO.SYSIN DD regress.d/t4.out echo regress.d/t4.sh 1>&2 sed 's/.//' >regress.d/t4.sh <<'//GO.SYSIN DD regress.d/t4.sh' -$GRE -v : t4.i //GO.SYSIN DD regress.d/t4.sh echo regress.d/t5.i 1>&2 sed 's/.//' >regress.d/t5.i <<'//GO.SYSIN DD regress.d/t5.i' -com 1037117850 -com -113451303 -com -253844186 -com -591640727 -com -192085666 -com 875206176 -com -688908411 -com 116220732 -com -815364609 -com 393021566 -com -197586762 -com -979497332 -com 580876342 -com 857752251 -com -282427433 -com 440265772 -com 903702654 -com 377371259 -com -790446649 -com -407893353 -com 601447097 -com 311585929 -com -990601410 -com 273028495 -com -421520583 -com -620551282 -com -768217422 -com 722547274 -com 313902943 -com -729597068 -com 306062132 -com 773754585 -com -678639313 -com -345701409 -com -290065002 -com -974307104 -com 1047184566 -com 210828681 -com 108982822 -com 68031245 -com -1047141482 -com 227569703 -com -530798398 -com -822779044 -com 440691738 -com 624275796 -com 843073732 -com 228971433 -com 258376249 -com -308161170 -com -995590232 -com 856677272 -com 132296249 -com 633658628 -com 25935234 -com -1063085400 -com 148654970 -com -824172925 -com -659459669 -com 196909720 -com -393774825 -com 736667556 -com 674673107 -com 1007653812 -com -261383312 -com 263123663 -com -946595190 -com -396442 -com -506832213 -com 149702652 -com -937852087 -com -500943193 -com -288026147 -com -653808189 -com 801559288 -com -653395420 -com -405217270 -com -749529781 -com 965720542 -com 396739912 -com 250804267 -com 1058925867 -com 121948720 -com 129329115 -com -503214654 -com 758365427 -com -569717820 -com 191932303 -com 1041195498 -com -178872661 -com 719024931 -com 389365053 -com -695930677 -com -720993320 -com 659352079 -com -445359373 -com -405581235 -com -495515453 -com -861910553 -com -35979929 -com 1056535300 -com 188042833 -com -220408267 -com -766533595 -com 718865736 -com -614647852 -com 637296265 -com 607439702 -com -996163547 -com -354301843 -com 187216170 -com -524246340 -com 165453004 -com -922340816 -com -392313676 -com 933400965 -com -357455062 -com 876069330 -com 619850004 -com 34785127 -com -204461692 -com -1021142281 -com 261505948 -com 713447396 -com -264424205 -com -757624021 -com -697742264 -com -67902535 -com 813305897 -com 611213298 -com 810009586 -com -351033158 -com -757580248 -com -754765998 -com 96550293 -com 818835421 -com 625544984 -com -301866740 -com -363940120 -com 196940655 -com -990799410 -com -650380493 -com -823008037 -com 229313079 -com 480371766 -com 934025272 -com -223072319 -com 481173087 -com 101019846 -com -954562179 -com -267806909 -com 1004678320 -com 267997081 -com -691653747 -com 821221633 -com 11472834 -com -852175935 -com 145665121 -com 636788309 -com -38553220 -com -594562227 -com 893269786 -com -515632420 -com -504118519 -com -795555924 -com -896489800 -com 381679431 -com 451163332 -com 945690716 -com -474968721 -com -181646048 -com -477705084 -com 179336691 -com 944752723 -com -106013482 -com 295161509 -com -1026918852 -com -1008494120 -com -368542058 -com 6153383 -com 269567191 -com 221084616 -com -1015567145 -com 326752359 -com -253427460 -com -990923267 -com -745673545 -com -772482393 -com 12783572 -com 695087221 -com 782623860 -com 239322275 -com -920492686 -com -461345191 -com 304590436 -com -141131273 -com -1024267294 -com -289620401 -com -495626460 -com 948528218 -com 87006518 -com 395454722 -com 577392034 -com 814343604 -com 497169207 -com -567127307 -com 764271483 -com -866721319 -com -387005272 -com -501938820 -com 567881079 -com 453665993 -com -790328887 -com 390097892 -com 141055035 -com 990378016 -com -730626518 -com 732985962 -com -286073373 -com 22747858 -com -326949321 -com 1022500944 -com 905679100 -com -448120658 -com 363118089 -com 819248817 -com -691522154 -com 59581781 -com -450349154 -com -729823626 -com 646115018 -com -65922779 -com -373376656 -com 1004572328 -com 466654801 -com 128208377 -com 958497476 -com 22952708 -com -822443770 -com 689913706 -com 726815914 -com -128674860 -com 779809535 -com -316931412 -com -1025891272 -com 4804418 -com 309313283 -com 536922264 -com -876904372 -com 700688221 -com 186984467 -com 791829735 -com 237211732 -com 515173384 -com -911728294 -com -783718602 -com 160345621 -com -716237348 -com -185346360 -com -634816499 -com -845917397 -com 460946577 -com 777785415 -com -579223277 -com -127944050 -com -351414763 -com -1006508563 -com 934284417 -com -414601720 -com -328845777 -com 701421432 -com -680992028 -com 444048798 -com -277796693 -com -1014985030 -com 213438258 -com -863232710 -com -236044310 -com -593324426 -com -269273068 -com -163992668 -com -1026411186 -com 537134594 -com 321391768 -com -872419201 -com -795875760 -com 373186979 -com 616631783 -com -567696334 -com 554407297 -com 723377442 -com 1062001538 -com 152160308 -com 43834651 -com 902450760 -com -390697289 -com 431114551 -com -851289267 -com 454377388 -com 470923853 -com -950885734 -com -313255930 -com -388083168 -com -267037738 -com -601696282 -com -848277038 -com 745209391 -com -423687675 -com 646585818 -com -613632730 -com 151442994 -com 868010020 -com -589969477 -com 756495308 -com 482257575 -com -546245706 -com -56416295 -com -922688644 -com -927591869 -com -193091648 -com 505183574 -com -696294953 -com -676843648 -com -458233039 -com 1016060900 -com 235279194 -com 255314418 -com 821562352 -com 677435672 -com -137977226 -com -296008805 -com -284837634 -com 992052324 -com 848130900 -com -612135722 -com -242663012 -com 40910582 -com -633235255 //GO.SYSIN DD regress.d/t5.i echo regress.d/t5.out 1>&2 sed 's/.//' >regress.d/t5.out <<'//GO.SYSIN DD regress.d/t5.out' -com 1037117850 -com -113451303 -com -253844186 -com -591640727 -com -192085666 -com 875206176 -com -688908411 -com 116220732 -com -815364609 -com 393021566 -com -197586762 -com -979497332 -com 580876342 -com 857752251 -com -282427433 -com 440265772 -com 903702654 -com 377371259 -com -790446649 -com -407893353 -com 601447097 -com 311585929 -com -990601410 -com 273028495 -com -421520583 -com -620551282 -com -768217422 -com 722547274 -com 313902943 -com -729597068 -com 306062132 -com 773754585 -com -678639313 -com -345701409 -com -290065002 -com -974307104 -com 1047184566 -com 210828681 -com 108982822 -com 68031245 -com -1047141482 -com 227569703 -com -530798398 -com -822779044 -com 440691738 -com 624275796 -com 843073732 -com 228971433 -com 258376249 -com -308161170 -com -995590232 -com 856677272 -com 132296249 -com 633658628 -com 25935234 -com -1063085400 -com 148654970 -com -824172925 -com -659459669 -com 196909720 -com -393774825 -com 736667556 -com 674673107 -com 1007653812 -com -261383312 -com 263123663 -com -946595190 -com -396442 -com -506832213 -com 149702652 -com -937852087 -com -500943193 -com -288026147 -com -653808189 -com 801559288 -com -653395420 -com -405217270 -com -749529781 -com 965720542 -com 396739912 -com 250804267 -com 1058925867 -com 121948720 -com 129329115 -com -503214654 -com 758365427 -com -569717820 -com 191932303 -com 1041195498 -com -178872661 -com 719024931 -com 389365053 -com -695930677 -com -720993320 -com 659352079 -com -445359373 -com -405581235 -com -495515453 -com -861910553 -com -35979929 -com 1056535300 -com 188042833 -com -220408267 -com -766533595 -com 718865736 -com -614647852 -com 637296265 -com 607439702 -com -996163547 -com -354301843 -com 187216170 -com -524246340 -com 165453004 -com -922340816 -com -392313676 -com 933400965 -com -357455062 -com 876069330 -com 619850004 -com 34785127 -com -204461692 -com -1021142281 -com 261505948 -com 713447396 -com -264424205 -com -757624021 -com -697742264 -com -67902535 -com 813305897 -com 611213298 -com 810009586 -com -351033158 -com -757580248 -com -754765998 -com 96550293 -com 818835421 -com 625544984 -com -301866740 -com -363940120 -com 196940655 -com -990799410 -com -650380493 -com -823008037 -com 229313079 -com 480371766 -com 934025272 -com -223072319 -com 481173087 -com 101019846 -com -954562179 -com -267806909 -com 1004678320 -com 267997081 -com -691653747 -com 821221633 -com 11472834 -com -852175935 -com 145665121 -com 636788309 -com -38553220 -com -594562227 -com 893269786 -com -515632420 -com -504118519 -com -795555924 -com -896489800 -com 381679431 -com 451163332 -com 945690716 -com -474968721 -com -181646048 -com -477705084 -com 179336691 -com 944752723 -com -106013482 -com 295161509 -com -1026918852 -com -1008494120 -com -368542058 -com 6153383 -com 269567191 -com 221084616 -com -1015567145 -com 326752359 -com -253427460 -com -990923267 -com -745673545 -com -772482393 -com 12783572 -com 695087221 -com 782623860 -com 239322275 -com -920492686 -com -461345191 -com 304590436 -com -141131273 -com -1024267294 -com -289620401 -com -495626460 -com 948528218 -com 87006518 -com 395454722 -com 577392034 -com 814343604 -com 497169207 -com -567127307 -com 764271483 -com -866721319 -com -387005272 -com -501938820 -com 567881079 -com 453665993 -com -790328887 -com 390097892 -com 141055035 -com 990378016 -com -730626518 -com 732985962 -com -286073373 -com 22747858 -com -326949321 -com 1022500944 -com 905679100 -com -448120658 -com 363118089 -com 819248817 -com -691522154 -com 59581781 -com -450349154 -com -729823626 -com 646115018 -com -65922779 -com -373376656 -com 1004572328 -com 466654801 -com 128208377 -com 958497476 -com 22952708 -com -822443770 -com 689913706 -com 726815914 -com -128674860 -com 779809535 -com -316931412 -com -1025891272 -com 4804418 -com 309313283 -com 536922264 -com -876904372 -com 700688221 -com 186984467 -com 791829735 -com 237211732 -com 515173384 -com -911728294 -com -783718602 -com 160345621 -com -716237348 -com -185346360 -com -634816499 -com -845917397 -com 460946577 -com 777785415 -com -579223277 -com -127944050 -com -351414763 -com -1006508563 -com 934284417 -com -414601720 -com -328845777 -com 701421432 -com -680992028 -com 444048798 -com -277796693 -com -1014985030 -com 213438258 -com -863232710 -com -236044310 -com -593324426 -com -269273068 -com -163992668 -com -1026411186 -com 537134594 -com 321391768 -com -872419201 -com -795875760 -com 373186979 -com 616631783 -com -567696334 -com 554407297 -com 723377442 -com 1062001538 -com 152160308 -com 43834651 -com 902450760 -com -390697289 -com 431114551 -com -851289267 -com 454377388 -com 470923853 -com -950885734 -com -313255930 -com -388083168 -com -267037738 -com -601696282 -com -848277038 -com 745209391 -com -423687675 -com 646585818 -com -613632730 -com 151442994 -com 868010020 -com -589969477 -com 756495308 -com 482257575 -com -546245706 -com -56416295 -com -922688644 -com -927591869 -com -193091648 -com 505183574 -com -696294953 -com -676843648 -com -458233039 -com 1016060900 -com 235279194 -com 255314418 -com 821562352 -com 677435672 -com -137977226 -com -296008805 -com -284837634 -com 992052324 -com 848130900 -com -612135722 -com -242663012 -com 40910582 -com -633235255 //GO.SYSIN DD regress.d/t5.out echo regress.d/t5.sh 1>&2 sed 's/.//' >regress.d/t5.sh <<'//GO.SYSIN DD regress.d/t5.sh' -$GRE '^com ' t5.i //GO.SYSIN DD regress.d/t5.sh echo regress.d/t6.i 1>&2 sed 's/.//' >regress.d/t6.i <<'//GO.SYSIN DD regress.d/t6.i' -#include "alloc.h" -#include <libc.h> - -char * -emalloc(unsigned long n) -{ - char *p; - p=malloc((unsigned)n); - if(p==0){ - warn("out of memory; exiting"); - exits("out of memory"); - } - return p; -} -char * -erealloc(char *p, unsigned long n) -{ - p=realloc(p, (unsigned)n); - if(p==0){ - warn("out of memory; exiting"); - exits("out of memory"); - } - return p; -} -#include "alloc.h" -#include "word.h" -#include "store.h" -#include "comm.h" -#include <libc.h> - -/* - * Push constants - */ - -ipushconst(Proc *proc) -{ - *proc->sp++=(SWord)*++proc->pc; - return 1; -} - -ipush_2(Proc *proc) -{ - *proc->sp++=-2; - return 1; -} - -ipush_1(Proc *proc) -{ - *proc->sp++=-1; - return 1; -} - -ipush0(Proc *proc) -{ - *proc->sp++=0; - return 1; -} - -ipush1(Proc *proc) -{ - *proc->sp++=1; - return 1; -} - -ipush2(Proc *proc) -{ - *proc->sp++=2; - return 1; -} - -ipush3(Proc *proc) -{ - *proc->sp++=3; - return 1; -} - -ipush4(Proc *proc) -{ - *proc->sp++=4; - return 1; -} - -ipush5(Proc *proc) -{ - *proc->sp++=5; - return 1; -} - -ipush6(Proc *proc) -{ - *proc->sp++=6; - return 1; -} - -ipush7(Proc *proc) -{ - *proc->sp++=7; - return 1; -} - -ipush8(Proc *proc) -{ - *proc->sp++=8; - return 1; -} - -ipush9(Proc *proc) -{ - *proc->sp++=9; - return 1; -} - -ipush10(Proc *proc) -{ - *proc->sp++=10; - return 1; -} - -/* - * Binary operators - */ -ige(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]>=proc->sp[0]; - return 1; -} - -ile(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]<=proc->sp[0]; - return 1; -} - -ine(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]!=proc->sp[0]; - return 1; -} - -ieq(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]==proc->sp[0]; - return 1; -} - -igt(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]>proc->sp[0]; - return 1; -} - -ilt(Proc *proc) -{ - --proc->sp; - proc->sp[-1]=proc->sp[-1]<proc->sp[0]; - return 1; -} - -iadd(Proc *proc) -{ - --proc->sp; - proc->sp[-1]+=proc->sp[0]; - return 1; -} - -isub(Proc *proc) -{ - --proc->sp; - proc->sp[-1]-=proc->sp[0]; - return 1; -} - -imul(Proc *proc) -{ - long l0, l1, l; - --proc->sp; - l0=proc->sp[-1]; - l1=proc->sp[0]; - l=l0*l1; - if(l1 && l/l1 != l0) - rerror("product overflow"); - proc->sp[-1]=l; - return 1; -} - -idiv(Proc *proc) -{ - --proc->sp; - if(proc->sp[0]==0) - rerror("zero divide"); - proc->sp[-1]/=proc->sp[0]; - return 1; -} - -imod(Proc *proc) -{ - --proc->sp; - if(proc->sp[0]==0) - rerror("zero modulo"); - proc->sp[-1]%=proc->sp[0]; - return 1; -} - -iand(Proc *proc) -{ - --proc->sp; - proc->sp[-1]&=proc->sp[0]; - return 1; -} - -ior(Proc *proc) -{ - --proc->sp; - proc->sp[-1]|=proc->sp[0]; - return 1; -} - -ixor(Proc *proc) -{ - --proc->sp; - proc->sp[-1]^=proc->sp[0]; - return 1; -} - -ilsh(Proc *proc) -{ - --proc->sp; - proc->sp[-1]<<=proc->sp[0]; - return 1; -} - -irsh(Proc *proc) -{ - --proc->sp; - proc->sp[-1]>>=proc->sp[0]; - return 1; -} - -imax(Proc *proc) -{ - SWord l; - l=*--proc->sp; - if(l>proc->sp[-1]) - proc->sp[-1]=l; - return 1; -} - -/* - * Unary operators - */ - -ineg(Proc *proc) -{ - proc->sp[-1]=-proc->sp[-1]; - return 1; -} - -inot(Proc *proc) -{ - proc->sp[-1]=~proc->sp[-1]; - return 1; -} - -ilnot(Proc *proc) -{ - proc->sp[-1]=!proc->sp[-1]; - return 1; -} - -iref(Proc *proc) -{ - Store *s=(Store *)*--proc->sp; - *proc->sp++=s->ref-1; - decref(&s); - return 1; -} - -ilen(Proc *proc) -{ - Store *s=(Store *)*--proc->sp; - *proc->sp++=s->len; - decref(&s); - return 1; -} - -/* - * String comparison: put value of strcmp() on stack - */ - -istrcmp(Proc *proc) -{ - int cmp; - Store *s1, *s2; - s1=(Store *)proc->sp[-2]; - s2=(Store *)proc->sp[-1]; - cmp=strcmp((char *)s1->data, (char *)s2->data); - decref(&s1); - decref(&s2); - proc->sp--; - proc->sp[-1]=cmp; - return 1; -} - -/* - * Print - */ - -iprintint(Proc *proc) -{ - pprint(proc, "%ld", *--proc->sp); - return 1; -} - -iprintnewline(Proc *proc) -{ - pprint(proc, "\n"); - return 1; -} - -iprintblank(Proc *proc) -{ - pprint(proc, " "); - return 1; -} - -iprintunit(Proc *proc) -{ - pprint(proc, "(unit)"); - return 1; -} - -iprintchar(Proc *proc) -{ - pprint(proc, "%c", *--proc->sp); - return 1; -} - -pprint(proc, fmt, a, b, c, d, e) - Proc *proc; - char *fmt; -{ - char buf[1024]; - long n; - n=sprint(buf, fmt, a, b, c, d, e); - if(proc->prbuf==0){ - proc->prbuf=emalloc(64+n); - proc->maxprbuf=64+n; - proc->nprbuf=0; - } - if(n+proc->nprbuf+1>proc->maxprbuf){ - proc->prbuf=erealloc(proc->prbuf, proc->maxprbuf+64+n); - proc->maxprbuf+=64+n; - } - strcpy(proc->prbuf+proc->nprbuf, buf); - proc->nprbuf+=n; -} -/* - * Stack management - */ - -ipop(Proc *proc) -{ - --proc->sp; - return 1; -} - -ipopptr(Proc *proc) -{ - decref((Store **)(proc->sp-1)); - --proc->sp; - return 1; -} - -idup(Proc *proc) -{ - proc->sp++; - proc->sp[-1]=proc->sp[-2]; - return 1; -} - -idupptr(Proc *proc) -{ - proc->sp++; - proc->sp[-1]=proc->sp[-2]; - ((Store *)(proc->sp[-1]))->ref++; - return 1; -} -#include "node.h" -#include "symbol.h" -#include "alloc.h" -#include "word.h" -#include "store.h" -#include "comm.h" -#include "inst.h" -#include <libc.h> - -#define FNS -#include "lib.h" -#undef FNS - -#define C 0x40000000 -#define I 0x20000000 -#define F 0x10000000 -#define M(x) ((x)&~(C|I|F)) - -long call0[]={ /* plain function, 0 arguments */ - I+Ipushfp, C+0, F, I+Iret, C+0*WS, I+Idone, 0 -}; -long call1[]={ /* plain function, 1 argument */ - I+Ipushfp, C+0, F, I+Iret, C+1*WS, I+Idone, 0 -}; -long call2[]={ /* plain function, 2 arguments */ - I+Ipushfp, C+0, F, I+Iret, C+2*WS, I+Idone, 0 -}; -long call3[]={ /* plain function, 3 arguments */ - I+Ipushfp, C+0, F, I+Iret, C+3*WS, I+Idone, 0 -}; -long call4[]={ /* plain function, 4 arguments */ - I+Ipushfp, C+0, F, I+Iret, C+4*WS, I+Idone, 0 -}; -long call5[]={ /* plain function, 5 arguments */ - I+Ipushfp, C+0, F, I+Iret, C+5*WS, I+Idone, 0 -}; -long call2_0[]={/* two-step function, 0 arguments */ - I+Ipushfp, C+0, F+0, F+1, I+Iret, C+0*WS, I+Idone, 0 -}; - -struct{ - char *name; - int (*fn[3])(); - int nargs; - long *template; -}bltin[]={ -#include "lib.h" - 0, {0, 0, 0}, 0, 0, -}; - -bltinlookup(char *s) -{ - int i; - for(i=0; bltin[i].name; i++) - if(strcmp(s, bltin[i].name)==0) - return i; - error("%s not a builtin", s); - return -1; -} - -long -bltinval(char *name, Node *t) -{ - int i, nargs, len; - long *template, *p; - Store *s; - SWord *d; - if(t->o.t!=TProg) - error("builtin %s not a function", name); - i=bltinlookup(name); - nargs=bltin[i].nargs; - if(nargs!=length(t->l)) /* necessary but not sufficient */ - error("wrong #args to builtin %s: %d (should be %d)", name, length(t->l), nargs); - template=bltin[i].template; - p=template; - for(len=0; *p; p++) - len++; - s=(Store *)emalloc(SHSZ+len*LWS); - s->ref=1; - s->type=Sprog; - s->sbits=0; - s->len=len; - d=s->data; - for(p=template; *p; p++) - if(*p&C) - *d++=(SWord)M(*p); - else if(*p&I) - *d++=(SWord)insttab[M(*p)].fp; - else if(*p&F) - *d++=(SWord)bltin[i].fn[M(*p)]; - return (long)s; -} - -Store * -mk(type, len) -{ - Store *s; - if(type==Sstruct) - len++; - s=(Store *)emalloc(SHSZ+len*LWS); - s->ref=1; - s->type=type; - if(type==Sstruct){ - s->sbits=1; - s->data[0]=0; - }else - s->sbits=0; - s->len=len; - return s; -} -#include "node.h" -#include "symbol.h" -#include "alloc.h" -#include "ydefs.h" -#include "word.h" -#include "store.h" -#include "comm.h" -#include "inst.h" -#include "errjmp.h" -#include <libc.h> - -long resultloc; -long returnloc; -Node *formals; -long autooffset; -extern int bflag; -extern int cflag; -extern int nscope; -extern Node arychartype; - -compile(n) /* called from parser only */ - Node *n; -{ - extern long autooffset; - Errjmp x; - n=constants(n); - if(cflag){ - fileline(); - fprint(2, "constants:\n"); - dump(n, 0); - } - errsave(x); - if(errmark()){ - autooffset=0; - freenode(n); - errrest(x); - errjmp(); - } - istart(); - gen(n, 0); - freenode(n); - errrest(x); -} - -gen(Node *n, int retain) -{ - int i; - if(n==0) - return; - switch(n->t){ - case NArrayref: - arygen(n->l, n->r, 0, 0L); - if(!retain) - popgen(n->l->o.s->val->type->r); - return; - case NBecome: - if(n->l->t==NCall && !bflag){ - callgen(n->l, Ibecome); - return; - } - gen(n->l, 1); - n=n->r; - if(n->o.t==TID) - n=typeoftid(n); - switch(n->o.t){ - case TInt: - case TChar: - emit(Istoreauto); - emitconst(-LWS*(3+length(formals))); - break; - case TArray: - case TChan: - case TProg: - case TStruct: - emit(Istoreptrauto); - emitconst(-LWS*(3+length(formals))); - break; - case TUnit: - break; - default: - panic("can't compile %t become", n->o.t); - } - scopedecrefgen(); - trlrgen(); - return; - case NBegin: - callgen(n->l, Ibegin); - return; - case NCall: - callgen(n, Icall); - if(!retain) - popgen(etypeoft(n->l)->r); - return; - case NDecl: - case NDeclsc: - declare(n, 0, 0, 1); - return; - case NExpr: - switch(n->o.i){ - case GE: - i=Ige; - Binop: - gen(n->l, 1); - gen(n->r, 1); - if(eqtype(etypeof(n->l), &arychartype)){ - emit(Istrcmp); - constgen(0L); - } - emit(i); - Popit: - if(!retain) - emit(Ipop); - return; - case LE: - i=Ile; - goto Binop; - case NE: - i=Ine; - goto Binop; - case EQ: - i=Ieq; - goto Binop; - case '>': - i=Igt; - goto Binop; - case '<': - i=Ilt; - goto Binop; - case '+': - i=Iadd; - goto Binop; - case '-': - i=Isub; - goto Binop; - case '*': - i=Imul; - goto Binop; - case '/': - i=Idiv; - goto Binop; - case '%': - i=Imod; - goto Binop; - case '&': - i=Iand; - goto Binop; - case '|': - i=Ior; - goto Binop; - case '^': - i=Ixor; - goto Binop; - case LSH: - i=Ilsh; - goto Binop; - case RSH: - i=Irsh; - goto Binop; - case ANDAND: - condgen(n->l, n->r, Ijmptrue, Ijmpfalse, 0L, 1L, retain); - return; - case OROR: - condgen(n->l, n->r, Ijmpfalse, Ijmptrue, 1L, 0L, retain); - return; - case PRINT: - gen(n->l, 1); - printgen(n->l); - emit(Isprint); - if(!retain) - emit(Iprint); - return; - case SND: - gen(n->l, 1); - constgen((long)Cissnd); - emit(Icommset1); - emit(Icommcln1); - gen(n->r, 1); - if(isptrtype(etypeoft(n->l)->r)) - emit(Isndptr); - else - emit(Isnd); - if(!retain) - popgen(etypeof(n)); - return; - case RCV: - gen(n->l, 1); - constgen(0L); /* not Cissnd */ - emit(Icommset1); - emit(Icommcln1); - return; - case '=': - gen(n->r, 1); - if(retain) - dupgen(etypeof(n->r), 1); - lgen(n->l); - return; - case LEN: - gen(n->l, 1); - emit(Ilen); - goto Popit; - case REF: - if(isptrtype(etypeof(n->l))){ - gen(n->l, 1); - emit(Iref); - }else - constgen(1L); - goto Popit; - case DEF: - if(retain && n->l->t==NID && isinttype(etypeof(n->l))){ - constgen(1L); - return; - } - /* - * don't really need to call lgen1, which will uniquify our - * array for us, but it does no harm, and it's easy. - */ - lgen1(n->l, Idefauto, Idef, Idefary); - goto Popit; - case UMINUS: - gen(n->l, 1); - emit(Ineg); - goto Popit; - case '~': - gen(n->l, 1); - emit(Inot); - goto Popit; - case '!': - gen(n->l, 1); - emit(Ilnot); - goto Popit; - case INC: - lgen1(n->l, Iincauto, Iinc, Iincary); - goto Popit; - case DEC: - lgen1(n->l, Idecauto, Idec, Idecary); - goto Popit; - default: - panic("can't compile %e expression", n->o.i); - } - - case NExprlist: - /* - * This is an arg or element list; first is pushed last - */ - gen(n->r, 1); - gen(n->l, 1); - return; - case NID: - if(!retain) - return; - switch(typeof(n)->o.t){ - case TInt: - case TChar: - if(n->o.s->val->isauto){ - emit(Ipushauto); - emitconst(n->o.s->val->store.off); - }else{ - emit(Ipush); - emitconst((long)&n->o.s->val->store.l); - } - return; - case TProg: - case TArray: - case TChan: - case TStruct: - if(n->o.s->val->isauto){ - emit(Ipushptrauto); - emitconst(n->o.s->val->store.off); - }else{ - emit(Ipushptr); - emitconst((long)&n->o.s->val->store.l); - } - return; - case TUnit: - if(retain) - constgen(0L); - return; - case TType: - lerror(n, "attempt to evaluate type variable %m", n); - default: - panic("can't compile type %t", n->o.s->val->type->o.t); - } - case NIf: - ifgen(n); - return; - case NList: - gen(n->l, 0); - gen(n->r, 0); - return; - case NLoop: - loopgen(n); - return; - case NMk: - mkgen(n->l, n->r); - return; - case NNum: - if(retain) - constgen(n->o.l); - return; - case NProg: - if(retain) - proggen(n->l, n->r); - return; - case NResult: - gen(n->l, 1); - emit(Ijmp); - emitconst((long)(resultloc-here()-1)*WS); - return; - case NScope: - pushscope(); - if(nscope==1){ - int nauto; - autooffset=0; - emit(Ipushfp); - nauto=here(); - emitconst(0L); - gen(n->l, 0); - patch((int)nauto, autooffset); - }else - gen(n->l, 0); - scopedecrefgen(); - popscope(); - return; - case NSelect: - selgen(n->l); - return; - case NSmash:{ - Value *vl, *vr; - vl=n->l->o.s->val; - vr=n->r->o.s->val; - if(vr->type->o.t==TType){ - freenode(vl->type); - vl->type=dupnode(vr->type); - return; - } - gen(n->r, 1); - /* - * Free old values; tricky: push as int, pop as ptr - */ - if(isptrtype(vl->type)){ - if(vl->isauto){ - emit(Ipushauto); - emitconst(vl->store.off); - }else{ - emit(Ipush); - emitconst((long)&vl->store.l); - } - emit(Ipopptr); - } - if(vl->isauto){ - emit(Istoreauto); - emitconst(vl->store.l); - return; - } - emit(Istore); - emitconst((long)&vl->store.l); - return; - } - case NString: - if(retain){ - Store *s; - s=(Store *)emalloc(SHSZ+strlen(n->o.c)+1); - strcpy((char *)(s->data), n->o.c); - s->ref=1; - s->len=strlen(n->o.c); - s->type=Sarychar; - emit(Ipushdata); - emitconst((long)s); - } - return; - case NStructref: - arygen(n->l, n->r, 1, n->o.l); - return; - case NSwitch: - switchgen(n->l, n->r); - return; - case NUnit: - if(retain) - constgen(0L); - return; - case NVal: - valgen(n->l); - if(!retain) - popgen(n->o.n); - return; - } - panic("can't compile node %n", n->t); - return; -} - -arygen(Node *a, Node *i, int isstr, long off) -{ - int ptr, ischar; - if(isstr){ - ptr=isptrtype(i); - constgen(off); - ischar=0; - }else{ - Node *t=etypeoft(a)->r; - ptr=isptrtype(t); - gen(i, 1); - ischar=t->o.t==TChar; - } - if(a->t!=NID){ - gen(a, 1); - emit(ptr? Ipusharyptrexpr : - (ischar? Ipusharycharexpr :Ipusharyexpr)); - }else if(a->o.s->val->isauto){ - emit(ptr? Ipusharyptrauto : - (ischar? Ipusharycharauto :Ipusharyauto)); - emitconst(a->o.s->val->store.off); - }else{ - emit(ptr? Ipusharyptr : - (ischar? Ipusharychar :Ipushary)); - emitconst((long)&a->o.s->val->store.l); - } -} - -lgen(Node *n) -{ - switch(n->t){ - case NID: - switch(typeof(n)->o.t){ - case TChar: - if(n->o.s->val->isauto){ - emit(Istorecharauto); - emitconst(n->o.s->val->store.off); - return; - } - emit(Istorechar); - emitconst((long)&n->o.s->val->store.l); - return; - case TInt: - case TUnit: - if(n->o.s->val->isauto){ - emit(Istoreauto); - emitconst(n->o.s->val->store.off); - return; - } - emit(Istore); - emitconst((long)&n->o.s->val->store.l); - return; - case TArray: - case TChan: - case TProg: - case TStruct: - if(n->o.s->val->isauto){ - emit(Istoreptrauto); - emitconst(n->o.s->val->store.off); - return; - } - emit(Istoreptr); - emitconst((long)&n->o.s->val->store.l); - return; - - default: - panic("lgen: ID type %t", n->o.s->val->type->o.t); - return; - } - case NArrayref: - gen(n->r, 1); - goto Genref; - case NStructref: - constgen(n->o.l); - Genref: - lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary); - emit(Istoreary); - return; - default: - panic("lgen: lvalue node %n", n->t); - } -} - -/* - * n is a compound object about to be assigned into - */ -lgen1(Node *n, int Iauto, int Ivar, int Iary) -{ - switch(n->t){ - case NID: - if(n->o.s->val->isauto){ - emit(Iauto); - emitconst(n->o.s->val->store.off); - return; - } - emit(Ivar); - emitconst((long)&n->o.s->val->store.l); - return; - case NArrayref: - gen(n->r, 1); - goto Genref; - case NStructref: - constgen(n->o.l); - Genref: - lgen1(n->l, Ipushuniqauto, Ipushuniq, Ipushuniqary); - emit(Iary); - return; - default: - panic("lgen1: lvalue node %n", n->t); - } -} - -ifgen(Node *n) -{ - int loc1, loc2; - gen(n->o.n, 1); - emit(Ijmpfalse); - loc1=here(); - emit(0); - gen(n->l, 0); - if(n->r==0){ - patch(loc1, (long)(here()-loc1-1)*WS); - return; - } - emit(Ijmp); - loc2=here(); - emit(0); - patch(loc1, (long)(here()-loc1-1)*WS); - gen(n->r, 0); - patch(loc2, (long)(here()-loc2-1)*WS); - return; -} - -valgen(Node *n) -{ - int loc1, loc2; - int orl; - emit(Ijmp); - loc1=here(); - emitconst(0L); - orl=resultloc; - resultloc=here(); - emit(Ijmp); - loc2=here(); - emitconst(0L); - patch(loc1, (long)(here()-loc1-1)*WS); - gen(n, 1); - emit(Ivalnoresult); - patch(loc2, (long)(here()-loc2-1)*WS); - resultloc=orl; -} - -loopgen(Node *n) -{ - int loc0, loc1, loc2; - if(n->o.i){ /* enter loop at top, so jump to body */ - emit(Ijmp); - loc0=here(); - emit(0); - } - gen(n->r->l, 0); /* left expr */ - if(n->r->r){ /* jump to condition */ - emit(Ijmp); - loc1=here(); - emit(0); - } - if(n->o.i) - patch(loc0, (here()-loc0-1)*LWS); - loc2=here(); - gen(n->l, 0); /* body */ - gen(n->r->o.n, 0); /* right expr */ - if(n->r->r){ - patch(loc1, (here()-loc1-1)*LWS); - gen(n->r->r, 1); - emit(Ijmptrue); - }else - emit(Ijmp); - emitconst((loc2-here()-1)*LWS); -} - -condgen(Node *l, Node *r, Inst i1, Inst i2, long t1, long t2, int retain) -{ - int loc1, loc2, loc3; - gen(l, 1); - emit(i1); - loc1=here(); - emit(0); - loc2=here(); - if(retain) - constgen(t1); - emit(Ijmp); - loc3=here(); - emit(0); - patch(loc1, (long)(here()-loc1-1)*WS); - gen(r, 1); - emit(i2); - emitconst((long)(loc2-here()-1)*WS); - if(retain) - constgen(t2); - patch(loc3, (long)(here()-loc3-1)*WS); -} - -callgen(Node *n, int callinst) -{ - Node *pt; - pt=etypeof(n->l); - /* - * Space for result - */ - constgen(0L); - /* - * Args - */ - gen(n->r, 1); - /* - * Call - */ - emit(Ipushconst); - if(n->l->t==NID) - emitconst((long)n->l->o.s->name); - else{ - char buf[128]; - char *p; - sprint(buf, "prog(){call on line %d}", n->line); - p=emalloc((unsigned long)strlen(buf)+1); - strcpy(p, buf); - emitconst((long)p); - } - gen(n->l, 1); - switch(callinst){ - case Icall: - emit(Icall); - return; - case Ibegin: - constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */ - emit(Ibegin); - return; - case Ibecome: - constgen(LWS*(1+1+length(pt->l))); /* result+procname+args */ - scopedecrefgen(); - fdecrefgen(formals, -3L*WS); - emit(Ibecome); - if(formals) - emitconst(length(formals)*LWS); - else - emitconst(0L); - return; - } - panic("callgen"); -} - -selgen(Node *n) -{ - int tbl, i; - long l; - int ends[200]; - selchangen(n); - l=length(n); - constgen(l); - emit(Icommset); - emit(Icommcln); - if(l>(sizeof ends/sizeof ends[0])) - panic("selgen table too small"); - tbl=here(); - emitspace(l); - i=0; - seltblgen(n, tbl, ends, &i); - for(i=0; i<l; i++) - patch(ends[i], (long)(here()-ends[i]-1)*WS); -} - -selchangen(Node *n) -{ - long flags; - if(n->t==NList){ - selchangen(n->l); - selchangen(n->r); - return; - } - if(n->t!=NCase) - panic("selchangen"); - n=n->l->l; - if(n->o.t=='=') - n=n->r; /* n is now RCV or SND */ - flags=0; - if(n->o.t==SND) - flags|=Cissnd; - n=n->l; /* n is now channel */ - if(n->t==NArraycom){ - flags|=Cisary; - n=n->l; - }else if(etypeoft(n)->o.t==TArray) - flags|=Cisary; - gen(n, 1); - constgen(flags); -} - -seltblgen(Node *n, int tbl, int *ends, int *ip) -{ - Node *c, *s, *l, *t; - if(n->t==NList){ - /* chans are eval'ed from the top, so table is backwards */ - seltblgen(n->r, tbl, ends, ip); - seltblgen(n->l, tbl, ends, ip); - return; - } - if(n->t!=NCase) - panic("seltblgen"); - if(n->l->t==NList) - error("sorry, empty cases not implemented"); - patch(tbl+*ip, (long)(here()-tbl)*WS); - c=n->l->l; /* communication */ - s=n->r; /* statement */ - l=0; - if(c->o.t=='='){ - l=c->l; /* lvalue */ - c=c->r; - } - if(c->o.t==SND){ - gen(c->r, 1); - if(isptrtype(etypeoft(c->l)->r)) - emit(Isndptr); - else - emit(Isnd); - } - c=c->l; /* channel expression */ - /* - * The value is still on the stack; save it or toss it - */ - if(l) - lgen(l); - else if(c->t==NArraycom){ - t=etypeoft(c->l)->r; - if(t->o.t==TID) - t=typeoftid(t); - popgen(t->r); - }else - popgen(etypeoft(c)->r); - if(c->t==NArraycom){ /* save array index */ - if(c->r) - lgen(c->r); - else - emit(Ipop); - } - gen(s, 0); - emit(Ijmp); - ends[*ip]=here(); - (*ip)++; - emitconst(0L); -} - -switchgen(Node *s, Node *e) -{ - int isptr, out; - isptr=isptrtype(etypeof(e)); - gen(e, 1); - emit(Ijmp); - emitconst(2*LWS); - emit(Ijmp); /* each case jumps to here to get out */ - out=here(); - emitconst(0L); - switchgen1(s, isptr, out-1); - /* pop leftover value if no case matched */ - if(isptr) - emit(Ipopptr); - else - emit(Ipop); - patch(out, (here()-out-1)*LWS); -} - -switchgen1(Node *s, int isptr, int out) -{ - Node *e; - int loc; - if(s->t==NList){ - switchgen1(s->l, isptr, out); - switchgen1(s->r, isptr, out); - return; - } - if(s->t!=NCase) - panic("switchgen1"); - if(s->r==0) - error("sorry; can't fold cases together yet"); - if(s->l->t==NDefault) - loc=-1; - else{ - e=s->l->l; - if(isptr){ /* string */ - emit(Idupptr); - gen(e, 1); - emit(Istrcmp); - constgen(0L); - }else{ - emit(Idup); - gen(e, 1); - } - emit(Ieq); - emit(Ijmpfalse); - loc=here(); - emitconst(0L); - } - if(isptr) - emit(Ipopptr); - else - emit(Ipop); - gen(s->r, 0); - emit(Ijmp); - emitconst((out-here()-1)*LWS); - if(loc!=-1) - patch(loc, (here()-loc-1)*LWS); -} - -popgen(Node *t) -{ - if(isptrtype(t)) - emit(Ipopptr); - else if(isinttype(t) || t->o.t==TUnit) - emit(Ipop); - else - panic("popgen %t\n", t->o.t); -} - -genfreeauto(Symbol *s) -{ - if(!s->val->isauto) - panic("genfreeauto"); - if(isptrtype(s->val->type)){ - emit(Idecrefauto); - emitconst(s->val->store.off); - } -} - -printgen(Node *n) -{ - Node *t; - if(n==0) - return; - if(n->t==NExprlist){ - printgen(n->l); - printgen(n->r); - return; - } - t=etypeoft(n); - switch(t->o.t){ - case TArray: - case TChan: - case TProg: - case TStruct: - emit(Iprintary); - break; - case TChar: - emit(Iprintchar); - break; - case TInt: - emit(Iprintint); - break; - case TUnit: - emit(Iprintunit); - break; - default: - panic("printgen: bad type %t", t->o.t); - } -} - -proggen(Node *t, Node *n) -{ - int or; - Node *of; - Errjmp s; - Store *p; - long len, loc; - long nauto, oao; - extern int (*prog[])(); - oao=autooffset; - or=returnloc; - of=formals; - autooffset=0; - returnloc=0; - formals=t->l; - errsave(s); - if(errmark()){ - returnloc=or; - formals=of; - autooffset=oao; - errrest(s); - errjmp(); - } - loc=here(); - pushscope(); - dclformals(t->l); - autooffset=0; - emit(Ipushfp); - nauto=here(); - emitconst(0L); - gen(n, 0); - trlrgen(); - patch((int)nauto, autooffset); - popscope(); - errrest(s); - autooffset=oao; - returnloc=or; - formals=of; - len=here()-loc+1; - p=(Store *)emalloc(SHSZ+len*LWS); - memcpy((char *)(p->data), (char *)(prog+loc), len*LWS); - p->ref=1; - p->len=len; - p->type=Sprog; - setprog(loc); - emit(Ipushdata); - emitconst((long)p); -} - -trlrgen() -{ - if(returnloc){ - emit(Ijmp); - emitconst((long)(returnloc-here()-1)*WS); - return; - } - returnloc=here(); - fdecrefgen(formals, -3L*WS); - emit(Iret); - if(formals) - emitconst(length(formals)*LWS); - else - emitconst(0L); -} - -fdecrefgen(Node *types, long offset) -{ - if(types==0) - return 0; - if(types->t==NList){ - offset=fdecrefgen(types->l, offset); - return fdecrefgen(types->r, offset); - } - if(types->t!=NFormal) - panic("fdecrefgen"); - types=types->r; - if(isptrtype(types)){ - emit(Idecrefauto); - emitconst(offset); - } - return offset-WS; -} - -dupgen(Node *t, int n) -{ - while(n--) - emit(isptrtype(t)? Idupptr : Idup); -} - -mkgen(Node *t, Node *v) -{ - switch(t->o.t){ - case TChar: - case TInt: - case TUnit: - if(v) - gen(v, 1); - else - constgen(0L); - return; - case TID: - mkgen(typeoftid(t), v); - return; - case TChan: - if(v) - gen(v, 1); - else{ - constgen((long)(sizeof(Chan)-sizeof(Store))); - mallocgen(t); - } - return; - case TArray: - if(v==0){ - gen(t->l, 1); - mallocgen(t); - return; - } - gen(v, 1); - if(v->t!=NExprlist && eqtype(t, etypeof(v))) - return; - if(v->t==NString) - constgen((long)strlen(v->o.c)); - else - constgen((long)length(v)); - emit(Idup); - if(t->l) - gen(t->l, 1); - else - constgen(0L); - emit(Imax); - mallocgen(t); - if(t->r->o.t==TChar){ - if(v->t==NString) - emit(Imemcpychar); - else - emit(Imemcpycharint); - }else - emit(Imemcpy); - return; - case TProg: - if(v==0){ - v=new(NProg, dupnode(t), (Node *)0, (Node *)0); - gen(v, 1); - freenode(v); - return; - } - gen(v, 1); - return; - case TStruct: - if(v==0){ - mallocgen(t); - return; - } - gen(v, 1); - if(v->t!=NExprlist && eqtype(t, etypeof(v))) - return; - constgen((long)length(v)); - mallocgen(t); - emit(Imemcpystruct); - return; - default: - panic("mkgen: bad type %t", t->o.t); - } -} - -mallocgen(Node *t) -{ - switch(t->o.t){ - case TArray: - t=t->r; - if(t->o.t==TID) - t=typeoftid(t); - if(isptrtype(t)){ - constgen((long)Saryptr); - emit(Imalloc); - }else if(t->o.t==TInt || t->o.t==TUnit){ - constgen((long)Saryint); - emit(Imalloc); - }else if(t->o.t==TChar) - emit(Imallocarychar); - else - panic("mallocgen array of %t", t->o.t); - return; - case TStruct:{ - int pos=0; - long bits=0; - t=t->l; - elembitsgen(t, &pos, &bits); - if(pos) - constgen(bits); - constgen((long)length(t)); - emit(Imallocstruct); - return; - } - case TChan: - constgen((long)Schan); - emit(Imalloc); - return; - } - panic("mallocgen of %t", t->o.t); -} - -elembitsgen(Node *t, int *pos, long *bits) -{ - int i; - if(t->t==NList){ - elembitsgen(t->l, pos, bits); - elembitsgen(t->r, pos, bits); - return; - } - if(t->t!=NElem) - panic("elembitsgen %n", t->t); - for(i=length(t); --i>=0; ){ - if(*pos==BPW){ - constgen(*bits); - *pos=0; - *bits=0; - } - if(isptrtype(t->r)) - *bits|=1L<<*pos; - (*pos)++; - } -} - -constgen(long l) -{ - if(l<-2 || l>10){ - emit(Ipushconst); - emitconst(l); - return; - }; - switch((int)l){ - case -2: - emit(Ipush_2); - break; - case -1: - emit(Ipush_1); - break; - case 0: - emit(Ipush0); - break; - case 1: - emit(Ipush1); - break; - case 2: - emit(Ipush2); - break; - case 3: - emit(Ipush3); - break; - case 4: - emit(Ipush4); - break; - case 5: - emit(Ipush5); - break; - case 6: - emit(Ipush6); - break; - case 7: - emit(Ipush7); - break; - case 8: - emit(Ipush8); - break; - case 9: - emit(Ipush9); - break; - case 10: - emit(Ipush10); - break; - default: - panic("constgen"); - } -} - -printable(Node *n) -{ - if(n==0) - return 0; - switch(n->t){ - case NExpr: - return n->o.t!='='; - case NArrayref: - case NCall: - case NID: - case NMk: - case NNum: - case NProg: - case NString: - case NStructref: - case NUnit: - case NVal: - return 1; - } - return 0; -} -#include "alloc.h" -#include "node.h" -#include "symbol.h" -#include "ydefs.h" -#include "word.h" -#include "store.h" -#include <libc.h> - -Node *doconst(); -extern int Cflag; - -Node * -constants(Node *n) -{ - if(n==0) - return 0; - if(Cflag) - return n; - switch(n->t){ - case NArrayref: - if(isconst(n)) - return doconst(n); - break; - case NArraycom: - break; - case NBecome: - break; - case NBegin: - break; - case NCall: - break; - case NCase: - break; - case NDecl: - n->r=constants(n->r); - n->o.n=constants(n->o.n); - declare(n, 0, 0, 0); - return n; - case NDeclsc: - break; - case NDefault: - return n; - case NElem: - n->r=constants(n->r); - return n; - case NExpr: - switch(n->o.i){ - case GE: - case LE: - case NE: - case EQ: - case '>': - case '<': - case '+': - case '-': - case '*': - case '/': - case '%': - case '&': - case '|': - case '^': - case ANDAND: - case OROR: - case LSH: - case RSH: - if(isconst(n->l) && isconst(n->r)) - return doconst(n); - break; - case DEF: - case REF: - case LEN: - case UMINUS: - case '~': - case '!': - if(isconst(n->l)) - return doconst(n); - break; - case PRINT: - case RCV: - case SND: - case INC: - case DEC: - break; - case '=': - break; - default: - fprint(2, "can't const expression %e\n", n->o.i); - return n; - } - break; - case NExprlist: - break; - case NFormal: - n->r=constants(n->r); - return n; - case NLabel: - break; - case NID: - if(isconst(n)) - return doconst(n); - break; - case NIf: - n->l=constants(n->l); - n->r=constants(n->r); - n->o.n=constants(n->o.n); - if(isconst(n->o.n)){ - Node *m; - gen(n->o.n, 1); - execute(); - if(topofstack()){ - m=n->l; - n->l=0; - }else{ - m=n->r; - n->r=0; - } - freenode(n); - return m; - } - return n; - case NList: - break; - case NLoop: - break; - case NLoopexpr: - n->o.n=constants(n->o.n); - break; - case NMk: - break; - case NNum: - return n; - case NProg: - pushscope(); - dclformals(n->l->l); - n->r=constants(n->r); - popscope(); - return n; - case NResult: - break; - case NScope: - pushscope(); - n->l=constants(n->l); - popscope(); - return n; - case NSelect: - break; - case NSmash: - return n; - case NString: - return n; - case NSwitch: - break; - case NStructref: - if(isconst(n)) - return (n); - break; - case NType: - break; - case NUnit: - break; - case NVal: - if(isconst(n->l)) - return doconst(n); - break; - default: - fprint(2, "can't const node %n\n", n->t); - return n; - } - n->l=constants(n->l); - n->r=constants(n->r); - return n; -} - -isconst(Node *n) -{ - if(n==0) - return 1; - switch(n->t){ - case NArrayref: - return isconst(n->l) && isconst(n->r); - case NCall: - return 0; - case NExpr: - switch(n->o.i){ - case GE: - case LE: - case NE: - case EQ: - case '>': - case '<': - case '+': - case '-': - case '*': - case '/': - case '%': - case '&': - case '|': - case '^': - case ANDAND: - case OROR: - case LSH: - case RSH: - return isconst(n->l) && isconst(n->r); - case DEF: - case LEN: - case UMINUS: - case '~': - case '!': - return isconst(n->l); - case REF: - case '=': - case RCV: - case SND: - case INC: - case DEC: - return 0; - } - fprint(2, "can't isconst expression %e", n->o.i); - return 0; - case NID: - return n->o.s->val->scope==0 && (n->o.s->val->stclass&SCconst); - case NIf: - return isconst(n->o.n) && isconst(n->l) && isconst(n->r); - case NList: - return 0; - case NLoop: - return 0; - case NNum: - return 1; - case NResult: - return isconst(n->l); - case NScope: - return isconst(n->l); - case NString: - return 1; - case NStructref: - return isconst(n->l); - case NVal: - return isconst(n->l); - case NUnit: - return 1; - } - fprint(2, "can't isconst node %n\n", n->t); - return 0; -} - -Node * -doconst(Node *n) -{ - Node *t; - if(n->t==NNum || n->t==NString || n->t==NUnit) - return n; /* already const */ - t=etypeoft(n); - switch(t->o.t){ - case TChar: - case TInt: - gen(n, 1); - freenode(n); - execute(); - return new(NNum, (Node *)0, (Node *)0, (Node *)topofstack()); - case TUnit: - return new(NUnit, (Node *)0, (Node *)0, (Node *)0); - case TArray: - if(t->r->o.t==TChar){ - Store *s; - char *c; - gen(n, 1); - freenode(n); - execute(); - s=(Store *)topofstack(); - c=emalloc(s->len+1); - strncpy(c, (char *)s->data, (int)s->len); - return newc(NString, (Node *)0, (Node *)0, c); - } - return n; - } - return n; -} -#include "alloc.h" -#include "word.h" -#include "store.h" -#include "comm.h" -#include <libc.h> - -extern int pflag; - -/* - * Jumps - */ - -ijmp(Proc *proc) -{ - SWord l; - l=(SWord)*++proc->pc; - proc->pc+=l/WS; - return 1; -} - -ijmpfalse(Proc *proc) -{ - SWord l; - l=(SWord)*++proc->pc; - if(*--proc->sp==0) - proc->pc+=l/WS; - return 1; -} - -ijmptrue(Proc *proc) -{ - SWord l; - l=(SWord)*++proc->pc; - if(*--proc->sp!=0) - proc->pc+=l/WS; - return 1; -} - -ivalnoresult(Proc *proc) -{ - rerror("val produces no result"); - return 0; -} - -/* - * Progs - * - * Layout of a stack frame - * - * sp: - * automatics - * fp: old fp - * old pc - * symbol - * arg1 - * arg2 - * ... - * result - */ - -iret(Proc *proc) -{ - SWord nargs; - nargs=(SWord)(proc->pc[1]); - proc->sp=(SWord *)proc->fp+1; - proc->fp=(SWord *)*--proc->sp; - proc->pc=(int (**)())*--proc->sp; - proc->sp-=(sizeof(char *)+nargs)/WS; - if(proc->pc==0){ - if(pflag) - fprint(2, "%d halts\n", proc->procnum); - halt(proc); - return 0; - } - return 1; -} - -ibecome(Proc *proc) -{ - int nargs; - int (**newpc)(); - SWord oldfp, oldpc, *oldresultaddr, *newresultaddr; - Store *s; - nargs=*--proc->sp/LWS; - nargs+=2; /* includes result and sym; add pc, fp */ - s=(Store *)*--proc->sp; - if(--(s->ref)==0) - rpanic("ibecome ref==0"); - newpc=((int (**)())s->data); - oldfp=proc->fp[0]; - oldpc=proc->fp[-1]; - *proc->sp++=oldpc; - *proc->sp++=oldfp; - oldresultaddr=proc->fp-3-(long)(*++proc->pc)/LWS; - newresultaddr=proc->sp-nargs; - memcpy((char *)oldresultaddr, (char *)newresultaddr, LWS*nargs); - /* args in place. do the call by hand, jmp to pushfp */ - proc->sp=oldresultaddr+(nargs-2); - *proc->sp++=oldpc; - proc->fp=(SWord *)oldfp; - proc->pc=newpc-1; - return 1; -} - -ipushfp(Proc *proc) -{ - int nauto; - *proc->sp=(SWord)proc->fp; - proc->fp=proc->sp++; - nauto=((SWord)*++proc->pc)/WS; - while(nauto--) - *proc->sp++=0; - if(proc->sp>=&proc->stack[NSTACK]) - rerror("stack overflow"); - return 1; -} - -icall(Proc *proc) -{ - int (**newpc)(); - Store *s; - s=(Store *)*--proc->sp; - if(--(s->ref)==0) - rpanic("icall ref==0"); - newpc=((int (**)())s->data); - *proc->sp++=(SWord)proc->pc; - proc->pc=newpc-1; - return 1; -} -#include "node.h" -#include "symbol.h" -#include "alloc.h" -#include "ydefs.h" -#include "word.h" -#include "store.h" -#include <libc.h> - -extern int nscope; - -declare(Node *n, int stclass, int dotypchk, int docomp) -{ - extern int iflag; - if(n==0) - return; - if(n->t==NList){ - declare(n->l, stclass, dotypchk, docomp); - declare(n->r, stclass, dotypchk, docomp); - return; - } - if(n->t==NDeclsc){ - declare(n->l, n->o.i, dotypchk, docomp); - return; - } - if(dotypchk) - type(n->o.n, 0); - if(n->r==0){ - if(n->o.n==0) - panic("declare: no type"); - if(n->o.n->t==NMk && n->o.n->l==0) - lerror(n, "can't derive type in declaration"); - n->r=dupnode(etypeof(n->o.n)); - } - if(dotypchk){ - type(n->r, 0); - if(n->o.n){ - /* - * Make it a mk - */ - if(n->o.n->t!=NMk) - n->o.n=new(NMk, (Node *)0, n->o.n, (Node *)0); - /* - * Default type for mk - */ - if(n->o.n->l==0) - n->o.n->l=dupnode(n->r); - else if(!compattype(n->r, n->o.n->l)) - lerror(n, "type clash in declaration (%t %t)\n", - n->r->o.t, etypeof(n->o.n)->o.t); - mkcheck(n->o.n->l, n->o.n->r); - } - } - if(docomp && n->o.n){ - if(dotypchk) /* top level declaration */ - n->o.n=constants(n->o.n); - gen(n->o.n, 1); - dupgen(n->r, length(n->l)-1); - }else - docomp=0; - dcl(n->l, n->r, stclass, n->o.n, docomp); - if(n->o.n && docomp && nscope==0){ - if(iflag) - idump(); - execute(); - } -} - -dcl(id, typ, stclass, val, docomp) - Node *id, *typ, *val; -{ - if(id->t==NList){ - dcl(id->l, typ, stclass, val, docomp); - dcl(id->r, typ, stclass, val, docomp); - return; - } - if(typ->o.t==TID && typ->l->o.s->val->type->o.t!=TType) - error("%m not a type", typ->l); - if(id->t!=NID) - panic("dcl not ID"); - pushval(id->o.s, dupnode(typ)); - if(stclass&SCbltin) - id->o.s->val->store.l=bltinval(id->o.s->name, typ); - if(docomp) - lgen(id); - id->o.s->val->stclass=stclass; -} - -/* - * To compile this - * rec { - * x : chan of T = f(x,y); - * y : chan of T = g(x,y); - * }; - * convert it to this - * x : chan of T = mk(); - * y : chan of T = mk(); - * x1 : chan of T = f(x,y); - * y1 : chan of T = g(x,y); - * x <- x1; - * y <- y1; - * toss x1, y1; - * where the operator x <- x1 means copy the representation of x1 into x. - * - * rec type T: struct of { t:T; }; - * - * is handled similarly. - */ - -Node * -op1(Node *n) -{ - Node *m; - if(n->t==NDeclsc){ - m=op1(n->l); - return newi(NDeclsc, m, (Node *)0, n->o.i); - } - if(n->r==0){ - if(n->o.n && (n->o.n->t==NProg || (n->o.n->t==NMk && n->o.n->l))) - n->r=dupnode(n->o.n->l); - else - lerror(n, "can't deduce type for rec decl"); - }else if(n->r->o.t==TType){ - m=newi(NType, (Node *)0, (Node *)0, n->r->l->o.t); - m=new(NDecl, dupnode(n->l), m, (Node *)0); - return m; - } - m=new(NMk, dupnode(n->r), (Node *)0, (Node *)0); - m=new(NDecl, dupnode(n->l), dupnode(n->r), m); - return m; -} - -Node * -op2(Node *n) -{ - Node *m; - char s[Namesize+2]; - if(n->t==NDeclsc){ - m=op2(n->l); - return newi(NDeclsc, m, (Node *)0, n->o.i); - } - if(n->l->t==NList) - error("no identifier lists in rec's, please"); - strcpy(s+1, n->l->o.s->name); - s[0]='*'; - m=new(NDecl, idnode(lookup(s, ID)), dupnode(n->r), dupnode(n->o.n)); - return m; -} - -Node * -op3(Node *n) -{ - Node *m; - char s[Namesize+2]; - if(n->t==NDeclsc) - return op3(n->l); - if(n->l->t==NList) - error("no lists in rec's, please"); - strcpy(s+1, n->l->o.s->name); - s[0]='*'; - m=new(NSmash, idnode(lookup(s+1, ID)), idnode(lookup(s, ID)), (Node *)0); - return m; -} - -Node * -rewr(Node *n, Node *(*f)()) -{ - if(n->t==NList) - return new(NList, rewr(n->l, f), rewr(n->r, f), (Node *)0); - return (*f)(n); -} - -recrewrite(Node *n) -{ - Node *n1, *n2, *n3; - n1=rewr(n->l, op1); - n2=rewr(n->l, op2); - n3=rewr(n->l, op3); - freenode(n->l); - n->t=NList; - n->r=n3; - n->l=new(NList, n1, n2, (Node *)0); - ndump(n); -} - -/* - * - * To compile this - * - * prog(a:int){ - * begin prog(b:int){ f(a, b); }(b); - * } - * - * convert it to this - * - * prog(a:int){ - * begin prog(b:int, a:int){ f(a, b); }(b, a); - * } - * - */ - -Node *begf; -Node *bega; -int fscope; -int progerr; - -proglocals(Node *n) -{ - progerr=1; - pushscope(); - fscope=nscope; - begf=n->l->l; - bega=0; - dclformals(begf); - progid(n->r); - popscope(); -} - -begrewrite(Node *n) -{ - progerr=0; - pushscope(); - fscope=nscope; - begf=n->l->l->l; - bega=n->r; - dclformals(begf); - progid(n->l->r); - popscope(); - n->l->l->l=begf; - n->r=bega; -} - -addformal(Node *n) -{ - Node *nf; - if(!alreadyformal(n, begf)){ - nf=new(NFormal, dupnode(n), dupnode(n->o.s->val->type), (Node *)0); - if(begf) - begf=new(NList, begf, nf, (Node *)0); - else - begf=nf; - nf=dupnode(n); - if(bega) - bega=new(NExprlist, bega, nf, (Node *)0); - else - bega=nf; - } -} - -alreadyformal(Node *n, Node *f) -{ - if(f==0) - return 0; - if(f->t==NList) - return alreadyformal(n, f->l) || alreadyformal(n, f->r); - return strcmp(n->o.s->name, f->l->o.s->name)==0; -} - -progid(Node *n) -{ - if(n==0) - return; - switch(n->t){ - case NArrayref: - case NArraycom: - case NBecome: - case NBegin: - case NCall: - case NCase: - break; - case NDecl: - progid(n->r); - progid(n->o.n); - declare(n, 0, 0, 0); - return; - case NDeclsc: - case NDefault: - break; - case NElem: - return; - case NExpr: - case NExprlist: - case NFormal: - break; - case NID: - if(n->o.s->val) - if(0<n->o.s->val->scope && n->o.s->val->scope<fscope){ - if(progerr) - lerror(n, "%m not in an accessible scope", n); - addformal(n); - } - return; - case NLabel: - case NList: - case NLoop: - break; - case NLoopexpr: - progid(n->o.n); - break; - case NIf: - progid(n->o.n); - break; - case NMk: - break; - case NNum: - return; - case NProg: - pushscope(); - dclformals(n->l->l); - progid(n->r); - popscope(); - return; - case NResult: - break; - case NScope: - pushscope(); - progid(n->l); - popscope(); - return; - case NSelect: - break; - case NSmash: - return; /* ?? */ - case NString: - return; - case NSwitch: - case NStructref: - break; - case NType: - break; - case NUnit: - return; - case NVal: - break; - default: - fprint(2, "can't progid node %n\n", n->t); - return; - } - progid(n->l); - progid(n->r); -} - -#include "nodenames.h" -#include "typenames.h" -#include "errjmp.h" -#include "node.h" -#include "symbol.h" -#include "ydefs.h" -#include <libc.h> - -lerror(Node *n, char *s, a, b, c, d, e, f) -{ - lfileline(n->line); - fprint(2, s, a, b, c, d, e, f); - if(s[strlen(s)-1]!='\n') - fprint(2, "\n"); - errflush(); - errjmp(); -} - -error(char *s, a, b, c, d, e, f) -{ - fileline(); - fprint(2, s, a, b, c, d, e, f); - if(s[strlen(s)-1]!='\n') - fprint(2, "\n"); - errflush(); - errjmp(); -} - -rerror(char *s, a, b, c, d, e, f) -{ - fileline(); - fprint(2, s, a, b, c, d, e, f); - fprint(2, "\n"); - processes(0); - errflush(); - errjmp(); -} - -warn(char *s, a, b, c, d, e, f) -{ - fileline(); - fprint(2, "warning: "); - fprint(2, s, a, b, c, d, e, f); - fprint(2, "\n"); -} - -panic(char *s, a, b, c, d, e, f) -{ - fileline(); - fprint(2, "internal error: "); - fprint(2, s, a, b, c, d, e, f); - fprint(2, "\n"); - abort(); -} - -rpanic(char *s, a, b, c, d, e, f) -{ - fileline(); - processes(0); - fprint(2, "internal error: "); - fprint(2, s, a, b, c, d, e, f); - fprint(2, "\n"); - abort(); -} - -bconv(int *o, int f1, int f2) -{ - extern int printcol; - while(printcol<*o-8) - strconv("\t", f1, f2); - strconv(" "+(8-(*o-printcol)), f1, f2); - return sizeof(int); -} - -nconv(int *o, int f1, int f2) -{ - if(*o<0 || sizeof(Ntypename)/sizeof(Ntypename[0])<=*o) - strconv("mystery node", f1, f2); - else - strconv(Ntypename[*o], f1, f2); - return sizeof(int); -} - -tconv(int *o, int f1, int f2) -{ - if(*o<0 || sizeof(Ttypename)/sizeof(Ttypename[0])<=*o) - strconv("mystery type", f1, f2); - else - strconv(Ttypename[*o], f1, f2); - return sizeof(int); -} - -char bufx[128][10]; -int bufno=9; - -char * -prbuf(){ - if(++bufno==10) - bufno=0; - return bufx[bufno]; -} - -econv(int *o, int f1, int f2) -{ - char *buf=prbuf(); - char *x; - int t=*o; - if(t<128 && strchr("+-*/%|&^~?!><=", t)) - sprint(buf, "%c", t); - else{ - switch(t){ - case GE: - x=">="; - break; - case LE: - x="<="; - break; - case NE: - x="!="; - break; - case EQ: - x="=="; - break; - case ANDAND: - x="&&"; - break; - case OROR: - x="||"; - break; - case REF: - x="ref"; - break; - case LEN: - x="len"; - break; - case UMINUS: - x="unary -"; - break; - case RCV: - x="rcv"; - break; - case SND: - x="send"; - break; - case LSH: - x="<<"; - break; - case RSH: - x=">>"; - break; - case DEC: - x="--"; - break; - case INC: - x="++"; - break; - default: - x="mystery expression"; - break; - } - strcpy(buf, x); - } - strconv(buf, f1, f2); - return sizeof(int); -} - -mconv(int *o, int f1, int f2) -{ - char *buf=prbuf(); - Node *n=(Node *)*o; - switch(n->t){ //GO.SYSIN DD regress.d/t6.i echo regress.d/t6.out 1>&2 sed 's/.//' >regress.d/t6.out <<'//GO.SYSIN DD regress.d/t6.out' -emalloc(unsigned long n) -erealloc(char *p, unsigned long n) -pprint(proc, fmt, a, b, c, d, e) -bltinval(char *name, Node *t) -mk(type, len) -compile(n) /* called from parser only */ -gen(Node *n, int retain) -lgen(Node *n) -genfreeauto(Symbol *s) -dupgen(Node *t, int n) -printable(Node *n) -constants(Node *n) -declare(Node *n, int stclass, int dotypchk, int docomp) -recrewrite(Node *n) -proglocals(Node *n) -begrewrite(Node *n) -lerror(Node *n, char *s, a, b, c, d, e, f) -error(char *s, a, b, c, d, e, f) -rerror(char *s, a, b, c, d, e, f) -warn(char *s, a, b, c, d, e, f) -panic(char *s, a, b, c, d, e, f) -rpanic(char *s, a, b, c, d, e, f) -bconv(int *o, int f1, int f2) -nconv(int *o, int f1, int f2) -tconv(int *o, int f1, int f2) -econv(int *o, int f1, int f2) -mconv(int *o, int f1, int f2) //GO.SYSIN DD regress.d/t6.out echo regress.d/t6.pat 1>&2 sed 's/.//' >regress.d/t6.pat <<'//GO.SYSIN DD regress.d/t6.pat' -^Aconv\( -^Cconv\( -^Uconv\( -^bconv\( -^begrewrite\( -^bi_bread\( -^bi_close\( -^bi_open\( -^bi_rand\( -^bi_read\( -^bi_write\( -^bltinval\( -^compattype\( -^compile\( -^concat\( -^constants\( -^curproc\( -^dclformals\( -^declare\( -^decref\( -^dump\( -^dupgen\( -^dupnode\( -^econv\( -^elemrewr\( -^emalloc\( -^emit\( -^emitconst\( -^emitspace\( -^eqtype\( -^erealloc\( -^errflush\( -^error\( -^etypeof\( -^etypeoft\( -^execute\( -^exits\( -^fileline\( -^freenode\( -^gen\( -^genfreeauto\( -^halt\( -^here\( -^iconv\( -^idnode\( -^idump\( -^istart\( -^istopscope\( -^length\( -^lerror\( -^lexinit\( -^lfileline\( -^lgen\( -^lookup\( -^mconv\( -^mk\( -^mkcheck\( -^nargs\( -^nconv\( -^ndump\( -^new\( -^newc\( -^newfile\( -^newi\( -^newl\( -^panic\( -^patch\( -^popscope\( -^pprint\( -^printable\( -^processes\( -^procinit\( -^proglocals\( -^pushscope\( -^pushval\( -^recrewrite\( -^rerror\( -^rpanic\( -^run\( -^scopedecrefgen\( -^setprog\( -^tconv\( -^topofstack\( -^topscope\( -^type\( -^typeinit\( -^typeof\( -^typeoftid\( -^warn\( -^yylex\( -^yyparse\( //GO.SYSIN DD regress.d/t6.pat echo regress.d/t6.sh 1>&2 sed 's/.//' >regress.d/t6.sh <<'//GO.SYSIN DD regress.d/t6.sh' -$GRE -f t6.pat < t6.i //GO.SYSIN DD regress.d/t6.sh echo regress.d/t7.i 1>&2 sed 's/.//' >regress.d/t7.i <<'//GO.SYSIN DD regress.d/t7.i' - if [ `cat $HISTFILE | lct` -gt "$HISTMAXL" ] - -for i in `ls [0-9]*# | egrep '^[0-9]+##?$' | sed -e 's/#*$//'` - -do case "`ps -lx$i" in ?*);; *) rm -f ${i}# ${i}##;; esac - -NBRFILES=`ls -f $pubdir/jbk | fgrep -vi -x '. - -..'|lct` //GO.SYSIN DD regress.d/t7.i echo regress.d/t7.out 1>&2 sed 's/.//' >regress.d/t7.out <<'//GO.SYSIN DD regress.d/t7.out' -do case "`ps -lx$i" in ?*);; *) rm -f ${i}# ${i}##;; esac -NBRFILES=`ls -f $pubdir/jbk | fgrep -vi -x '. -..'|lct` //GO.SYSIN DD regress.d/t7.out echo regress.d/t7.sh 1>&2 sed 's/.//' >regress.d/t7.sh <<'//GO.SYSIN DD regress.d/t7.sh' -$GRE -G '^[^`]*`[^`]*$' < t7.i //GO.SYSIN DD regress.d/t7.sh echo regress.d/t8.i 1>&2 sed 's/.//' >regress.d/t8.i <<'//GO.SYSIN DD regress.d/t8.i' -b -ba //GO.SYSIN DD regress.d/t8.i echo regress.d/t8.out 1>&2 sed 's/.//' >regress.d/t8.out <<'//GO.SYSIN DD regress.d/t8.out' -b -ba //GO.SYSIN DD regress.d/t8.out echo regress.d/t8.sh 1>&2 sed 's/.//' >regress.d/t8.sh <<'//GO.SYSIN DD regress.d/t8.sh' -$GRE -F -x -f t8.i < t8.i //GO.SYSIN DD regress.d/t8.sh echo regress.d/t9.i 1>&2 sed 's/.//' >regress.d/t9.i <<'//GO.SYSIN DD regress.d/t9.i' -aba -cad -bad -acb //GO.SYSIN DD regress.d/t9.i echo regress.d/t9.out 1>&2 sed 's/.//' >regress.d/t9.out <<'//GO.SYSIN DD regress.d/t9.out' -aba -bad -acb //GO.SYSIN DD regress.d/t9.out echo regress.d/t9.sh 1>&2 sed 's/.//' >regress.d/t9.sh <<'//GO.SYSIN DD regress.d/t9.sh' -$GRE -F -f t8.i < t9.i //GO.SYSIN DD regress.d/t9.sh echo mkfile 1>&2 sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile' -NPROC=2 -CFLAGS=-DMEMMOVE -N -I/usr/include/lcc -I/usr/include/libc # -A -p -DPROFILING # -DUSE_STDIO -# CC should be an ansi compiler (or c++); OCC any old compiler -CC=lcc -OCC=cc -NAMES=main dofgrep dogre fns buffer -OBJ=${NAMES:%=%.o} -LIB=libc.a -LNAMES=cw bm re eg egcomp eglit egpos egstate egcw egbr egerror refile\ - egparen egmatch egcanon -LOBJ=${LNAMES:%=$LIB(%.o)} -LLOBJ=${LNAMES:%=%.o} -SRC=${NAMES:%=%.c} ${LNAMES:%=%.c} -BUILTINS='%.o: %.c - $CC $CFLAGS -c $stem.c -'"`cat DEPEND`" - -all:V: gre cyntax - -gre: $OBJ $LIB - $CC $CFLAGS -o $target $prereq - -regress:VQ: #hcheck - make CC=$CC regress - -oregress:VQ: - rm -fr tmp - mkdir tmp tmp/regress.d - for i in $SRC *.h - do - awk -f deansify.awk $i > tmp/$i - done - cp makefile tmp - cp regress.d/* tmp/regress.d - (cd tmp; make CC=$OCC regress) - rm -fr tmp - -lt1: lt1.o $LIB - $CC $CFLAGS -o $target $prereq - -pp:V: - pr mkfile hdr.h $SRC | lp -dpsu -n2 - -htest.o: htest.c - $CC $CFLAGS -DUSE_STDIO -c $prereq -htest: htest.o $LIB - $CC $CFLAGS -o $target $prereq -hcheck: htest - echo aabcdd | htest 'a+(b|c)*d+' tempa 0 - echo abccccc | htest '^(a|b)*(abc+|c)' tempa 0 - echo bccc | htest '(bc|bc+)' tempa 0 - echo abab | htest '((b|a)+)\1' tempa 0 - echo vivi | htest '^.+$' tempa '^(.+)$' tempb 01 - echo acbb | htest '((.)+)\1' tempa 0 - echo !gryphon.att.com!eby | time htest '^!([^!.]+)\.att\.com!(.+)$' tempa 0 - -h1:V: htest - echo abc | time htest '^^.+!([^!]+2!([^!]+)$$' tempa 0 - -check:V: - rm -f *.o gre refile libc.a - mk gre refile regress oregress - rm -f *.o gre refile libc.a - -bm.o: re.h lre.h hdr.h -buffer.o: re.h lre.h hdr.h -cw.o: re.h lre.h hdr.h -dofgrep.o: re.h lre.h hdr.h -dogre.o: re.h lre.h hdr.h -eg.o: re.h lre.h hdr.h -egbr.o: re.h lre.h hdr.h -egcomp.o: re.h lre.h hdr.h -egcw.o: re.h lre.h hdr.h -egerror.o: re.h /usr/include/stdio.h -eglit.o: re.h lre.h hdr.h -egmatch.o: re.h lre.h hdr.h -egparen.o: re.h lre.h hdr.h -egpos.o: re.h lre.h hdr.h -egstate.o: re.h lre.h hdr.h -fns.o: re.h lre.h hdr.h -main.o: re.h lre.h hdr.h -re.o: re.h lre.h hdr.h -refile.o: re.h lre.h - -$LIB(%.o):N: %.o - -$LIB:Q: $LOBJ - names=`membername $newprereq` - ar rv $target $names && rm $names - ranlib $target - -export:VQ: - what="$SRC hdr.h io.h re.h lre.h libc.h" - what="$what getopt.c" # for those without - what="$what `echo regress.d/*` mkfile makefile README" - what="$what tmac.an re.3 gre.1 deansify.awk" - cp /n/bowell/usr/man/man3/re.3 . - cp /n/bowell/usr/man/man1/gre.1 . - cp /usr/lib/tmac/tmac.an . - cp /usr/include/libc.h . - (echo mkdir regress.d; bundle $what) > gre.bundle - ls -l gre.bundle - rm re.3 libc.h gre.1 tmac.an - -%.rcp:V: - rcp gre.bundle $stem:/tmp - rsh $stem "cd /tmp; rm -fr gre; mkdir gre; cd gre; sh < ../gre.bundle; make regress && (cd ..; rm -fr gre gre.bundle)" - -DEPEND:D: $SRC - cdepend $OBJ $LLOBJ > DEPEND - -refile: refile.c $LIB - $CC $CFLAGS -DUSE_STDIO -o $target -DMAIN $prereq && rm refile.o -refile.o: refile.c - $CC $CFLAGS -DUSE_STDIO -c refile.c -extern:V: $LIB - nm $LIB | egrep -v ' [dtUb] |:| _re| _eg' | sort -u | mc - -poot:V: gre - gre -x '.|..' filex //GO.SYSIN DD mkfile echo makefile 1>&2 sed 's/.//' >makefile <<'//GO.SYSIN DD makefile' -CFLAGS=-g -DUSE_STDIO -I. #-p -DPROFILING # -OBJ=main.o dofgrep.o dogre.o fns.o buffer.o cw.o bm.o eg.o egcomp.o eglit.o egpos.o egstate.o egcw.o egbr.o egmatch.o egcanon.o -HOBJ=htest.o eg.o egcomp.o eglit.o egpos.o egstate.o egcw.o egbr.o egmatch.o re.o cw.o refile.o egerror.o #dofgrep.o dogre.o fns.o buffer.o cw.o bm.o egcanon.o - -gre: $(OBJ) - $(CC) $(CFLAGS) -o gre $(OBJ) - -htest: $(HOBJ) - $(CC) $(CFLAGS) -o htest $(HOBJ) - -regress: - rm -f buffer.o; make CC=$(CC) CFLAGS="$(CFLAGS) -DBUFSIZE=500" gre - cd regress.d; make GRE=../gre - rm -f buffer.o gre //GO.SYSIN DD makefile echo README 1>&2 sed 's/.//' >README <<'//GO.SYSIN DD README' -installation should be quite easy. set CFLAGS (in makefile) -to include a -DUSE_STDIO if you want to use stdio. otherwise -you will need fio. if you have a memmove in your C library, -use -DMEMMOVE; otherwise it will use memcpy (definition in hdr.h). - -a simple regression test can be done by make regress. - -the default C compiler is assumed to be ansi compliant (or c++). -if you don't have one, there is a deansify.awk to help. -look at the target oregress for how i use it. - -bugs to andrew@research.att.com - - -things to do: - multibyte chars //GO.SYSIN DD README echo tmac.an 1>&2 sed 's/.//' >tmac.an <<'//GO.SYSIN DD tmac.an' -'''\" PWB Manual Entry Macros - 1.36 of 11/11/80 -'''\" Nroff/Troff Version @(#)1.36 -'''\" Option -rs1 short (9") pages -'''\" Option -rp# set no. of first page, put no. of pgs. on stderr -'''\" Option -rd1 give modified date instead of printed date -.deth -.tmwrong version of man entry macros - use -man6 -.ab -.. -.ifn .ds Tm \uTM\d -.ift .ds Tm \v'-0.5m'\s-4TM\s+4\v'0.5m' -.de}E -.}f -.in\\n()Ru+\\n(INu -.ll\\n(LLu -.lt\\n(LLu -.pl\\n()Lu -.. -.deDT -.ift .ta 3.6m 7.2m 10.8m 14.4m 18m 21.6m 25.2m 28.8m 32.4m 36m 39.6m 43.2m 46.8m -.ifn .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n -.. -.de HY -.hy14 -.. -.de}f -.ift .vs \\n()Vp -.ps\\n()S -.ft1 -.. -.de}H -.ev1 -.}C -.}E -.ie\\n()s 'sp |2v -.el'sp |3v -.".ps\\n()S-1 -.".iet .bd1 3 -.".el.bd1 0 -.tl \\*(]H\\*(]L\\*(]H -.bd1 -.ps\\n()S -.ie\\n()s 'sp 1.5v -.el'sp 3v -.ev -.ns -.if \\n(CL .2C -.. -.de}F -.ev1 -.}E -.if\\n()s 'sp |\\n(.pu-1v-1p -.if\\n()t 'sp |\\n(.pu-3v -.ifn 'sp |\\n(.pu-4v -.ifn .tl Page %\\*(]D\\*(]W -.if\\n()s .tl - % - -.if\\n()t \{.if o .tl Page %\\*(]D\\*(]W -.ife .tl \\*(]W\\*(]DPage % \} -.ev -'bp -.. -.ifn .ig -.de}C -.if "\\*(.T"aps"\{\ -. po0i -. lt7.5i -. if\\n()s .tl \l0.25i\l0.25i\h1i\l0.25i -. if\\n()t .tl \l0.25i\l0.25i -. lt -. po\} -.. -.de}M -.}N -.wh-.5p }C -.ll\\n(LLu -.}P -.. -.de}K -.}N -.pl1 -.ll\\n(LLu -.. -.de}P -.nr )P \\n%+1-\\np -.if \\nq .tm \\n(.F \\n()P \\np -.bp -.if \\nq .nr p \\n% -.. -.deTH -.PD -.nrIN \\n()Mu -.ift .ds ]H \\$1\^(\^\\$2\^) -.ifn .ds ]H \\$1(\\$2) -.if\\n()s .ds ]D -.if\\n()t .ds ]D Tenth Edition -.ifn .ds ]D Tenth Edition -.ds]L -.if!\\$3 .ds ]L (\^\\$3\^) -.if!\\$4 .ds ]D \\$4 -.wh0 }H -.wh-\\n(:mu }F -.em}M -.if\\n(nl .}P -.nr)I \\n()Mu -.nr)R 0 -.}E -.DT -.ifn \{.na -.nh\} -.ift \{.bd S 3 3 -.HY \} -.. -.deSH -.PD -.}X 0 "\\$1" smaller -.nr)E 2 -\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 -.. -.deSS -.}X 3n "" "" -.nr)E 2 -\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 -.. -.de}X -.}E -.ti\\$1 -.sp\\n(PDu -.ne1.1v -.nr)R 0 -.fi -'''ss12 -'''if\\$2SYNOPSIS .ss 18 -.it1 }N -.if!\\$3 .SM -.iet .bd1 3 -.el.bd1 0 -.. -.de}2 -.nr)E 0 -.}E -.nr)I \\n()Mu -.ns -.bd1 -.. -.deSM -.nh -.ps\\n()S-1 -.if!\\$1 \&\\$1 -.if!\\$2 \&\\$2 -.if!\\$3 \&\\$3 -.if!\\$4 \&\\$4 -.if!\\$5 \&\\$5 -.if!\\$6 \&\\$6 -.if!\\$1 .ps \\n()S -.if\\$1 .it 1 }N -.HY -.. -.deI -.nh -.ft2 -.it1 }N -.if!\\$1 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 -.HY -.. -.deB -.nh -.it1 }N -.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 -.el .ft5 -.HY -.. -.deL -.nh -.it1 }N -.ift \{.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 -.el .ft5 \} -.ifn \{.ft5 -.if!\\$1 \{.ie\\$2 `\\$1' -.el .ie\\$3 `\\$1 \\$2' -.el .ie\\$4 `\\$1 \\$2 \\$3' -.el .ie\\$5 `\\$1 \\$2 \\$3 \\$4' -.el .ie\\$6 `\\$1 \\$2 \\$3 \\$4 \\$5' -.el `\\$1 \\$2 \\$3 \\$4 \\$5 \\$6'\}\} -.HY -.. -.deF -.nh -.it1 }N -.ie!\\$1 \%\&\f5\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 -.el .ft5 -.HY -.. -.deRI -.nh -.}S 1 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.deIR -.nh -.}S 2 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.deIB -.nh -.ift .}S 2 5 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.ifn .}S 2 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.deRB -.nh -.ift .}S 1 5 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.ifn .}S 1 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.deBR -.nh -.ift .}S 5 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.ifn .}S 1 1 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.deBI -.nh -.ift .}S 5 2 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.ifn .}S 1 2 \%\& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.HY -.}f -.. -.de LR -.nh -.ift \%\&\f5\\$1\f1\\$2 -.ifn \%`\\$1'\\$2 -.HY -.. -.de RL -.nh -.ift \%\&\f1\\$1\\f5\\$2\\f1\\$3 -.ifn \%\\$1`\\$2'\\$3 -.HY -.. -.de}S -.ds]F -.if\\$12 .if !\\$5 .ds ]F \^ -.if\\$22 .if !\\$5 .ds ]F \^ -.ie!\\$4 .}S \\$2 \\$1 "\\$3\f\\$1\\$4\\*(]F" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" -.el\\$3 -.}f -.. -.deFR -\%\&\f5\\$1\f1\\$2 \\$3 \\$4 \\$5 \\$6 -.. -.deRF -\%\&\f1\\$1\f5\\$2\f1\\$3 -.. -.deEX -.ift .ft5 -.nf -.. -.deEE -.ft1 -.fi -.. -.dePP -.sp\\n(PDu -.ne1.1v -.}E -.nr)I \\n()Mu -.ns -.. -.deP -.PP -.. -.deLP -.PP -.. -.dePD -.ift .nr PD .4v -.ifn .nr PD 1v -.if!\\$1 .nr PD \\$1v -.. -.deHP -.sp\\n(PDu -.ne1.1v -.if!\\$1 .nr )I \\$1n -.ll\\n(LLu -.in\\n()Ru+\\n(INu+\\n()Iu -.ti\\n()Ru+\\n(INu -.}f -.. -.deIP -.ie!\\$1 \{.TP "\\$2" -\&\\$1\} -.el\{.sp\\n(PDu -.ne1.1v -.if!\\$2 .nr )I \\$2n -.}f -.ll\\n(LLu -.in\\n()Ru+\\n(INu+\\n()Iu -.lg\} -.. -.deTP -.if!\\$1 \{.nr )I \\$1n -.if\\$10 .nr )I \\n()M\} -.sp\\n(PDu -.ne1.1v -.in\\n()Ru -.lg0 -.ns -.it1 }N -.nr)E 1 -.di]B -.. -.deTF -.IP "" \w'\f5\\$1\ \ \fP'u -.PD0 -.. -.de}1 -.ds]X \&\\*(]B\\ -.rm]B -.nr)E 0 -.if!\\$1 .nr )I \\$1n -.}f -.ll\\n(LLu -.in\\n()Ru+\\n(INu+\\n()Iu -.ti\\n(INu -.ie!\\n()Iu+\\n()Ru-\w\\*(]Xu-3p \{\\*(]X -.br\} -.el\\*(]X\h|\\n()Iu+\\n()Ru\c -.}f -.lg -.. -.de}N -.if\\n()E .br -.if\\n()E1 .di -.if\\n()E0 .}f -.if\\n()E1 .}1 -.if\\n()E2 .}2 -.. -.deRS -.nr]\\n+()p \\n()I -.nr)\\n()p \\n()R -.ie!\\$1 .nr )R +\\$1n -.el.nr )R +\\n()I -.nr)I \\n()Mu -.}E -.. -.deRE -.if!\\$1 \{.ie \\$10 .nr )p 1 1 -.el.nr )p \\$1 1 \} -.ds]i \\*(]I\\n()p -.ds]r \\*(]R\\n()p -.nr)I \\*(]i -.nr)R \\*(]r -.if\\n()p .nr )p -1 -.}E -.. -'''\" .2C begin 2-column display, by diversion -'''\" CC=amount of text that will fit on page -'''\" CL=1 multicolumn in effect, else 0 -'''\" CI saved indent -'''\" CB contains diverted text -.de 2C -.ne 2 -.nf -.nr CC \\n(.t/1v*2v -.nr CI \\n(IN -.nr IN 0 -.di CB -.nr CL 1 -.}E -.dt \\n(CCu C1 -.. -'''\" .1C return to 1-column -.de 1C -.nr CL 0 -.C1 -.fi -.. -'''\" end of diversion, at end of page or return to 1-column -'''\" CC=pos of nominal column end -.de C1 -.dt -\!.C3 -.di -.if \\n(dn \{.nr CC \\n(dnu/2u+\\n(nlu -.wh \\n(CCu C2 -.mk -.nf -.nr IN \\n(CIu -.}E -.CB \} -.. -'''\" end of first column retrieved from diversion -'''\" CC=pos of actual column end -.de C2 -.wh \\n(CCu -.mk CC -.po +(\\n(LLu/2u)u -.rt -.if \\n(dn>1v .ns -.. -'''\" end of second column -.de C3 -.br -.po -(\\n(LLu/2u)u -.if \\n(CC>\\n(nl .sp |\\n(CCu -.ne 2 -.. -.dePM -.if\\$1 .nr !K 0 -.if\w\\$1 \{\ -.ie\\$1P .nr !K 1 -.el.ie \\$1BP .nr !K 3 -.el.ie \\$1BR .nr !K 4 -.el.nr !K 2 \} -.if\\n(!K .wh -(\\n(:mu+5v) )G -.. -.de)G -.if\\n(!K 'sp 2v -.ie\\n(!K=1 \{\ -.iet .bd1 3 -.el.bd1 0 -.tlPRIVATE -.bd1 -.tlThis information should not be disclosed to unauthorized persons. -.tlIt is meant solely for use by authorized Bell System employees. \} -.el.ie \\n(!K=3 \{\ -.iet .bd1 3 -.el.bd1 0 -.tlBELL LABORATORIES PROPRIETARY -.bd1 -.tlNot for use or disclosure outside Bell Laboratories except by -.tlwritten approval of the director of the distributing organization. \} -.el.ie \\n(!K=4 \{\ -.iet .bd1 3 -.el.bd1 0 -.tlBELL LABORATORIES RESTRICTED -.bd1 -.tlThe information herein is meant solely for use by authorized -.tlBell Laboratories employees and is not to be disclosed to others. \} -.el.if \\n(!K=2 \{\ -.iet .bd1 3 -.el.bd1 0 -.tlNOTICE -.bd1 -.tlNot for use or disclosure outside the -.tlBell System except under written agreement. \} -.. -.nr)s 0 -.ift .if \ns .nr )s 1 -.nr)t 0 -.ift .if !\ns .nr )t 1 -.if\n()s \{.nr )L 9i -.nrLL 4.75i -.nr)O .75i -.nr)S 9 -.nr)V 10 \} -.if\n()t \{.nr )L 11i -.nrLL 6.5i -.nr)O 1i -.nr)S 10 -.nr)V 12 \} -.ift \{.ds R \(rg -.dsS \s\n()S -..\} -.ifn \{.nr )L 11i -.nrLL 6.5i -.nr)O .463i -.if '\*(.T'think' \{.nrLL 80n -.nr)O 0\} -.if '\*(.T'thinksmall' \{.nrLL 142n -.vs 9p -.nr)O 0\} -.dsR (Reg.) -.dsS -..\} -.if\nT .nr LL 80n -.if\nV>1 \{ -.nrLL 82n -.nr)L 84v -.rmul \} -.nr)p 0 1 -.ds]I \\\\n(] -.ds]R \\\\n() -.if\nd0 .nr m \n(mo-1 -.if\nm0 .ds ]m January -.if\nm1 .ds ]m February -.if\nm2 .ds ]m March -.if\nm3 .ds ]m April -.if\nm4 .ds ]m May -.if\nm5 .ds ]m June -.if\nm6 .ds ]m July -.if\nm7 .ds ]m August -.if\nm8 .ds ]m September -.if\nm9 .ds ]m October -.if\nm10 .ds ]m November -.if\nm11 .ds ]m December -.ifn \{.nr m \nm+1 -.ie\nd .ds ]W (last mod. \nm/\nd/\ny) -.el.ds ]W (printed \n(mo/\n(dy/\n(yr) -..\} -.if\n()s .ds ]W -.if\n()t \{.ie \nd .ds ]W \*(]m \nd, 19\ny -.el.ds ]W \*(]m \n(dy, 19\n(yr -..\} -.pl\n()Lu -.ll\n(LLu -.lt\n(LLu -.po\n()Ou -.fp 5 L CW -.ift .tr \``\'' -.}f -.if\n()s .nr :m 3.5v -.if\n()t .nr :m 6v -.ifn .nr :m 7v -.ift .nr )M 3.6m -.ifn .nr )M 5n -.em}K -.nr q \np -.if!\np .nr p 1 -.pn \np //GO.SYSIN DD tmac.an echo re.3 1>&2 sed 's/.//' >re.3 <<'//GO.SYSIN DD re.3' -.TH RE 3 -.CT 2 data_man -.SH NAME -re_bm, re_cw, re_re \(mi string and pattern matching -.SH SYNOPSIS -.nf -.2C -.B "#include <re.h>" -.PP -.B "re_bm *re_bmcomp(b, e, map)" -.B "char *b, *e;" -.B "unsigned char map[256];" -.PP -.B "int re_bmexec(pat, rdfn, matchfn)" -.B re_bm *pat; -.B int (*rdfn)(), (*matchfn)(); -.PP -.B void re_bmfree(pat); -.B re_bm *pat; -.PP -.BR "re_cw *re_cwinit(map)" -.B unsigned char map[256]; -.PP -.BR "void re_cwadd(pat, b, e)" -.B re_cw *pat; -.B char *b, *e; -.PP -.BR "void re_cwcomp(pat)" -.B re_cw *pat; -.PP -.B "int re_cwexec(pat, rdfn, matchfn)" -.B re_cw *pat; -.B int (*rdfn)(), (*matchfn)(); -.PP -.B void re_cwfree(pat); -.B re_cw *pat; -.PP -.BR "re_re *re_recomp(b, e, map)" -.B char *b, *e; -.B unsigned char map[256]; -.PP -.B "re_reexec(pat, b, e, match)" -.B re_re *pat; -.B char *b, *e, *match[10][2]; -.PP -.B void re_refree(pat); -.B re_re *pat; -.PP -.B void re_error(str); -.B char *str; -.1C -.fi -.SH DESCRIPTION -These routines search for patterns in strings. -The -.I re_re -routines search for general regular expressions (defined below) -using a lazily evaluated deterministic finite automaton. -The more specialized and faster -.I re_cw -routines search for multiple literal strings -using the Commentz-Walter algorithm. -The still more specialized and efficient -.I re_bm -routines search for a single string using the Boyer-Moore algorithm. -The routines handle strings designated by pointers to -the first character of the string -and to the character following the string. -.PP -To use the -.I re_bm -routines, first build a recognizer by calling -.I re_bmcomp, -which takes the search string and a character map; -all characters are compared after mapping. -Typically, -.I map -is initialized by a loop similar to -.EE -for(i = 0; i < 256; i++) map[i] = i; -.EX -and its value is no longer required after the call to -.I re_bmcomp. -The recognizer can be run (multiple times) by calling -.I re_bmexec, -which stops and returns the first non-positive return from either -.I rdfn -or -.IR matchfn . -The recognizer calls the supplied function -.I rdfn -to obtain input and -.I matchfn -to report text matching the search string. -.PP -.I Rdfn -should be declared as -.IP -.EX -int rdfn(pb, pe) -char **pb, **pe; -.EE -.LP -where -.B *pb -and -.B *pe -delimit an as yet unprocessed text fragment -(none if -.LR *pb==*pe ) -to be saved across the call to -.IR rdfn . -On return, -.B *pb -and -.B *pe -point to the new text, including the saved fragment. -.I Rdfn -returns 0 for EOF, negative for error, and positive otherwise. -The first call to -.I rdfn -from each invocation of -.I re_bmexec -has -.BR *pb==0 . -.PP -.I Matchfn -should be declared as -.IP -.EX -int matchfn(pb, pe) -char **pb, **pe; -.EE -.LP -where -.B *pb -and -.B *pe -delimit the matched text. -.I Matchfn -sets -.BR *pb , -.BR *pe , -and returns a value in the same way as -.I rdfn. -.PP -To use the -.I re_cw -routines, first build the recognizer by calling -.IR re_cwinit , -then -.I re_cwadd -for each string, and finally -.IR re_cwcomp . -The recognizer is run by -.I re_cwexec -analogously to -.IR re_bmexec . -.PP -A full regular expression recognizer is compiled by -.I re_recomp -and executed by -.I re_reexec, -which returns 1 if there was a match and 0 if there wasn't. -The strings that match subexpressions are returned in array -.I match -using the above convention. -.L match[0] -refers to the whole matched expression. -If -.I match -is zero, then no match delimiters are set. -.PP -The routine -.I re_error -prints its argument on standard error and exits. -You may supply your own version for specialized error handling. -If -.I re_error -returns rather than exits, the compiling routines (e.g. -.IR re_bmcomp ) -will return 0. -.PP -The recognizers that these routines construct occupy storage -obtained from -.IR malloc (3). -The storage can be deallocated by -.I re_refree. -.SS Regular Expressions -The syntax for a regular expression -.B e0 -is -.EX -e3: literal | charclass | '.' | '^' | '$' | '\e'\fIn\fP | '(' e0 ')' - -e2: e3 - | e2 REP -REP: '*' | '+' | '?' | '\e{' RANGE '\e}' -RANGE: int | int ',' | int ',' int - -e1: e2 - | e1 e2 - -e0: e1 - | e0 ALT e1 -ALT: '|' | newline -.EE -.PP -A literal is any non-metacharacter or a metacharacter -(one of -.BR .*+?[]()|\e^$ ) -preceded by -.LR \e . -.PP -A charclass is a nonempty string -.I s -bracketed -.BI [ \|s\| ] -(or -.BI [^ s\| ]\fR); -it matches any character in (or not in) -.I s. -In -.I s, -the metacharacters other than -.L ] -have no special meaning, and -.L ] -may only appear as -the first letter. -A substring -.IB a - b , -with -.I a -and -.I b -in ascending -.SM ASCII -order, stands for the inclusive -range of -.SM ASCII -characters between -.I a -and -.IR b . -.PP -A -.L \e -followed by a digit -.I n -matches a copy of the string that the -parenthesized subexpression beginning with the -.IR n th -.LR ( , -counting from 1, matched. -.PP -A -.L . -matches any character. -.PP -A -.L ^ -matches the beginning of the input string; -.L $ -matches the end. -.PP -The -.B REP -operators match zero or more -.RB ( * ), -one or more -.RB ( + ), -zero or one -.RB ( ? ), -exactly -.I m -.BI \f1(\fP\e{ m \e}\f1),\fP -.I m -or more -.BI \f1(\fP\e{ m ,\e}\f1),\fP -and any number between -.I m -and -.I n -inclusive -.BI \f1(\fP\e{ m , n \e}\f1),\fP -instances respectively of the preceding regular expression -.BR e2 . -.PP -A concatenated regular expression, -.BR "e1 e2" , -matches a match to -.B e1 -followed by a match to -.BR e2 . -.PP -An alternative regular expression, -.BR "e0 ALT e1" , -matches either a match to -.B e0 -or a match to -.BR e1 . -.PP -A match to any part of a regular expression -extends as far as possible without preventing -a match to the remainder of the regular expression. -.SH SEE ALSO -.IR regexp (3), -.IR gre (1) -.SH DIAGNOSTICS -Routines that return pointers return 0 on error. -.SH BUGS -Between -.IR re (3) -and -.IR regexp (3) -there are too many routines. //GO.SYSIN DD re.3 echo gre.1 1>&2 sed 's/.//' >gre.1 <<'//GO.SYSIN DD gre.1' -.TH GRE 1 -.CT 1 files -.SH NAME -gre, grep, egrep, fgrep \(mi search a file for a pattern -.SH SYNOPSIS -.B gre -[ -.I option ... -] -.I pattern -[ -.I file ... -] -.PP -.B grep -[ -.I option ... -] -.I pattern -[ -.I file ... -] -.PP -.B egrep -[ -.I option ... -] -.I pattern -[ -.I file ... -] -.PP -.B fgrep -[ -.I option ... -] -.I strings -[ -.I file ... -] -.SH DESCRIPTION -.I Gre\^ -searches the input -.I files\^ -(standard input default) -for lines (with newlines excluded) that match the -.I pattern, -a regular expression as defined in -.IR re (3). -A file name of -.B - -is interpreted as standard input. -Normally, each line matching the pattern is `selected', -and each selected line is copied to the standard output. -The options are -.TP -.B -1 -Print only the first selected line of each file argument. -.PD 0 -.TP -.B -b -Mark each printed line with its byte position in its file. -This is sometimes useful in locating patterns in non-text files. -.TP -.B -c -Print only a count of matching lines. -.TP -.BI -e " pattern" -Same as a simple -.I pattern -argument, -but useful when -.I pattern -begins with a -.BR - . -.TP -.B -E -Simulate -.IR egrep. -.TP -.BI -f " file" -Read the pattern from -.IR file ; -there is no -.I pattern -argument -.TP -.B -F -Simulate -.IR fgrep. -.TP -.B -G -Simulate -.IR grep. -.TP -.B -h -Do not print filename tags (headers) with output lines. -.TP -.B -i -Ignore alphabetic case distinctions. -.TP -.B -l -Print the names of files with selected lines; don't print the lines. -.TP -.B -L -Print the names of files with no selected lines; -the converse of -.BR -l . -.TP -.B -n -Mark each printed line with its line number counted in its file. -.TP -.B -s -Produce no output, but return status. -.TP -.B -v -Reverse: print lines that do not match the pattern. -.TP -.B -x -Exact match: The pattern is -.BI ^( pattern )$ . -The implicit parentheses count in back references. -.PD -.PP -Output lines are tagged by filename when there is more than one -input file. -(To force this tagging, include -.B /dev/null -as a filename argument.) -If the output line exceeds some internal limit, -a warning is given and a small block of text surrounding the match is printed. -.PP -Care should be taken when -using the shell metacharacters -.B $*[^|()\e -and newline -in -.IR pattern ; -it is safest to enclose the -entire expression -in single quotes -.BR \&\|\(fm \|.\|.\|.\| \(fm . -.PP -.I Gre -supplants three classic programs, which are still available: -.PP -.I Grep -handles only -.IR ed (1)-like -regular expressions. -It uses -.L \e(\|\e) -instead of -.LR (\|) . -.PP -.I Egrep -handles the same patterns as -.I gre -except for back-referencing with -.BR \e1 , -.BR \e2 , -\&... -.PP -.I Fgrep -handles no operators except newline (alternation). -.SH SEE ALSO -.IR re (3), -.IR awk (1), -.IR sed (1), -.IR sam (9.1), -.IR strings (1) -.SH DIAGNOSTICS -Exit status is 0 if any lines are selected, -1 if none, 2 for syntax errors, inaccessible files -(even if matches were found). -Warnings will be given for input lines that exceed -a (generous) internal limit. -.SH BUGS -.I Grep, egrep, -and -.I fgrep -do not support some options and print block numbers -rather than byte numbers for option -.BR -b . //GO.SYSIN DD gre.1 echo deansify.awk 1>&2 sed 's/.//' >deansify.awk <<'//GO.SYSIN DD deansify.awk' -# De-ANSI-fy C programs - -# change void* to char * - { gsub(/void *\*/, "char *") } - -# remove args from function declarations and typedefs -# assume one per line (fitting on one line) - -/^[a-zA-Z0-9_]+.*\([^(]*\);.*/ { - if($0 !~ /^print\(/ && $0 !~ /^fprint\(/ && $0 !~ /^if\(/) { - sub(/\([^(]*\);/, "();") - print - next - } - } - -# change function definition headers to old-style -# function definition headers on one line, ending with ')', -# with the return type (if not omitted) on previous line -# assume no parentheses inside arg list - -/^[a-zA-Z0-9_]+\(.*\)$/ { - st = index($0, "(") + 1 - n = length($0) - st - rawargs = substr($0, st, n) - printf("%s(", substr($0, 1, st-2)) - if( rawargs == "void" ) { - printf(")\n"); - next - } - nargs = split(rawargs, args, ", *") - for(i = 1; i <= nargs; i++){ - if(! match(args[i], /[a-zA-Z0-9_]+ *$/)){ - if(! match(args[i], /[a-zA-Z0-9_]+\[.*\]$/)) - id = "OOPS" - else { - id = substr(args[i], RSTART) - sub(/\[.*\]/, "", id) - } - } else - id = substr(args[i], RSTART, RLENGTH) - printf("%s", id) - if(i < nargs) printf(", ") - } - printf(")\n") - for(i = 1; i <= nargs; i++) - printf("\t%s;\n", args[i]) - next - } - -# remove pragmas - -/^#[ ]*pragma/ { next } - -# just print remaining lines - { print } //GO.SYSIN DD deansify.awk