148264Sbostic /*-
2*62021Sbostic * Copyright (c) 1991, 1993
3*62021Sbostic * The Regents of the University of California. All rights reserved.
448264Sbostic *
548264Sbostic * %sccs.include.proprietary.c%
648264Sbostic */
748264Sbostic
814464Ssam #ifndef lint
9*62021Sbostic static char copyright[] =
10*62021Sbostic "@(#) Copyright (c) 1991, 1993\n\
11*62021Sbostic The Regents of the University of California. All rights reserved.\n";
1248264Sbostic #endif /* not lint */
136641Smckusick
1448264Sbostic #ifndef lint
15*62021Sbostic static char sccsid[] = "@(#)old.bin.grep.c 8.1 (Berkeley) 06/06/93";
1648264Sbostic #endif /* not lint */
1748264Sbostic
186641Smckusick /*
196641Smckusick * grep -- print lines matching (or not matching) a pattern
206641Smckusick *
216641Smckusick * status returns:
226641Smckusick * 0 - ok, and some matches
236641Smckusick * 1 - ok, but no matches
246641Smckusick * 2 - some error
256641Smckusick */
266641Smckusick
276641Smckusick #include <stdio.h>
286641Smckusick #include <ctype.h>
296641Smckusick
306641Smckusick #define CBRA 1
316641Smckusick #define CCHR 2
326641Smckusick #define CDOT 4
336641Smckusick #define CCL 6
346641Smckusick #define NCCL 8
356641Smckusick #define CDOL 10
366641Smckusick #define CEOF 11
376641Smckusick #define CKET 12
3813484Ssam #define CBRC 14
3913484Ssam #define CLET 15
406641Smckusick #define CBACK 18
416641Smckusick
426641Smckusick #define STAR 01
436641Smckusick
446641Smckusick #define LBSIZE BUFSIZ
456641Smckusick #define ESIZE 256
466641Smckusick #define NBRA 9
476641Smckusick
486641Smckusick char expbuf[ESIZE];
496641Smckusick long lnum;
506641Smckusick char linebuf[LBSIZE+1];
516641Smckusick char ybuf[ESIZE];
526641Smckusick int bflag;
536641Smckusick int lflag;
546641Smckusick int nflag;
556641Smckusick int cflag;
566641Smckusick int vflag;
576641Smckusick int nfile;
586641Smckusick int hflag = 1;
5932365Sbostic int oflag;
606641Smckusick int sflag;
616641Smckusick int yflag;
6213484Ssam int wflag;
6311579Sedward int retcode = 0;
646641Smckusick int circf;
656641Smckusick int blkno;
666641Smckusick long tln;
676641Smckusick int nsucc;
686641Smckusick char *braslist[NBRA];
696641Smckusick char *braelist[NBRA];
706641Smckusick char bittab[] = {
716641Smckusick 1,
726641Smckusick 2,
736641Smckusick 4,
746641Smckusick 8,
756641Smckusick 16,
766641Smckusick 32,
776641Smckusick 64,
786641Smckusick 128
796641Smckusick };
806641Smckusick
main(argc,argv)816641Smckusick main(argc, argv)
8233378Sbostic int argc;
8333378Sbostic char **argv;
846641Smckusick {
8533378Sbostic extern char *optarg;
8633378Sbostic extern int optind;
8733378Sbostic int ch;
886641Smckusick
8954252Sbostic while ((ch = getopt(argc, argv, "iywohsvblcne:")) != EOF)
9033378Sbostic switch((char)ch) {
9113484Ssam case 'i':
926641Smckusick case 'y':
936641Smckusick yflag++;
9433378Sbostic break;
9513484Ssam case 'w':
9613484Ssam wflag++;
9733378Sbostic break;
9832365Sbostic case 'o':
9932365Sbostic oflag++;
10033378Sbostic break;
1016641Smckusick case 'h':
1026641Smckusick hflag = 0;
10333378Sbostic break;
1046641Smckusick case 's':
1056641Smckusick sflag++;
10633378Sbostic break;
1076641Smckusick case 'v':
1086641Smckusick vflag++;
10933378Sbostic break;
1106641Smckusick case 'b':
1116641Smckusick bflag++;
11233378Sbostic break;
1136641Smckusick case 'l':
1146641Smckusick lflag++;
11533378Sbostic break;
1166641Smckusick case 'c':
1176641Smckusick cflag++;
11833378Sbostic break;
1196641Smckusick case 'n':
1206641Smckusick nflag++;
12133378Sbostic break;
1226641Smckusick case 'e':
12354252Sbostic argv += optind - 1;
12454252Sbostic argc -= optind - 1;
12533378Sbostic *argv = optarg;
1266641Smckusick goto out;
12733378Sbostic case '?':
1286641Smckusick default:
1296641Smckusick errexit("grep: unknown flag\n", (char *)NULL);
1306641Smckusick }
13133378Sbostic argv += optind;
13233378Sbostic argc -= optind;
13333378Sbostic
1346641Smckusick out:
1356641Smckusick if (argc<=0)
1366641Smckusick exit(2);
1376641Smckusick if (yflag) {
1386641Smckusick register char *p, *s;
1396641Smckusick for (s = ybuf, p = *argv; *p; ) {
1406641Smckusick if (*p == '\\') {
1416641Smckusick *s++ = *p++;
1426641Smckusick if (*p)
1436641Smckusick *s++ = *p++;
1446641Smckusick } else if (*p == '[') {
1456641Smckusick while (*p != '\0' && *p != ']')
1466641Smckusick *s++ = *p++;
1476641Smckusick } else if (islower(*p)) {
1486641Smckusick *s++ = '[';
1496641Smckusick *s++ = toupper(*p);
1506641Smckusick *s++ = *p++;
1516641Smckusick *s++ = ']';
1526641Smckusick } else
1536641Smckusick *s++ = *p++;
1546641Smckusick if (s >= ybuf+ESIZE-5)
1556641Smckusick errexit("grep: argument too long\n", (char *)NULL);
1566641Smckusick }
1576641Smckusick *s = '\0';
1586641Smckusick *argv = ybuf;
1596641Smckusick }
1606641Smckusick compile(*argv);
1616641Smckusick nfile = --argc;
1626641Smckusick if (argc<=0) {
1636641Smckusick if (lflag)
1646641Smckusick exit(1);
1656641Smckusick execute((char *)NULL);
1666641Smckusick } else while (--argc >= 0) {
1676641Smckusick argv++;
1686641Smckusick execute(*argv);
1696641Smckusick }
17011579Sedward exit(retcode != 0 ? retcode : nsucc == 0);
1716641Smckusick }
1726641Smckusick
compile(astr)1736641Smckusick compile(astr)
1746641Smckusick char *astr;
1756641Smckusick {
1766641Smckusick register c;
1776641Smckusick register char *ep, *sp;
1786641Smckusick char *cstart;
1796641Smckusick char *lastep;
1806641Smckusick int cclcnt;
1816641Smckusick char bracket[NBRA], *bracketp;
1826641Smckusick int closed;
1836641Smckusick char numbra;
1846641Smckusick char neg;
1856641Smckusick
1866641Smckusick ep = expbuf;
1876641Smckusick sp = astr;
1886641Smckusick lastep = 0;
1896641Smckusick bracketp = bracket;
1906641Smckusick closed = numbra = 0;
1916641Smckusick if (*sp == '^') {
1926641Smckusick circf++;
1936641Smckusick sp++;
1946641Smckusick }
19513484Ssam if (wflag)
19613484Ssam *ep++ = CBRC;
1976641Smckusick for (;;) {
1986641Smckusick if (ep >= &expbuf[ESIZE])
1996641Smckusick goto cerror;
2006641Smckusick if ((c = *sp++) != '*')
2016641Smckusick lastep = ep;
2026641Smckusick switch (c) {
2036641Smckusick
2046641Smckusick case '\0':
20513484Ssam if (wflag)
20613484Ssam *ep++ = CLET;
2076641Smckusick *ep++ = CEOF;
2086641Smckusick return;
2096641Smckusick
2106641Smckusick case '.':
2116641Smckusick *ep++ = CDOT;
2126641Smckusick continue;
2136641Smckusick
2146641Smckusick case '*':
21513484Ssam if (lastep==0 || *lastep==CBRA || *lastep==CKET ||
21613484Ssam *lastep == CBRC || *lastep == CLET)
2176641Smckusick goto defchar;
2186641Smckusick *lastep |= STAR;
2196641Smckusick continue;
2206641Smckusick
2216641Smckusick case '$':
2226641Smckusick if (*sp != '\0')
2236641Smckusick goto defchar;
2246641Smckusick *ep++ = CDOL;
2256641Smckusick continue;
2266641Smckusick
2276641Smckusick case '[':
2286641Smckusick if(&ep[17] >= &expbuf[ESIZE])
2296641Smckusick goto cerror;
2306641Smckusick *ep++ = CCL;
2316641Smckusick neg = 0;
2326641Smckusick if((c = *sp++) == '^') {
2336641Smckusick neg = 1;
2346641Smckusick c = *sp++;
2356641Smckusick }
2366641Smckusick cstart = sp;
2376641Smckusick do {
2386641Smckusick if (c=='\0')
2396641Smckusick goto cerror;
2406641Smckusick if (c=='-' && sp>cstart && *sp!=']') {
2416641Smckusick for (c = sp[-2]; c<*sp; c++)
2426641Smckusick ep[c>>3] |= bittab[c&07];
2436641Smckusick sp++;
2446641Smckusick }
2456641Smckusick ep[c>>3] |= bittab[c&07];
2466641Smckusick } while((c = *sp++) != ']');
2476641Smckusick if(neg) {
2486641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++)
2496641Smckusick ep[cclcnt] ^= -1;
2506641Smckusick ep[0] &= 0376;
2516641Smckusick }
2526641Smckusick
2536641Smckusick ep += 16;
2546641Smckusick
2556641Smckusick continue;
2566641Smckusick
2576641Smckusick case '\\':
25813484Ssam if((c = *sp++) == 0)
25913484Ssam goto cerror;
26013484Ssam if(c == '<') {
26113484Ssam *ep++ = CBRC;
26213484Ssam continue;
26313484Ssam }
26413484Ssam if(c == '>') {
26513484Ssam *ep++ = CLET;
26613484Ssam continue;
26713484Ssam }
26813484Ssam if(c == '(') {
2696641Smckusick if(numbra >= NBRA) {
2706641Smckusick goto cerror;
2716641Smckusick }
2726641Smckusick *bracketp++ = numbra;
2736641Smckusick *ep++ = CBRA;
2746641Smckusick *ep++ = numbra++;
2756641Smckusick continue;
2766641Smckusick }
2776641Smckusick if(c == ')') {
2786641Smckusick if(bracketp <= bracket) {
2796641Smckusick goto cerror;
2806641Smckusick }
2816641Smckusick *ep++ = CKET;
2826641Smckusick *ep++ = *--bracketp;
2836641Smckusick closed++;
2846641Smckusick continue;
2856641Smckusick }
2866641Smckusick
2876641Smckusick if(c >= '1' && c <= '9') {
2886641Smckusick if((c -= '1') >= closed)
2896641Smckusick goto cerror;
2906641Smckusick *ep++ = CBACK;
2916641Smckusick *ep++ = c;
2926641Smckusick continue;
2936641Smckusick }
2946641Smckusick
2956641Smckusick defchar:
2966641Smckusick default:
2976641Smckusick *ep++ = CCHR;
2986641Smckusick *ep++ = c;
2996641Smckusick }
3006641Smckusick }
3016641Smckusick cerror:
3026641Smckusick errexit("grep: RE error\n", (char *)NULL);
3036641Smckusick }
3046641Smckusick
execute(file)3056641Smckusick execute(file)
3066641Smckusick char *file;
3076641Smckusick {
3086641Smckusick register char *p1, *p2;
3096641Smckusick register c;
3106641Smckusick
3116641Smckusick if (file) {
31211579Sedward if (freopen(file, "r", stdin) == NULL) {
31312096Smckusick perror(file);
31411579Sedward retcode = 2;
31511579Sedward }
3166641Smckusick }
3176641Smckusick lnum = 0;
3186641Smckusick tln = 0;
3196641Smckusick for (;;) {
3206641Smckusick lnum++;
3216641Smckusick p1 = linebuf;
3226641Smckusick while ((c = getchar()) != '\n') {
3236641Smckusick if (c == EOF) {
3246641Smckusick if (cflag) {
3256641Smckusick if (nfile>1)
3266641Smckusick printf("%s:", file);
3276641Smckusick printf("%D\n", tln);
3286641Smckusick fflush(stdout);
3296641Smckusick }
3306641Smckusick return;
3316641Smckusick }
3326641Smckusick *p1++ = c;
3336641Smckusick if (p1 >= &linebuf[LBSIZE-1])
3346641Smckusick break;
3356641Smckusick }
3366641Smckusick *p1++ = '\0';
3376641Smckusick p1 = linebuf;
3386641Smckusick p2 = expbuf;
3396641Smckusick if (circf) {
3406641Smckusick if (advance(p1, p2))
3416641Smckusick goto found;
3426641Smckusick goto nfound;
3436641Smckusick }
3446641Smckusick /* fast check for first character */
3456641Smckusick if (*p2==CCHR) {
3466641Smckusick c = p2[1];
3476641Smckusick do {
3486641Smckusick if (*p1!=c)
3496641Smckusick continue;
3506641Smckusick if (advance(p1, p2))
3516641Smckusick goto found;
3526641Smckusick } while (*p1++);
3536641Smckusick goto nfound;
3546641Smckusick }
3556641Smckusick /* regular algorithm */
3566641Smckusick do {
3576641Smckusick if (advance(p1, p2))
3586641Smckusick goto found;
3596641Smckusick } while (*p1++);
3606641Smckusick nfound:
3616641Smckusick if (vflag)
3626641Smckusick succeed(file);
3636641Smckusick continue;
3646641Smckusick found:
3656641Smckusick if (vflag==0)
3666641Smckusick succeed(file);
3676641Smckusick }
3686641Smckusick }
3696641Smckusick
advance(lp,ep)3706641Smckusick advance(lp, ep)
3716641Smckusick register char *lp, *ep;
3726641Smckusick {
3736641Smckusick register char *curlp;
3746641Smckusick char c;
3756641Smckusick char *bbeg;
3766641Smckusick int ct;
3776641Smckusick
3786641Smckusick for (;;) switch (*ep++) {
3796641Smckusick
3806641Smckusick case CCHR:
3816641Smckusick if (*ep++ == *lp++)
3826641Smckusick continue;
3836641Smckusick return(0);
3846641Smckusick
3856641Smckusick case CDOT:
3866641Smckusick if (*lp++)
3876641Smckusick continue;
3886641Smckusick return(0);
3896641Smckusick
3906641Smckusick case CDOL:
3916641Smckusick if (*lp==0)
3926641Smckusick continue;
3936641Smckusick return(0);
3946641Smckusick
3956641Smckusick case CEOF:
3966641Smckusick return(1);
3976641Smckusick
3986641Smckusick case CCL:
3996641Smckusick c = *lp++ & 0177;
4006641Smckusick if(ep[c>>3] & bittab[c & 07]) {
4016641Smckusick ep += 16;
4026641Smckusick continue;
4036641Smckusick }
4046641Smckusick return(0);
4056641Smckusick case CBRA:
4066641Smckusick braslist[*ep++] = lp;
4076641Smckusick continue;
4086641Smckusick
4096641Smckusick case CKET:
4106641Smckusick braelist[*ep++] = lp;
4116641Smckusick continue;
4126641Smckusick
4136641Smckusick case CBACK:
4146641Smckusick bbeg = braslist[*ep];
4156641Smckusick if (braelist[*ep]==0)
4166641Smckusick return(0);
4176641Smckusick ct = braelist[*ep++] - bbeg;
4186641Smckusick if(ecmp(bbeg, lp, ct)) {
4196641Smckusick lp += ct;
4206641Smckusick continue;
4216641Smckusick }
4226641Smckusick return(0);
4236641Smckusick
4246641Smckusick case CBACK|STAR:
4256641Smckusick bbeg = braslist[*ep];
4266641Smckusick if (braelist[*ep]==0)
4276641Smckusick return(0);
4286641Smckusick ct = braelist[*ep++] - bbeg;
4296641Smckusick curlp = lp;
4306641Smckusick while(ecmp(bbeg, lp, ct))
4316641Smckusick lp += ct;
4326641Smckusick while(lp >= curlp) {
4336641Smckusick if(advance(lp, ep)) return(1);
4346641Smckusick lp -= ct;
4356641Smckusick }
4366641Smckusick return(0);
4376641Smckusick
4386641Smckusick
4396641Smckusick case CDOT|STAR:
4406641Smckusick curlp = lp;
4416641Smckusick while (*lp++);
4426641Smckusick goto star;
4436641Smckusick
4446641Smckusick case CCHR|STAR:
4456641Smckusick curlp = lp;
4466641Smckusick while (*lp++ == *ep);
4476641Smckusick ep++;
4486641Smckusick goto star;
4496641Smckusick
4506641Smckusick case CCL|STAR:
4516641Smckusick curlp = lp;
4526641Smckusick do {
4536641Smckusick c = *lp++ & 0177;
4546641Smckusick } while(ep[c>>3] & bittab[c & 07]);
4556641Smckusick ep += 16;
4566641Smckusick goto star;
4576641Smckusick
4586641Smckusick star:
4596641Smckusick if(--lp == curlp) {
4606641Smckusick continue;
4616641Smckusick }
4626641Smckusick
4636641Smckusick if(*ep == CCHR) {
4646641Smckusick c = ep[1];
4656641Smckusick do {
4666641Smckusick if(*lp != c)
4676641Smckusick continue;
4686641Smckusick if(advance(lp, ep))
4696641Smckusick return(1);
4706641Smckusick } while(lp-- > curlp);
4716641Smckusick return(0);
4726641Smckusick }
4736641Smckusick
4746641Smckusick do {
4756641Smckusick if (advance(lp, ep))
4766641Smckusick return(1);
4776641Smckusick } while (lp-- > curlp);
4786641Smckusick return(0);
4796641Smckusick
48013484Ssam case CBRC:
48113484Ssam if (lp == expbuf)
48213484Ssam continue;
48313484Ssam #define uletter(c) (isalpha(c) || (c) == '_')
48413484Ssam if (uletter(*lp) || isdigit(*lp))
48513484Ssam if (!uletter(lp[-1]) && !isdigit(lp[-1]))
48613484Ssam continue;
48713484Ssam return (0);
48813484Ssam
48913484Ssam case CLET:
49013484Ssam if (!uletter(*lp) && !isdigit(*lp))
49113484Ssam continue;
49213484Ssam return (0);
49313484Ssam
4946641Smckusick default:
4956641Smckusick errexit("grep RE botch\n", (char *)NULL);
4966641Smckusick }
4976641Smckusick }
4986641Smckusick
succeed(f)4996641Smckusick succeed(f)
5006641Smckusick char *f;
5016641Smckusick {
5026641Smckusick nsucc = 1;
5036641Smckusick if (sflag)
5046641Smckusick return;
5056641Smckusick if (cflag) {
5066641Smckusick tln++;
5076641Smckusick return;
5086641Smckusick }
5096641Smckusick if (lflag) {
5106641Smckusick printf("%s\n", f);
5116641Smckusick fflush(stdout);
5126641Smckusick fseek(stdin, 0l, 2);
5136641Smckusick return;
5146641Smckusick }
51532365Sbostic if (nfile > 1 && hflag || oflag)
5166641Smckusick printf("%s:", f);
5176641Smckusick if (bflag)
5186641Smckusick printf("%u:", blkno);
5196641Smckusick if (nflag)
5206641Smckusick printf("%ld:", lnum);
5216641Smckusick printf("%s\n", linebuf);
5226641Smckusick fflush(stdout);
5236641Smckusick }
5246641Smckusick
ecmp(a,b,count)5256641Smckusick ecmp(a, b, count)
5266641Smckusick char *a, *b;
5276641Smckusick {
5286641Smckusick register cc = count;
5296641Smckusick while(cc--)
5306641Smckusick if(*a++ != *b++) return(0);
5316641Smckusick return(1);
5326641Smckusick }
5336641Smckusick
errexit(s,f)5346641Smckusick errexit(s, f)
5356641Smckusick char *s, *f;
5366641Smckusick {
5376641Smckusick fprintf(stderr, s, f);
5386641Smckusick exit(2);
5396641Smckusick }
540