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