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