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