1*6641Smckusick /* old.bin.grep.c 4.1 82/05/07 */ 2*6641Smckusick 3*6641Smckusick /* 4*6641Smckusick * grep -- print lines matching (or not matching) a pattern 5*6641Smckusick * 6*6641Smckusick * status returns: 7*6641Smckusick * 0 - ok, and some matches 8*6641Smckusick * 1 - ok, but no matches 9*6641Smckusick * 2 - some error 10*6641Smckusick */ 11*6641Smckusick 12*6641Smckusick #include <stdio.h> 13*6641Smckusick #include <ctype.h> 14*6641Smckusick 15*6641Smckusick #define CBRA 1 16*6641Smckusick #define CCHR 2 17*6641Smckusick #define CDOT 4 18*6641Smckusick #define CCL 6 19*6641Smckusick #define NCCL 8 20*6641Smckusick #define CDOL 10 21*6641Smckusick #define CEOF 11 22*6641Smckusick #define CKET 12 23*6641Smckusick #define CBACK 18 24*6641Smckusick 25*6641Smckusick #define STAR 01 26*6641Smckusick 27*6641Smckusick #define LBSIZE BUFSIZ 28*6641Smckusick #define ESIZE 256 29*6641Smckusick #define NBRA 9 30*6641Smckusick 31*6641Smckusick char expbuf[ESIZE]; 32*6641Smckusick long lnum; 33*6641Smckusick char linebuf[LBSIZE+1]; 34*6641Smckusick char ybuf[ESIZE]; 35*6641Smckusick int bflag; 36*6641Smckusick int lflag; 37*6641Smckusick int nflag; 38*6641Smckusick int cflag; 39*6641Smckusick int vflag; 40*6641Smckusick int nfile; 41*6641Smckusick int hflag = 1; 42*6641Smckusick int sflag; 43*6641Smckusick int yflag; 44*6641Smckusick int circf; 45*6641Smckusick int blkno; 46*6641Smckusick long tln; 47*6641Smckusick int nsucc; 48*6641Smckusick char *braslist[NBRA]; 49*6641Smckusick char *braelist[NBRA]; 50*6641Smckusick char bittab[] = { 51*6641Smckusick 1, 52*6641Smckusick 2, 53*6641Smckusick 4, 54*6641Smckusick 8, 55*6641Smckusick 16, 56*6641Smckusick 32, 57*6641Smckusick 64, 58*6641Smckusick 128 59*6641Smckusick }; 60*6641Smckusick 61*6641Smckusick main(argc, argv) 62*6641Smckusick char **argv; 63*6641Smckusick { 64*6641Smckusick extern char _sobuf[]; 65*6641Smckusick setbuf(stdout, _sobuf); 66*6641Smckusick while (--argc > 0 && (++argv)[0][0]=='-') 67*6641Smckusick switch (argv[0][1]) { 68*6641Smckusick 69*6641Smckusick case 'y': 70*6641Smckusick yflag++; 71*6641Smckusick continue; 72*6641Smckusick 73*6641Smckusick case 'h': 74*6641Smckusick hflag = 0; 75*6641Smckusick continue; 76*6641Smckusick 77*6641Smckusick case 's': 78*6641Smckusick sflag++; 79*6641Smckusick continue; 80*6641Smckusick 81*6641Smckusick case 'v': 82*6641Smckusick vflag++; 83*6641Smckusick continue; 84*6641Smckusick 85*6641Smckusick case 'b': 86*6641Smckusick bflag++; 87*6641Smckusick continue; 88*6641Smckusick 89*6641Smckusick case 'l': 90*6641Smckusick lflag++; 91*6641Smckusick continue; 92*6641Smckusick 93*6641Smckusick case 'c': 94*6641Smckusick cflag++; 95*6641Smckusick continue; 96*6641Smckusick 97*6641Smckusick case 'n': 98*6641Smckusick nflag++; 99*6641Smckusick continue; 100*6641Smckusick 101*6641Smckusick case 'e': 102*6641Smckusick --argc; 103*6641Smckusick ++argv; 104*6641Smckusick goto out; 105*6641Smckusick 106*6641Smckusick default: 107*6641Smckusick errexit("grep: unknown flag\n", (char *)NULL); 108*6641Smckusick continue; 109*6641Smckusick } 110*6641Smckusick out: 111*6641Smckusick if (argc<=0) 112*6641Smckusick exit(2); 113*6641Smckusick if (yflag) { 114*6641Smckusick register char *p, *s; 115*6641Smckusick for (s = ybuf, p = *argv; *p; ) { 116*6641Smckusick if (*p == '\\') { 117*6641Smckusick *s++ = *p++; 118*6641Smckusick if (*p) 119*6641Smckusick *s++ = *p++; 120*6641Smckusick } else if (*p == '[') { 121*6641Smckusick while (*p != '\0' && *p != ']') 122*6641Smckusick *s++ = *p++; 123*6641Smckusick } else if (islower(*p)) { 124*6641Smckusick *s++ = '['; 125*6641Smckusick *s++ = toupper(*p); 126*6641Smckusick *s++ = *p++; 127*6641Smckusick *s++ = ']'; 128*6641Smckusick } else 129*6641Smckusick *s++ = *p++; 130*6641Smckusick if (s >= ybuf+ESIZE-5) 131*6641Smckusick errexit("grep: argument too long\n", (char *)NULL); 132*6641Smckusick } 133*6641Smckusick *s = '\0'; 134*6641Smckusick *argv = ybuf; 135*6641Smckusick } 136*6641Smckusick compile(*argv); 137*6641Smckusick nfile = --argc; 138*6641Smckusick if (argc<=0) { 139*6641Smckusick if (lflag) 140*6641Smckusick exit(1); 141*6641Smckusick execute((char *)NULL); 142*6641Smckusick } else while (--argc >= 0) { 143*6641Smckusick argv++; 144*6641Smckusick execute(*argv); 145*6641Smckusick } 146*6641Smckusick exit(nsucc == 0); 147*6641Smckusick } 148*6641Smckusick 149*6641Smckusick compile(astr) 150*6641Smckusick char *astr; 151*6641Smckusick { 152*6641Smckusick register c; 153*6641Smckusick register char *ep, *sp; 154*6641Smckusick char *cstart; 155*6641Smckusick char *lastep; 156*6641Smckusick int cclcnt; 157*6641Smckusick char bracket[NBRA], *bracketp; 158*6641Smckusick int closed; 159*6641Smckusick char numbra; 160*6641Smckusick char neg; 161*6641Smckusick 162*6641Smckusick ep = expbuf; 163*6641Smckusick sp = astr; 164*6641Smckusick lastep = 0; 165*6641Smckusick bracketp = bracket; 166*6641Smckusick closed = numbra = 0; 167*6641Smckusick if (*sp == '^') { 168*6641Smckusick circf++; 169*6641Smckusick sp++; 170*6641Smckusick } 171*6641Smckusick for (;;) { 172*6641Smckusick if (ep >= &expbuf[ESIZE]) 173*6641Smckusick goto cerror; 174*6641Smckusick if ((c = *sp++) != '*') 175*6641Smckusick lastep = ep; 176*6641Smckusick switch (c) { 177*6641Smckusick 178*6641Smckusick case '\0': 179*6641Smckusick *ep++ = CEOF; 180*6641Smckusick return; 181*6641Smckusick 182*6641Smckusick case '.': 183*6641Smckusick *ep++ = CDOT; 184*6641Smckusick continue; 185*6641Smckusick 186*6641Smckusick case '*': 187*6641Smckusick if (lastep==0 || *lastep==CBRA || *lastep==CKET) 188*6641Smckusick goto defchar; 189*6641Smckusick *lastep |= STAR; 190*6641Smckusick continue; 191*6641Smckusick 192*6641Smckusick case '$': 193*6641Smckusick if (*sp != '\0') 194*6641Smckusick goto defchar; 195*6641Smckusick *ep++ = CDOL; 196*6641Smckusick continue; 197*6641Smckusick 198*6641Smckusick case '[': 199*6641Smckusick if(&ep[17] >= &expbuf[ESIZE]) 200*6641Smckusick goto cerror; 201*6641Smckusick *ep++ = CCL; 202*6641Smckusick neg = 0; 203*6641Smckusick if((c = *sp++) == '^') { 204*6641Smckusick neg = 1; 205*6641Smckusick c = *sp++; 206*6641Smckusick } 207*6641Smckusick cstart = sp; 208*6641Smckusick do { 209*6641Smckusick if (c=='\0') 210*6641Smckusick goto cerror; 211*6641Smckusick if (c=='-' && sp>cstart && *sp!=']') { 212*6641Smckusick for (c = sp[-2]; c<*sp; c++) 213*6641Smckusick ep[c>>3] |= bittab[c&07]; 214*6641Smckusick sp++; 215*6641Smckusick } 216*6641Smckusick ep[c>>3] |= bittab[c&07]; 217*6641Smckusick } while((c = *sp++) != ']'); 218*6641Smckusick if(neg) { 219*6641Smckusick for(cclcnt = 0; cclcnt < 16; cclcnt++) 220*6641Smckusick ep[cclcnt] ^= -1; 221*6641Smckusick ep[0] &= 0376; 222*6641Smckusick } 223*6641Smckusick 224*6641Smckusick ep += 16; 225*6641Smckusick 226*6641Smckusick continue; 227*6641Smckusick 228*6641Smckusick case '\\': 229*6641Smckusick if((c = *sp++) == '(') { 230*6641Smckusick if(numbra >= NBRA) { 231*6641Smckusick goto cerror; 232*6641Smckusick } 233*6641Smckusick *bracketp++ = numbra; 234*6641Smckusick *ep++ = CBRA; 235*6641Smckusick *ep++ = numbra++; 236*6641Smckusick continue; 237*6641Smckusick } 238*6641Smckusick if(c == ')') { 239*6641Smckusick if(bracketp <= bracket) { 240*6641Smckusick goto cerror; 241*6641Smckusick } 242*6641Smckusick *ep++ = CKET; 243*6641Smckusick *ep++ = *--bracketp; 244*6641Smckusick closed++; 245*6641Smckusick continue; 246*6641Smckusick } 247*6641Smckusick 248*6641Smckusick if(c >= '1' && c <= '9') { 249*6641Smckusick if((c -= '1') >= closed) 250*6641Smckusick goto cerror; 251*6641Smckusick *ep++ = CBACK; 252*6641Smckusick *ep++ = c; 253*6641Smckusick continue; 254*6641Smckusick } 255*6641Smckusick 256*6641Smckusick defchar: 257*6641Smckusick default: 258*6641Smckusick *ep++ = CCHR; 259*6641Smckusick *ep++ = c; 260*6641Smckusick } 261*6641Smckusick } 262*6641Smckusick cerror: 263*6641Smckusick errexit("grep: RE error\n", (char *)NULL); 264*6641Smckusick } 265*6641Smckusick 266*6641Smckusick execute(file) 267*6641Smckusick char *file; 268*6641Smckusick { 269*6641Smckusick register char *p1, *p2; 270*6641Smckusick register c; 271*6641Smckusick 272*6641Smckusick if (file) { 273*6641Smckusick if (freopen(file, "r", stdin) == NULL) 274*6641Smckusick errexit("grep: can't open %s\n", file); 275*6641Smckusick } 276*6641Smckusick lnum = 0; 277*6641Smckusick tln = 0; 278*6641Smckusick for (;;) { 279*6641Smckusick lnum++; 280*6641Smckusick p1 = linebuf; 281*6641Smckusick while ((c = getchar()) != '\n') { 282*6641Smckusick if (c == EOF) { 283*6641Smckusick if (cflag) { 284*6641Smckusick if (nfile>1) 285*6641Smckusick printf("%s:", file); 286*6641Smckusick printf("%D\n", tln); 287*6641Smckusick fflush(stdout); 288*6641Smckusick } 289*6641Smckusick return; 290*6641Smckusick } 291*6641Smckusick *p1++ = c; 292*6641Smckusick if (p1 >= &linebuf[LBSIZE-1]) 293*6641Smckusick break; 294*6641Smckusick } 295*6641Smckusick *p1++ = '\0'; 296*6641Smckusick p1 = linebuf; 297*6641Smckusick p2 = expbuf; 298*6641Smckusick if (circf) { 299*6641Smckusick if (advance(p1, p2)) 300*6641Smckusick goto found; 301*6641Smckusick goto nfound; 302*6641Smckusick } 303*6641Smckusick /* fast check for first character */ 304*6641Smckusick if (*p2==CCHR) { 305*6641Smckusick c = p2[1]; 306*6641Smckusick do { 307*6641Smckusick if (*p1!=c) 308*6641Smckusick continue; 309*6641Smckusick if (advance(p1, p2)) 310*6641Smckusick goto found; 311*6641Smckusick } while (*p1++); 312*6641Smckusick goto nfound; 313*6641Smckusick } 314*6641Smckusick /* regular algorithm */ 315*6641Smckusick do { 316*6641Smckusick if (advance(p1, p2)) 317*6641Smckusick goto found; 318*6641Smckusick } while (*p1++); 319*6641Smckusick nfound: 320*6641Smckusick if (vflag) 321*6641Smckusick succeed(file); 322*6641Smckusick continue; 323*6641Smckusick found: 324*6641Smckusick if (vflag==0) 325*6641Smckusick succeed(file); 326*6641Smckusick } 327*6641Smckusick } 328*6641Smckusick 329*6641Smckusick advance(lp, ep) 330*6641Smckusick register char *lp, *ep; 331*6641Smckusick { 332*6641Smckusick register char *curlp; 333*6641Smckusick char c; 334*6641Smckusick char *bbeg; 335*6641Smckusick int ct; 336*6641Smckusick 337*6641Smckusick for (;;) switch (*ep++) { 338*6641Smckusick 339*6641Smckusick case CCHR: 340*6641Smckusick if (*ep++ == *lp++) 341*6641Smckusick continue; 342*6641Smckusick return(0); 343*6641Smckusick 344*6641Smckusick case CDOT: 345*6641Smckusick if (*lp++) 346*6641Smckusick continue; 347*6641Smckusick return(0); 348*6641Smckusick 349*6641Smckusick case CDOL: 350*6641Smckusick if (*lp==0) 351*6641Smckusick continue; 352*6641Smckusick return(0); 353*6641Smckusick 354*6641Smckusick case CEOF: 355*6641Smckusick return(1); 356*6641Smckusick 357*6641Smckusick case CCL: 358*6641Smckusick c = *lp++ & 0177; 359*6641Smckusick if(ep[c>>3] & bittab[c & 07]) { 360*6641Smckusick ep += 16; 361*6641Smckusick continue; 362*6641Smckusick } 363*6641Smckusick return(0); 364*6641Smckusick case CBRA: 365*6641Smckusick braslist[*ep++] = lp; 366*6641Smckusick continue; 367*6641Smckusick 368*6641Smckusick case CKET: 369*6641Smckusick braelist[*ep++] = lp; 370*6641Smckusick continue; 371*6641Smckusick 372*6641Smckusick case CBACK: 373*6641Smckusick bbeg = braslist[*ep]; 374*6641Smckusick if (braelist[*ep]==0) 375*6641Smckusick return(0); 376*6641Smckusick ct = braelist[*ep++] - bbeg; 377*6641Smckusick if(ecmp(bbeg, lp, ct)) { 378*6641Smckusick lp += ct; 379*6641Smckusick continue; 380*6641Smckusick } 381*6641Smckusick return(0); 382*6641Smckusick 383*6641Smckusick case CBACK|STAR: 384*6641Smckusick bbeg = braslist[*ep]; 385*6641Smckusick if (braelist[*ep]==0) 386*6641Smckusick return(0); 387*6641Smckusick ct = braelist[*ep++] - bbeg; 388*6641Smckusick curlp = lp; 389*6641Smckusick while(ecmp(bbeg, lp, ct)) 390*6641Smckusick lp += ct; 391*6641Smckusick while(lp >= curlp) { 392*6641Smckusick if(advance(lp, ep)) return(1); 393*6641Smckusick lp -= ct; 394*6641Smckusick } 395*6641Smckusick return(0); 396*6641Smckusick 397*6641Smckusick 398*6641Smckusick case CDOT|STAR: 399*6641Smckusick curlp = lp; 400*6641Smckusick while (*lp++); 401*6641Smckusick goto star; 402*6641Smckusick 403*6641Smckusick case CCHR|STAR: 404*6641Smckusick curlp = lp; 405*6641Smckusick while (*lp++ == *ep); 406*6641Smckusick ep++; 407*6641Smckusick goto star; 408*6641Smckusick 409*6641Smckusick case CCL|STAR: 410*6641Smckusick curlp = lp; 411*6641Smckusick do { 412*6641Smckusick c = *lp++ & 0177; 413*6641Smckusick } while(ep[c>>3] & bittab[c & 07]); 414*6641Smckusick ep += 16; 415*6641Smckusick goto star; 416*6641Smckusick 417*6641Smckusick star: 418*6641Smckusick if(--lp == curlp) { 419*6641Smckusick continue; 420*6641Smckusick } 421*6641Smckusick 422*6641Smckusick if(*ep == CCHR) { 423*6641Smckusick c = ep[1]; 424*6641Smckusick do { 425*6641Smckusick if(*lp != c) 426*6641Smckusick continue; 427*6641Smckusick if(advance(lp, ep)) 428*6641Smckusick return(1); 429*6641Smckusick } while(lp-- > curlp); 430*6641Smckusick return(0); 431*6641Smckusick } 432*6641Smckusick 433*6641Smckusick do { 434*6641Smckusick if (advance(lp, ep)) 435*6641Smckusick return(1); 436*6641Smckusick } while (lp-- > curlp); 437*6641Smckusick return(0); 438*6641Smckusick 439*6641Smckusick default: 440*6641Smckusick errexit("grep RE botch\n", (char *)NULL); 441*6641Smckusick } 442*6641Smckusick } 443*6641Smckusick 444*6641Smckusick succeed(f) 445*6641Smckusick char *f; 446*6641Smckusick { 447*6641Smckusick nsucc = 1; 448*6641Smckusick if (sflag) 449*6641Smckusick return; 450*6641Smckusick if (cflag) { 451*6641Smckusick tln++; 452*6641Smckusick return; 453*6641Smckusick } 454*6641Smckusick if (lflag) { 455*6641Smckusick printf("%s\n", f); 456*6641Smckusick fflush(stdout); 457*6641Smckusick fseek(stdin, 0l, 2); 458*6641Smckusick return; 459*6641Smckusick } 460*6641Smckusick if (nfile > 1 && hflag) 461*6641Smckusick printf("%s:", f); 462*6641Smckusick if (bflag) 463*6641Smckusick printf("%u:", blkno); 464*6641Smckusick if (nflag) 465*6641Smckusick printf("%ld:", lnum); 466*6641Smckusick printf("%s\n", linebuf); 467*6641Smckusick fflush(stdout); 468*6641Smckusick } 469*6641Smckusick 470*6641Smckusick ecmp(a, b, count) 471*6641Smckusick char *a, *b; 472*6641Smckusick { 473*6641Smckusick register cc = count; 474*6641Smckusick while(cc--) 475*6641Smckusick if(*a++ != *b++) return(0); 476*6641Smckusick return(1); 477*6641Smckusick } 478*6641Smckusick 479*6641Smckusick errexit(s, f) 480*6641Smckusick char *s, *f; 481*6641Smckusick { 482*6641Smckusick fprintf(stderr, s, f); 483*6641Smckusick exit(2); 484*6641Smckusick } 485