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