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