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