date and time created 82/05/07 14:21:37 by mckusick
[unix-history] / usr / src / usr.bin / grep / old.bin.grep / old.bin.grep.c
CommitLineData
49d08d24
KM
1/* old.bin.grep.c 4.1 82/05/07 */
2
3/*
4 * grep -- print lines matching (or not matching) a pattern
5 *
6 * status returns:
7 * 0 - ok, and some matches
8 * 1 - ok, but no matches
9 * 2 - some error
10 */
11
12#include <stdio.h>
13#include <ctype.h>
14
15#define CBRA 1
16#define CCHR 2
17#define CDOT 4
18#define CCL 6
19#define NCCL 8
20#define CDOL 10
21#define CEOF 11
22#define CKET 12
23#define CBACK 18
24
25#define STAR 01
26
27#define LBSIZE BUFSIZ
28#define ESIZE 256
29#define NBRA 9
30
31char expbuf[ESIZE];
32long lnum;
33char linebuf[LBSIZE+1];
34char ybuf[ESIZE];
35int bflag;
36int lflag;
37int nflag;
38int cflag;
39int vflag;
40int nfile;
41int hflag = 1;
42int sflag;
43int yflag;
44int circf;
45int blkno;
46long tln;
47int nsucc;
48char *braslist[NBRA];
49char *braelist[NBRA];
50char bittab[] = {
51 1,
52 2,
53 4,
54 8,
55 16,
56 32,
57 64,
58 128
59};
60
61main(argc, argv)
62char **argv;
63{
64 extern char _sobuf[];
65 setbuf(stdout, _sobuf);
66 while (--argc > 0 && (++argv)[0][0]=='-')
67 switch (argv[0][1]) {
68
69 case 'y':
70 yflag++;
71 continue;
72
73 case 'h':
74 hflag = 0;
75 continue;
76
77 case 's':
78 sflag++;
79 continue;
80
81 case 'v':
82 vflag++;
83 continue;
84
85 case 'b':
86 bflag++;
87 continue;
88
89 case 'l':
90 lflag++;
91 continue;
92
93 case 'c':
94 cflag++;
95 continue;
96
97 case 'n':
98 nflag++;
99 continue;
100
101 case 'e':
102 --argc;
103 ++argv;
104 goto out;
105
106 default:
107 errexit("grep: unknown flag\n", (char *)NULL);
108 continue;
109 }
110out:
111 if (argc<=0)
112 exit(2);
113 if (yflag) {
114 register char *p, *s;
115 for (s = ybuf, p = *argv; *p; ) {
116 if (*p == '\\') {
117 *s++ = *p++;
118 if (*p)
119 *s++ = *p++;
120 } else if (*p == '[') {
121 while (*p != '\0' && *p != ']')
122 *s++ = *p++;
123 } else if (islower(*p)) {
124 *s++ = '[';
125 *s++ = toupper(*p);
126 *s++ = *p++;
127 *s++ = ']';
128 } else
129 *s++ = *p++;
130 if (s >= ybuf+ESIZE-5)
131 errexit("grep: argument too long\n", (char *)NULL);
132 }
133 *s = '\0';
134 *argv = ybuf;
135 }
136 compile(*argv);
137 nfile = --argc;
138 if (argc<=0) {
139 if (lflag)
140 exit(1);
141 execute((char *)NULL);
142 } else while (--argc >= 0) {
143 argv++;
144 execute(*argv);
145 }
146 exit(nsucc == 0);
147}
148
149compile(astr)
150char *astr;
151{
152 register c;
153 register char *ep, *sp;
154 char *cstart;
155 char *lastep;
156 int cclcnt;
157 char bracket[NBRA], *bracketp;
158 int closed;
159 char numbra;
160 char neg;
161
162 ep = expbuf;
163 sp = astr;
164 lastep = 0;
165 bracketp = bracket;
166 closed = numbra = 0;
167 if (*sp == '^') {
168 circf++;
169 sp++;
170 }
171 for (;;) {
172 if (ep >= &expbuf[ESIZE])
173 goto cerror;
174 if ((c = *sp++) != '*')
175 lastep = ep;
176 switch (c) {
177
178 case '\0':
179 *ep++ = CEOF;
180 return;
181
182 case '.':
183 *ep++ = CDOT;
184 continue;
185
186 case '*':
187 if (lastep==0 || *lastep==CBRA || *lastep==CKET)
188 goto defchar;
189 *lastep |= STAR;
190 continue;
191
192 case '$':
193 if (*sp != '\0')
194 goto defchar;
195 *ep++ = CDOL;
196 continue;
197
198 case '[':
199 if(&ep[17] >= &expbuf[ESIZE])
200 goto cerror;
201 *ep++ = CCL;
202 neg = 0;
203 if((c = *sp++) == '^') {
204 neg = 1;
205 c = *sp++;
206 }
207 cstart = sp;
208 do {
209 if (c=='\0')
210 goto cerror;
211 if (c=='-' && sp>cstart && *sp!=']') {
212 for (c = sp[-2]; c<*sp; c++)
213 ep[c>>3] |= bittab[c&07];
214 sp++;
215 }
216 ep[c>>3] |= bittab[c&07];
217 } while((c = *sp++) != ']');
218 if(neg) {
219 for(cclcnt = 0; cclcnt < 16; cclcnt++)
220 ep[cclcnt] ^= -1;
221 ep[0] &= 0376;
222 }
223
224 ep += 16;
225
226 continue;
227
228 case '\\':
229 if((c = *sp++) == '(') {
230 if(numbra >= NBRA) {
231 goto cerror;
232 }
233 *bracketp++ = numbra;
234 *ep++ = CBRA;
235 *ep++ = numbra++;
236 continue;
237 }
238 if(c == ')') {
239 if(bracketp <= bracket) {
240 goto cerror;
241 }
242 *ep++ = CKET;
243 *ep++ = *--bracketp;
244 closed++;
245 continue;
246 }
247
248 if(c >= '1' && c <= '9') {
249 if((c -= '1') >= closed)
250 goto cerror;
251 *ep++ = CBACK;
252 *ep++ = c;
253 continue;
254 }
255
256 defchar:
257 default:
258 *ep++ = CCHR;
259 *ep++ = c;
260 }
261 }
262 cerror:
263 errexit("grep: RE error\n", (char *)NULL);
264}
265
266execute(file)
267char *file;
268{
269 register char *p1, *p2;
270 register c;
271
272 if (file) {
273 if (freopen(file, "r", stdin) == NULL)
274 errexit("grep: can't open %s\n", file);
275 }
276 lnum = 0;
277 tln = 0;
278 for (;;) {
279 lnum++;
280 p1 = linebuf;
281 while ((c = getchar()) != '\n') {
282 if (c == EOF) {
283 if (cflag) {
284 if (nfile>1)
285 printf("%s:", file);
286 printf("%D\n", tln);
287 fflush(stdout);
288 }
289 return;
290 }
291 *p1++ = c;
292 if (p1 >= &linebuf[LBSIZE-1])
293 break;
294 }
295 *p1++ = '\0';
296 p1 = linebuf;
297 p2 = expbuf;
298 if (circf) {
299 if (advance(p1, p2))
300 goto found;
301 goto nfound;
302 }
303 /* fast check for first character */
304 if (*p2==CCHR) {
305 c = p2[1];
306 do {
307 if (*p1!=c)
308 continue;
309 if (advance(p1, p2))
310 goto found;
311 } while (*p1++);
312 goto nfound;
313 }
314 /* regular algorithm */
315 do {
316 if (advance(p1, p2))
317 goto found;
318 } while (*p1++);
319 nfound:
320 if (vflag)
321 succeed(file);
322 continue;
323 found:
324 if (vflag==0)
325 succeed(file);
326 }
327}
328
329advance(lp, ep)
330register char *lp, *ep;
331{
332 register char *curlp;
333 char c;
334 char *bbeg;
335 int ct;
336
337 for (;;) switch (*ep++) {
338
339 case CCHR:
340 if (*ep++ == *lp++)
341 continue;
342 return(0);
343
344 case CDOT:
345 if (*lp++)
346 continue;
347 return(0);
348
349 case CDOL:
350 if (*lp==0)
351 continue;
352 return(0);
353
354 case CEOF:
355 return(1);
356
357 case CCL:
358 c = *lp++ & 0177;
359 if(ep[c>>3] & bittab[c & 07]) {
360 ep += 16;
361 continue;
362 }
363 return(0);
364 case CBRA:
365 braslist[*ep++] = lp;
366 continue;
367
368 case CKET:
369 braelist[*ep++] = lp;
370 continue;
371
372 case CBACK:
373 bbeg = braslist[*ep];
374 if (braelist[*ep]==0)
375 return(0);
376 ct = braelist[*ep++] - bbeg;
377 if(ecmp(bbeg, lp, ct)) {
378 lp += ct;
379 continue;
380 }
381 return(0);
382
383 case CBACK|STAR:
384 bbeg = braslist[*ep];
385 if (braelist[*ep]==0)
386 return(0);
387 ct = braelist[*ep++] - bbeg;
388 curlp = lp;
389 while(ecmp(bbeg, lp, ct))
390 lp += ct;
391 while(lp >= curlp) {
392 if(advance(lp, ep)) return(1);
393 lp -= ct;
394 }
395 return(0);
396
397
398 case CDOT|STAR:
399 curlp = lp;
400 while (*lp++);
401 goto star;
402
403 case CCHR|STAR:
404 curlp = lp;
405 while (*lp++ == *ep);
406 ep++;
407 goto star;
408
409 case CCL|STAR:
410 curlp = lp;
411 do {
412 c = *lp++ & 0177;
413 } while(ep[c>>3] & bittab[c & 07]);
414 ep += 16;
415 goto star;
416
417 star:
418 if(--lp == curlp) {
419 continue;
420 }
421
422 if(*ep == CCHR) {
423 c = ep[1];
424 do {
425 if(*lp != c)
426 continue;
427 if(advance(lp, ep))
428 return(1);
429 } while(lp-- > curlp);
430 return(0);
431 }
432
433 do {
434 if (advance(lp, ep))
435 return(1);
436 } while (lp-- > curlp);
437 return(0);
438
439 default:
440 errexit("grep RE botch\n", (char *)NULL);
441 }
442}
443
444succeed(f)
445char *f;
446{
447 nsucc = 1;
448 if (sflag)
449 return;
450 if (cflag) {
451 tln++;
452 return;
453 }
454 if (lflag) {
455 printf("%s\n", f);
456 fflush(stdout);
457 fseek(stdin, 0l, 2);
458 return;
459 }
460 if (nfile > 1 && hflag)
461 printf("%s:", f);
462 if (bflag)
463 printf("%u:", blkno);
464 if (nflag)
465 printf("%ld:", lnum);
466 printf("%s\n", linebuf);
467 fflush(stdout);
468}
469
470ecmp(a, b, count)
471char *a, *b;
472{
473 register cc = count;
474 while(cc--)
475 if(*a++ != *b++) return(0);
476 return(1);
477}
478
479errexit(s, f)
480char *s, *f;
481{
482 fprintf(stderr, s, f);
483 exit(2);
484}