|
|
1.1 root 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: int 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, "fgrep: 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, "fgrep: 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[BUFSIZ*2];
119: int f;
120: int failed, ecnt;
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 = -1;
134: p = buf;
135: nlp = p;
136: c = w;
137: for (;;) {
138: if (--ccount <= 0) {
139: if (p == &buf[BUFSIZ*2]) p = buf;
140: if (p > &buf[BUFSIZ]) {
141: if ((ccount = read(f, p, &buf[BUFSIZ] - p)) <= 0) break;
142: }
143: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;
144: blkno++;
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: ecnt = 0;
172: while (*p++ != '\n') {
173: ecnt++;
174: if (--ccount <= 0) {
175: if (p == &buf[BUFSIZ*2]) p = buf;
176: if (p > &buf[BUFSIZ]) {
177: if ((ccount = read(f, p, &buf[BUFSIZ] - p)) <= 0) break;
178: }
179: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;
180: blkno++;
181: }
182: }
183: if (vflag == 0) {
184: if (xflag)
185: if (failed || ecnt > 1) goto nogood;
186: succeed: nsucc = 1;
187: if (cflag) tln++;
188: else if (sflag)
189: ; /* ugh */
190: else if (lflag) {
191: printf("%s\n", file);
192: close(f);
193: return;
194: }
195: else {
196: if (nfile > 1 && hflag) printf("%s:", file);
197: if (bflag) printf("%d:", blkno);
198: if (nflag) printf("%ld:", lnum);
199: if (p <= nlp) {
200: while (nlp < &buf[BUFSIZ*2]) putchar(*nlp++);
201: nlp = buf;
202: }
203: while (nlp < p) putchar(*nlp++);
204: }
205: }
206: nogood: lnum++;
207: nlp = p;
208: c = w;
209: failed = 0;
210: continue;
211: }
212: if (*p++ == '\n')
213: if (vflag) goto succeed;
214: else {
215: lnum++;
216: nlp = p;
217: c = w;
218: failed = 0;
219: }
220: }
221: close(f);
222: if (cflag) {
223: if (nfile > 1)
224: printf("%s:", file);
225: printf("%ld\n", tln);
226: }
227: }
228:
229: getargc()
230: {
231: register c;
232: if (wordf)
233: return(getc(wordf));
234: if ((c = *argptr++) == '\0')
235: return(EOF);
236: return(c);
237: }
238:
239: cgotofn() {
240: register c;
241: register struct words *s;
242:
243: s = smax = w;
244: nword: for(;;) {
245: c = getargc();
246: if (c==EOF)
247: return;
248: if (c == '\n') {
249: if (xflag) {
250: for(;;) {
251: if (s->inp == c) {
252: s = s->nst;
253: break;
254: }
255: if (s->inp == 0) goto nenter;
256: if (s->link == 0) {
257: if (smax >= &w[MAXSIZ -1]) overflo();
258: s->link = ++smax;
259: s = smax;
260: goto nenter;
261: }
262: s = s->link;
263: }
264: }
265: s->out = 1;
266: s = w;
267: } else {
268: loop: if (s->inp == c) {
269: s = s->nst;
270: continue;
271: }
272: if (s->inp == 0) goto enter;
273: if (s->link == 0) {
274: if (smax >= &w[MAXSIZ - 1]) overflo();
275: s->link = ++smax;
276: s = smax;
277: goto enter;
278: }
279: s = s->link;
280: goto loop;
281: }
282: }
283:
284: enter:
285: do {
286: s->inp = c;
287: if (smax >= &w[MAXSIZ - 1]) overflo();
288: s->nst = ++smax;
289: s = smax;
290: } while ((c = getargc()) != '\n' && c!=EOF);
291: if (xflag) {
292: nenter: s->inp = '\n';
293: if (smax >= &w[MAXSIZ -1]) overflo();
294: s->nst = ++smax;
295: }
296: smax->out = 1;
297: s = w;
298: if (c != EOF)
299: goto nword;
300: }
301:
302: overflo() {
303: fprintf(stderr, "wordlist too large\n");
304: exit(2);
305: }
306: cfail() {
307: struct words *queue[QSIZE];
308: struct words **front, **rear;
309: struct words *state;
310: register char c;
311: register struct words *s;
312: s = w;
313: front = rear = queue;
314: init: if ((s->inp) != 0) {
315: *rear++ = s->nst;
316: if (rear >= &queue[QSIZE - 1]) overflo();
317: }
318: if ((s = s->link) != 0) {
319: goto init;
320: }
321:
322: while (rear!=front) {
323: s = *front;
324: if (front == &queue[QSIZE-1])
325: front = queue;
326: else front++;
327: cloop: if ((c = s->inp) != 0) {
328: *rear = (q = s->nst);
329: if (front < rear)
330: if (rear >= &queue[QSIZE-1])
331: if (front == queue) overflo();
332: else rear = queue;
333: else rear++;
334: else
335: if (++rear == front) overflo();
336: state = s->fail;
337: floop: if (state == 0) state = w;
338: if (state->inp == c) {
339: q->fail = state->nst;
340: if ((state->nst)->out == 1) q->out = 1;
341: continue;
342: }
343: else if ((state = state->link) != 0)
344: goto floop;
345: }
346: if ((s = s->link) != 0)
347: goto cloop;
348: }
349: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.