Bell 32V development
[unix-history] / usr / src / cmd / fgrep.c
CommitLineData
4e6205be
TL
1/*
2 * fgrep -- print all lines containing any of a set of keywords
3 *
4 * status returns:
5 * 0 - ok, and some matches
6 * 1 - ok, but no matches
7 * 2 - some error
8 */
9
10#include <stdio.h>
11
12#define MAXSIZ 6000
13#define QSIZE 400
14struct words {
15 char inp;
16 char out;
17 struct words *nst;
18 struct words *link;
19 struct words *fail;
20} w[MAXSIZ], *smax, *q;
21
22long lnum;
23int bflag, cflag, fflag, lflag, nflag, vflag, xflag;
24int hflag = 1;
25int sflag;
26int nfile;
27int blkno;
28int nsucc;
29long tln;
30FILE *wordf;
31char *argptr;
32
33main(argc, argv)
34char **argv;
35{
36 while (--argc > 0 && (++argv)[0][0]=='-')
37 switch (argv[0][1]) {
38
39 case 's':
40 sflag++;
41 continue;
42
43 case 'h':
44 hflag = 0;
45 continue;
46
47 case 'b':
48 bflag++;
49 continue;
50
51 case 'c':
52 cflag++;
53 continue;
54
55 case 'e':
56 argc--;
57 argv++;
58 goto out;
59
60 case 'f':
61 fflag++;
62 continue;
63
64 case 'l':
65 lflag++;
66 continue;
67
68 case 'n':
69 nflag++;
70 continue;
71
72 case 'v':
73 vflag++;
74 continue;
75
76 case 'x':
77 xflag++;
78 continue;
79
80 default:
81 fprintf(stderr, "egrep: unknown flag\n");
82 continue;
83 }
84out:
85 if (argc<=0)
86 exit(2);
87 if (fflag) {
88 wordf = fopen(*argv, "r");
89 if (wordf==NULL) {
90 fprintf(stderr, "egrep: can't open %s\n", *argv);
91 exit(2);
92 }
93 }
94 else argptr = *argv;
95 argc--;
96 argv++;
97
98 cgotofn();
99 cfail();
100 nfile = argc;
101 if (argc<=0) {
102 if (lflag) exit(1);
103 execute((char *)NULL);
104 }
105 else while (--argc >= 0) {
106 execute(*argv);
107 argv++;
108 }
109 exit(nsucc == 0);
110}
111
112execute(file)
113char *file;
114{
115 register char *p;
116 register struct words *c;
117 register ccount;
118 char buf[1024];
119 int f;
120 int failed, ecnt;
121 char *nlp;
122 if (file) {
123 if ((f = open(file, 0)) < 0) {
124 fprintf(stderr, "fgrep: can't open %s\n", file);
125 exit(2);
126 }
127 }
128 else f = 0;
129 ccount = 0;
130 failed = 0;
131 lnum = 1;
132 tln = 0;
133 blkno = -1;
134 p = buf;
135 nlp = p;
136 c = w;
137 for (;;) {
138 if (--ccount <= 0) {
139 if (p == &buf[1024]) p = buf;
140 if (p > &buf[512]) {
141 if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
142 }
143 else if ((ccount = read(f, p, 512)) <= 0) break;
144 blkno++;
145 }
146 nstate:
147 if (c->inp == *p) {
148 c = c->nst;
149 }
150 else if (c->link != 0) {
151 c = c->link;
152 goto nstate;
153 }
154 else {
155 c = c->fail;
156 failed = 1;
157 if (c==0) {
158 c = w;
159 istate:
160 if (c->inp == *p) {
161 c = c->nst;
162 }
163 else if (c->link != 0) {
164 c = c->link;
165 goto istate;
166 }
167 }
168 else goto nstate;
169 }
170 if (c->out) {
171 ecnt = 0;
172 while (*p++ != '\n') {
173 ecnt++;
174 if (--ccount <= 0) {
175 if (p == &buf[1024]) p = buf;
176 if (p > &buf[512]) {
177 if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
178 }
179 else if ((ccount = read(f, p, 512)) <= 0) break;
180 blkno++;
181 }
182 }
183 if (vflag == 0) {
184 if (xflag)
185 if (failed || ecnt > 1) goto nogood;
186 succeed: nsucc = 1;
187 if (cflag) tln++;
188 else if (sflag)
189 ; /* ugh */
190 else if (lflag) {
191 printf("%s\n", file);
192 close(f);
193 return;
194 }
195 else {
196 if (nfile > 1 && hflag) printf("%s:", file);
197 if (bflag) printf("%d:", blkno);
198 if (nflag) printf("%ld:", lnum);
199 if (p <= nlp) {
200 while (nlp < &buf[1024]) putchar(*nlp++);
201 nlp = buf;
202 }
203 while (nlp < p) putchar(*nlp++);
204 }
205 }
206 nogood: lnum++;
207 nlp = p;
208 c = w;
209 failed = 0;
210 continue;
211 }
212 if (*p++ == '\n')
213 if (vflag) goto succeed;
214 else {
215 lnum++;
216 nlp = p;
217 c = w;
218 failed = 0;
219 }
220 }
221 close(f);
222 if (cflag) {
223 if (nfile > 1)
224 printf("%s:", file);
225 printf("%ld\n", tln);
226 }
227}
228
229getargc()
230{
231 register c;
232 if (wordf)
233 return(getc(wordf));
234 if ((c = *argptr++) == '\0')
235 return(EOF);
236 return(c);
237}
238
239cgotofn() {
240 register c;
241 register struct words *s;
242
243 s = smax = w;
244nword: for(;;) {
245 c = getargc();
246 if (c==EOF)
247 return;
248 if (c == '\n') {
249 if (xflag) {
250 for(;;) {
251 if (s->inp == c) {
252 s = s->nst;
253 break;
254 }
255 if (s->inp == 0) goto nenter;
256 if (s->link == 0) {
257 if (smax >= &w[MAXSIZ -1]) overflo();
258 s->link = ++smax;
259 s = smax;
260 goto nenter;
261 }
262 s = s->link;
263 }
264 }
265 s->out = 1;
266 s = w;
267 } else {
268 loop: if (s->inp == c) {
269 s = s->nst;
270 continue;
271 }
272 if (s->inp == 0) goto enter;
273 if (s->link == 0) {
274 if (smax >= &w[MAXSIZ - 1]) overflo();
275 s->link = ++smax;
276 s = smax;
277 goto enter;
278 }
279 s = s->link;
280 goto loop;
281 }
282 }
283
284 enter:
285 do {
286 s->inp = c;
287 if (smax >= &w[MAXSIZ - 1]) overflo();
288 s->nst = ++smax;
289 s = smax;
290 } while ((c = getargc()) != '\n' && c!=EOF);
291 if (xflag) {
292 nenter: s->inp = '\n';
293 if (smax >= &w[MAXSIZ -1]) overflo();
294 s->nst = ++smax;
295 }
296 smax->out = 1;
297 s = w;
298 if (c != EOF)
299 goto nword;
300}
301
302overflo() {
303 fprintf(stderr, "wordlist too large\n");
304 exit(2);
305}
306cfail() {
307 struct words *queue[QSIZE];
308 struct words **front, **rear;
309 struct words *state;
310 register char c;
311 register struct words *s;
312 s = w;
313 front = rear = queue;
314init: 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: if ((c = s->inp) != 0) {
328 *rear = (q = s->nst);
329 if (front < rear)
330 if (rear >= &queue[QSIZE-1])
331 if (front == queue) overflo();
332 else rear = queue;
333 else rear++;
334 else
335 if (++rear == front) overflo();
336 state = s->fail;
337 floop: if (state == 0) state = w;
338 if (state->inp == c) {
339 q->fail = state->nst;
340 if ((state->nst)->out == 1) q->out = 1;
341 continue;
342 }
343 else if ((state = state->link) != 0)
344 goto floop;
345 }
346 if ((s = s->link) != 0)
347 goto cloop;
348 }
349}