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