|
|
1.1 root 1: static char *sccsid = "@(#)old.fgrep.c 4.4 (Berkeley) 10/7/87";
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 oflag;
31: int sflag;
32: int retcode = 0;
33: int nfile;
34: long blkno;
35: int nsucc;
36: long tln;
37: FILE *wordf;
38: char *argptr;
39:
40: main(argc, argv)
41: char **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:
54: case 'o':
55: oflag++;
56: continue;
57:
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: }
99: out:
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)
129: execute(file)
130: char *file;
131: {
132: register struct words *c;
133: register ccount;
134: register char ch;
135: register char *p;
136: static char *buf;
137: static int blksize;
138: struct stat stb;
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;
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: }
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) {
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;
175: }
176: else if ((ccount = read(f, p, blksize)) <= 0) break;
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) {
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;
209: }
210: else if ((ccount = read(f, p, blksize)) <= 0) break;
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 {
226: if (nfile > 1 && hflag || oflag) printf("%s:", file);
227: if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE);
228: if (nflag) printf("%ld:", lnum);
229: if (p <= nlp) {
230: while (nlp < &buf[2*blksize]) putchar(*nlp++);
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:
258: getargc()
259: {
260: register c;
261: if (wordf)
262: return(getc(wordf));
263: if ((c = *argptr++) == '\0')
264: return(EOF);
265: return(c);
266: }
267:
268: cgotofn() {
269: register c;
270: register struct words *s;
271:
272: s = smax = w;
273: nword: 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:
331: overflo() {
332: fprintf(stderr, "wordlist too large\n");
333: exit(2);
334: }
335: cfail() {
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;
344: init: 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.