148266Sbostic /*-
2*62027Sbostic * Copyright (c) 1991, 1993
3*62027Sbostic * The Regents of the University of California. All rights reserved.
448266Sbostic *
548266Sbostic * %sccs.include.proprietary.c%
648266Sbostic */
748266Sbostic
848266Sbostic #ifndef lint
9*62027Sbostic static char copyright[] =
10*62027Sbostic "@(#) Copyright (c) 1991, 1993\n\
11*62027Sbostic The Regents of the University of California. All rights reserved.\n";
1248266Sbostic #endif /* not lint */
1348266Sbostic
1448266Sbostic #ifndef lint
15*62027Sbostic static char sccsid[] = "@(#)old.fgrep.c 8.1 (Berkeley) 06/06/93";
1648266Sbostic #endif /* not lint */
1748266Sbostic
181010Sbill /*
191010Sbill * fgrep -- print all lines containing any of a set of keywords
201010Sbill *
211010Sbill * status returns:
221010Sbill * 0 - ok, and some matches
231010Sbill * 1 - ok, but no matches
241010Sbill * 2 - some error
251010Sbill */
261010Sbill
278726Smckusick #include <stdio.h>
288726Smckusick #include <ctype.h>
2921395Smckusick #include <sys/param.h>
3021395Smckusick #include <sys/stat.h>
311010Sbill
3221395Smckusick #define BLKSIZE 8192
331010Sbill #define MAXSIZ 6000
341010Sbill #define QSIZE 400
351010Sbill struct words {
361010Sbill char inp;
371010Sbill char out;
381010Sbill struct words *nst;
391010Sbill struct words *link;
401010Sbill struct words *fail;
411010Sbill } w[MAXSIZ], *smax, *q;
421010Sbill
431010Sbill long lnum;
441010Sbill int bflag, cflag, fflag, lflag, nflag, vflag, xflag, yflag;
451010Sbill int hflag = 1;
4632365Sbostic int oflag;
471010Sbill int sflag;
481010Sbill int retcode = 0;
491010Sbill int nfile;
501010Sbill long blkno;
511010Sbill int nsucc;
521010Sbill long tln;
531010Sbill FILE *wordf;
541010Sbill char *argptr;
551010Sbill
main(argc,argv)561010Sbill main(argc, argv)
571010Sbill char **argv;
581010Sbill {
591010Sbill while (--argc > 0 && (++argv)[0][0]=='-')
601010Sbill switch (argv[0][1]) {
611010Sbill
621010Sbill case 's':
631010Sbill sflag++;
641010Sbill continue;
651010Sbill
661010Sbill case 'h':
671010Sbill hflag = 0;
681010Sbill continue;
691010Sbill
7032365Sbostic case 'o':
7132365Sbostic oflag++;
7232365Sbostic continue;
7332365Sbostic
741010Sbill case 'b':
751010Sbill bflag++;
761010Sbill continue;
771010Sbill
781010Sbill case 'c':
791010Sbill cflag++;
801010Sbill continue;
811010Sbill
821010Sbill case 'e':
831010Sbill argc--;
841010Sbill argv++;
851010Sbill goto out;
861010Sbill
871010Sbill case 'f':
881010Sbill fflag++;
891010Sbill continue;
901010Sbill
911010Sbill case 'l':
921010Sbill lflag++;
931010Sbill continue;
941010Sbill
951010Sbill case 'n':
961010Sbill nflag++;
971010Sbill continue;
981010Sbill
991010Sbill case 'v':
1001010Sbill vflag++;
1011010Sbill continue;
1021010Sbill
1031010Sbill case 'x':
1041010Sbill xflag++;
1051010Sbill continue;
1061010Sbill
1071010Sbill case 'i': /* Berkeley */
1081010Sbill case 'y': /* Btl */
1091010Sbill yflag++;
1101010Sbill continue;
1111010Sbill default:
1121010Sbill fprintf(stderr, "fgrep: unknown flag\n");
1131010Sbill continue;
1141010Sbill }
1151010Sbill out:
1161010Sbill if (argc<=0)
1171010Sbill exit(2);
1181010Sbill if (fflag) {
1191010Sbill wordf = fopen(*argv, "r");
1201010Sbill if (wordf==NULL) {
1211010Sbill fprintf(stderr, "fgrep: can't open %s\n", *argv);
1221010Sbill exit(2);
1231010Sbill }
1241010Sbill }
1251010Sbill else argptr = *argv;
1261010Sbill argc--;
1271010Sbill argv++;
1281010Sbill
1291010Sbill cgotofn();
1301010Sbill cfail();
1311010Sbill nfile = argc;
1321010Sbill if (argc<=0) {
1331010Sbill if (lflag) exit(1);
1341010Sbill execute((char *)NULL);
1351010Sbill }
1361010Sbill else while (--argc >= 0) {
1371010Sbill execute(*argv);
1381010Sbill argv++;
1391010Sbill }
1401010Sbill exit(retcode != 0 ? retcode : nsucc == 0);
1411010Sbill }
1421010Sbill
1431010Sbill # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b)
1441010Sbill # define lca(x) (isupper(x) ? tolower(x) : x)
execute(file)1451010Sbill execute(file)
1461010Sbill char *file;
1471010Sbill {
1481010Sbill register struct words *c;
1491010Sbill register ccount;
1501010Sbill register char ch;
1511010Sbill register char *p;
15221395Smckusick static char *buf;
15321395Smckusick static int blksize;
15421395Smckusick struct stat stb;
1551010Sbill int f;
1561010Sbill int failed;
1571010Sbill char *nlp;
1581010Sbill if (file) {
1591010Sbill if ((f = open(file, 0)) < 0) {
1601010Sbill fprintf(stderr, "fgrep: can't open %s\n", file);
1611010Sbill retcode = 2;
1621010Sbill return;
1631010Sbill }
1641010Sbill }
1651010Sbill else f = 0;
16621395Smckusick if (buf == NULL) {
16721395Smckusick if (fstat(f, &stb) > 0 && stb.st_blksize > 0)
16821395Smckusick blksize = stb.st_blksize;
16921395Smckusick else
17021395Smckusick blksize = BLKSIZE;
17121395Smckusick buf = (char *)malloc(2*blksize);
17221395Smckusick if (buf == NULL) {
17321395Smckusick fprintf(stderr, "egrep: no memory for %s\n", file);
17421395Smckusick retcode = 2;
17521395Smckusick return;
17621395Smckusick }
17721395Smckusick }
1781010Sbill ccount = 0;
1791010Sbill failed = 0;
1801010Sbill lnum = 1;
1811010Sbill tln = 0;
1821010Sbill blkno = 0;
1831010Sbill p = buf;
1841010Sbill nlp = p;
1851010Sbill c = w;
1861010Sbill for (;;) {
1871010Sbill if (--ccount <= 0) {
18821395Smckusick if (p == &buf[2*blksize]) p = buf;
18921395Smckusick if (p > &buf[blksize]) {
19021395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
1911010Sbill }
19221395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break;
1931010Sbill blkno += ccount;
1941010Sbill }
1951010Sbill nstate:
1961010Sbill if (ccomp(c->inp, *p)) {
1971010Sbill c = c->nst;
1981010Sbill }
1991010Sbill else if (c->link != 0) {
2001010Sbill c = c->link;
2011010Sbill goto nstate;
2021010Sbill }
2031010Sbill else {
2041010Sbill c = c->fail;
2051010Sbill failed = 1;
2061010Sbill if (c==0) {
2071010Sbill c = w;
2081010Sbill istate:
2091010Sbill if (ccomp(c->inp , *p)) {
2101010Sbill c = c->nst;
2111010Sbill }
2121010Sbill else if (c->link != 0) {
2131010Sbill c = c->link;
2141010Sbill goto istate;
2151010Sbill }
2161010Sbill }
2171010Sbill else goto nstate;
2181010Sbill }
2191010Sbill if (c->out) {
2201010Sbill while (*p++ != '\n') {
2211010Sbill if (--ccount <= 0) {
22221395Smckusick if (p == &buf[2*blksize]) p = buf;
22321395Smckusick if (p > &buf[blksize]) {
22421395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
2251010Sbill }
22621395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break;
2271010Sbill blkno += ccount;
2281010Sbill }
2291010Sbill }
2301010Sbill if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
2311010Sbill goto nomatch;
2321010Sbill succeed: nsucc = 1;
2331010Sbill if (cflag) tln++;
2341010Sbill else if (sflag)
2351010Sbill ; /* ugh */
2361010Sbill else if (lflag) {
2371010Sbill printf("%s\n", file);
2381010Sbill close(f);
2391010Sbill return;
2401010Sbill }
2411010Sbill else {
24232365Sbostic if (nfile > 1 && hflag || oflag) printf("%s:", file);
24321395Smckusick if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE);
2441010Sbill if (nflag) printf("%ld:", lnum);
2451010Sbill if (p <= nlp) {
24621395Smckusick while (nlp < &buf[2*blksize]) putchar(*nlp++);
2471010Sbill nlp = buf;
2481010Sbill }
2491010Sbill while (nlp < p) putchar(*nlp++);
2501010Sbill }
2511010Sbill nomatch: lnum++;
2521010Sbill nlp = p;
2531010Sbill c = w;
2541010Sbill failed = 0;
2551010Sbill continue;
2561010Sbill }
2571010Sbill if (*p++ == '\n')
2581010Sbill if (vflag) goto succeed;
2591010Sbill else {
2601010Sbill lnum++;
2611010Sbill nlp = p;
2621010Sbill c = w;
2631010Sbill failed = 0;
2641010Sbill }
2651010Sbill }
2661010Sbill close(f);
2671010Sbill if (cflag) {
2681010Sbill if (nfile > 1)
2691010Sbill printf("%s:", file);
2701010Sbill printf("%ld\n", tln);
2711010Sbill }
2721010Sbill }
2731010Sbill
getargc()2741010Sbill getargc()
2751010Sbill {
2761010Sbill register c;
2771010Sbill if (wordf)
2781010Sbill return(getc(wordf));
2791010Sbill if ((c = *argptr++) == '\0')
2801010Sbill return(EOF);
2811010Sbill return(c);
2821010Sbill }
2831010Sbill
cgotofn()2841010Sbill cgotofn() {
2851010Sbill register c;
2861010Sbill register struct words *s;
2871010Sbill
2881010Sbill s = smax = w;
2891010Sbill nword: for(;;) {
2901010Sbill c = getargc();
2911010Sbill if (c==EOF)
2921010Sbill return;
2931010Sbill if (c == '\n') {
2941010Sbill if (xflag) {
2951010Sbill for(;;) {
2961010Sbill if (s->inp == c) {
2971010Sbill s = s->nst;
2981010Sbill break;
2991010Sbill }
3001010Sbill if (s->inp == 0) goto nenter;
3011010Sbill if (s->link == 0) {
3021010Sbill if (smax >= &w[MAXSIZ -1]) overflo();
3031010Sbill s->link = ++smax;
3041010Sbill s = smax;
3051010Sbill goto nenter;
3061010Sbill }
3071010Sbill s = s->link;
3081010Sbill }
3091010Sbill }
3101010Sbill s->out = 1;
3111010Sbill s = w;
3121010Sbill } else {
3131010Sbill loop: if (s->inp == c) {
3141010Sbill s = s->nst;
3151010Sbill continue;
3161010Sbill }
3171010Sbill if (s->inp == 0) goto enter;
3181010Sbill if (s->link == 0) {
3191010Sbill if (smax >= &w[MAXSIZ - 1]) overflo();
3201010Sbill s->link = ++smax;
3211010Sbill s = smax;
3221010Sbill goto enter;
3231010Sbill }
3241010Sbill s = s->link;
3251010Sbill goto loop;
3261010Sbill }
3271010Sbill }
3281010Sbill
3291010Sbill enter:
3301010Sbill do {
3311010Sbill s->inp = c;
3321010Sbill if (smax >= &w[MAXSIZ - 1]) overflo();
3331010Sbill s->nst = ++smax;
3341010Sbill s = smax;
3351010Sbill } while ((c = getargc()) != '\n' && c!=EOF);
3361010Sbill if (xflag) {
3371010Sbill nenter: s->inp = '\n';
3381010Sbill if (smax >= &w[MAXSIZ -1]) overflo();
3391010Sbill s->nst = ++smax;
3401010Sbill }
3411010Sbill smax->out = 1;
3421010Sbill s = w;
3431010Sbill if (c != EOF)
3441010Sbill goto nword;
3451010Sbill }
3461010Sbill
overflo()3471010Sbill overflo() {
3481010Sbill fprintf(stderr, "wordlist too large\n");
3491010Sbill exit(2);
3501010Sbill }
cfail()3511010Sbill cfail() {
3521010Sbill struct words *queue[QSIZE];
3531010Sbill struct words **front, **rear;
3541010Sbill struct words *state;
3551010Sbill int bstart;
3561010Sbill register char c;
3571010Sbill register struct words *s;
3581010Sbill s = w;
3591010Sbill front = rear = queue;
3601010Sbill init: if ((s->inp) != 0) {
3611010Sbill *rear++ = s->nst;
3621010Sbill if (rear >= &queue[QSIZE - 1]) overflo();
3631010Sbill }
3641010Sbill if ((s = s->link) != 0) {
3651010Sbill goto init;
3661010Sbill }
3671010Sbill
3681010Sbill while (rear!=front) {
3691010Sbill s = *front;
3701010Sbill if (front == &queue[QSIZE-1])
3711010Sbill front = queue;
3721010Sbill else front++;
3731010Sbill cloop: if ((c = s->inp) != 0) {
3741010Sbill bstart = 0;
3751010Sbill *rear = (q = s->nst);
3761010Sbill if (front < rear)
3771010Sbill if (rear >= &queue[QSIZE-1])
3781010Sbill if (front == queue) overflo();
3791010Sbill else rear = queue;
3801010Sbill else rear++;
3811010Sbill else
3821010Sbill if (++rear == front) overflo();
3831010Sbill state = s->fail;
3841010Sbill floop: if (state == 0) {
3851010Sbill state = w;
3861010Sbill bstart = 1;
3871010Sbill }
3881010Sbill if (state->inp == c) {
3891010Sbill qloop: q->fail = state->nst;
3901010Sbill if ((state->nst)->out == 1) q->out = 1;
3911010Sbill if ((q = q->link) != 0) goto qloop;
3921010Sbill }
3931010Sbill else if ((state = state->link) != 0)
3941010Sbill goto floop;
3951010Sbill else if(bstart == 0){
3961010Sbill state = 0;
3971010Sbill goto floop;
3981010Sbill }
3991010Sbill }
4001010Sbill if ((s = s->link) != 0)
4011010Sbill goto cloop;
4021010Sbill }
4031010Sbill }
404