1*12096Smckusick /* old.bin.grep.c 4.3 83/04/29 */ 26641Smckusick 36641Smckusick /* 46641Smckusick * grep -- print lines matching (or not matching) a pattern 56641Smckusick * 66641Smckusick * status returns: 76641Smckusick * 0 - ok, and some matches 86641Smckusick * 1 - ok, but no matches 96641Smckusick * 2 - some error 106641Smckusick */ 116641Smckusick 126641Smckusick #include <stdio.h> 136641Smckusick #include <ctype.h> 146641Smckusick 156641Smckusick #define CBRA 1 166641Smckusick #define CCHR 2 176641Smckusick #define CDOT 4 186641Smckusick #define CCL 6 196641Smckusick #define NCCL 8 206641Smckusick #define CDOL 10 216641Smckusick #define CEOF 11 226641Smckusick #define CKET 12 236641Smckusick #define CBACK 18 246641Smckusick 256641Smckusick #define STAR 01 266641Smckusick 276641Smckusick #define LBSIZE BUFSIZ 286641Smckusick #define ESIZE 256 296641Smckusick #define NBRA 9 306641Smckusick 316641Smckusick char expbuf[ESIZE]; 326641Smckusick long lnum; 336641Smckusick char linebuf[LBSIZE+1]; 346641Smckusick char ybuf[ESIZE]; 356641Smckusick int bflag; 366641Smckusick int lflag; 376641Smckusick int nflag; 386641Smckusick int cflag; 396641Smckusick int vflag; 406641Smckusick int nfile; 416641Smckusick int hflag = 1; 426641Smckusick int sflag; 436641Smckusick int yflag; 4411579Sedward int retcode = 0; 456641Smckusick int circf; 466641Smckusick int blkno; 476641Smckusick long tln; 486641Smckusick int nsucc; 496641Smckusick char *braslist[NBRA]; 506641Smckusick char *braelist[NBRA]; 516641Smckusick char bittab[] = { 526641Smckusick 1, 536641Smckusick 2, 546641Smckusick 4, 556641Smckusick 8, 566641Smckusick 16, 576641Smckusick 32, 586641Smckusick 64, 596641Smckusick 128 606641Smckusick }; 616641Smckusick 626641Smckusick main(argc, argv) 636641Smckusick char **argv; 646641Smckusick { 656641Smckusick extern char _sobuf[]; 666641Smckusick setbuf(stdout, _sobuf); 676641Smckusick while (--argc > 0 && (++argv)[0][0]=='-') 686641Smckusick switch (argv[0][1]) { 696641Smckusick 706641Smckusick case 'y': 716641Smckusick yflag++; 726641Smckusick continue; 736641Smckusick 746641Smckusick case 'h': 756641Smckusick hflag = 0; 766641Smckusick continue; 776641Smckusick 786641Smckusick case 's': 796641Smckusick sflag++; 806641Smckusick continue; 816641Smckusick 826641Smckusick case 'v': 836641Smckusick vflag++; 846641Smckusick continue; 856641Smckusick 866641Smckusick case 'b': 876641Smckusick bflag++; 886641Smckusick continue; 896641Smckusick 906641Smckusick case 'l': 916641Smckusick lflag++; 926641Smckusick continue; 936641Smckusick 946641Smckusick case 'c': 956641Smckusick cflag++; 966641Smckusick continue; 976641Smckusick 986641Smckusick case 'n': 996641Smckusick nflag++; 1006641Smckusick continue; 1016641Smckusick 1026641Smckusick case 'e': 1036641Smckusick --argc; 1046641Smckusick ++argv; 1056641Smckusick goto out; 1066641Smckusick 1076641Smckusick default: 1086641Smckusick errexit("grep: unknown flag\n", (char *)NULL); 1096641Smckusick continue; 1106641Smckusick } 1116641Smckusick out: 1126641Smckusick if (argc<=0) 1136641Smckusick exit(2); 1146641Smckusick if (yflag) { 1156641Smckusick register char *p, *s; 1166641Smckusick for (s = ybuf, p = *argv; *p; ) { 1176641Smckusick if (*p == '\\') { 1186641Smckusick *s++ = *p++; 1196641Smckusick if (*p) 1206641Smckusick *s++ = *p++; 1216641Smckusick } else if (*p == '[') { 1226641Smckusick while (*p != '\0' && *p != ']') 1236641Smckusick *s++ = *p++; 1246641Smckusick } else if (islower(*p)) { 1256641Smckusick *s++ = '['; 1266641Smckusick *s++ = toupper(*p); 1276641Smckusick *s++ = *p++; 1286641Smckusick *s++ = ']'; 1296641Smckusick } else 1306641Smckusick *s++ = *p++; 1316641Smckusick if (s >= ybuf+ESIZE-5) 1326641Smckusick errexit("grep: argument too long\n", (char *)NULL); 1336641Smckusick } 1346641Smckusick *s = '\0'; 1356641Smckusick *argv = ybuf; 1366641Smckusick } 1376641Smckusick compile(*argv); 1386641Smckusick nfile = --argc; 1396641Smckusick if (argc<=0) { 1406641Smckusick if (lflag) 1416641Smckusick exit(1); 1426641Smckusick execute((char *)NULL); 1436641Smckusick } else while (--argc >= 0) { 1446641Smckusick argv++; 1456641Smckusick execute(*argv); 1466641Smckusick } 14711579Sedward exit(retcode != 0 ? retcode : nsucc == 0); 1486641Smckusick } 1496641Smckusick 1506641Smckusick compile(astr) 1516641Smckusick char *astr; 1526641Smckusick { 1536641Smckusick register c; 1546641Smckusick register char *ep, *sp; 1556641Smckusick char *cstart; 1566641Smckusick char *lastep; 1576641Smckusick int cclcnt; 1586641Smckusick char bracket[NBRA], *bracketp; 1596641Smckusick int closed; 1606641Smckusick char numbra; 1616641Smckusick char neg; 1626641Smckusick 1636641Smckusick ep = expbuf; 1646641Smckusick sp = astr; 1656641Smckusick lastep = 0; 1666641Smckusick bracketp = bracket; 1676641Smckusick closed = numbra = 0; 1686641Smckusick if (*sp == '^') { 1696641Smckusick circf++; 1706641Smckusick sp++; 1716641Smckusick } 1726641Smckusick for (;;) { 1736641Smckusick if (ep >= &expbuf[ESIZE]) 1746641Smckusick goto cerror; 1756641Smckusick if ((c = *sp++) != '*') 1766641Smckusick lastep = ep; 1776641Smckusick switch (c) { 1786641Smckusick 1796641Smckusick case '\0': 1806641Smckusick *ep++ = CEOF; 1816641Smckusick return; 1826641Smckusick 1836641Smckusick case '.': 1846641Smckusick *ep++ = CDOT; 1856641Smckusick continue; 1866641Smckusick 1876641Smckusick case '*': 1886641Smckusick if (lastep==0 || *lastep==CBRA || *lastep==CKET) 1896641Smckusick goto defchar; 1906641Smckusick *lastep |= STAR; 1916641Smckusick continue; 1926641Smckusick 1936641Smckusick case '$': 1946641Smckusick if (*sp != '\0') 1956641Smckusick goto defchar; 1966641Smckusick *ep++ = CDOL; 1976641Smckusick continue; 1986641Smckusick 1996641Smckusick case '[': 2006641Smckusick if(&ep[17] >= &expbuf[ESIZE]) 2016641Smckusick goto cerror; 2026641Smckusick *ep++ = CCL; 2036641Smckusick neg = 0; 2046641Smckusick if((c = *sp++) == '^') { 2056641Smckusick neg = 1; 2066641Smckusick c = *sp++; 2076641Smckusick } 2086641Smckusick cstart = sp; 2096641Smckusick do { 2106641Smckusick if (c=='\0') 2116641Smckusick goto cerror; 2126641Smckusick if (c=='-' && sp>cstart && *sp!=']') { 2136641Smckusick for (c = sp[-2]; c<*sp; c++) 2146641Smckusick ep[c>>3] |= bittab[c&07]; 2156641Smckusick sp++; 2166641Smckusick } 2176641Smckusick ep[c>>3] |= bittab[c&07]; 2186641Smckusick } while((c = *sp++) != ']'); 2196641Smckusick if(neg) { 2206641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++) 2216641Smckusick ep[cclcnt] ^= -1; 2226641Smckusick ep[0] &= 0376; 2236641Smckusick } 2246641Smckusick 2256641Smckusick ep += 16; 2266641Smckusick 2276641Smckusick continue; 2286641Smckusick 2296641Smckusick case '\\': 2306641Smckusick if((c = *sp++) == '(') { 2316641Smckusick if(numbra >= NBRA) { 2326641Smckusick goto cerror; 2336641Smckusick } 2346641Smckusick *bracketp++ = numbra; 2356641Smckusick *ep++ = CBRA; 2366641Smckusick *ep++ = numbra++; 2376641Smckusick continue; 2386641Smckusick } 2396641Smckusick if(c == ')') { 2406641Smckusick if(bracketp <= bracket) { 2416641Smckusick goto cerror; 2426641Smckusick } 2436641Smckusick *ep++ = CKET; 2446641Smckusick *ep++ = *--bracketp; 2456641Smckusick closed++; 2466641Smckusick continue; 2476641Smckusick } 2486641Smckusick 2496641Smckusick if(c >= '1' && c <= '9') { 2506641Smckusick if((c -= '1') >= closed) 2516641Smckusick goto cerror; 2526641Smckusick *ep++ = CBACK; 2536641Smckusick *ep++ = c; 2546641Smckusick continue; 2556641Smckusick } 2566641Smckusick 2576641Smckusick defchar: 2586641Smckusick default: 2596641Smckusick *ep++ = CCHR; 2606641Smckusick *ep++ = c; 2616641Smckusick } 2626641Smckusick } 2636641Smckusick cerror: 2646641Smckusick errexit("grep: RE error\n", (char *)NULL); 2656641Smckusick } 2666641Smckusick 2676641Smckusick execute(file) 2686641Smckusick char *file; 2696641Smckusick { 2706641Smckusick register char *p1, *p2; 2716641Smckusick register c; 2726641Smckusick 2736641Smckusick if (file) { 27411579Sedward if (freopen(file, "r", stdin) == NULL) { 275*12096Smckusick perror(file); 27611579Sedward retcode = 2; 27711579Sedward } 2786641Smckusick } 2796641Smckusick lnum = 0; 2806641Smckusick tln = 0; 2816641Smckusick for (;;) { 2826641Smckusick lnum++; 2836641Smckusick p1 = linebuf; 2846641Smckusick while ((c = getchar()) != '\n') { 2856641Smckusick if (c == EOF) { 2866641Smckusick if (cflag) { 2876641Smckusick if (nfile>1) 2886641Smckusick printf("%s:", file); 2896641Smckusick printf("%D\n", tln); 2906641Smckusick fflush(stdout); 2916641Smckusick } 2926641Smckusick return; 2936641Smckusick } 2946641Smckusick *p1++ = c; 2956641Smckusick if (p1 >= &linebuf[LBSIZE-1]) 2966641Smckusick break; 2976641Smckusick } 2986641Smckusick *p1++ = '\0'; 2996641Smckusick p1 = linebuf; 3006641Smckusick p2 = expbuf; 3016641Smckusick if (circf) { 3026641Smckusick if (advance(p1, p2)) 3036641Smckusick goto found; 3046641Smckusick goto nfound; 3056641Smckusick } 3066641Smckusick /* fast check for first character */ 3076641Smckusick if (*p2==CCHR) { 3086641Smckusick c = p2[1]; 3096641Smckusick do { 3106641Smckusick if (*p1!=c) 3116641Smckusick continue; 3126641Smckusick if (advance(p1, p2)) 3136641Smckusick goto found; 3146641Smckusick } while (*p1++); 3156641Smckusick goto nfound; 3166641Smckusick } 3176641Smckusick /* regular algorithm */ 3186641Smckusick do { 3196641Smckusick if (advance(p1, p2)) 3206641Smckusick goto found; 3216641Smckusick } while (*p1++); 3226641Smckusick nfound: 3236641Smckusick if (vflag) 3246641Smckusick succeed(file); 3256641Smckusick continue; 3266641Smckusick found: 3276641Smckusick if (vflag==0) 3286641Smckusick succeed(file); 3296641Smckusick } 3306641Smckusick } 3316641Smckusick 3326641Smckusick advance(lp, ep) 3336641Smckusick register char *lp, *ep; 3346641Smckusick { 3356641Smckusick register char *curlp; 3366641Smckusick char c; 3376641Smckusick char *bbeg; 3386641Smckusick int ct; 3396641Smckusick 3406641Smckusick for (;;) switch (*ep++) { 3416641Smckusick 3426641Smckusick case CCHR: 3436641Smckusick if (*ep++ == *lp++) 3446641Smckusick continue; 3456641Smckusick return(0); 3466641Smckusick 3476641Smckusick case CDOT: 3486641Smckusick if (*lp++) 3496641Smckusick continue; 3506641Smckusick return(0); 3516641Smckusick 3526641Smckusick case CDOL: 3536641Smckusick if (*lp==0) 3546641Smckusick continue; 3556641Smckusick return(0); 3566641Smckusick 3576641Smckusick case CEOF: 3586641Smckusick return(1); 3596641Smckusick 3606641Smckusick case CCL: 3616641Smckusick c = *lp++ & 0177; 3626641Smckusick if(ep[c>>3] & bittab[c & 07]) { 3636641Smckusick ep += 16; 3646641Smckusick continue; 3656641Smckusick } 3666641Smckusick return(0); 3676641Smckusick case CBRA: 3686641Smckusick braslist[*ep++] = lp; 3696641Smckusick continue; 3706641Smckusick 3716641Smckusick case CKET: 3726641Smckusick braelist[*ep++] = lp; 3736641Smckusick continue; 3746641Smckusick 3756641Smckusick case CBACK: 3766641Smckusick bbeg = braslist[*ep]; 3776641Smckusick if (braelist[*ep]==0) 3786641Smckusick return(0); 3796641Smckusick ct = braelist[*ep++] - bbeg; 3806641Smckusick if(ecmp(bbeg, lp, ct)) { 3816641Smckusick lp += ct; 3826641Smckusick continue; 3836641Smckusick } 3846641Smckusick return(0); 3856641Smckusick 3866641Smckusick case CBACK|STAR: 3876641Smckusick bbeg = braslist[*ep]; 3886641Smckusick if (braelist[*ep]==0) 3896641Smckusick return(0); 3906641Smckusick ct = braelist[*ep++] - bbeg; 3916641Smckusick curlp = lp; 3926641Smckusick while(ecmp(bbeg, lp, ct)) 3936641Smckusick lp += ct; 3946641Smckusick while(lp >= curlp) { 3956641Smckusick if(advance(lp, ep)) return(1); 3966641Smckusick lp -= ct; 3976641Smckusick } 3986641Smckusick return(0); 3996641Smckusick 4006641Smckusick 4016641Smckusick case CDOT|STAR: 4026641Smckusick curlp = lp; 4036641Smckusick while (*lp++); 4046641Smckusick goto star; 4056641Smckusick 4066641Smckusick case CCHR|STAR: 4076641Smckusick curlp = lp; 4086641Smckusick while (*lp++ == *ep); 4096641Smckusick ep++; 4106641Smckusick goto star; 4116641Smckusick 4126641Smckusick case CCL|STAR: 4136641Smckusick curlp = lp; 4146641Smckusick do { 4156641Smckusick c = *lp++ & 0177; 4166641Smckusick } while(ep[c>>3] & bittab[c & 07]); 4176641Smckusick ep += 16; 4186641Smckusick goto star; 4196641Smckusick 4206641Smckusick star: 4216641Smckusick if(--lp == curlp) { 4226641Smckusick continue; 4236641Smckusick } 4246641Smckusick 4256641Smckusick if(*ep == CCHR) { 4266641Smckusick c = ep[1]; 4276641Smckusick do { 4286641Smckusick if(*lp != c) 4296641Smckusick continue; 4306641Smckusick if(advance(lp, ep)) 4316641Smckusick return(1); 4326641Smckusick } while(lp-- > curlp); 4336641Smckusick return(0); 4346641Smckusick } 4356641Smckusick 4366641Smckusick do { 4376641Smckusick if (advance(lp, ep)) 4386641Smckusick return(1); 4396641Smckusick } while (lp-- > curlp); 4406641Smckusick return(0); 4416641Smckusick 4426641Smckusick default: 4436641Smckusick errexit("grep RE botch\n", (char *)NULL); 4446641Smckusick } 4456641Smckusick } 4466641Smckusick 4476641Smckusick succeed(f) 4486641Smckusick char *f; 4496641Smckusick { 4506641Smckusick nsucc = 1; 4516641Smckusick if (sflag) 4526641Smckusick return; 4536641Smckusick if (cflag) { 4546641Smckusick tln++; 4556641Smckusick return; 4566641Smckusick } 4576641Smckusick if (lflag) { 4586641Smckusick printf("%s\n", f); 4596641Smckusick fflush(stdout); 4606641Smckusick fseek(stdin, 0l, 2); 4616641Smckusick return; 4626641Smckusick } 4636641Smckusick if (nfile > 1 && hflag) 4646641Smckusick printf("%s:", f); 4656641Smckusick if (bflag) 4666641Smckusick printf("%u:", blkno); 4676641Smckusick if (nflag) 4686641Smckusick printf("%ld:", lnum); 4696641Smckusick printf("%s\n", linebuf); 4706641Smckusick fflush(stdout); 4716641Smckusick } 4726641Smckusick 4736641Smckusick ecmp(a, b, count) 4746641Smckusick char *a, *b; 4756641Smckusick { 4766641Smckusick register cc = count; 4776641Smckusick while(cc--) 4786641Smckusick if(*a++ != *b++) return(0); 4796641Smckusick return(1); 4806641Smckusick } 4816641Smckusick 4826641Smckusick errexit(s, f) 4836641Smckusick char *s, *f; 4846641Smckusick { 4856641Smckusick fprintf(stderr, s, f); 4866641Smckusick exit(2); 4876641Smckusick } 488