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