|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)glue5.c 4.1 (Berkeley) 5/6/83";
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: instr = nsucc = need = inct = rflag = numwords = nfound = 0;
42: flag = 0;
43: if (www==0)
44: www = zalloc(MAXSIZ, sizeof (*www));
45: if (www==NULL)
46: err("Can't get space for machines", 0);
47: for (q=www; q<www+MAXSIZ; q++) {
48: q->inp =0; q->out =0; q->nst =0; q->link =0; 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 = xargv[1];
61: xargv++; xargc--;
62: break;
63: case 'i':
64: instr = xargv[1];
65: inct = 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[2*BUFSIZ]) p = buf;
128: if (p > &buf[BUFSIZ]) {
129: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break;
130: }
131: else if ((ccount = read(f, p, BUFSIZ)) <= 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[2*BUFSIZ] %o\n",p,nlp,ccount,buf,buf+2*BUFSIZ);
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[2*BUFSIZ]) p = buf;
183: if (p > &buf[BUFSIZ]) {
184: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break;
185: }
186: else if ((ccount = read(f, p, BUFSIZ)) <= 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[2*BUFSIZ] - 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: continue;
220: }
221: # if D2
222: fprintf(stderr, "nr end loop p %o\n",p);
223: # endif
224: if (instr)
225: p++;
226: else
227: if (*p++ == '\n')
228: {
229: nlp = p;
230: c = www;
231: nfound=0;
232: }
233: }
234: if (instr==0)
235: close(f);
236: }
237:
238: cgotofn() {
239: register c;
240: register struct words *s;
241: s = smax = www;
242: nword:
243: for(;;) {
244: # if D1
245: fprintf(stderr, " in for loop c now %o %c\n",c, c>' ' ? c : ' ');
246: # endif
247: if ((c = gch())==0) return;
248: else if (c == '\n') {
249: s->out = 1;
250: s = www;
251: }
252: else {
253: loop:
254: if (s->inp == c) {
255: s = s->nst;
256: continue;
257: }
258: if (s->inp == 0) goto enter;
259: if (s->link == 0) {
260: if (smax >= &www[MAXSIZ - 1]) overflo();
261: s->link = ++smax;
262: s = smax;
263: goto enter;
264: }
265: s = s->link;
266: goto loop;
267: }
268: }
269:
270: enter:
271: do {
272: s->inp = c;
273: if (smax >= &www[MAXSIZ - 1]) overflo();
274: s->nst = ++smax;
275: s = smax;
276: }
277: while ((c = gch()) != '\n');
278: smax->out = 1;
279: s = www;
280: numwords++;
281: goto nword;
282:
283: }
284:
285: gch()
286: {
287: static char *s;
288: if (flag==0)
289: {
290: flag=1;
291: s = *xargv++;
292: # if D1
293: fprintf(stderr, "next arg is %s xargc %d\n",s,xargc);
294: # endif
295: if (xargc-- <=0) return(0);
296: }
297: if (*s) return(*s++);
298: for(flag=0; flag<2*BUFSIZ; flag++)
299: buf[flag]=0;
300: flag=0;
301: return('\n');
302: }
303:
304: overflo() {
305: write(2,"wordlist too large\n", 19);
306: exit(2);
307: }
308: cfail() {
309: struct words *queue[QSIZE];
310: struct words **front, **rear;
311: struct words *state;
312: register char c;
313: register struct words *s;
314: s = www;
315: front = rear = queue;
316: init:
317: if ((s->inp) != 0) {
318: *rear++ = s->nst;
319: if (rear >= &queue[QSIZE - 1]) overflo();
320: }
321: if ((s = s->link) != 0) {
322: goto init;
323: }
324:
325: while (rear!=front) {
326: s = *front;
327: if (front == &queue[QSIZE-1])
328: front = queue;
329: else front++;
330: cloop:
331: if ((c = s->inp) != 0) {
332: *rear = (q = s->nst);
333: if (front < rear)
334: if (rear >= &queue[QSIZE-1])
335: if (front == queue) overflo();
336: else rear = queue;
337: else rear++;
338: else
339: if (++rear == front) overflo();
340: state = s->fail;
341: floop:
342: if (state == 0) state = www;
343: if (state->inp == c) {
344: q->fail = state->nst;
345: if ((state->nst)->out == 1) q->out = 1;
346: continue;
347: }
348: else if ((state = state->link) != 0)
349: goto floop;
350: }
351: if ((s = s->link) != 0)
352: goto cloop;
353: }
354: }
355:
356: static int seen[50];
357: new (x)
358: {
359: int i;
360: for(i=0; i<nfound; i++)
361: if (seen[i]==x)
362: return(0);
363: seen[i]=x;
364: return(1);
365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.