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