1*13484Ssam /* old.bin.grep.c 4.4 83/06/30 */ 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 23*13484Ssam #define CBRC 14 24*13484Ssam #define CLET 15 256641Smckusick #define CBACK 18 266641Smckusick 276641Smckusick #define STAR 01 286641Smckusick 296641Smckusick #define LBSIZE BUFSIZ 306641Smckusick #define ESIZE 256 316641Smckusick #define NBRA 9 326641Smckusick 336641Smckusick char expbuf[ESIZE]; 346641Smckusick long lnum; 356641Smckusick char linebuf[LBSIZE+1]; 366641Smckusick char ybuf[ESIZE]; 376641Smckusick int bflag; 386641Smckusick int lflag; 396641Smckusick int nflag; 406641Smckusick int cflag; 416641Smckusick int vflag; 426641Smckusick int nfile; 436641Smckusick int hflag = 1; 446641Smckusick int sflag; 456641Smckusick int yflag; 46*13484Ssam int wflag; 4711579Sedward int retcode = 0; 486641Smckusick int circf; 496641Smckusick int blkno; 506641Smckusick long tln; 516641Smckusick int nsucc; 526641Smckusick char *braslist[NBRA]; 536641Smckusick char *braelist[NBRA]; 546641Smckusick char bittab[] = { 556641Smckusick 1, 566641Smckusick 2, 576641Smckusick 4, 586641Smckusick 8, 596641Smckusick 16, 606641Smckusick 32, 616641Smckusick 64, 626641Smckusick 128 636641Smckusick }; 646641Smckusick 656641Smckusick main(argc, argv) 666641Smckusick char **argv; 676641Smckusick { 686641Smckusick extern char _sobuf[]; 696641Smckusick setbuf(stdout, _sobuf); 706641Smckusick while (--argc > 0 && (++argv)[0][0]=='-') 716641Smckusick switch (argv[0][1]) { 726641Smckusick 73*13484Ssam case 'i': 746641Smckusick case 'y': 756641Smckusick yflag++; 766641Smckusick continue; 776641Smckusick 78*13484Ssam case 'w': 79*13484Ssam wflag++; 80*13484Ssam continue; 81*13484Ssam 826641Smckusick case 'h': 836641Smckusick hflag = 0; 846641Smckusick continue; 856641Smckusick 866641Smckusick case 's': 876641Smckusick sflag++; 886641Smckusick continue; 896641Smckusick 906641Smckusick case 'v': 916641Smckusick vflag++; 926641Smckusick continue; 936641Smckusick 946641Smckusick case 'b': 956641Smckusick bflag++; 966641Smckusick continue; 976641Smckusick 986641Smckusick case 'l': 996641Smckusick lflag++; 1006641Smckusick continue; 1016641Smckusick 1026641Smckusick case 'c': 1036641Smckusick cflag++; 1046641Smckusick continue; 1056641Smckusick 1066641Smckusick case 'n': 1076641Smckusick nflag++; 1086641Smckusick continue; 1096641Smckusick 1106641Smckusick case 'e': 1116641Smckusick --argc; 1126641Smckusick ++argv; 1136641Smckusick goto out; 1146641Smckusick 1156641Smckusick default: 1166641Smckusick errexit("grep: unknown flag\n", (char *)NULL); 1176641Smckusick continue; 1186641Smckusick } 1196641Smckusick out: 1206641Smckusick if (argc<=0) 1216641Smckusick exit(2); 1226641Smckusick if (yflag) { 1236641Smckusick register char *p, *s; 1246641Smckusick for (s = ybuf, p = *argv; *p; ) { 1256641Smckusick if (*p == '\\') { 1266641Smckusick *s++ = *p++; 1276641Smckusick if (*p) 1286641Smckusick *s++ = *p++; 1296641Smckusick } else if (*p == '[') { 1306641Smckusick while (*p != '\0' && *p != ']') 1316641Smckusick *s++ = *p++; 1326641Smckusick } else if (islower(*p)) { 1336641Smckusick *s++ = '['; 1346641Smckusick *s++ = toupper(*p); 1356641Smckusick *s++ = *p++; 1366641Smckusick *s++ = ']'; 1376641Smckusick } else 1386641Smckusick *s++ = *p++; 1396641Smckusick if (s >= ybuf+ESIZE-5) 1406641Smckusick errexit("grep: argument too long\n", (char *)NULL); 1416641Smckusick } 1426641Smckusick *s = '\0'; 1436641Smckusick *argv = ybuf; 1446641Smckusick } 1456641Smckusick compile(*argv); 1466641Smckusick nfile = --argc; 1476641Smckusick if (argc<=0) { 1486641Smckusick if (lflag) 1496641Smckusick exit(1); 1506641Smckusick execute((char *)NULL); 1516641Smckusick } else while (--argc >= 0) { 1526641Smckusick argv++; 1536641Smckusick execute(*argv); 1546641Smckusick } 15511579Sedward exit(retcode != 0 ? retcode : nsucc == 0); 1566641Smckusick } 1576641Smckusick 1586641Smckusick compile(astr) 1596641Smckusick char *astr; 1606641Smckusick { 1616641Smckusick register c; 1626641Smckusick register char *ep, *sp; 1636641Smckusick char *cstart; 1646641Smckusick char *lastep; 1656641Smckusick int cclcnt; 1666641Smckusick char bracket[NBRA], *bracketp; 1676641Smckusick int closed; 1686641Smckusick char numbra; 1696641Smckusick char neg; 1706641Smckusick 1716641Smckusick ep = expbuf; 1726641Smckusick sp = astr; 1736641Smckusick lastep = 0; 1746641Smckusick bracketp = bracket; 1756641Smckusick closed = numbra = 0; 1766641Smckusick if (*sp == '^') { 1776641Smckusick circf++; 1786641Smckusick sp++; 1796641Smckusick } 180*13484Ssam if (wflag) 181*13484Ssam *ep++ = CBRC; 1826641Smckusick for (;;) { 1836641Smckusick if (ep >= &expbuf[ESIZE]) 1846641Smckusick goto cerror; 1856641Smckusick if ((c = *sp++) != '*') 1866641Smckusick lastep = ep; 1876641Smckusick switch (c) { 1886641Smckusick 1896641Smckusick case '\0': 190*13484Ssam if (wflag) 191*13484Ssam *ep++ = CLET; 1926641Smckusick *ep++ = CEOF; 1936641Smckusick return; 1946641Smckusick 1956641Smckusick case '.': 1966641Smckusick *ep++ = CDOT; 1976641Smckusick continue; 1986641Smckusick 1996641Smckusick case '*': 200*13484Ssam if (lastep==0 || *lastep==CBRA || *lastep==CKET || 201*13484Ssam *lastep == CBRC || *lastep == CLET) 2026641Smckusick goto defchar; 2036641Smckusick *lastep |= STAR; 2046641Smckusick continue; 2056641Smckusick 2066641Smckusick case '$': 2076641Smckusick if (*sp != '\0') 2086641Smckusick goto defchar; 2096641Smckusick *ep++ = CDOL; 2106641Smckusick continue; 2116641Smckusick 2126641Smckusick case '[': 2136641Smckusick if(&ep[17] >= &expbuf[ESIZE]) 2146641Smckusick goto cerror; 2156641Smckusick *ep++ = CCL; 2166641Smckusick neg = 0; 2176641Smckusick if((c = *sp++) == '^') { 2186641Smckusick neg = 1; 2196641Smckusick c = *sp++; 2206641Smckusick } 2216641Smckusick cstart = sp; 2226641Smckusick do { 2236641Smckusick if (c=='\0') 2246641Smckusick goto cerror; 2256641Smckusick if (c=='-' && sp>cstart && *sp!=']') { 2266641Smckusick for (c = sp[-2]; c<*sp; c++) 2276641Smckusick ep[c>>3] |= bittab[c&07]; 2286641Smckusick sp++; 2296641Smckusick } 2306641Smckusick ep[c>>3] |= bittab[c&07]; 2316641Smckusick } while((c = *sp++) != ']'); 2326641Smckusick if(neg) { 2336641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++) 2346641Smckusick ep[cclcnt] ^= -1; 2356641Smckusick ep[0] &= 0376; 2366641Smckusick } 2376641Smckusick 2386641Smckusick ep += 16; 2396641Smckusick 2406641Smckusick continue; 2416641Smckusick 2426641Smckusick case '\\': 243*13484Ssam if((c = *sp++) == 0) 244*13484Ssam goto cerror; 245*13484Ssam if(c == '<') { 246*13484Ssam *ep++ = CBRC; 247*13484Ssam continue; 248*13484Ssam } 249*13484Ssam if(c == '>') { 250*13484Ssam *ep++ = CLET; 251*13484Ssam continue; 252*13484Ssam } 253*13484Ssam if(c == '(') { 2546641Smckusick if(numbra >= NBRA) { 2556641Smckusick goto cerror; 2566641Smckusick } 2576641Smckusick *bracketp++ = numbra; 2586641Smckusick *ep++ = CBRA; 2596641Smckusick *ep++ = numbra++; 2606641Smckusick continue; 2616641Smckusick } 2626641Smckusick if(c == ')') { 2636641Smckusick if(bracketp <= bracket) { 2646641Smckusick goto cerror; 2656641Smckusick } 2666641Smckusick *ep++ = CKET; 2676641Smckusick *ep++ = *--bracketp; 2686641Smckusick closed++; 2696641Smckusick continue; 2706641Smckusick } 2716641Smckusick 2726641Smckusick if(c >= '1' && c <= '9') { 2736641Smckusick if((c -= '1') >= closed) 2746641Smckusick goto cerror; 2756641Smckusick *ep++ = CBACK; 2766641Smckusick *ep++ = c; 2776641Smckusick continue; 2786641Smckusick } 2796641Smckusick 2806641Smckusick defchar: 2816641Smckusick default: 2826641Smckusick *ep++ = CCHR; 2836641Smckusick *ep++ = c; 2846641Smckusick } 2856641Smckusick } 2866641Smckusick cerror: 2876641Smckusick errexit("grep: RE error\n", (char *)NULL); 2886641Smckusick } 2896641Smckusick 2906641Smckusick execute(file) 2916641Smckusick char *file; 2926641Smckusick { 2936641Smckusick register char *p1, *p2; 2946641Smckusick register c; 2956641Smckusick 2966641Smckusick if (file) { 29711579Sedward if (freopen(file, "r", stdin) == NULL) { 29812096Smckusick perror(file); 29911579Sedward retcode = 2; 30011579Sedward } 3016641Smckusick } 3026641Smckusick lnum = 0; 3036641Smckusick tln = 0; 3046641Smckusick for (;;) { 3056641Smckusick lnum++; 3066641Smckusick p1 = linebuf; 3076641Smckusick while ((c = getchar()) != '\n') { 3086641Smckusick if (c == EOF) { 3096641Smckusick if (cflag) { 3106641Smckusick if (nfile>1) 3116641Smckusick printf("%s:", file); 3126641Smckusick printf("%D\n", tln); 3136641Smckusick fflush(stdout); 3146641Smckusick } 3156641Smckusick return; 3166641Smckusick } 3176641Smckusick *p1++ = c; 3186641Smckusick if (p1 >= &linebuf[LBSIZE-1]) 3196641Smckusick break; 3206641Smckusick } 3216641Smckusick *p1++ = '\0'; 3226641Smckusick p1 = linebuf; 3236641Smckusick p2 = expbuf; 3246641Smckusick if (circf) { 3256641Smckusick if (advance(p1, p2)) 3266641Smckusick goto found; 3276641Smckusick goto nfound; 3286641Smckusick } 3296641Smckusick /* fast check for first character */ 3306641Smckusick if (*p2==CCHR) { 3316641Smckusick c = p2[1]; 3326641Smckusick do { 3336641Smckusick if (*p1!=c) 3346641Smckusick continue; 3356641Smckusick if (advance(p1, p2)) 3366641Smckusick goto found; 3376641Smckusick } while (*p1++); 3386641Smckusick goto nfound; 3396641Smckusick } 3406641Smckusick /* regular algorithm */ 3416641Smckusick do { 3426641Smckusick if (advance(p1, p2)) 3436641Smckusick goto found; 3446641Smckusick } while (*p1++); 3456641Smckusick nfound: 3466641Smckusick if (vflag) 3476641Smckusick succeed(file); 3486641Smckusick continue; 3496641Smckusick found: 3506641Smckusick if (vflag==0) 3516641Smckusick succeed(file); 3526641Smckusick } 3536641Smckusick } 3546641Smckusick 3556641Smckusick advance(lp, ep) 3566641Smckusick register char *lp, *ep; 3576641Smckusick { 3586641Smckusick register char *curlp; 3596641Smckusick char c; 3606641Smckusick char *bbeg; 3616641Smckusick int ct; 3626641Smckusick 3636641Smckusick for (;;) switch (*ep++) { 3646641Smckusick 3656641Smckusick case CCHR: 3666641Smckusick if (*ep++ == *lp++) 3676641Smckusick continue; 3686641Smckusick return(0); 3696641Smckusick 3706641Smckusick case CDOT: 3716641Smckusick if (*lp++) 3726641Smckusick continue; 3736641Smckusick return(0); 3746641Smckusick 3756641Smckusick case CDOL: 3766641Smckusick if (*lp==0) 3776641Smckusick continue; 3786641Smckusick return(0); 3796641Smckusick 3806641Smckusick case CEOF: 3816641Smckusick return(1); 3826641Smckusick 3836641Smckusick case CCL: 3846641Smckusick c = *lp++ & 0177; 3856641Smckusick if(ep[c>>3] & bittab[c & 07]) { 3866641Smckusick ep += 16; 3876641Smckusick continue; 3886641Smckusick } 3896641Smckusick return(0); 3906641Smckusick case CBRA: 3916641Smckusick braslist[*ep++] = lp; 3926641Smckusick continue; 3936641Smckusick 3946641Smckusick case CKET: 3956641Smckusick braelist[*ep++] = lp; 3966641Smckusick continue; 3976641Smckusick 3986641Smckusick case CBACK: 3996641Smckusick bbeg = braslist[*ep]; 4006641Smckusick if (braelist[*ep]==0) 4016641Smckusick return(0); 4026641Smckusick ct = braelist[*ep++] - bbeg; 4036641Smckusick if(ecmp(bbeg, lp, ct)) { 4046641Smckusick lp += ct; 4056641Smckusick continue; 4066641Smckusick } 4076641Smckusick return(0); 4086641Smckusick 4096641Smckusick case CBACK|STAR: 4106641Smckusick bbeg = braslist[*ep]; 4116641Smckusick if (braelist[*ep]==0) 4126641Smckusick return(0); 4136641Smckusick ct = braelist[*ep++] - bbeg; 4146641Smckusick curlp = lp; 4156641Smckusick while(ecmp(bbeg, lp, ct)) 4166641Smckusick lp += ct; 4176641Smckusick while(lp >= curlp) { 4186641Smckusick if(advance(lp, ep)) return(1); 4196641Smckusick lp -= ct; 4206641Smckusick } 4216641Smckusick return(0); 4226641Smckusick 4236641Smckusick 4246641Smckusick case CDOT|STAR: 4256641Smckusick curlp = lp; 4266641Smckusick while (*lp++); 4276641Smckusick goto star; 4286641Smckusick 4296641Smckusick case CCHR|STAR: 4306641Smckusick curlp = lp; 4316641Smckusick while (*lp++ == *ep); 4326641Smckusick ep++; 4336641Smckusick goto star; 4346641Smckusick 4356641Smckusick case CCL|STAR: 4366641Smckusick curlp = lp; 4376641Smckusick do { 4386641Smckusick c = *lp++ & 0177; 4396641Smckusick } while(ep[c>>3] & bittab[c & 07]); 4406641Smckusick ep += 16; 4416641Smckusick goto star; 4426641Smckusick 4436641Smckusick star: 4446641Smckusick if(--lp == curlp) { 4456641Smckusick continue; 4466641Smckusick } 4476641Smckusick 4486641Smckusick if(*ep == CCHR) { 4496641Smckusick c = ep[1]; 4506641Smckusick do { 4516641Smckusick if(*lp != c) 4526641Smckusick continue; 4536641Smckusick if(advance(lp, ep)) 4546641Smckusick return(1); 4556641Smckusick } while(lp-- > curlp); 4566641Smckusick return(0); 4576641Smckusick } 4586641Smckusick 4596641Smckusick do { 4606641Smckusick if (advance(lp, ep)) 4616641Smckusick return(1); 4626641Smckusick } while (lp-- > curlp); 4636641Smckusick return(0); 4646641Smckusick 465*13484Ssam case CBRC: 466*13484Ssam if (lp == expbuf) 467*13484Ssam continue; 468*13484Ssam #define uletter(c) (isalpha(c) || (c) == '_') 469*13484Ssam if (uletter(*lp) || isdigit(*lp)) 470*13484Ssam if (!uletter(lp[-1]) && !isdigit(lp[-1])) 471*13484Ssam continue; 472*13484Ssam return (0); 473*13484Ssam 474*13484Ssam case CLET: 475*13484Ssam if (!uletter(*lp) && !isdigit(*lp)) 476*13484Ssam continue; 477*13484Ssam return (0); 478*13484Ssam 4796641Smckusick default: 4806641Smckusick errexit("grep RE botch\n", (char *)NULL); 4816641Smckusick } 4826641Smckusick } 4836641Smckusick 4846641Smckusick succeed(f) 4856641Smckusick char *f; 4866641Smckusick { 4876641Smckusick nsucc = 1; 4886641Smckusick if (sflag) 4896641Smckusick return; 4906641Smckusick if (cflag) { 4916641Smckusick tln++; 4926641Smckusick return; 4936641Smckusick } 4946641Smckusick if (lflag) { 4956641Smckusick printf("%s\n", f); 4966641Smckusick fflush(stdout); 4976641Smckusick fseek(stdin, 0l, 2); 4986641Smckusick return; 4996641Smckusick } 5006641Smckusick if (nfile > 1 && hflag) 5016641Smckusick printf("%s:", f); 5026641Smckusick if (bflag) 5036641Smckusick printf("%u:", blkno); 5046641Smckusick if (nflag) 5056641Smckusick printf("%ld:", lnum); 5066641Smckusick printf("%s\n", linebuf); 5076641Smckusick fflush(stdout); 5086641Smckusick } 5096641Smckusick 5106641Smckusick ecmp(a, b, count) 5116641Smckusick char *a, *b; 5126641Smckusick { 5136641Smckusick register cc = count; 5146641Smckusick while(cc--) 5156641Smckusick if(*a++ != *b++) return(0); 5166641Smckusick return(1); 5176641Smckusick } 5186641Smckusick 5196641Smckusick errexit(s, f) 5206641Smckusick char *s, *f; 5216641Smckusick { 5226641Smckusick fprintf(stderr, s, f); 5236641Smckusick exit(2); 5246641Smckusick } 525