114464Ssam #ifndef lint 2*33378Sbostic static char sccsid[] = "@(#)old.bin.grep.c 4.8 (Berkeley) 01/21/88"; 314464Ssam #endif 46641Smckusick 56641Smckusick /* 66641Smckusick * grep -- print lines matching (or not matching) a pattern 76641Smckusick * 86641Smckusick * status returns: 96641Smckusick * 0 - ok, and some matches 106641Smckusick * 1 - ok, but no matches 116641Smckusick * 2 - some error 126641Smckusick */ 136641Smckusick 146641Smckusick #include <stdio.h> 156641Smckusick #include <ctype.h> 166641Smckusick 176641Smckusick #define CBRA 1 186641Smckusick #define CCHR 2 196641Smckusick #define CDOT 4 206641Smckusick #define CCL 6 216641Smckusick #define NCCL 8 226641Smckusick #define CDOL 10 236641Smckusick #define CEOF 11 246641Smckusick #define CKET 12 2513484Ssam #define CBRC 14 2613484Ssam #define CLET 15 276641Smckusick #define CBACK 18 286641Smckusick 296641Smckusick #define STAR 01 306641Smckusick 316641Smckusick #define LBSIZE BUFSIZ 326641Smckusick #define ESIZE 256 336641Smckusick #define NBRA 9 346641Smckusick 356641Smckusick char expbuf[ESIZE]; 366641Smckusick long lnum; 376641Smckusick char linebuf[LBSIZE+1]; 386641Smckusick char ybuf[ESIZE]; 396641Smckusick int bflag; 406641Smckusick int lflag; 416641Smckusick int nflag; 426641Smckusick int cflag; 436641Smckusick int vflag; 446641Smckusick int nfile; 456641Smckusick int hflag = 1; 4632365Sbostic int oflag; 476641Smckusick int sflag; 486641Smckusick int yflag; 4913484Ssam int wflag; 5011579Sedward int retcode = 0; 516641Smckusick int circf; 526641Smckusick int blkno; 536641Smckusick long tln; 546641Smckusick int nsucc; 556641Smckusick char *braslist[NBRA]; 566641Smckusick char *braelist[NBRA]; 576641Smckusick char bittab[] = { 586641Smckusick 1, 596641Smckusick 2, 606641Smckusick 4, 616641Smckusick 8, 626641Smckusick 16, 636641Smckusick 32, 646641Smckusick 64, 656641Smckusick 128 666641Smckusick }; 676641Smckusick 686641Smckusick main(argc, argv) 69*33378Sbostic int argc; 70*33378Sbostic char **argv; 716641Smckusick { 72*33378Sbostic extern char *optarg; 73*33378Sbostic extern int optind; 74*33378Sbostic int ch; 756641Smckusick 76*33378Sbostic while ((ch = getopt(argc, argv, "iywohsvblcne")) != EOF) 77*33378Sbostic switch((char)ch) { 7813484Ssam case 'i': 796641Smckusick case 'y': 806641Smckusick yflag++; 81*33378Sbostic break; 8213484Ssam case 'w': 8313484Ssam wflag++; 84*33378Sbostic break; 8532365Sbostic case 'o': 8632365Sbostic oflag++; 87*33378Sbostic break; 886641Smckusick case 'h': 896641Smckusick hflag = 0; 90*33378Sbostic break; 916641Smckusick case 's': 926641Smckusick sflag++; 93*33378Sbostic break; 946641Smckusick case 'v': 956641Smckusick vflag++; 96*33378Sbostic break; 976641Smckusick case 'b': 986641Smckusick bflag++; 99*33378Sbostic break; 1006641Smckusick case 'l': 1016641Smckusick lflag++; 102*33378Sbostic break; 1036641Smckusick case 'c': 1046641Smckusick cflag++; 105*33378Sbostic break; 1066641Smckusick case 'n': 1076641Smckusick nflag++; 108*33378Sbostic break; 1096641Smckusick case 'e': 110*33378Sbostic argv += optind; 111*33378Sbostic argc -= optind; 112*33378Sbostic *argv = optarg; 1136641Smckusick goto out; 114*33378Sbostic case '?': 1156641Smckusick default: 1166641Smckusick errexit("grep: unknown flag\n", (char *)NULL); 1176641Smckusick } 118*33378Sbostic argv += optind; 119*33378Sbostic argc -= optind; 120*33378Sbostic 1216641Smckusick out: 1226641Smckusick if (argc<=0) 1236641Smckusick exit(2); 1246641Smckusick if (yflag) { 1256641Smckusick register char *p, *s; 1266641Smckusick for (s = ybuf, p = *argv; *p; ) { 1276641Smckusick if (*p == '\\') { 1286641Smckusick *s++ = *p++; 1296641Smckusick if (*p) 1306641Smckusick *s++ = *p++; 1316641Smckusick } else if (*p == '[') { 1326641Smckusick while (*p != '\0' && *p != ']') 1336641Smckusick *s++ = *p++; 1346641Smckusick } else if (islower(*p)) { 1356641Smckusick *s++ = '['; 1366641Smckusick *s++ = toupper(*p); 1376641Smckusick *s++ = *p++; 1386641Smckusick *s++ = ']'; 1396641Smckusick } else 1406641Smckusick *s++ = *p++; 1416641Smckusick if (s >= ybuf+ESIZE-5) 1426641Smckusick errexit("grep: argument too long\n", (char *)NULL); 1436641Smckusick } 1446641Smckusick *s = '\0'; 1456641Smckusick *argv = ybuf; 1466641Smckusick } 1476641Smckusick compile(*argv); 1486641Smckusick nfile = --argc; 1496641Smckusick if (argc<=0) { 1506641Smckusick if (lflag) 1516641Smckusick exit(1); 1526641Smckusick execute((char *)NULL); 1536641Smckusick } else while (--argc >= 0) { 1546641Smckusick argv++; 1556641Smckusick execute(*argv); 1566641Smckusick } 15711579Sedward exit(retcode != 0 ? retcode : nsucc == 0); 1586641Smckusick } 1596641Smckusick 1606641Smckusick compile(astr) 1616641Smckusick char *astr; 1626641Smckusick { 1636641Smckusick register c; 1646641Smckusick register char *ep, *sp; 1656641Smckusick char *cstart; 1666641Smckusick char *lastep; 1676641Smckusick int cclcnt; 1686641Smckusick char bracket[NBRA], *bracketp; 1696641Smckusick int closed; 1706641Smckusick char numbra; 1716641Smckusick char neg; 1726641Smckusick 1736641Smckusick ep = expbuf; 1746641Smckusick sp = astr; 1756641Smckusick lastep = 0; 1766641Smckusick bracketp = bracket; 1776641Smckusick closed = numbra = 0; 1786641Smckusick if (*sp == '^') { 1796641Smckusick circf++; 1806641Smckusick sp++; 1816641Smckusick } 18213484Ssam if (wflag) 18313484Ssam *ep++ = CBRC; 1846641Smckusick for (;;) { 1856641Smckusick if (ep >= &expbuf[ESIZE]) 1866641Smckusick goto cerror; 1876641Smckusick if ((c = *sp++) != '*') 1886641Smckusick lastep = ep; 1896641Smckusick switch (c) { 1906641Smckusick 1916641Smckusick case '\0': 19213484Ssam if (wflag) 19313484Ssam *ep++ = CLET; 1946641Smckusick *ep++ = CEOF; 1956641Smckusick return; 1966641Smckusick 1976641Smckusick case '.': 1986641Smckusick *ep++ = CDOT; 1996641Smckusick continue; 2006641Smckusick 2016641Smckusick case '*': 20213484Ssam if (lastep==0 || *lastep==CBRA || *lastep==CKET || 20313484Ssam *lastep == CBRC || *lastep == CLET) 2046641Smckusick goto defchar; 2056641Smckusick *lastep |= STAR; 2066641Smckusick continue; 2076641Smckusick 2086641Smckusick case '$': 2096641Smckusick if (*sp != '\0') 2106641Smckusick goto defchar; 2116641Smckusick *ep++ = CDOL; 2126641Smckusick continue; 2136641Smckusick 2146641Smckusick case '[': 2156641Smckusick if(&ep[17] >= &expbuf[ESIZE]) 2166641Smckusick goto cerror; 2176641Smckusick *ep++ = CCL; 2186641Smckusick neg = 0; 2196641Smckusick if((c = *sp++) == '^') { 2206641Smckusick neg = 1; 2216641Smckusick c = *sp++; 2226641Smckusick } 2236641Smckusick cstart = sp; 2246641Smckusick do { 2256641Smckusick if (c=='\0') 2266641Smckusick goto cerror; 2276641Smckusick if (c=='-' && sp>cstart && *sp!=']') { 2286641Smckusick for (c = sp[-2]; c<*sp; c++) 2296641Smckusick ep[c>>3] |= bittab[c&07]; 2306641Smckusick sp++; 2316641Smckusick } 2326641Smckusick ep[c>>3] |= bittab[c&07]; 2336641Smckusick } while((c = *sp++) != ']'); 2346641Smckusick if(neg) { 2356641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++) 2366641Smckusick ep[cclcnt] ^= -1; 2376641Smckusick ep[0] &= 0376; 2386641Smckusick } 2396641Smckusick 2406641Smckusick ep += 16; 2416641Smckusick 2426641Smckusick continue; 2436641Smckusick 2446641Smckusick case '\\': 24513484Ssam if((c = *sp++) == 0) 24613484Ssam goto cerror; 24713484Ssam if(c == '<') { 24813484Ssam *ep++ = CBRC; 24913484Ssam continue; 25013484Ssam } 25113484Ssam if(c == '>') { 25213484Ssam *ep++ = CLET; 25313484Ssam continue; 25413484Ssam } 25513484Ssam if(c == '(') { 2566641Smckusick if(numbra >= NBRA) { 2576641Smckusick goto cerror; 2586641Smckusick } 2596641Smckusick *bracketp++ = numbra; 2606641Smckusick *ep++ = CBRA; 2616641Smckusick *ep++ = numbra++; 2626641Smckusick continue; 2636641Smckusick } 2646641Smckusick if(c == ')') { 2656641Smckusick if(bracketp <= bracket) { 2666641Smckusick goto cerror; 2676641Smckusick } 2686641Smckusick *ep++ = CKET; 2696641Smckusick *ep++ = *--bracketp; 2706641Smckusick closed++; 2716641Smckusick continue; 2726641Smckusick } 2736641Smckusick 2746641Smckusick if(c >= '1' && c <= '9') { 2756641Smckusick if((c -= '1') >= closed) 2766641Smckusick goto cerror; 2776641Smckusick *ep++ = CBACK; 2786641Smckusick *ep++ = c; 2796641Smckusick continue; 2806641Smckusick } 2816641Smckusick 2826641Smckusick defchar: 2836641Smckusick default: 2846641Smckusick *ep++ = CCHR; 2856641Smckusick *ep++ = c; 2866641Smckusick } 2876641Smckusick } 2886641Smckusick cerror: 2896641Smckusick errexit("grep: RE error\n", (char *)NULL); 2906641Smckusick } 2916641Smckusick 2926641Smckusick execute(file) 2936641Smckusick char *file; 2946641Smckusick { 2956641Smckusick register char *p1, *p2; 2966641Smckusick register c; 2976641Smckusick 2986641Smckusick if (file) { 29911579Sedward if (freopen(file, "r", stdin) == NULL) { 30012096Smckusick perror(file); 30111579Sedward retcode = 2; 30211579Sedward } 3036641Smckusick } 3046641Smckusick lnum = 0; 3056641Smckusick tln = 0; 3066641Smckusick for (;;) { 3076641Smckusick lnum++; 3086641Smckusick p1 = linebuf; 3096641Smckusick while ((c = getchar()) != '\n') { 3106641Smckusick if (c == EOF) { 3116641Smckusick if (cflag) { 3126641Smckusick if (nfile>1) 3136641Smckusick printf("%s:", file); 3146641Smckusick printf("%D\n", tln); 3156641Smckusick fflush(stdout); 3166641Smckusick } 3176641Smckusick return; 3186641Smckusick } 3196641Smckusick *p1++ = c; 3206641Smckusick if (p1 >= &linebuf[LBSIZE-1]) 3216641Smckusick break; 3226641Smckusick } 3236641Smckusick *p1++ = '\0'; 3246641Smckusick p1 = linebuf; 3256641Smckusick p2 = expbuf; 3266641Smckusick if (circf) { 3276641Smckusick if (advance(p1, p2)) 3286641Smckusick goto found; 3296641Smckusick goto nfound; 3306641Smckusick } 3316641Smckusick /* fast check for first character */ 3326641Smckusick if (*p2==CCHR) { 3336641Smckusick c = p2[1]; 3346641Smckusick do { 3356641Smckusick if (*p1!=c) 3366641Smckusick continue; 3376641Smckusick if (advance(p1, p2)) 3386641Smckusick goto found; 3396641Smckusick } while (*p1++); 3406641Smckusick goto nfound; 3416641Smckusick } 3426641Smckusick /* regular algorithm */ 3436641Smckusick do { 3446641Smckusick if (advance(p1, p2)) 3456641Smckusick goto found; 3466641Smckusick } while (*p1++); 3476641Smckusick nfound: 3486641Smckusick if (vflag) 3496641Smckusick succeed(file); 3506641Smckusick continue; 3516641Smckusick found: 3526641Smckusick if (vflag==0) 3536641Smckusick succeed(file); 3546641Smckusick } 3556641Smckusick } 3566641Smckusick 3576641Smckusick advance(lp, ep) 3586641Smckusick register char *lp, *ep; 3596641Smckusick { 3606641Smckusick register char *curlp; 3616641Smckusick char c; 3626641Smckusick char *bbeg; 3636641Smckusick int ct; 3646641Smckusick 3656641Smckusick for (;;) switch (*ep++) { 3666641Smckusick 3676641Smckusick case CCHR: 3686641Smckusick if (*ep++ == *lp++) 3696641Smckusick continue; 3706641Smckusick return(0); 3716641Smckusick 3726641Smckusick case CDOT: 3736641Smckusick if (*lp++) 3746641Smckusick continue; 3756641Smckusick return(0); 3766641Smckusick 3776641Smckusick case CDOL: 3786641Smckusick if (*lp==0) 3796641Smckusick continue; 3806641Smckusick return(0); 3816641Smckusick 3826641Smckusick case CEOF: 3836641Smckusick return(1); 3846641Smckusick 3856641Smckusick case CCL: 3866641Smckusick c = *lp++ & 0177; 3876641Smckusick if(ep[c>>3] & bittab[c & 07]) { 3886641Smckusick ep += 16; 3896641Smckusick continue; 3906641Smckusick } 3916641Smckusick return(0); 3926641Smckusick case CBRA: 3936641Smckusick braslist[*ep++] = lp; 3946641Smckusick continue; 3956641Smckusick 3966641Smckusick case CKET: 3976641Smckusick braelist[*ep++] = lp; 3986641Smckusick continue; 3996641Smckusick 4006641Smckusick case CBACK: 4016641Smckusick bbeg = braslist[*ep]; 4026641Smckusick if (braelist[*ep]==0) 4036641Smckusick return(0); 4046641Smckusick ct = braelist[*ep++] - bbeg; 4056641Smckusick if(ecmp(bbeg, lp, ct)) { 4066641Smckusick lp += ct; 4076641Smckusick continue; 4086641Smckusick } 4096641Smckusick return(0); 4106641Smckusick 4116641Smckusick case CBACK|STAR: 4126641Smckusick bbeg = braslist[*ep]; 4136641Smckusick if (braelist[*ep]==0) 4146641Smckusick return(0); 4156641Smckusick ct = braelist[*ep++] - bbeg; 4166641Smckusick curlp = lp; 4176641Smckusick while(ecmp(bbeg, lp, ct)) 4186641Smckusick lp += ct; 4196641Smckusick while(lp >= curlp) { 4206641Smckusick if(advance(lp, ep)) return(1); 4216641Smckusick lp -= ct; 4226641Smckusick } 4236641Smckusick return(0); 4246641Smckusick 4256641Smckusick 4266641Smckusick case CDOT|STAR: 4276641Smckusick curlp = lp; 4286641Smckusick while (*lp++); 4296641Smckusick goto star; 4306641Smckusick 4316641Smckusick case CCHR|STAR: 4326641Smckusick curlp = lp; 4336641Smckusick while (*lp++ == *ep); 4346641Smckusick ep++; 4356641Smckusick goto star; 4366641Smckusick 4376641Smckusick case CCL|STAR: 4386641Smckusick curlp = lp; 4396641Smckusick do { 4406641Smckusick c = *lp++ & 0177; 4416641Smckusick } while(ep[c>>3] & bittab[c & 07]); 4426641Smckusick ep += 16; 4436641Smckusick goto star; 4446641Smckusick 4456641Smckusick star: 4466641Smckusick if(--lp == curlp) { 4476641Smckusick continue; 4486641Smckusick } 4496641Smckusick 4506641Smckusick if(*ep == CCHR) { 4516641Smckusick c = ep[1]; 4526641Smckusick do { 4536641Smckusick if(*lp != c) 4546641Smckusick continue; 4556641Smckusick if(advance(lp, ep)) 4566641Smckusick return(1); 4576641Smckusick } while(lp-- > curlp); 4586641Smckusick return(0); 4596641Smckusick } 4606641Smckusick 4616641Smckusick do { 4626641Smckusick if (advance(lp, ep)) 4636641Smckusick return(1); 4646641Smckusick } while (lp-- > curlp); 4656641Smckusick return(0); 4666641Smckusick 46713484Ssam case CBRC: 46813484Ssam if (lp == expbuf) 46913484Ssam continue; 47013484Ssam #define uletter(c) (isalpha(c) || (c) == '_') 47113484Ssam if (uletter(*lp) || isdigit(*lp)) 47213484Ssam if (!uletter(lp[-1]) && !isdigit(lp[-1])) 47313484Ssam continue; 47413484Ssam return (0); 47513484Ssam 47613484Ssam case CLET: 47713484Ssam if (!uletter(*lp) && !isdigit(*lp)) 47813484Ssam continue; 47913484Ssam return (0); 48013484Ssam 4816641Smckusick default: 4826641Smckusick errexit("grep RE botch\n", (char *)NULL); 4836641Smckusick } 4846641Smckusick } 4856641Smckusick 4866641Smckusick succeed(f) 4876641Smckusick char *f; 4886641Smckusick { 4896641Smckusick nsucc = 1; 4906641Smckusick if (sflag) 4916641Smckusick return; 4926641Smckusick if (cflag) { 4936641Smckusick tln++; 4946641Smckusick return; 4956641Smckusick } 4966641Smckusick if (lflag) { 4976641Smckusick printf("%s\n", f); 4986641Smckusick fflush(stdout); 4996641Smckusick fseek(stdin, 0l, 2); 5006641Smckusick return; 5016641Smckusick } 50232365Sbostic if (nfile > 1 && hflag || oflag) 5036641Smckusick printf("%s:", f); 5046641Smckusick if (bflag) 5056641Smckusick printf("%u:", blkno); 5066641Smckusick if (nflag) 5076641Smckusick printf("%ld:", lnum); 5086641Smckusick printf("%s\n", linebuf); 5096641Smckusick fflush(stdout); 5106641Smckusick } 5116641Smckusick 5126641Smckusick ecmp(a, b, count) 5136641Smckusick char *a, *b; 5146641Smckusick { 5156641Smckusick register cc = count; 5166641Smckusick while(cc--) 5176641Smckusick if(*a++ != *b++) return(0); 5186641Smckusick return(1); 5196641Smckusick } 5206641Smckusick 5216641Smckusick errexit(s, f) 5226641Smckusick char *s, *f; 5236641Smckusick { 5246641Smckusick fprintf(stderr, s, f); 5256641Smckusick exit(2); 5266641Smckusick } 527