1: static char *sccsid = "@(#)fgrep.c 4.3 (Berkeley) 5/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: }
Defined functions
main
defined in line
39;
never used
Defined variables
bflag
defined in line
28; used 2 times
blkno
defined in line
33; used 4 times
cflag
defined in line
28; used 3 times
fflag
defined in line
28; used 2 times
hflag
defined in line
29; used 2 times
lflag
defined in line
28; used 3 times
lnum
defined in line
27; used 4 times
nfile
defined in line
32; used 3 times
nflag
defined in line
28; used 2 times
nsucc
defined in line
34; used 2 times
q
defined in line
25; used 5 times
sccsid
defined in line
1;
never used
sflag
defined in line
30; used 2 times
smax
defined in line
25; used 13 times
tln
defined in line
35; used 3 times
vflag
defined in line
28; used 4 times
w
defined in line
25; used 13 times
- in line 164,
186,
232,
241,
267,
281,
290,
298,
311,
317-321(2),
337,
364
xflag
defined in line
28; used 5 times
yflag
defined in line
28; used 2 times
Defined struct's
words
defined in line
19; used 18 times
Defined macros
QSIZE
defined in line
18; used 4 times
lca
defined in line
123; used 2 times