|
|
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, iflag;
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':
84: iflag++;
85: continue;
86: default:
87: fprintf(stderr, "fgrep: unknown flag\n");
88: continue;
89: }
90: out:
91: if (argc<=0)
92: exit(2);
93: if (fflag) {
94: wordf = fopen(*argv, "r");
95: if (wordf==NULL) {
96: fprintf(stderr, "fgrep: can't open %s\n", *argv);
97: exit(2);
98: }
99: }
100: else argptr = *argv;
101: argc--;
102: argv++;
103:
104: cgotofn();
105: cfail();
106: nfile = argc;
107: if (argc<=0) {
108: if (lflag) exit(1);
109: execute((char *)NULL);
110: }
111: else while (--argc >= 0) {
112: execute(*argv);
113: argv++;
114: }
115: exit(retcode != 0 ? retcode : nsucc == 0);
116: }
117:
118: # define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b)
119: # define lca(x) (isupper(x) ? ((x)+'a'-'A') : x)
120: execute(file)
121: char *file;
122: {
123: register struct words *c;
124: register ccount;
125: register char ch;
126: register char *p;
127: char buf[2*BUFSIZ];
128: int f;
129: int failed;
130: char *nlp;
131: if (file) {
132: if ((f = open(file, 0)) < 0) {
133: fprintf(stderr, "fgrep: can't open %s\n", file);
134: retcode = 2;
135: return;
136: }
137: }
138: else f = 0;
139: ccount = 0;
140: failed = 0;
141: lnum = 1;
142: tln = 0;
143: blkno = 0;
144: p = buf;
145: nlp = p;
146: c = w;
147: for (;;) {
148: if (--ccount <= 0) {
149: if (p == &buf[2*BUFSIZ]) p = buf;
150: if (p > &buf[BUFSIZ]) {
151: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break;
152: }
153: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;
154: blkno += ccount;
155: }
156: nstate:
157: if (ccomp(c->inp, *p)) {
158: c = c->nst;
159: }
160: else if (c->link != 0) {
161: c = c->link;
162: goto nstate;
163: }
164: else {
165: c = c->fail;
166: failed = 1;
167: if (c==0) {
168: c = w;
169: istate:
170: if (ccomp(c->inp , *p)) {
171: c = c->nst;
172: }
173: else if (c->link != 0) {
174: c = c->link;
175: goto istate;
176: }
177: }
178: else goto nstate;
179: }
180: if (c->out) {
181: while (*p++ != '\n') {
182: if (--ccount <= 0) {
183: if (p == &buf[2*BUFSIZ]) p = buf;
184: if (p > &buf[BUFSIZ]) {
185: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break;
186: }
187: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;
188: blkno += ccount;
189: }
190: }
191: if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
192: goto nomatch;
193: succeed: nsucc = 1;
194: if (cflag) tln++;
195: else if (sflag)
196: ; /* ugh */
197: else if (lflag) {
198: printf("%s\n", file);
199: close(f);
200: return;
201: }
202: else {
203: if (nfile > 1 && hflag) printf("%s:", file);
204: if (bflag) printf("%ld:", (blkno-ccount-1)/BUFSIZ);
205: if (nflag) printf("%ld:", lnum);
206: if (p <= nlp) {
207: while (nlp < &buf[2*BUFSIZ]) putchar(*nlp++);
208: nlp = buf;
209: }
210: while (nlp < p) putchar(*nlp++);
211: }
212: nomatch: lnum++;
213: nlp = p;
214: c = w;
215: failed = 0;
216: continue;
217: }
218: if (*p++ == '\n')
219: if (vflag) goto succeed;
220: else {
221: lnum++;
222: nlp = p;
223: c = w;
224: failed = 0;
225: }
226: }
227: close(f);
228: if (cflag) {
229: if (nfile > 1)
230: printf("%s:", file);
231: printf("%ld\n", tln);
232: }
233: }
234:
235: getargc()
236: {
237: register c;
238: if (wordf)
239: return(getc(wordf));
240: if ((c = *argptr++) == '\0')
241: return(EOF);
242: return(c);
243: }
244:
245: cgotofn() {
246: register c;
247: register struct words *s;
248:
249: s = smax = w;
250: nword: for(;;) {
251: c = getargc();
252: if (c==EOF)
253: return;
254: if (c == '\n') {
255: if (xflag) {
256: for(;;) {
257: if (s->inp == c) {
258: s = s->nst;
259: break;
260: }
261: if (s->inp == 0) goto nenter;
262: if (s->link == 0) {
263: if (smax >= &w[MAXSIZ -1]) overflo();
264: s->link = ++smax;
265: s = smax;
266: goto nenter;
267: }
268: s = s->link;
269: }
270: }
271: s->out = 1;
272: s = w;
273: } else {
274: loop: if (s->inp == c) {
275: s = s->nst;
276: continue;
277: }
278: if (s->inp == 0) goto enter;
279: if (s->link == 0) {
280: if (smax >= &w[MAXSIZ - 1]) overflo();
281: s->link = ++smax;
282: s = smax;
283: goto enter;
284: }
285: s = s->link;
286: goto loop;
287: }
288: }
289:
290: enter:
291: do {
292: s->inp = c;
293: if (smax >= &w[MAXSIZ - 1]) overflo();
294: s->nst = ++smax;
295: s = smax;
296: } while ((c = getargc()) != '\n' && c!=EOF);
297: if (xflag) {
298: nenter: s->inp = '\n';
299: if (smax >= &w[MAXSIZ -1]) overflo();
300: s->nst = ++smax;
301: }
302: smax->out = 1;
303: s = w;
304: if (c != EOF)
305: goto nword;
306: }
307:
308: overflo() {
309: fprintf(stderr, "wordlist too large\n");
310: exit(2);
311: }
312: cfail() {
313: struct words *queue[QSIZE];
314: struct words **front, **rear;
315: struct words *state;
316: register char c;
317: register struct words *s;
318: s = w;
319: front = rear = queue;
320: init: if ((s->inp) != 0) {
321: *rear++ = s->nst;
322: if (rear >= &queue[QSIZE - 1]) overflo();
323: }
324: if ((s = s->link) != 0) {
325: goto init;
326: }
327:
328: while (rear!=front) {
329: s = *front; /* s is next state in queue */
330: if (front == &queue[QSIZE-1])
331: front = queue;
332: else front++;
333: cloop: if ((c = s->inp) != 0) { /* g(s,c) != 0 */
334: *rear = (q = s->nst); /* add q = g(s,c) to queue */
335: if (front < rear)
336: if (rear >= &queue[QSIZE-1])
337: if (front == queue) overflo();
338: else rear = queue;
339: else rear++;
340: else
341: if (++rear == front) overflo();
342: state = s->fail; /* state = f(s) */
343: floop: if (state == 0)
344: state = w;
345: if (state->inp == c)
346: do { /* f(q) = g(state,c) for all q links */
347: q->fail = state->nst;
348: if ((state->nst)->out == 1) q->out = 1;
349: } while ((q = q->link) != 0);
350: else if (state->link != 0) {
351: state = state->link;
352: goto floop;
353: }
354: else if ((state = state->fail) != 0)
355: goto floop; /* state = f(state) */
356: }
357: if ((s = s->link) != 0)
358: goto cloop;
359: }
360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.