114516Ssam #ifndef lint 2*21391Smckusick static char sccsid[] = "@(#)old.ucb.grep.c 4.5 (Berkeley) 05/30/85"; 314516Ssam #endif 46639Smckusick 56639Smckusick #include <stdio.h> 6*21391Smckusick #include <sys/types.h> 7*21391Smckusick #include <sys/stat.h> 86639Smckusick /* 96639Smckusick * grep -- print lines matching (or not matching) a pattern 106639Smckusick */ 116639Smckusick 12*21391Smckusick #define BLKSIZE 8192 136639Smckusick #define CCHR 2 146639Smckusick #define CDOT 4 156639Smckusick #define CCL 6 166639Smckusick #define NCCL 8 176639Smckusick #define CDOL 10 186639Smckusick #define CEOF 11 196639Smckusick 206639Smckusick #define CBRC 14 216639Smckusick #define CLET 15 226639Smckusick #define STAR 01 236639Smckusick 246639Smckusick #define ESIZE 256 256639Smckusick 266639Smckusick char expbuf[ESIZE]; 276639Smckusick long lnum; 28*21391Smckusick char linebuf[BUFSIZ+1]; 296639Smckusick int bflag; 306639Smckusick int nflag; 316639Smckusick int cflag; 326639Smckusick int vflag; 336639Smckusick int nfile; 346639Smckusick int iflag; 356639Smckusick int lflag; 366639Smckusick int wflag; 376639Smckusick int sflag; 386639Smckusick int nsucc; 396639Smckusick int circf; 406639Smckusick int blkno; 416639Smckusick long tln; 426639Smckusick 436639Smckusick main(argc, argv) 446639Smckusick char **argv; 456639Smckusick { 466639Smckusick 476639Smckusick while (--argc > 0 && (++argv)[0][0]=='-') { 486639Smckusick char *cp = argv[0] + 1; 496639Smckusick while (*cp) switch (*cp++) { 506639Smckusick 516639Smckusick case 'v': 526639Smckusick vflag++; 536639Smckusick continue; 546639Smckusick 556639Smckusick case 'b': 566639Smckusick bflag++; 576639Smckusick continue; 586639Smckusick 596639Smckusick case 'i': 606639Smckusick case 'y': /* -y for compatibility with btl grep */ 616639Smckusick iflag++; 626639Smckusick continue; 636639Smckusick 646639Smckusick case 'l': 656639Smckusick lflag++; 666639Smckusick case 'c': 676639Smckusick cflag++; 686639Smckusick continue; 696639Smckusick 706639Smckusick case 'w': 716639Smckusick wflag++; 726639Smckusick continue; 736639Smckusick 746639Smckusick case 's': 756639Smckusick sflag++; 766639Smckusick continue; 776639Smckusick 786639Smckusick case 'n': 796639Smckusick nflag++; 806639Smckusick continue; 816639Smckusick 826639Smckusick case 'e': 836639Smckusick --argc; 846639Smckusick ++argv; 856639Smckusick goto out; 866639Smckusick 876639Smckusick default: 886639Smckusick fprintf(stderr, "Unknown flag\n"); 896639Smckusick continue; 906639Smckusick } 916639Smckusick } 926639Smckusick out: 936639Smckusick if (argc<=0) 946639Smckusick exit(2); 956639Smckusick compile(*argv); 966639Smckusick nfile = --argc; 976639Smckusick if (argc<=0) { 986639Smckusick if (lflag) 996639Smckusick exit(1); 1006639Smckusick execute(0); 1016639Smckusick } 1026639Smckusick else while (--argc >= 0) { 1036639Smckusick argv++; 1046639Smckusick execute(*argv); 1056639Smckusick } 1066639Smckusick exit(nsucc == 0); 1076639Smckusick } 1086639Smckusick 1096639Smckusick compile(astr) 1106639Smckusick char *astr; 1116639Smckusick { 1126639Smckusick register c; 1136639Smckusick register char *ep, *sp; 1146639Smckusick char *lastep; 1156639Smckusick int cclcnt; 1166639Smckusick 1176639Smckusick ep = expbuf; 1186639Smckusick sp = astr; 1196639Smckusick if (*sp == '^') { 1206639Smckusick circf++; 1216639Smckusick sp++; 1226639Smckusick } 1236639Smckusick if (wflag) 1246639Smckusick *ep++ = CBRC; 1256639Smckusick for (;;) { 1266639Smckusick if (ep >= &expbuf[ESIZE]) 1276639Smckusick goto cerror; 1286639Smckusick if ((c = *sp++) != '*') 1296639Smckusick lastep = ep; 1306639Smckusick switch (c) { 1316639Smckusick 1326639Smckusick case '\0': 1336639Smckusick if (wflag) 1346639Smckusick *ep++ = CLET; 1356639Smckusick *ep++ = CEOF; 1366639Smckusick return; 1376639Smckusick 1386639Smckusick case '.': 1396639Smckusick *ep++ = CDOT; 1406639Smckusick continue; 1416639Smckusick 1426639Smckusick case '*': 1436639Smckusick if (lastep==0) 1446639Smckusick goto defchar; 1456639Smckusick *lastep |= STAR; 1466639Smckusick continue; 1476639Smckusick 1486639Smckusick case '$': 1496639Smckusick if (*sp != '\0') 1506639Smckusick goto defchar; 1516639Smckusick *ep++ = CDOL; 1526639Smckusick continue; 1536639Smckusick 1546639Smckusick case '[': 1556639Smckusick *ep++ = CCL; 1566639Smckusick *ep++ = 0; 1576639Smckusick cclcnt = 1; 1586639Smckusick if ((c = *sp++) == '^') { 1596639Smckusick c = *sp++; 1606639Smckusick ep[-2] = NCCL; 1616639Smckusick } 1626639Smckusick do { 1636639Smckusick *ep++ = c; 1646639Smckusick cclcnt++; 1656639Smckusick if (c=='\0' || ep >= &expbuf[ESIZE]) 1666639Smckusick goto cerror; 1676639Smckusick } while ((c = *sp++) != ']'); 1686639Smckusick lastep[1] = cclcnt; 1696639Smckusick continue; 1706639Smckusick 1716639Smckusick case '\\': 1726639Smckusick if ((c = *sp++) == '\0') 1736639Smckusick goto cerror; 1746639Smckusick if (c == '<') { 1756639Smckusick *ep++ = CBRC; 1766639Smckusick continue; 1776639Smckusick } 1786639Smckusick if (c == '>') { 1796639Smckusick *ep++ = CLET; 1806639Smckusick continue; 1816639Smckusick } 1826639Smckusick defchar: 1836639Smckusick default: 1846639Smckusick *ep++ = CCHR; 1856639Smckusick *ep++ = c; 1866639Smckusick } 1876639Smckusick } 1886639Smckusick cerror: 1896639Smckusick fprintf(stderr, "RE error\n"); 1906639Smckusick } 1916639Smckusick 1926639Smckusick same(a, b) 1936639Smckusick register int a, b; 1946639Smckusick { 1956639Smckusick 1966639Smckusick return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b)); 1976639Smckusick } 1986639Smckusick 1996639Smckusick letter(c) 2006639Smckusick register int c; 2016639Smckusick { 2026639Smckusick 2036639Smckusick if (c >= 'a' && c <= 'z') 2046639Smckusick return (c); 2056639Smckusick if (c >= 'A' && c <= 'Z') 2066639Smckusick return (c + 'a' - 'A'); 2076639Smckusick return (0); 2086639Smckusick } 2096639Smckusick 2106639Smckusick execute(file) 2116639Smckusick { 2126639Smckusick register char *p1, *p2; 2136639Smckusick register c; 2146639Smckusick int f; 2156639Smckusick char *ebp, *cbp; 216*21391Smckusick static char *buf; 217*21391Smckusick static int blksize; 218*21391Smckusick struct stat stb; 2196639Smckusick 2206639Smckusick if (file) { 2216639Smckusick if ((f = open(file, 0)) < 0) { 22212090Smckusick perror(file); 2236639Smckusick } 2246639Smckusick } else 2256639Smckusick f = 0; 226*21391Smckusick if (buf == NULL) { 227*21391Smckusick if (fstat(f, &stb) > 0 && stb.st_blksize > 0) 228*21391Smckusick blksize = stb.st_blksize; 229*21391Smckusick else 230*21391Smckusick blksize = BLKSIZE; 231*21391Smckusick buf = (char *)malloc(blksize); 232*21391Smckusick if (buf == NULL) { 233*21391Smckusick fprintf(stderr, "egrep: no memory for %s\n", file); 234*21391Smckusick return; 235*21391Smckusick } 236*21391Smckusick } 237*21391Smckusick ebp = buf; 238*21391Smckusick cbp = buf; 2396639Smckusick lnum = 0; 2406639Smckusick tln = 0; 2416639Smckusick blkno = -1; 2426639Smckusick for (;;) { 2436639Smckusick lnum++; 2446639Smckusick if((lnum&0377) == 0) 2456639Smckusick fflush(stdout); 2466639Smckusick p1 = linebuf; 2476639Smckusick p2 = cbp; 2486639Smckusick for (;;) { 2496639Smckusick if (p2 >= ebp) { 250*21391Smckusick if ((c = read(f, buf, blksize)) <= 0) { 2516639Smckusick close(f); 2526639Smckusick if (cflag) { 2536639Smckusick if (lflag) { 2546639Smckusick if (tln) 2556639Smckusick printf("%s\n", file); 2566639Smckusick } else { 2576639Smckusick if (nfile > 1) 2586639Smckusick printf("%s:", file); 2596639Smckusick printf("%ld\n", tln); 2606639Smckusick } 2616639Smckusick } 2626639Smckusick return; 2636639Smckusick } 2646639Smckusick blkno++; 265*21391Smckusick p2 = buf; 266*21391Smckusick ebp = buf+c; 2676639Smckusick } 2686639Smckusick if ((c = *p2++) == '\n') 2696639Smckusick break; 2706639Smckusick if(c) 271*21391Smckusick if (p1 < &linebuf[BUFSIZ-1]) 2726639Smckusick *p1++ = c; 2736639Smckusick } 2746639Smckusick *p1++ = 0; 2756639Smckusick cbp = p2; 2766639Smckusick p1 = linebuf; 2776639Smckusick p2 = expbuf; 2786639Smckusick if (circf) { 2796639Smckusick if (advance(p1, p2)) 2806639Smckusick goto found; 2816639Smckusick goto nfound; 2826639Smckusick } 2836639Smckusick /* fast check for first character */ 2846639Smckusick if (*p2==CCHR) { 2856639Smckusick c = p2[1]; 2866639Smckusick do { 2876639Smckusick if (*p1!=c && (!iflag || (c ^ *p1) != ' ' 2886639Smckusick || letter(c) != letter(*p1))) 2896639Smckusick continue; 2906639Smckusick if (advance(p1, p2)) 2916639Smckusick goto found; 2926639Smckusick } while (*p1++); 2936639Smckusick goto nfound; 2946639Smckusick } 2956639Smckusick /* regular algorithm */ 2966639Smckusick do { 2976639Smckusick if (advance(p1, p2)) 2986639Smckusick goto found; 2996639Smckusick } while (*p1++); 3006639Smckusick nfound: 3016639Smckusick if (vflag) 3026639Smckusick succeed(file); 3036639Smckusick continue; 3046639Smckusick found: 3056639Smckusick if (vflag==0) 3066639Smckusick succeed(file); 3076639Smckusick } 3086639Smckusick } 3096639Smckusick 3106639Smckusick advance(alp, aep) 3116639Smckusick char *alp, *aep; 3126639Smckusick { 3136639Smckusick register char *lp, *ep, *curlp; 3146639Smckusick char *nextep; 3156639Smckusick 3166639Smckusick lp = alp; 3176639Smckusick ep = aep; 3186639Smckusick for (;;) switch (*ep++) { 3196639Smckusick 3206639Smckusick case CCHR: 3216639Smckusick if (!same(*ep, *lp)) 3226639Smckusick return (0); 3236639Smckusick ep++, lp++; 3246639Smckusick continue; 3256639Smckusick 3266639Smckusick case CDOT: 3276639Smckusick if (*lp++) 3286639Smckusick continue; 3296639Smckusick return(0); 3306639Smckusick 3316639Smckusick case CDOL: 3326639Smckusick if (*lp==0) 3336639Smckusick continue; 3346639Smckusick return(0); 3356639Smckusick 3366639Smckusick case CEOF: 3376639Smckusick return(1); 3386639Smckusick 3396639Smckusick case CCL: 3406639Smckusick if (cclass(ep, *lp++, 1)) { 3416639Smckusick ep += *ep; 3426639Smckusick continue; 3436639Smckusick } 3446639Smckusick return(0); 3456639Smckusick 3466639Smckusick case NCCL: 3476639Smckusick if (cclass(ep, *lp++, 0)) { 3486639Smckusick ep += *ep; 3496639Smckusick continue; 3506639Smckusick } 3516639Smckusick return(0); 3526639Smckusick 3536639Smckusick case CDOT|STAR: 3546639Smckusick curlp = lp; 3556639Smckusick while (*lp++); 3566639Smckusick goto star; 3576639Smckusick 3586639Smckusick case CCHR|STAR: 3596639Smckusick curlp = lp; 3606639Smckusick while (same(*lp, *ep)) 3616639Smckusick lp++; 3626639Smckusick lp++; 3636639Smckusick ep++; 3646639Smckusick goto star; 3656639Smckusick 3666639Smckusick case CCL|STAR: 3676639Smckusick case NCCL|STAR: 3686639Smckusick curlp = lp; 3696639Smckusick while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); 3706639Smckusick ep += *ep; 3716639Smckusick goto star; 3726639Smckusick 3736639Smckusick star: 3746639Smckusick do { 3756639Smckusick lp--; 3766639Smckusick if (advance(lp, ep)) 3776639Smckusick return(1); 3786639Smckusick } while (lp > curlp); 3796639Smckusick return(0); 3806639Smckusick 3816639Smckusick case CBRC: 3826639Smckusick if (lp == expbuf) 3836639Smckusick continue; 3846639Smckusick #define uletter(c) (letter(c) || c == '_') 3856639Smckusick if ( ( uletter(*lp) || digit ( * lp ) ) && !uletter(lp[-1]) && !digit(lp[-1])) 3866639Smckusick continue; 3876639Smckusick return (0); 3886639Smckusick 3896639Smckusick case CLET: 3906639Smckusick if (!uletter(*lp) && !digit(*lp)) 3916639Smckusick continue; 3926639Smckusick return (0); 3936639Smckusick 3946639Smckusick default: 3956639Smckusick fprintf(stderr, "RE botch\n"); 3966639Smckusick } 3976639Smckusick } 3986639Smckusick 3996639Smckusick cclass(aset, ac, af) 4006639Smckusick char *aset; 4016639Smckusick { 4026639Smckusick register char *set, c; 4036639Smckusick register n; 4046639Smckusick 4056639Smckusick set = aset; 4066639Smckusick if ((c = ac) == 0) 4076639Smckusick return(0); 4086639Smckusick n = *set++; 4096639Smckusick while (--n) 4106639Smckusick if (n > 2 && set[1] == '-') { 4116639Smckusick if (c >= (set[0] & 0177) && c <= (set[2] & 0177)) 4126639Smckusick return (af); 4136639Smckusick set += 3; 4146639Smckusick n -= 2; 4156639Smckusick } else 4166639Smckusick if ((*set++ & 0177) == c) 4176639Smckusick return(af); 4186639Smckusick return(!af); 4196639Smckusick } 4206639Smckusick 4216639Smckusick succeed(f) 4226639Smckusick { 4236639Smckusick nsucc = 1; 4246639Smckusick if (sflag) 4256639Smckusick return; 4266639Smckusick if (cflag) { 4276639Smckusick tln++; 4286639Smckusick return; 4296639Smckusick } 4306639Smckusick if (nfile > 1) 4316639Smckusick printf("%s:", f); 4326639Smckusick if (bflag) 4336639Smckusick printf("%d:", blkno); 4346639Smckusick if (nflag) 4356639Smckusick printf("%ld:", lnum); 4366639Smckusick printf("%s\n", linebuf); 4376639Smckusick } 4386639Smckusick 4396639Smckusick digit(c) 4406639Smckusick char c; 4416639Smckusick { 4426639Smckusick return (c>='0' && c<='9'); 4436639Smckusick } 444