114464Ssam #ifndef lint 2*32365Sbostic static char sccsid[] = "@(#)old.bin.grep.c 4.7 (Berkeley) 10/07/87"; 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; 46*32365Sbostic 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) 696641Smckusick char **argv; 706641Smckusick { 716641Smckusick while (--argc > 0 && (++argv)[0][0]=='-') 726641Smckusick switch (argv[0][1]) { 736641Smckusick 7413484Ssam case 'i': 756641Smckusick case 'y': 766641Smckusick yflag++; 776641Smckusick continue; 786641Smckusick 7913484Ssam case 'w': 8013484Ssam wflag++; 8113484Ssam continue; 8213484Ssam 83*32365Sbostic case 'o': 84*32365Sbostic oflag++; 85*32365Sbostic continue; 86*32365Sbostic 876641Smckusick case 'h': 886641Smckusick hflag = 0; 896641Smckusick continue; 906641Smckusick 916641Smckusick case 's': 926641Smckusick sflag++; 936641Smckusick continue; 946641Smckusick 956641Smckusick case 'v': 966641Smckusick vflag++; 976641Smckusick continue; 986641Smckusick 996641Smckusick case 'b': 1006641Smckusick bflag++; 1016641Smckusick continue; 1026641Smckusick 1036641Smckusick case 'l': 1046641Smckusick lflag++; 1056641Smckusick continue; 1066641Smckusick 1076641Smckusick case 'c': 1086641Smckusick cflag++; 1096641Smckusick continue; 1106641Smckusick 1116641Smckusick case 'n': 1126641Smckusick nflag++; 1136641Smckusick continue; 1146641Smckusick 1156641Smckusick case 'e': 1166641Smckusick --argc; 1176641Smckusick ++argv; 1186641Smckusick goto out; 1196641Smckusick 1206641Smckusick default: 1216641Smckusick errexit("grep: unknown flag\n", (char *)NULL); 1226641Smckusick continue; 1236641Smckusick } 1246641Smckusick out: 1256641Smckusick if (argc<=0) 1266641Smckusick exit(2); 1276641Smckusick if (yflag) { 1286641Smckusick register char *p, *s; 1296641Smckusick for (s = ybuf, p = *argv; *p; ) { 1306641Smckusick if (*p == '\\') { 1316641Smckusick *s++ = *p++; 1326641Smckusick if (*p) 1336641Smckusick *s++ = *p++; 1346641Smckusick } else if (*p == '[') { 1356641Smckusick while (*p != '\0' && *p != ']') 1366641Smckusick *s++ = *p++; 1376641Smckusick } else if (islower(*p)) { 1386641Smckusick *s++ = '['; 1396641Smckusick *s++ = toupper(*p); 1406641Smckusick *s++ = *p++; 1416641Smckusick *s++ = ']'; 1426641Smckusick } else 1436641Smckusick *s++ = *p++; 1446641Smckusick if (s >= ybuf+ESIZE-5) 1456641Smckusick errexit("grep: argument too long\n", (char *)NULL); 1466641Smckusick } 1476641Smckusick *s = '\0'; 1486641Smckusick *argv = ybuf; 1496641Smckusick } 1506641Smckusick compile(*argv); 1516641Smckusick nfile = --argc; 1526641Smckusick if (argc<=0) { 1536641Smckusick if (lflag) 1546641Smckusick exit(1); 1556641Smckusick execute((char *)NULL); 1566641Smckusick } else while (--argc >= 0) { 1576641Smckusick argv++; 1586641Smckusick execute(*argv); 1596641Smckusick } 16011579Sedward exit(retcode != 0 ? retcode : nsucc == 0); 1616641Smckusick } 1626641Smckusick 1636641Smckusick compile(astr) 1646641Smckusick char *astr; 1656641Smckusick { 1666641Smckusick register c; 1676641Smckusick register char *ep, *sp; 1686641Smckusick char *cstart; 1696641Smckusick char *lastep; 1706641Smckusick int cclcnt; 1716641Smckusick char bracket[NBRA], *bracketp; 1726641Smckusick int closed; 1736641Smckusick char numbra; 1746641Smckusick char neg; 1756641Smckusick 1766641Smckusick ep = expbuf; 1776641Smckusick sp = astr; 1786641Smckusick lastep = 0; 1796641Smckusick bracketp = bracket; 1806641Smckusick closed = numbra = 0; 1816641Smckusick if (*sp == '^') { 1826641Smckusick circf++; 1836641Smckusick sp++; 1846641Smckusick } 18513484Ssam if (wflag) 18613484Ssam *ep++ = CBRC; 1876641Smckusick for (;;) { 1886641Smckusick if (ep >= &expbuf[ESIZE]) 1896641Smckusick goto cerror; 1906641Smckusick if ((c = *sp++) != '*') 1916641Smckusick lastep = ep; 1926641Smckusick switch (c) { 1936641Smckusick 1946641Smckusick case '\0': 19513484Ssam if (wflag) 19613484Ssam *ep++ = CLET; 1976641Smckusick *ep++ = CEOF; 1986641Smckusick return; 1996641Smckusick 2006641Smckusick case '.': 2016641Smckusick *ep++ = CDOT; 2026641Smckusick continue; 2036641Smckusick 2046641Smckusick case '*': 20513484Ssam if (lastep==0 || *lastep==CBRA || *lastep==CKET || 20613484Ssam *lastep == CBRC || *lastep == CLET) 2076641Smckusick goto defchar; 2086641Smckusick *lastep |= STAR; 2096641Smckusick continue; 2106641Smckusick 2116641Smckusick case '$': 2126641Smckusick if (*sp != '\0') 2136641Smckusick goto defchar; 2146641Smckusick *ep++ = CDOL; 2156641Smckusick continue; 2166641Smckusick 2176641Smckusick case '[': 2186641Smckusick if(&ep[17] >= &expbuf[ESIZE]) 2196641Smckusick goto cerror; 2206641Smckusick *ep++ = CCL; 2216641Smckusick neg = 0; 2226641Smckusick if((c = *sp++) == '^') { 2236641Smckusick neg = 1; 2246641Smckusick c = *sp++; 2256641Smckusick } 2266641Smckusick cstart = sp; 2276641Smckusick do { 2286641Smckusick if (c=='\0') 2296641Smckusick goto cerror; 2306641Smckusick if (c=='-' && sp>cstart && *sp!=']') { 2316641Smckusick for (c = sp[-2]; c<*sp; c++) 2326641Smckusick ep[c>>3] |= bittab[c&07]; 2336641Smckusick sp++; 2346641Smckusick } 2356641Smckusick ep[c>>3] |= bittab[c&07]; 2366641Smckusick } while((c = *sp++) != ']'); 2376641Smckusick if(neg) { 2386641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++) 2396641Smckusick ep[cclcnt] ^= -1; 2406641Smckusick ep[0] &= 0376; 2416641Smckusick } 2426641Smckusick 2436641Smckusick ep += 16; 2446641Smckusick 2456641Smckusick continue; 2466641Smckusick 2476641Smckusick case '\\': 24813484Ssam if((c = *sp++) == 0) 24913484Ssam goto cerror; 25013484Ssam if(c == '<') { 25113484Ssam *ep++ = CBRC; 25213484Ssam continue; 25313484Ssam } 25413484Ssam if(c == '>') { 25513484Ssam *ep++ = CLET; 25613484Ssam continue; 25713484Ssam } 25813484Ssam if(c == '(') { 2596641Smckusick if(numbra >= NBRA) { 2606641Smckusick goto cerror; 2616641Smckusick } 2626641Smckusick *bracketp++ = numbra; 2636641Smckusick *ep++ = CBRA; 2646641Smckusick *ep++ = numbra++; 2656641Smckusick continue; 2666641Smckusick } 2676641Smckusick if(c == ')') { 2686641Smckusick if(bracketp <= bracket) { 2696641Smckusick goto cerror; 2706641Smckusick } 2716641Smckusick *ep++ = CKET; 2726641Smckusick *ep++ = *--bracketp; 2736641Smckusick closed++; 2746641Smckusick continue; 2756641Smckusick } 2766641Smckusick 2776641Smckusick if(c >= '1' && c <= '9') { 2786641Smckusick if((c -= '1') >= closed) 2796641Smckusick goto cerror; 2806641Smckusick *ep++ = CBACK; 2816641Smckusick *ep++ = c; 2826641Smckusick continue; 2836641Smckusick } 2846641Smckusick 2856641Smckusick defchar: 2866641Smckusick default: 2876641Smckusick *ep++ = CCHR; 2886641Smckusick *ep++ = c; 2896641Smckusick } 2906641Smckusick } 2916641Smckusick cerror: 2926641Smckusick errexit("grep: RE error\n", (char *)NULL); 2936641Smckusick } 2946641Smckusick 2956641Smckusick execute(file) 2966641Smckusick char *file; 2976641Smckusick { 2986641Smckusick register char *p1, *p2; 2996641Smckusick register c; 3006641Smckusick 3016641Smckusick if (file) { 30211579Sedward if (freopen(file, "r", stdin) == NULL) { 30312096Smckusick perror(file); 30411579Sedward retcode = 2; 30511579Sedward } 3066641Smckusick } 3076641Smckusick lnum = 0; 3086641Smckusick tln = 0; 3096641Smckusick for (;;) { 3106641Smckusick lnum++; 3116641Smckusick p1 = linebuf; 3126641Smckusick while ((c = getchar()) != '\n') { 3136641Smckusick if (c == EOF) { 3146641Smckusick if (cflag) { 3156641Smckusick if (nfile>1) 3166641Smckusick printf("%s:", file); 3176641Smckusick printf("%D\n", tln); 3186641Smckusick fflush(stdout); 3196641Smckusick } 3206641Smckusick return; 3216641Smckusick } 3226641Smckusick *p1++ = c; 3236641Smckusick if (p1 >= &linebuf[LBSIZE-1]) 3246641Smckusick break; 3256641Smckusick } 3266641Smckusick *p1++ = '\0'; 3276641Smckusick p1 = linebuf; 3286641Smckusick p2 = expbuf; 3296641Smckusick if (circf) { 3306641Smckusick if (advance(p1, p2)) 3316641Smckusick goto found; 3326641Smckusick goto nfound; 3336641Smckusick } 3346641Smckusick /* fast check for first character */ 3356641Smckusick if (*p2==CCHR) { 3366641Smckusick c = p2[1]; 3376641Smckusick do { 3386641Smckusick if (*p1!=c) 3396641Smckusick continue; 3406641Smckusick if (advance(p1, p2)) 3416641Smckusick goto found; 3426641Smckusick } while (*p1++); 3436641Smckusick goto nfound; 3446641Smckusick } 3456641Smckusick /* regular algorithm */ 3466641Smckusick do { 3476641Smckusick if (advance(p1, p2)) 3486641Smckusick goto found; 3496641Smckusick } while (*p1++); 3506641Smckusick nfound: 3516641Smckusick if (vflag) 3526641Smckusick succeed(file); 3536641Smckusick continue; 3546641Smckusick found: 3556641Smckusick if (vflag==0) 3566641Smckusick succeed(file); 3576641Smckusick } 3586641Smckusick } 3596641Smckusick 3606641Smckusick advance(lp, ep) 3616641Smckusick register char *lp, *ep; 3626641Smckusick { 3636641Smckusick register char *curlp; 3646641Smckusick char c; 3656641Smckusick char *bbeg; 3666641Smckusick int ct; 3676641Smckusick 3686641Smckusick for (;;) switch (*ep++) { 3696641Smckusick 3706641Smckusick case CCHR: 3716641Smckusick if (*ep++ == *lp++) 3726641Smckusick continue; 3736641Smckusick return(0); 3746641Smckusick 3756641Smckusick case CDOT: 3766641Smckusick if (*lp++) 3776641Smckusick continue; 3786641Smckusick return(0); 3796641Smckusick 3806641Smckusick case CDOL: 3816641Smckusick if (*lp==0) 3826641Smckusick continue; 3836641Smckusick return(0); 3846641Smckusick 3856641Smckusick case CEOF: 3866641Smckusick return(1); 3876641Smckusick 3886641Smckusick case CCL: 3896641Smckusick c = *lp++ & 0177; 3906641Smckusick if(ep[c>>3] & bittab[c & 07]) { 3916641Smckusick ep += 16; 3926641Smckusick continue; 3936641Smckusick } 3946641Smckusick return(0); 3956641Smckusick case CBRA: 3966641Smckusick braslist[*ep++] = lp; 3976641Smckusick continue; 3986641Smckusick 3996641Smckusick case CKET: 4006641Smckusick braelist[*ep++] = lp; 4016641Smckusick continue; 4026641Smckusick 4036641Smckusick case CBACK: 4046641Smckusick bbeg = braslist[*ep]; 4056641Smckusick if (braelist[*ep]==0) 4066641Smckusick return(0); 4076641Smckusick ct = braelist[*ep++] - bbeg; 4086641Smckusick if(ecmp(bbeg, lp, ct)) { 4096641Smckusick lp += ct; 4106641Smckusick continue; 4116641Smckusick } 4126641Smckusick return(0); 4136641Smckusick 4146641Smckusick case CBACK|STAR: 4156641Smckusick bbeg = braslist[*ep]; 4166641Smckusick if (braelist[*ep]==0) 4176641Smckusick return(0); 4186641Smckusick ct = braelist[*ep++] - bbeg; 4196641Smckusick curlp = lp; 4206641Smckusick while(ecmp(bbeg, lp, ct)) 4216641Smckusick lp += ct; 4226641Smckusick while(lp >= curlp) { 4236641Smckusick if(advance(lp, ep)) return(1); 4246641Smckusick lp -= ct; 4256641Smckusick } 4266641Smckusick return(0); 4276641Smckusick 4286641Smckusick 4296641Smckusick case CDOT|STAR: 4306641Smckusick curlp = lp; 4316641Smckusick while (*lp++); 4326641Smckusick goto star; 4336641Smckusick 4346641Smckusick case CCHR|STAR: 4356641Smckusick curlp = lp; 4366641Smckusick while (*lp++ == *ep); 4376641Smckusick ep++; 4386641Smckusick goto star; 4396641Smckusick 4406641Smckusick case CCL|STAR: 4416641Smckusick curlp = lp; 4426641Smckusick do { 4436641Smckusick c = *lp++ & 0177; 4446641Smckusick } while(ep[c>>3] & bittab[c & 07]); 4456641Smckusick ep += 16; 4466641Smckusick goto star; 4476641Smckusick 4486641Smckusick star: 4496641Smckusick if(--lp == curlp) { 4506641Smckusick continue; 4516641Smckusick } 4526641Smckusick 4536641Smckusick if(*ep == CCHR) { 4546641Smckusick c = ep[1]; 4556641Smckusick do { 4566641Smckusick if(*lp != c) 4576641Smckusick continue; 4586641Smckusick if(advance(lp, ep)) 4596641Smckusick return(1); 4606641Smckusick } while(lp-- > curlp); 4616641Smckusick return(0); 4626641Smckusick } 4636641Smckusick 4646641Smckusick do { 4656641Smckusick if (advance(lp, ep)) 4666641Smckusick return(1); 4676641Smckusick } while (lp-- > curlp); 4686641Smckusick return(0); 4696641Smckusick 47013484Ssam case CBRC: 47113484Ssam if (lp == expbuf) 47213484Ssam continue; 47313484Ssam #define uletter(c) (isalpha(c) || (c) == '_') 47413484Ssam if (uletter(*lp) || isdigit(*lp)) 47513484Ssam if (!uletter(lp[-1]) && !isdigit(lp[-1])) 47613484Ssam continue; 47713484Ssam return (0); 47813484Ssam 47913484Ssam case CLET: 48013484Ssam if (!uletter(*lp) && !isdigit(*lp)) 48113484Ssam continue; 48213484Ssam return (0); 48313484Ssam 4846641Smckusick default: 4856641Smckusick errexit("grep RE botch\n", (char *)NULL); 4866641Smckusick } 4876641Smckusick } 4886641Smckusick 4896641Smckusick succeed(f) 4906641Smckusick char *f; 4916641Smckusick { 4926641Smckusick nsucc = 1; 4936641Smckusick if (sflag) 4946641Smckusick return; 4956641Smckusick if (cflag) { 4966641Smckusick tln++; 4976641Smckusick return; 4986641Smckusick } 4996641Smckusick if (lflag) { 5006641Smckusick printf("%s\n", f); 5016641Smckusick fflush(stdout); 5026641Smckusick fseek(stdin, 0l, 2); 5036641Smckusick return; 5046641Smckusick } 505*32365Sbostic if (nfile > 1 && hflag || oflag) 5066641Smckusick printf("%s:", f); 5076641Smckusick if (bflag) 5086641Smckusick printf("%u:", blkno); 5096641Smckusick if (nflag) 5106641Smckusick printf("%ld:", lnum); 5116641Smckusick printf("%s\n", linebuf); 5126641Smckusick fflush(stdout); 5136641Smckusick } 5146641Smckusick 5156641Smckusick ecmp(a, b, count) 5166641Smckusick char *a, *b; 5176641Smckusick { 5186641Smckusick register cc = count; 5196641Smckusick while(cc--) 5206641Smckusick if(*a++ != *b++) return(0); 5216641Smckusick return(1); 5226641Smckusick } 5236641Smckusick 5246641Smckusick errexit(s, f) 5256641Smckusick char *s, *f; 5266641Smckusick { 5276641Smckusick fprintf(stderr, s, f); 5286641Smckusick exit(2); 5296641Smckusick } 530