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