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: */
10: #define MAXSIZ 700
11: #define QSIZE 400
12: struct words {
13: char inp;
14: char out;
15: struct words *nst;
16: struct words *link;
17: struct words *fail;
18: }
19: *www, *smax, *q;
20:
21: char buf[1024];
22: int nsucc;
23: int need;
24: char *instr;
25: int inct;
26: int rflag;
27: int xargc;
28: char **xargv;
29: int numwords;
30: int found;
31: static int flag 0;
32: int grepin = 0, grepout = 1;
33:
34:
35: fgrep(argc, argv)
36: char **argv;
37: {
38: instr = nsucc = need = inct = rflag = numwords = found = 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 = q->out = q->nst = q->link = q->fail =0;
46: xargc = argc-1;
47: xargv = argv+1;
48: while (xargc>0 && xargv[0][0]=='-')
49: {
50: switch(xargv[0][1])
51: {
52: case 'r': /* return value only */
53: rflag++;
54: break;
55: case 'n': /* number of answers needed */
56: need = xargv[1];
57: xargv++;
58: 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;
67: xargc -= 2;
68: break;
69: }
70: xargv++;
71: xargc--;
72: }
73: if (xargc<=0)
74: err("bad fgrep call", 0);
75: cgotofn();
76: cfail();
77: execute();
78: return(nsucc == 0);
79: }
80:
81: execute()
82: {
83: register char *p;
84: register c;
85: register ch;
86: register ccount;
87: char *nlp;
88: ccount = instr ? inct : 0;
89: found=0;
90: p = instr ? instr : buf;
91: if (need == 0) need = numwords;
92: nlp = p;
93: c = www;
94: for (;;) {
95: if (--ccount <= 0) {
96: if (instr) break;
97: if (p == &buf[1024]) p = buf;
98: if (p > &buf[512]) {
99: if ((ccount = read(grepin, p, &buf[1024] - p)) <= 0) break;
100: }
101: else if ((ccount = read(grepin, p, 512)) <= 0) break;
102: }
103: nstate:
104: ch = *p;
105: if (isupper(ch)) ch |= 040;
106: if (c->inp == ch) {
107: c = c->nst;
108: }
109: else if (c->link != 0) {
110: c = c->link;
111: goto nstate;
112: }
113: else {
114: c = c->fail;
115: if (c==0) {
116: c = www;
117: istate:
118: if (c->inp == ch) {
119: c = c->nst;
120: }
121: else if (c->link != 0) {
122: c = c->link;
123: goto istate;
124: }
125: }
126: else goto nstate;
127: }
128: if (c->out && new (c)) {
129: if (++found >= need)
130: {
131: if (instr==0)
132: while (*p++ != '\n') {
133: if (--ccount <= 0) {
134: if (p == &buf[1024]) p = buf;
135: if (p > &buf[512]) {
136: if ((ccount = read(grepin, p, &buf[1024] - p)) <= 0) break;
137: }
138: else if ((ccount = read(grepin, p, 512)) <= 0) break;
139: }
140: }
141: nsucc = 1;
142: if (rflag==0)
143: {
144: if (p > nlp) write(grepout, nlp, p-nlp);
145: else {
146: write(grepout, nlp, &buf[1024] - nlp);
147: write(grepout, buf, p-&buf[0]);
148: }
149: if (p[-1]!= '\n') write (1, "\n", 1);
150: }
151: if (instr==0)
152: {
153: nlp = p;
154: c = www;
155: found=0;
156: }
157: }
158: else
159: ccount++;
160: continue;
161: }
162: if (instr)
163: p++;
164: else
165: if (*p++ == '\n')
166: {
167: nlp = p;
168: c = www;
169: found=0;
170: }
171: }
172: if (instr==0)
173: close(grepin);
174: }
175:
176: cgotofn() {
177: register c;
178: register s;
179: s = smax = www;
180: nword:
181: for(;;) {
182: if ((c = gch())==0) return;
183: else if (c == '\n') {
184: s->out = 1;
185: s = www;
186: }
187: else {
188: loop:
189: if (s->inp == c) {
190: s = s->nst;
191: continue;
192: }
193: if (s->inp == 0) goto enter;
194: if (s->link == 0) {
195: if (smax >= &www[MAXSIZ - 1]) overflo();
196: s->link = ++smax;
197: s = smax;
198: goto enter;
199: }
200: s = s->link;
201: goto loop;
202: }
203: }
204:
205: enter:
206: do {
207: s->inp = c;
208: if (smax >= &www[MAXSIZ - 1]) overflo();
209: s->nst = ++smax;
210: s = smax;
211: }
212: while ((c = gch()) != '\n');
213: smax->out = 1;
214: s = www;
215: numwords++;
216: goto nword;
217:
218: }
219:
220: gch()
221: {
222: static char *s;
223: if (flag==0)
224: {
225: flag=1;
226: s = *xargv++;
227: if (xargc-- <=0) return(0);
228: }
229: if (*s) return(*s++);
230: for(flag=0; flag<1024; flag++)
231: buf[flag]=0;
232: flag=0;
233: return('\n');
234: }
235:
236: overflo() {
237: write(2,"wordlist too large\n", 19);
238: exit(2);
239: }
240: cfail() {
241: struct words *queue[QSIZE];
242: struct words **front, **rear;
243: struct words *state;
244: register char c;
245: register s;
246: s = www;
247: front = rear = queue;
248: init:
249: if ((s->inp) != 0) {
250: *rear++ = s->nst;
251: if (rear >= &queue[QSIZE - 1]) overflo();
252: }
253: if ((s = s->link) != 0) {
254: goto init;
255: }
256:
257: while (rear!=front) {
258: s = *front;
259: if (front == &queue[QSIZE-1])
260: front = queue;
261: else front++;
262: cloop:
263: if ((c = s->inp) != 0) {
264: *rear = (q = s->nst);
265: if (front < rear)
266: if (rear >= &queue[QSIZE-1])
267: if (front == queue) overflo();
268: else rear = queue;
269: else rear++;
270: else
271: if (++rear == front) overflo();
272: state = s->fail;
273: floop:
274: if (state == 0) state = www;
275: if (state->inp == c) {
276: q->fail = state->nst;
277: if ((state->nst)->out == 1) q->out = 1;
278: continue;
279: }
280: else if ((state = state->link) != 0)
281: goto floop;
282: }
283: if ((s = s->link) != 0)
284: goto cloop;
285: }
286: }
287: static int seen[50];
288: new (x)
289: {
290: int i;
291: for(i=0; i<found; i++)
292: if (seen[i]==x)
293: return(0);
294: seen[i]=x;
295: return(1);
296: }
Defined functions
fgrep
defined in line
35; used 2 times
gch
defined in line
220; used 2 times
new
defined in line
288; used 1 times
Defined variables
buf
defined in line
21; used 13 times
flag
defined in line
31; used 8 times
found
defined in line
30; used 6 times
inct
defined in line
25; used 4 times
instr
defined in line
24; used 10 times
need
defined in line
23; used 5 times
nsucc
defined in line
22; used 3 times
q
defined in line
19; used 11 times
rflag
defined in line
26; used 3 times
seen
defined in line
287; used 2 times
smax
defined in line
19; used 8 times
www
defined in line
19; used 17 times
- in line 40-44(6),
93,
116,
154,
168,
179,
185,
195,
208,
214,
246,
274
xargc
defined in line
27; used 7 times
xargv
defined in line
28; used 12 times
Defined struct's
words
defined in line
12; used 12 times
Defined macros
QSIZE
defined in line
11; used 4 times