1 static char *sccsid = "@(#)old.fgrep.c	4.3 (Berkeley) 05/30/85";
2 /*
3  * fgrep -- print all lines containing any of a set of keywords
4  *
5  *	status returns:
6  *		0 - ok, and some matches
7  *		1 - ok, but no matches
8  *		2 - some error
9  */
10 
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <sys/param.h>
14 #include <sys/stat.h>
15 
16 #define BLKSIZE 8192
17 #define	MAXSIZ 6000
18 #define QSIZE 400
19 struct words {
20 	char 	inp;
21 	char	out;
22 	struct	words *nst;
23 	struct	words *link;
24 	struct	words *fail;
25 } w[MAXSIZ], *smax, *q;
26 
27 long	lnum;
28 int	bflag, cflag, fflag, lflag, nflag, vflag, xflag, yflag;
29 int	hflag	= 1;
30 int	sflag;
31 int	retcode = 0;
32 int	nfile;
33 long	blkno;
34 int	nsucc;
35 long	tln;
36 FILE	*wordf;
37 char	*argptr;
38 
39 main(argc, argv)
40 char **argv;
41 {
42 	while (--argc > 0 && (++argv)[0][0]=='-')
43 		switch (argv[0][1]) {
44 
45 		case 's':
46 			sflag++;
47 			continue;
48 
49 		case 'h':
50 			hflag = 0;
51 			continue;
52 
53 		case 'b':
54 			bflag++;
55 			continue;
56 
57 		case 'c':
58 			cflag++;
59 			continue;
60 
61 		case 'e':
62 			argc--;
63 			argv++;
64 			goto out;
65 
66 		case 'f':
67 			fflag++;
68 			continue;
69 
70 		case 'l':
71 			lflag++;
72 			continue;
73 
74 		case 'n':
75 			nflag++;
76 			continue;
77 
78 		case 'v':
79 			vflag++;
80 			continue;
81 
82 		case 'x':
83 			xflag++;
84 			continue;
85 
86 		case 'i':		/* Berkeley */
87 		case 'y':		/* Btl */
88 			yflag++;
89 			continue;
90 		default:
91 			fprintf(stderr, "fgrep: unknown flag\n");
92 			continue;
93 		}
94 out:
95 	if (argc<=0)
96 		exit(2);
97 	if (fflag) {
98 		wordf = fopen(*argv, "r");
99 		if (wordf==NULL) {
100 			fprintf(stderr, "fgrep: can't open %s\n", *argv);
101 			exit(2);
102 		}
103 	}
104 	else argptr = *argv;
105 	argc--;
106 	argv++;
107 
108 	cgotofn();
109 	cfail();
110 	nfile = argc;
111 	if (argc<=0) {
112 		if (lflag) exit(1);
113 		execute((char *)NULL);
114 	}
115 	else while (--argc >= 0) {
116 		execute(*argv);
117 		argv++;
118 	}
119 	exit(retcode != 0 ? retcode : nsucc == 0);
120 }
121 
122 # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b)
123 # define lca(x) (isupper(x) ? tolower(x) : x)
124 execute(file)
125 char *file;
126 {
127 	register struct words *c;
128 	register ccount;
129 	register char ch;
130 	register char *p;
131 	static char *buf;
132 	static int blksize;
133 	struct stat stb;
134 	int f;
135 	int failed;
136 	char *nlp;
137 	if (file) {
138 		if ((f = open(file, 0)) < 0) {
139 			fprintf(stderr, "fgrep: can't open %s\n", file);
140 			retcode = 2;
141 			return;
142 		}
143 	}
144 	else f = 0;
145 	if (buf == NULL) {
146 		if (fstat(f, &stb) > 0 && stb.st_blksize > 0)
147 			blksize = stb.st_blksize;
148 		else
149 			blksize = BLKSIZE;
150 		buf = (char *)malloc(2*blksize);
151 		if (buf == NULL) {
152 			fprintf(stderr, "egrep: no memory for %s\n", file);
153 			retcode = 2;
154 			return;
155 		}
156 	}
157 	ccount = 0;
158 	failed = 0;
159 	lnum = 1;
160 	tln = 0;
161 	blkno = 0;
162 	p = buf;
163 	nlp = p;
164 	c = w;
165 	for (;;) {
166 		if (--ccount <= 0) {
167 			if (p == &buf[2*blksize]) p = buf;
168 			if (p > &buf[blksize]) {
169 				if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
170 			}
171 			else if ((ccount = read(f, p, blksize)) <= 0) break;
172 			blkno += ccount;
173 		}
174 		nstate:
175 			if (ccomp(c->inp, *p)) {
176 				c = c->nst;
177 			}
178 			else if (c->link != 0) {
179 				c = c->link;
180 				goto nstate;
181 			}
182 			else {
183 				c = c->fail;
184 				failed = 1;
185 				if (c==0) {
186 					c = w;
187 					istate:
188 					if (ccomp(c->inp ,  *p)) {
189 						c = c->nst;
190 					}
191 					else if (c->link != 0) {
192 						c = c->link;
193 						goto istate;
194 					}
195 				}
196 				else goto nstate;
197 			}
198 		if (c->out) {
199 			while (*p++ != '\n') {
200 				if (--ccount <= 0) {
201 					if (p == &buf[2*blksize]) p = buf;
202 					if (p > &buf[blksize]) {
203 						if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
204 					}
205 					else if ((ccount = read(f, p, blksize)) <= 0) break;
206 					blkno += ccount;
207 				}
208 			}
209 			if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
210 				goto nomatch;
211 	succeed:	nsucc = 1;
212 			if (cflag) tln++;
213 			else if (sflag)
214 				;	/* ugh */
215 			else if (lflag) {
216 				printf("%s\n", file);
217 				close(f);
218 				return;
219 			}
220 			else {
221 				if (nfile > 1 && hflag) printf("%s:", file);
222 				if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE);
223 				if (nflag) printf("%ld:", lnum);
224 				if (p <= nlp) {
225 					while (nlp < &buf[2*blksize]) putchar(*nlp++);
226 					nlp = buf;
227 				}
228 				while (nlp < p) putchar(*nlp++);
229 			}
230 	nomatch:	lnum++;
231 			nlp = p;
232 			c = w;
233 			failed = 0;
234 			continue;
235 		}
236 		if (*p++ == '\n')
237 			if (vflag) goto succeed;
238 			else {
239 				lnum++;
240 				nlp = p;
241 				c = w;
242 				failed = 0;
243 			}
244 	}
245 	close(f);
246 	if (cflag) {
247 		if (nfile > 1)
248 			printf("%s:", file);
249 		printf("%ld\n", tln);
250 	}
251 }
252 
253 getargc()
254 {
255 	register c;
256 	if (wordf)
257 		return(getc(wordf));
258 	if ((c = *argptr++) == '\0')
259 		return(EOF);
260 	return(c);
261 }
262 
263 cgotofn() {
264 	register c;
265 	register struct words *s;
266 
267 	s = smax = w;
268 nword:	for(;;) {
269 		c = getargc();
270 		if (c==EOF)
271 			return;
272 		if (c == '\n') {
273 			if (xflag) {
274 				for(;;) {
275 					if (s->inp == c) {
276 						s = s->nst;
277 						break;
278 					}
279 					if (s->inp == 0) goto nenter;
280 					if (s->link == 0) {
281 						if (smax >= &w[MAXSIZ -1]) overflo();
282 						s->link = ++smax;
283 						s = smax;
284 						goto nenter;
285 					}
286 					s = s->link;
287 				}
288 			}
289 			s->out = 1;
290 			s = w;
291 		} else {
292 		loop:	if (s->inp == c) {
293 				s = s->nst;
294 				continue;
295 			}
296 			if (s->inp == 0) goto enter;
297 			if (s->link == 0) {
298 				if (smax >= &w[MAXSIZ - 1]) overflo();
299 				s->link = ++smax;
300 				s = smax;
301 				goto enter;
302 			}
303 			s = s->link;
304 			goto loop;
305 		}
306 	}
307 
308 	enter:
309 	do {
310 		s->inp = c;
311 		if (smax >= &w[MAXSIZ - 1]) overflo();
312 		s->nst = ++smax;
313 		s = smax;
314 	} while ((c = getargc()) != '\n' && c!=EOF);
315 	if (xflag) {
316 	nenter:	s->inp = '\n';
317 		if (smax >= &w[MAXSIZ -1]) overflo();
318 		s->nst = ++smax;
319 	}
320 	smax->out = 1;
321 	s = w;
322 	if (c != EOF)
323 		goto nword;
324 }
325 
326 overflo() {
327 	fprintf(stderr, "wordlist too large\n");
328 	exit(2);
329 }
330 cfail() {
331 	struct words *queue[QSIZE];
332 	struct words **front, **rear;
333 	struct words *state;
334 	int bstart;
335 	register char c;
336 	register struct words *s;
337 	s = w;
338 	front = rear = queue;
339 init:	if ((s->inp) != 0) {
340 		*rear++ = s->nst;
341 		if (rear >= &queue[QSIZE - 1]) overflo();
342 	}
343 	if ((s = s->link) != 0) {
344 		goto init;
345 	}
346 
347 	while (rear!=front) {
348 		s = *front;
349 		if (front == &queue[QSIZE-1])
350 			front = queue;
351 		else front++;
352 	cloop:	if ((c = s->inp) != 0) {
353 			bstart = 0;
354 			*rear = (q = s->nst);
355 			if (front < rear)
356 				if (rear >= &queue[QSIZE-1])
357 					if (front == queue) overflo();
358 					else rear = queue;
359 				else rear++;
360 			else
361 				if (++rear == front) overflo();
362 			state = s->fail;
363 		floop:	if (state == 0) {
364 				state = w;
365 				bstart = 1;
366 			}
367 			if (state->inp == c) {
368 			qloop:	q->fail = state->nst;
369 				if ((state->nst)->out == 1) q->out = 1;
370 				if ((q = q->link) != 0) goto qloop;
371 			}
372 			else if ((state = state->link) != 0)
373 				goto floop;
374 			else if(bstart == 0){
375 				state = 0;
376 				goto floop;
377 			}
378 		}
379 		if ((s = s->link) != 0)
380 			goto cloop;
381 	}
382 }
383