1*6639Smckusick /* old.ucb.grep.c 4.1 82/05/07 */ 2*6639Smckusick 3*6639Smckusick #include <stdio.h> 4*6639Smckusick /* 5*6639Smckusick * grep -- print lines matching (or not matching) a pattern 6*6639Smckusick */ 7*6639Smckusick 8*6639Smckusick #define CCHR 2 9*6639Smckusick #define CDOT 4 10*6639Smckusick #define CCL 6 11*6639Smckusick #define NCCL 8 12*6639Smckusick #define CDOL 10 13*6639Smckusick #define CEOF 11 14*6639Smckusick 15*6639Smckusick #define CBRC 14 16*6639Smckusick #define CLET 15 17*6639Smckusick #define STAR 01 18*6639Smckusick 19*6639Smckusick #define LBSIZE BUFSIZ 20*6639Smckusick #define ESIZE 256 21*6639Smckusick 22*6639Smckusick char expbuf[ESIZE]; 23*6639Smckusick long lnum; 24*6639Smckusick char linebuf[LBSIZE+1]; 25*6639Smckusick int bflag; 26*6639Smckusick int nflag; 27*6639Smckusick int cflag; 28*6639Smckusick int vflag; 29*6639Smckusick int nfile; 30*6639Smckusick int iflag; 31*6639Smckusick int lflag; 32*6639Smckusick int wflag; 33*6639Smckusick int sflag; 34*6639Smckusick int nsucc; 35*6639Smckusick int circf; 36*6639Smckusick int blkno; 37*6639Smckusick char ibuf[BUFSIZ]; 38*6639Smckusick long tln; 39*6639Smckusick 40*6639Smckusick main(argc, argv) 41*6639Smckusick char **argv; 42*6639Smckusick { 43*6639Smckusick char obuf[BUFSIZ]; 44*6639Smckusick 45*6639Smckusick setbuf(stdout, obuf); 46*6639Smckusick while (--argc > 0 && (++argv)[0][0]=='-') { 47*6639Smckusick char *cp = argv[0] + 1; 48*6639Smckusick while (*cp) switch (*cp++) { 49*6639Smckusick 50*6639Smckusick case 'v': 51*6639Smckusick vflag++; 52*6639Smckusick continue; 53*6639Smckusick 54*6639Smckusick case 'b': 55*6639Smckusick bflag++; 56*6639Smckusick continue; 57*6639Smckusick 58*6639Smckusick case 'i': 59*6639Smckusick case 'y': /* -y for compatibility with btl grep */ 60*6639Smckusick iflag++; 61*6639Smckusick continue; 62*6639Smckusick 63*6639Smckusick case 'l': 64*6639Smckusick lflag++; 65*6639Smckusick case 'c': 66*6639Smckusick cflag++; 67*6639Smckusick continue; 68*6639Smckusick 69*6639Smckusick case 'w': 70*6639Smckusick wflag++; 71*6639Smckusick continue; 72*6639Smckusick 73*6639Smckusick case 's': 74*6639Smckusick sflag++; 75*6639Smckusick continue; 76*6639Smckusick 77*6639Smckusick case 'n': 78*6639Smckusick nflag++; 79*6639Smckusick continue; 80*6639Smckusick 81*6639Smckusick case 'e': 82*6639Smckusick --argc; 83*6639Smckusick ++argv; 84*6639Smckusick goto out; 85*6639Smckusick 86*6639Smckusick default: 87*6639Smckusick fprintf(stderr, "Unknown flag\n"); 88*6639Smckusick continue; 89*6639Smckusick } 90*6639Smckusick } 91*6639Smckusick out: 92*6639Smckusick if (argc<=0) 93*6639Smckusick exit(2); 94*6639Smckusick compile(*argv); 95*6639Smckusick nfile = --argc; 96*6639Smckusick if (argc<=0) { 97*6639Smckusick if (lflag) 98*6639Smckusick exit(1); 99*6639Smckusick execute(0); 100*6639Smckusick } 101*6639Smckusick else while (--argc >= 0) { 102*6639Smckusick argv++; 103*6639Smckusick execute(*argv); 104*6639Smckusick } 105*6639Smckusick exit(nsucc == 0); 106*6639Smckusick } 107*6639Smckusick 108*6639Smckusick compile(astr) 109*6639Smckusick char *astr; 110*6639Smckusick { 111*6639Smckusick register c; 112*6639Smckusick register char *ep, *sp; 113*6639Smckusick char *lastep; 114*6639Smckusick int cclcnt; 115*6639Smckusick 116*6639Smckusick ep = expbuf; 117*6639Smckusick sp = astr; 118*6639Smckusick if (*sp == '^') { 119*6639Smckusick circf++; 120*6639Smckusick sp++; 121*6639Smckusick } 122*6639Smckusick if (wflag) 123*6639Smckusick *ep++ = CBRC; 124*6639Smckusick for (;;) { 125*6639Smckusick if (ep >= &expbuf[ESIZE]) 126*6639Smckusick goto cerror; 127*6639Smckusick if ((c = *sp++) != '*') 128*6639Smckusick lastep = ep; 129*6639Smckusick switch (c) { 130*6639Smckusick 131*6639Smckusick case '\0': 132*6639Smckusick if (wflag) 133*6639Smckusick *ep++ = CLET; 134*6639Smckusick *ep++ = CEOF; 135*6639Smckusick return; 136*6639Smckusick 137*6639Smckusick case '.': 138*6639Smckusick *ep++ = CDOT; 139*6639Smckusick continue; 140*6639Smckusick 141*6639Smckusick case '*': 142*6639Smckusick if (lastep==0) 143*6639Smckusick goto defchar; 144*6639Smckusick *lastep |= STAR; 145*6639Smckusick continue; 146*6639Smckusick 147*6639Smckusick case '$': 148*6639Smckusick if (*sp != '\0') 149*6639Smckusick goto defchar; 150*6639Smckusick *ep++ = CDOL; 151*6639Smckusick continue; 152*6639Smckusick 153*6639Smckusick case '[': 154*6639Smckusick *ep++ = CCL; 155*6639Smckusick *ep++ = 0; 156*6639Smckusick cclcnt = 1; 157*6639Smckusick if ((c = *sp++) == '^') { 158*6639Smckusick c = *sp++; 159*6639Smckusick ep[-2] = NCCL; 160*6639Smckusick } 161*6639Smckusick do { 162*6639Smckusick *ep++ = c; 163*6639Smckusick cclcnt++; 164*6639Smckusick if (c=='\0' || ep >= &expbuf[ESIZE]) 165*6639Smckusick goto cerror; 166*6639Smckusick } while ((c = *sp++) != ']'); 167*6639Smckusick lastep[1] = cclcnt; 168*6639Smckusick continue; 169*6639Smckusick 170*6639Smckusick case '\\': 171*6639Smckusick if ((c = *sp++) == '\0') 172*6639Smckusick goto cerror; 173*6639Smckusick if (c == '<') { 174*6639Smckusick *ep++ = CBRC; 175*6639Smckusick continue; 176*6639Smckusick } 177*6639Smckusick if (c == '>') { 178*6639Smckusick *ep++ = CLET; 179*6639Smckusick continue; 180*6639Smckusick } 181*6639Smckusick defchar: 182*6639Smckusick default: 183*6639Smckusick *ep++ = CCHR; 184*6639Smckusick *ep++ = c; 185*6639Smckusick } 186*6639Smckusick } 187*6639Smckusick cerror: 188*6639Smckusick fprintf(stderr, "RE error\n"); 189*6639Smckusick } 190*6639Smckusick 191*6639Smckusick same(a, b) 192*6639Smckusick register int a, b; 193*6639Smckusick { 194*6639Smckusick 195*6639Smckusick return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b)); 196*6639Smckusick } 197*6639Smckusick 198*6639Smckusick letter(c) 199*6639Smckusick register int c; 200*6639Smckusick { 201*6639Smckusick 202*6639Smckusick if (c >= 'a' && c <= 'z') 203*6639Smckusick return (c); 204*6639Smckusick if (c >= 'A' && c <= 'Z') 205*6639Smckusick return (c + 'a' - 'A'); 206*6639Smckusick return (0); 207*6639Smckusick } 208*6639Smckusick 209*6639Smckusick execute(file) 210*6639Smckusick { 211*6639Smckusick register char *p1, *p2; 212*6639Smckusick register c; 213*6639Smckusick int f; 214*6639Smckusick char *ebp, *cbp; 215*6639Smckusick 216*6639Smckusick if (file) { 217*6639Smckusick if ((f = open(file, 0)) < 0) { 218*6639Smckusick fprintf(stderr, "Can't open %s\n", file); 219*6639Smckusick } 220*6639Smckusick } else 221*6639Smckusick f = 0; 222*6639Smckusick ebp = ibuf; 223*6639Smckusick cbp = ibuf; 224*6639Smckusick lnum = 0; 225*6639Smckusick tln = 0; 226*6639Smckusick blkno = -1; 227*6639Smckusick for (;;) { 228*6639Smckusick lnum++; 229*6639Smckusick if((lnum&0377) == 0) 230*6639Smckusick fflush(stdout); 231*6639Smckusick p1 = linebuf; 232*6639Smckusick p2 = cbp; 233*6639Smckusick for (;;) { 234*6639Smckusick if (p2 >= ebp) { 235*6639Smckusick if ((c = read(f, ibuf, BUFSIZ)) <= 0) { 236*6639Smckusick close(f); 237*6639Smckusick if (cflag) { 238*6639Smckusick if (lflag) { 239*6639Smckusick if (tln) 240*6639Smckusick printf("%s\n", file); 241*6639Smckusick } else { 242*6639Smckusick if (nfile > 1) 243*6639Smckusick printf("%s:", file); 244*6639Smckusick printf("%ld\n", tln); 245*6639Smckusick } 246*6639Smckusick } 247*6639Smckusick return; 248*6639Smckusick } 249*6639Smckusick blkno++; 250*6639Smckusick p2 = ibuf; 251*6639Smckusick ebp = ibuf+c; 252*6639Smckusick } 253*6639Smckusick if ((c = *p2++) == '\n') 254*6639Smckusick break; 255*6639Smckusick if(c) 256*6639Smckusick if (p1 < &linebuf[LBSIZE-1]) 257*6639Smckusick *p1++ = c; 258*6639Smckusick } 259*6639Smckusick *p1++ = 0; 260*6639Smckusick cbp = p2; 261*6639Smckusick p1 = linebuf; 262*6639Smckusick p2 = expbuf; 263*6639Smckusick if (circf) { 264*6639Smckusick if (advance(p1, p2)) 265*6639Smckusick goto found; 266*6639Smckusick goto nfound; 267*6639Smckusick } 268*6639Smckusick /* fast check for first character */ 269*6639Smckusick if (*p2==CCHR) { 270*6639Smckusick c = p2[1]; 271*6639Smckusick do { 272*6639Smckusick if (*p1!=c && (!iflag || (c ^ *p1) != ' ' 273*6639Smckusick || letter(c) != letter(*p1))) 274*6639Smckusick continue; 275*6639Smckusick if (advance(p1, p2)) 276*6639Smckusick goto found; 277*6639Smckusick } while (*p1++); 278*6639Smckusick goto nfound; 279*6639Smckusick } 280*6639Smckusick /* regular algorithm */ 281*6639Smckusick do { 282*6639Smckusick if (advance(p1, p2)) 283*6639Smckusick goto found; 284*6639Smckusick } while (*p1++); 285*6639Smckusick nfound: 286*6639Smckusick if (vflag) 287*6639Smckusick succeed(file); 288*6639Smckusick continue; 289*6639Smckusick found: 290*6639Smckusick if (vflag==0) 291*6639Smckusick succeed(file); 292*6639Smckusick } 293*6639Smckusick } 294*6639Smckusick 295*6639Smckusick advance(alp, aep) 296*6639Smckusick char *alp, *aep; 297*6639Smckusick { 298*6639Smckusick register char *lp, *ep, *curlp; 299*6639Smckusick char *nextep; 300*6639Smckusick 301*6639Smckusick lp = alp; 302*6639Smckusick ep = aep; 303*6639Smckusick for (;;) switch (*ep++) { 304*6639Smckusick 305*6639Smckusick case CCHR: 306*6639Smckusick if (!same(*ep, *lp)) 307*6639Smckusick return (0); 308*6639Smckusick ep++, lp++; 309*6639Smckusick continue; 310*6639Smckusick 311*6639Smckusick case CDOT: 312*6639Smckusick if (*lp++) 313*6639Smckusick continue; 314*6639Smckusick return(0); 315*6639Smckusick 316*6639Smckusick case CDOL: 317*6639Smckusick if (*lp==0) 318*6639Smckusick continue; 319*6639Smckusick return(0); 320*6639Smckusick 321*6639Smckusick case CEOF: 322*6639Smckusick return(1); 323*6639Smckusick 324*6639Smckusick case CCL: 325*6639Smckusick if (cclass(ep, *lp++, 1)) { 326*6639Smckusick ep += *ep; 327*6639Smckusick continue; 328*6639Smckusick } 329*6639Smckusick return(0); 330*6639Smckusick 331*6639Smckusick case NCCL: 332*6639Smckusick if (cclass(ep, *lp++, 0)) { 333*6639Smckusick ep += *ep; 334*6639Smckusick continue; 335*6639Smckusick } 336*6639Smckusick return(0); 337*6639Smckusick 338*6639Smckusick case CDOT|STAR: 339*6639Smckusick curlp = lp; 340*6639Smckusick while (*lp++); 341*6639Smckusick goto star; 342*6639Smckusick 343*6639Smckusick case CCHR|STAR: 344*6639Smckusick curlp = lp; 345*6639Smckusick while (same(*lp, *ep)) 346*6639Smckusick lp++; 347*6639Smckusick lp++; 348*6639Smckusick ep++; 349*6639Smckusick goto star; 350*6639Smckusick 351*6639Smckusick case CCL|STAR: 352*6639Smckusick case NCCL|STAR: 353*6639Smckusick curlp = lp; 354*6639Smckusick while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); 355*6639Smckusick ep += *ep; 356*6639Smckusick goto star; 357*6639Smckusick 358*6639Smckusick star: 359*6639Smckusick do { 360*6639Smckusick lp--; 361*6639Smckusick if (advance(lp, ep)) 362*6639Smckusick return(1); 363*6639Smckusick } while (lp > curlp); 364*6639Smckusick return(0); 365*6639Smckusick 366*6639Smckusick case CBRC: 367*6639Smckusick if (lp == expbuf) 368*6639Smckusick continue; 369*6639Smckusick #define uletter(c) (letter(c) || c == '_') 370*6639Smckusick if ( ( uletter(*lp) || digit ( * lp ) ) && !uletter(lp[-1]) && !digit(lp[-1])) 371*6639Smckusick continue; 372*6639Smckusick return (0); 373*6639Smckusick 374*6639Smckusick case CLET: 375*6639Smckusick if (!uletter(*lp) && !digit(*lp)) 376*6639Smckusick continue; 377*6639Smckusick return (0); 378*6639Smckusick 379*6639Smckusick default: 380*6639Smckusick fprintf(stderr, "RE botch\n"); 381*6639Smckusick } 382*6639Smckusick } 383*6639Smckusick 384*6639Smckusick cclass(aset, ac, af) 385*6639Smckusick char *aset; 386*6639Smckusick { 387*6639Smckusick register char *set, c; 388*6639Smckusick register n; 389*6639Smckusick 390*6639Smckusick set = aset; 391*6639Smckusick if ((c = ac) == 0) 392*6639Smckusick return(0); 393*6639Smckusick n = *set++; 394*6639Smckusick while (--n) 395*6639Smckusick if (n > 2 && set[1] == '-') { 396*6639Smckusick if (c >= (set[0] & 0177) && c <= (set[2] & 0177)) 397*6639Smckusick return (af); 398*6639Smckusick set += 3; 399*6639Smckusick n -= 2; 400*6639Smckusick } else 401*6639Smckusick if ((*set++ & 0177) == c) 402*6639Smckusick return(af); 403*6639Smckusick return(!af); 404*6639Smckusick } 405*6639Smckusick 406*6639Smckusick succeed(f) 407*6639Smckusick { 408*6639Smckusick nsucc = 1; 409*6639Smckusick if (sflag) 410*6639Smckusick return; 411*6639Smckusick if (cflag) { 412*6639Smckusick tln++; 413*6639Smckusick return; 414*6639Smckusick } 415*6639Smckusick if (nfile > 1) 416*6639Smckusick printf("%s:", f); 417*6639Smckusick if (bflag) 418*6639Smckusick printf("%d:", blkno); 419*6639Smckusick if (nflag) 420*6639Smckusick printf("%ld:", lnum); 421*6639Smckusick printf("%s\n", linebuf); 422*6639Smckusick } 423*6639Smckusick 424*6639Smckusick digit(c) 425*6639Smckusick char c; 426*6639Smckusick { 427*6639Smckusick return (c>='0' && c<='9'); 428*6639Smckusick } 429