home *** CD-ROM | disk | FTP | other *** search
- /*
- * fgrep -- print all lines containing any of a set of keywords
- *
- * status returns:
- * 0 - ok, and some matches
- * 1 - ok, but no matches
- * 2 - some error
- */
-
- #include <stdio.h>
-
- #define MAXSIZ 6000
- #define QSIZE 400
- struct words {
- char inp;
- char out;
- struct words *nst;
- struct words *link;
- struct words *fail;
- } w[MAXSIZ], *smax, *q;
-
- long lnum;
- int bflag, cflag, fflag, lflag, nflag, vflag, xflag;
- int hflag = 1;
- int sflag;
- int nfile;
- long blkno;
- int nsucc;
- long tln;
- FILE *wordf;
- char *argptr;
-
- main(argc, argv)
- char **argv;
- {
- while (--argc > 0 && (++argv)[0][0]=='-')
- switch (argv[0][1]) {
-
- case 's':
- sflag++;
- continue;
-
- case 'h':
- hflag = 0;
- continue;
-
- case 'b':
- bflag++;
- continue;
-
- case 'c':
- cflag++;
- continue;
-
- case 'e':
- argc--;
- argv++;
- goto out;
-
- case 'f':
- fflag++;
- continue;
-
- case 'l':
- lflag++;
- continue;
-
- case 'n':
- nflag++;
- continue;
-
- case 'v':
- vflag++;
- continue;
-
- case 'x':
- xflag++;
- continue;
-
- default:
- fprintf(stderr, "egrep: unknown flag\n");
- continue;
- }
- out:
- if (argc<=0)
- exit(2);
- if (fflag) {
- wordf = fopen(*argv, "r");
- if (wordf==NULL) {
- fprintf(stderr, "egrep: can't open %s\n", *argv);
- exit(2);
- }
- }
- else argptr = *argv;
- argc--;
- argv++;
-
- cgotofn();
- cfail();
- nfile = argc;
- if (argc<=0) {
- if (lflag) exit(1);
- execute((char *)NULL);
- }
- else while (--argc >= 0) {
- execute(*argv);
- argv++;
- }
- exit(nsucc == 0);
- }
-
- execute(file)
- char *file;
- {
- register char *p;
- register struct words *c;
- register ccount;
- char buf[1024];
- int f;
- int failed;
- char *nlp;
- if (file) {
- if ((f = open(file, 0)) < 0) {
- fprintf(stderr, "fgrep: can't open %s\n", file);
- exit(2);
- }
- }
- else f = 0;
- ccount = 0;
- failed = 0;
- lnum = 1;
- tln = 0;
- blkno = 0;
- p = buf;
- nlp = p;
- c = w;
- for (;;) {
- if (--ccount <= 0) {
- if (p == &buf[1024]) p = buf;
- if (p > &buf[512]) {
- if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
- }
- else if ((ccount = read(f, p, 512)) <= 0) break;
- blkno += ccount;
- }
- nstate:
- if (c->inp == *p) {
- c = c->nst;
- }
- else if (c->link != 0) {
- c = c->link;
- goto nstate;
- }
- else {
- c = c->fail;
- failed = 1;
- if (c==0) {
- c = w;
- istate:
- if (c->inp == *p) {
- c = c->nst;
- }
- else if (c->link != 0) {
- c = c->link;
- goto istate;
- }
- }
- else goto nstate;
- }
- if (c->out) {
- while (*p++ != '\n') {
- if (--ccount <= 0) {
- if (p == &buf[1024]) p = buf;
- if (p > &buf[512]) {
- if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
- }
- else if ((ccount = read(f, p, 512)) <= 0) break;
- blkno += ccount;
- }
- }
- if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
- goto nomatch;
- succeed: nsucc = 1;
- if (cflag) tln++;
- else if (sflag)
- ; /* ugh */
- else if (lflag) {
- printf("%s\n", file);
- close(f);
- return;
- }
- else {
- if (nfile > 1 && hflag) printf("%s:", file);
- if (bflag) printf("%ld:", (blkno-ccount-1)/512);
- if (nflag) printf("%ld:", lnum);
- if (p <= nlp) {
- while (nlp < &buf[1024]) putchar(*nlp++);
- nlp = buf;
- }
- while (nlp < p) putchar(*nlp++);
- }
- nomatch: lnum++;
- nlp = p;
- c = w;
- failed = 0;
- continue;
- }
- if (*p++ == '\n')
- if (vflag) goto succeed;
- else {
- lnum++;
- nlp = p;
- c = w;
- failed = 0;
- }
- }
- close(f);
- if (cflag) {
- if (nfile > 1)
- printf("%s:", file);
- printf("%ld\n", tln);
- }
- }
-
- getargc()
- {
- register c;
- if (wordf)
- return(getc(wordf));
- if ((c = *argptr++) == '\0')
- return(EOF);
- return(c);
- }
-
- cgotofn() {
- register c;
- register struct words *s;
-
- s = smax = w;
- nword: for(;;) {
- c = getargc();
- if (c==EOF)
- return;
- if (c == '\n') {
- if (xflag) {
- for(;;) {
- if (s->inp == c) {
- s = s->nst;
- break;
- }
- if (s->inp == 0) goto nenter;
- if (s->link == 0) {
- if (smax >= &w[MAXSIZ -1]) overflo();
- s->link = ++smax;
- s = smax;
- goto nenter;
- }
- s = s->link;
- }
- }
- s->out = 1;
- s = w;
- } else {
- loop: if (s->inp == c) {
- s = s->nst;
- continue;
- }
- if (s->inp == 0) goto enter;
- if (s->link == 0) {
- if (smax >= &w[MAXSIZ - 1]) overflo();
- s->link = ++smax;
- s = smax;
- goto enter;
- }
- s = s->link;
- goto loop;
- }
- }
-
- enter:
- do {
- s->inp = c;
- if (smax >= &w[MAXSIZ - 1]) overflo();
- s->nst = ++smax;
- s = smax;
- } while ((c = getargc()) != '\n' && c!=EOF);
- if (xflag) {
- nenter: s->inp = '\n';
- if (smax >= &w[MAXSIZ -1]) overflo();
- s->nst = ++smax;
- }
- smax->out = 1;
- s = w;
- if (c != EOF)
- goto nword;
- }
-
- overflo() {
- fprintf(stderr, "wordlist too large\n");
- exit(2);
- }
- cfail() {
- struct words *queue[QSIZE];
- struct words **front, **rear;
- struct words *state;
- register char c;
- register struct words *s;
- s = w;
- front = rear = queue;
- init: if ((s->inp) != 0) {
- *rear++ = s->nst;
- if (rear >= &queue[QSIZE - 1]) overflo();
- }
- if ((s = s->link) != 0) {
- goto init;
- }
-
- while (rear!=front) {
- s = *front;
- if (front == &queue[QSIZE-1])
- front = queue;
- else front++;
- cloop: if ((c = s->inp) != 0) {
- *rear = (q = s->nst);
- if (front < rear)
- if (rear >= &queue[QSIZE-1])
- if (front == queue) overflo();
- else rear = queue;
- else rear++;
- else
- if (++rear == front) overflo();
- state = s->fail;
- floop: if (state == 0) state = w;
- if (state->inp == c) {
- q->fail = state->nst;
- if ((state->nst)->out == 1) q->out = 1;
- continue;
- }
- else if ((state = state->link) != 0)
- goto floop;
- }
- if ((s = s->link) != 0)
- goto cloop;
- }
- }
-