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