148264Sbostic /*- 248264Sbostic * Copyright (c) 1991 The Regents of the University of California. 348264Sbostic * All rights reserved. 448264Sbostic * 548264Sbostic * %sccs.include.proprietary.c% 648264Sbostic */ 748264Sbostic 814464Ssam #ifndef lint 948264Sbostic char copyright[] = 1048264Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 1148264Sbostic All rights reserved.\n"; 1248264Sbostic #endif /* not lint */ 136641Smckusick 1448264Sbostic #ifndef lint 15*54252Sbostic static char sccsid[] = "@(#)old.bin.grep.c 4.10 (Berkeley) 06/22/92"; 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 816641Smckusick main(argc, argv) 8233378Sbostic int argc; 8333378Sbostic char **argv; 846641Smckusick { 8533378Sbostic extern char *optarg; 8633378Sbostic extern int optind; 8733378Sbostic int ch; 886641Smckusick 89*54252Sbostic 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': 123*54252Sbostic argv += optind - 1; 124*54252Sbostic 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 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 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 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 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 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 5346641Smckusick errexit(s, f) 5356641Smckusick char *s, *f; 5366641Smckusick { 5376641Smckusick fprintf(stderr, s, f); 5386641Smckusick exit(2); 5396641Smckusick } 540