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