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