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