|
|
1.1 root 1: # include "stdio.h"
2: # include "ctype.h"
3: /*
4: * fgrep -- print all lines containing any of a set of keywords
5: *
6: * status returns:
7: * 0 - ok, and some matches
8: * 1 - ok, but no matches
9: * 2 - some error
10: */
11: #define MAXSIZ 700
12: #define QSIZE 400
13: struct words {
14: char inp;
15: char out;
16: struct words *nst;
17: struct words *link;
18: struct words *fail;
19: }
20: *www, *smax, *q;
21:
22: struct words *zalloc();
23: char buf[1024];
24: int nsucc;
25: int need;
26: char *instr;
27: int inct;
28: int rflag;
29: int xargc;
30: char **xargv;
31: int numwords;
32: int nfound;
33: static int flag = 0;
34:
35:
36: fgrep(argc, argv)
37: char **argv;
38: {
39: nsucc = need = inct = rflag = numwords = nfound = 0;
40: instr = 0;
41: flag = 0;
42: if (www==0)
43: www = zalloc(MAXSIZ, sizeof (*www));
44: if (www==NULL)
45: err("Can't get space for machines", 0);
46: for (q=www; q<www+MAXSIZ; q++)
47: {
48: q->inp = q->out = 0; q->nst = q->link = q->fail =0;
49: }
50: xargc = argc-1;
51: xargv = argv+1;
52: while (xargc>0 && xargv[0][0]=='-')
53: {
54: switch(xargv[0][1])
55: {
56: case 'r': /* return value only */
57: rflag++;
58: break;
59: case 'n': /* number of answers needed */
60: need = (int) xargv[1];
61: xargv++; xargc--;
62: break;
63: case 'i':
64: instr = xargv[1];
65: inct = (int) xargv[2]+2;
66: # if D2
67: fprintf(stderr,"inct %d xargv.2. %o %d\n",inct, xargv[2],xargv[2]);
68: # endif
69: xargv += 2; xargc -= 2;
70: break;
71: }
72: xargv++; xargc--;
73: }
74: if (xargc<=0)
75: {
76: write (2, "bad fgrep call\n", 15);
77: exit(2);
78: }
79: # if D1
80: fprintf(stderr, "before cgoto\n");
81: # endif
82: cgotofn();
83: # if D1
84: fprintf(stderr, "before cfail\n");
85: # endif
86: cfail();
87: # if D1
88: fprintf(stderr, "before execute instr %.20s\n", instr? instr: "");
89: fprintf(stderr, "end of string %d %c %c %c\n", inct, instr[inct-3],
90: instr[inct-2], instr[inct-1]);
91: # endif
92: execute();
93: # if D1
94: fprintf(stderr, "returning nsucc %d\n", nsucc);
95: fprintf(stderr, "fgrep done www %o\n",www);
96: # endif
97: return(nsucc == 0);
98: }
99:
100: execute()
101: {
102: register char *p;
103: register struct words * c;
104: register ch;
105: register ccount;
106: int f;
107: char *nlp;
108: f=0;
109: ccount = instr ? inct : 0;
110: nfound=0;
111: p = instr ? instr : buf;
112: if (need == 0) need = numwords;
113: nlp = p;
114: c = www;
115: # if D2
116: fprintf(stderr, "in execute ccount %d inct %d\n",ccount, inct );
117: # endif
118: for (;;) {
119: # if D3
120: fprintf(stderr, "down ccount\n");
121: # endif
122: if (--ccount <= 0) {
123: # if D2
124: fprintf(stderr, "ex loop ccount %d instr %o\n",ccount, instr);
125: # endif
126: if (instr) break;
127: if (p == &buf[1024]) p = buf;
128: if (p > &buf[512]) {
129: if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
130: }
131: else if ((ccount = read(f, p, 512)) <= 0) break;
132: # if D2
133: fprintf(stderr, " normal read %d bytres\n", ccount);
134: {char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);
135: fprintf(stderr, xx, p);
136: }
137: # endif
138: }
139: nstate:
140: ch = *p;
141: # if D2
142: fprintf(stderr, "roaming along in ex ch %c c %o\n",ch,c);
143: # endif
144: if (isupper(ch)) ch |= 040;
145: if (c->inp == ch) {
146: c = c->nst;
147: }
148: else if (c->link != 0) {
149: c = c->link;
150: goto nstate;
151: }
152: else {
153: c = c->fail;
154: if (c==0) {
155: c = www;
156: istate:
157: if (c->inp == ch) {
158: c = c->nst;
159: }
160: else if (c->link != 0) {
161: c = c->link;
162: goto istate;
163: }
164: }
165: else goto nstate;
166: }
167: if (c->out && new (c)) {
168: # if D2
169: fprintf(stderr, " found: nfound %d need %d\n",nfound,need);
170: # endif
171: if (++nfound >= need)
172: {
173: # if D1
174: fprintf(stderr, "found, p %o nlp %o ccount %d buf %o buf[1024] %o\n",p,nlp,ccount,buf,buf+1024);
175: # endif
176: if (instr==0)
177: while (*p++ != '\n') {
178: # if D3
179: fprintf(stderr, "down ccount2\n");
180: # endif
181: if (--ccount <= 0) {
182: if (p == &buf[1024]) p = buf;
183: if (p > &buf[512]) {
184: if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
185: }
186: else if ((ccount = read(f, p, 512)) <= 0) break;
187: # if D2
188: fprintf(stderr, " read %d bytes\n",ccount);
189: { char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);
190: fprintf(stderr, xx, p);
191: }
192: # endif
193: }
194: }
195: nsucc = 1;
196: if (rflag==0)
197: {
198: # if D2
199: fprintf(stderr, "p %o nlp %o buf %o\n",p,nlp,buf);
200: if (p>nlp)
201: {write (2, "XX\n", 3); write (2, nlp, p-nlp); write (2, "XX\n", 3);}
202: # endif
203: if (p > nlp) write(1, nlp, p-nlp);
204: else {
205: write(1, nlp, &buf[1024] - nlp);
206: write(1, buf, p-&buf[0]);
207: }
208: if (p[-1]!= '\n') write (1, "\n", 1);
209: }
210: if (instr==0)
211: {
212: nlp = p;
213: c = www;
214: nfound=0;
215: }
216: }
217: else {
218: ccount++;
219: p++;
220: }
221: continue;
222: }
223: # if D2
224: fprintf(stderr, "nr end loop p %o\n",p);
225: # endif
226: if (instr)
227: p++;
228: else
229: if (*p++ == '\n')
230: {
231: nlp = p;
232: c = www;
233: nfound=0;
234: }
235: }
236: if (instr==0)
237: close(f);
238: }
239:
240: cgotofn() {
241: register c;
242: register struct words * s;
243: s = smax = www;
244: nword:
245: for(;;) {
246: # if D1
247: fprintf(stderr, " in for loop c now %o %c\n",c, c>' ' ? c : ' ');
248: # endif
249: if ((c = gch())==0) return;
250: else if (c == '\n') {
251: s->out = 1;
252: s = www;
253: }
254: else {
255: loop:
256: if (s->inp == c) {
257: s = s->nst;
258: continue;
259: }
260: if (s->inp == 0) goto enter;
261: if (s->link == 0) {
262: if (smax >= &www[MAXSIZ - 1]) overflo();
263: s->link = ++smax;
264: s = smax;
265: goto enter;
266: }
267: s = s->link;
268: goto loop;
269: }
270: }
271:
272: enter:
273: do {
274: s->inp = c;
275: if (smax >= &www[MAXSIZ - 1]) overflo();
276: s->nst = ++smax;
277: s = smax;
278: }
279: while ((c = gch()) != '\n');
280: smax->out = 1;
281: s = www;
282: numwords++;
283: goto nword;
284:
285: }
286:
287: gch()
288: {
289: static char *s;
290: if (flag==0)
291: {
292: flag=1;
293: s = *xargv++;
294: # if D1
295: fprintf(stderr, "next arg is %s xargc %d\n",s,xargc);
296: # endif
297: if (xargc-- <=0) return(0);
298: }
299: if (*s) return(*s++);
300: for(flag=0; flag<1024; flag++)
301: buf[flag]=0;
302: flag=0;
303: return('\n');
304: }
305:
306: overflo() {
307: write(2,"wordlist too large\n", 19);
308: exit(2);
309: }
310: cfail() {
311: struct words *queue[QSIZE];
312: struct words **front, **rear;
313: struct words *state;
314: register char c;
315: register struct words * s;
316: s = www;
317: front = rear = queue;
318: init:
319: if ((s->inp) != 0) {
320: *rear++ = s->nst;
321: if (rear >= &queue[QSIZE - 1]) overflo();
322: }
323: if ((s = s->link) != 0) {
324: goto init;
325: }
326:
327: while (rear!=front) {
328: s = *front;
329: if (front == &queue[QSIZE-1])
330: front = queue;
331: else front++;
332: cloop:
333: if ((c = s->inp) != 0) {
334: *rear = (q = s->nst);
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;
343: floop:
344: if (state == 0) state = www;
345: if (state->inp == c) {
346: q->fail = state->nst;
347: if ((state->nst)->out == 1) q->out = 1;
348: continue;
349: }
350: else if ((state = state->link) != 0)
351: goto floop;
352: }
353: if ((s = s->link) != 0)
354: goto cloop;
355: }
356: }
357: static int seen[50];
358: new (x)
359: {
360: int i;
361: for(i=0; i<nfound; i++)
362: if (seen[i]==x)
363: return(0);
364: seen[i]=x;
365: return(1);
366: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.