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