|
|
1.1 ! root 1: /* ! 2: * grep -- print lines matching (or not matching) a pattern ! 3: * ! 4: * status returns: ! 5: * 0 - ok, and some matches ! 6: * 1 - ok, but no matches ! 7: * 2 - some error ! 8: */ ! 9: /*#define DOSTATS /* define this to gather stats */ ! 10: #ifdef DOSTATS ! 11: char *statsexpr; ! 12: long nlines, nbytes, ndepth, nmaxdepth; ! 13: char statsflags[1024], *statsfptr = statsflags; ! 14: dostats(); ! 15: #endif ! 16: ! 17: #include <ctype.h> ! 18: #include <stdio.h> ! 19: #include <fio.h> ! 20: ! 21: #define CBRA 1 ! 22: #define CCHR 2 ! 23: #define CDOT 4 ! 24: #define CCL 6 ! 25: #define NCCL 8 ! 26: #define CDOL 10 ! 27: #define CEOF 11 ! 28: #define CKET 12 ! 29: #define CBACK 18 ! 30: ! 31: #define STAR 01 ! 32: ! 33: #define LBSIZE 512 ! 34: #define ESIZE 256 ! 35: #define NBRA 9 ! 36: ! 37: char expbuf[ESIZE]; ! 38: long lnum; ! 39: char stdbuf[BUFSIZ]; ! 40: char *linebuf = stdbuf; ! 41: char ybuf[5000]; ! 42: int bflag; ! 43: int lflag; ! 44: int nflag; ! 45: int cflag; ! 46: int vflag; ! 47: int nfile; ! 48: int hflag = 1; ! 49: int sflag; ! 50: int scanexit; ! 51: int iflag; ! 52: int retcode = 0; ! 53: int circf; ! 54: long tln; ! 55: int nsucc; ! 56: char *braslist[NBRA]; ! 57: char *braelist[NBRA]; ! 58: char bittab[] = { ! 59: 1, ! 60: 2, ! 61: 4, ! 62: 8, ! 63: 16, ! 64: 32, ! 65: 64, ! 66: 128 ! 67: }; ! 68: ! 69: main(argc, argv) ! 70: char **argv; ! 71: { ! 72: extern etext(); ! 73: ! 74: while (--argc > 0 && (++argv)[0][0]=='-'){ ! 75: #ifdef DOSTATS ! 76: *statsfptr++ = argv[0][1]; ! 77: #endif ! 78: switch (argv[0][1]) { ! 79: ! 80: case 'i': ! 81: iflag++; ! 82: continue; ! 83: ! 84: case 'h': ! 85: hflag = 0; ! 86: continue; ! 87: ! 88: case 's': ! 89: sflag++; ! 90: continue; ! 91: ! 92: case 'v': ! 93: vflag++; ! 94: continue; ! 95: ! 96: case 'b': ! 97: bflag++; ! 98: continue; ! 99: ! 100: case 'l': ! 101: lflag++; ! 102: continue; ! 103: ! 104: case 'c': ! 105: cflag++; ! 106: continue; ! 107: ! 108: case 'n': ! 109: nflag++; ! 110: continue; ! 111: ! 112: case 'e': ! 113: --argc; ! 114: ++argv; ! 115: goto out; ! 116: ! 117: default: ! 118: errexit("grep: unknown flag %c\n", argv[0][1]); ! 119: continue; ! 120: } ! 121: } ! 122: out: ! 123: if (argc<=0) ! 124: exit(2); ! 125: if (iflag) { ! 126: register char *p; ! 127: for ( p = *argv; *p; p++ ) ! 128: *p = tolower(*p); ! 129: } ! 130: ! 131: #ifdef DOSTATS ! 132: statsexpr = (char *)strdup(*argv); ! 133: onexit(dostats); ! 134: #endif ! 135: compile(*argv); ! 136: nfile = --argc; ! 137: if (argc<=0) { ! 138: scanexit = 1; ! 139: execute("/dev/stdin"); ! 140: } else while (--argc >= 0) { ! 141: argv++; ! 142: scanexit = argc == 0; ! 143: execute(*argv); ! 144: } ! 145: exit (retcode != 0 ? retcode : nsucc == 0); ! 146: } ! 147: ! 148: compile(astr) ! 149: char *astr; ! 150: { ! 151: register c; ! 152: register char *ep, *sp; ! 153: char *cstart; ! 154: char *lastep; ! 155: int cclcnt; ! 156: char bracket[NBRA], *bracketp; ! 157: char numbra; ! 158: char neg; ! 159: ! 160: ep = expbuf; ! 161: sp = astr; ! 162: lastep = 0; ! 163: bracketp = bracket; ! 164: numbra = 0; ! 165: if (*sp == '^') { ! 166: circf++; ! 167: sp++; ! 168: } ! 169: for (;;) { ! 170: if (ep >= &expbuf[ESIZE]) ! 171: goto cerror; ! 172: if ((c = *sp++) != '*') ! 173: lastep = ep; ! 174: switch (c) { ! 175: ! 176: case '\0': ! 177: *ep++ = CEOF; ! 178: return; ! 179: ! 180: case '.': ! 181: *ep++ = CDOT; ! 182: continue; ! 183: ! 184: case '*': ! 185: if (lastep==0 || *lastep==CBRA || *lastep==CKET) ! 186: goto defchar; ! 187: *lastep |= STAR; ! 188: continue; ! 189: ! 190: case '$': ! 191: if (*sp != '\0') ! 192: goto defchar; ! 193: *ep++ = CDOL; ! 194: continue; ! 195: ! 196: case '[': ! 197: if(&ep[17] >= &expbuf[ESIZE]) ! 198: goto cerror; ! 199: *ep++ = CCL; ! 200: neg = 0; ! 201: if((c = *sp++) == '^') { ! 202: neg = 1; ! 203: c = *sp++; ! 204: } ! 205: cstart = sp; ! 206: do { ! 207: if (c=='\0') ! 208: goto cerror; ! 209: if (c=='-' && sp>cstart && *sp!=']') { ! 210: for (c = sp[-2]; c<*sp; c++) ! 211: ep[c>>3] |= bittab[c&07]; ! 212: sp++; ! 213: } ! 214: ep[c>>3] |= bittab[c&07]; ! 215: } while((c = *sp++) != ']'); ! 216: if(neg) { ! 217: for(cclcnt = 0; cclcnt < 16; cclcnt++) ! 218: ep[cclcnt] ^= -1; ! 219: ep[0] &= 0376; ! 220: } ! 221: ! 222: ep += 16; ! 223: ! 224: continue; ! 225: ! 226: case '\\': ! 227: if((c = *sp++) == '(') { ! 228: if(numbra >= NBRA) { ! 229: goto cerror; ! 230: } ! 231: *bracketp++ = numbra; ! 232: *ep++ = CBRA; ! 233: *ep++ = numbra++; ! 234: continue; ! 235: } ! 236: if(c == ')') { ! 237: if(bracketp <= bracket) { ! 238: goto cerror; ! 239: } ! 240: *ep++ = CKET; ! 241: *ep++ = *--bracketp; ! 242: continue; ! 243: } ! 244: ! 245: if(c >= '1' && c <= '9') { ! 246: char *bp; ! 247: c -= '1'; ! 248: if(c >= numbra) ! 249: goto cerror; ! 250: for(bp=bracket; bp<bracketp; bp++) ! 251: if(c == *bp) ! 252: goto cerror; ! 253: *ep++ = CBACK; ! 254: *ep++ = c; ! 255: continue; ! 256: } ! 257: ! 258: defchar: ! 259: default: ! 260: *ep++ = CCHR; ! 261: *ep++ = c; ! 262: } ! 263: } ! 264: cerror: ! 265: errexit("grep: RE error\n", (char *)0); ! 266: } ! 267: ! 268: execute(file) ! 269: char *file; ! 270: { ! 271: register char *p1, *p2; ! 272: register c; ! 273: register fd; ! 274: ! 275: if ((fd = open(file, 0)) < 0) { ! 276: Fprint(2, "grep: can't open %s\n", file); ! 277: retcode = 2; ! 278: return; ! 279: } ! 280: Finit(fd, (char *)0); ! 281: Ftie(fd, 1); ! 282: lnum = 0; ! 283: tln = 0; ! 284: for (;;) { ! 285: if (tln && lflag) { ! 286: close(fd); ! 287: return; ! 288: } ! 289: lnum++; ! 290: if((p1 = linebuf = Frdline(fd)) == 0) { ! 291: if (cflag) { ! 292: if (nfile>1) ! 293: Fprint(1, "%s:", file); ! 294: Fprint(1, "%ld\n", tln); ! 295: } ! 296: #ifdef DOSTATS ! 297: nbytes += FIOSEEK(fd); ! 298: nlines += lnum-1; ! 299: #endif ! 300: close(fd); ! 301: return; ! 302: } ! 303: if (iflag) { ! 304: char *s = p1; ! 305: char *t = ybuf; ! 306: do { ! 307: *t++ = tolower(*s); ! 308: } while (*s++); ! 309: p1 = ybuf; ! 310: } ! 311: p2 = expbuf; ! 312: if (circf) { ! 313: if (advance(p1, p2)) ! 314: goto found; ! 315: goto nfound; ! 316: } ! 317: /* fast check for first character */ ! 318: if (*p2==CCHR) { ! 319: c = p2[1]; ! 320: do { ! 321: if (*p1!=c) ! 322: continue; ! 323: if (advance(p1, p2)) ! 324: goto found; ! 325: } while (*p1++); ! 326: goto nfound; ! 327: } ! 328: /* regular algorithm */ ! 329: do { ! 330: if (advance(p1, p2)) ! 331: goto found; ! 332: } while (*p1++); ! 333: nfound: ! 334: if (vflag) ! 335: succeed(file, fd); ! 336: continue; ! 337: found: ! 338: if (vflag==0) ! 339: succeed(file, fd); ! 340: } ! 341: } ! 342: ! 343: advance(lp, ep) ! 344: register char *lp, *ep; ! 345: { ! 346: register char *curlp; ! 347: char c; ! 348: char *bbeg; ! 349: int ct; ! 350: ! 351: #ifdef DOSTATS ! 352: if(++ndepth > nmaxdepth) nmaxdepth = ndepth; ! 353: #endif ! 354: for (;;) switch (*ep++) { ! 355: ! 356: case CCHR: ! 357: if (*ep++ == *lp++) ! 358: continue; ! 359: #ifdef DOSTATS ! 360: ndepth--; ! 361: #endif ! 362: return(0); ! 363: ! 364: case CDOT: ! 365: if (*lp++) ! 366: continue; ! 367: #ifdef DOSTATS ! 368: ndepth--; ! 369: #endif ! 370: return(0); ! 371: ! 372: case CDOL: ! 373: if (*lp==0) ! 374: continue; ! 375: #ifdef DOSTATS ! 376: ndepth--; ! 377: #endif ! 378: return(0); ! 379: ! 380: case CEOF: ! 381: #ifdef DOSTATS ! 382: ndepth--; ! 383: #endif ! 384: return(1); ! 385: ! 386: case CCL: ! 387: c = *lp++ & 0177; ! 388: if(ep[c>>3] & bittab[c & 07]) { ! 389: ep += 16; ! 390: continue; ! 391: } ! 392: #ifdef DOSTATS ! 393: ndepth--; ! 394: #endif ! 395: return(0); ! 396: case CBRA: ! 397: braslist[*ep++] = lp; ! 398: continue; ! 399: ! 400: case CKET: ! 401: braelist[*ep++] = lp; ! 402: continue; ! 403: ! 404: case CBACK: ! 405: bbeg = braslist[*ep]; ! 406: if (braelist[*ep]==0){ ! 407: #ifdef DOSTATS ! 408: ndepth--; ! 409: #endif ! 410: return(0); ! 411: } ! 412: ct = braelist[*ep++] - bbeg; ! 413: if(ecmp(bbeg, lp, ct)) { ! 414: lp += ct; ! 415: continue; ! 416: } ! 417: #ifdef DOSTATS ! 418: ndepth--; ! 419: #endif ! 420: return(0); ! 421: ! 422: case CBACK|STAR: ! 423: bbeg = braslist[*ep]; ! 424: if (braelist[*ep]==0){ ! 425: #ifdef DOSTATS ! 426: ndepth--; ! 427: #endif ! 428: return(0); ! 429: } ! 430: ct = braelist[*ep++] - bbeg; ! 431: curlp = lp; ! 432: while(ecmp(bbeg, lp, ct)) ! 433: lp += ct; ! 434: while(lp >= curlp) { ! 435: if(advance(lp, ep)){ ! 436: #ifdef DOSTATS ! 437: ndepth--; ! 438: #endif ! 439: return(1); ! 440: } ! 441: lp -= ct; ! 442: } ! 443: #ifdef DOSTATS ! 444: ndepth--; ! 445: #endif ! 446: return(0); ! 447: ! 448: ! 449: case CDOT|STAR: ! 450: curlp = lp; ! 451: while (*lp++); ! 452: goto star; ! 453: ! 454: case CCHR|STAR: ! 455: curlp = lp; ! 456: while (*lp++ == *ep); ! 457: ep++; ! 458: goto star; ! 459: ! 460: case CCL|STAR: ! 461: curlp = lp; ! 462: do { ! 463: c = *lp++ & 0177; ! 464: } while(ep[c>>3] & bittab[c & 07]); ! 465: ep += 16; ! 466: goto star; ! 467: ! 468: star: ! 469: if(--lp == curlp) { ! 470: continue; ! 471: } ! 472: ! 473: if(*ep == CCHR) { ! 474: c = ep[1]; ! 475: do { ! 476: if(*lp != c) ! 477: continue; ! 478: if(advance(lp, ep)){ ! 479: #ifdef DOSTATS ! 480: ndepth--; ! 481: #endif ! 482: return(1); ! 483: } ! 484: } while(lp-- > curlp); ! 485: #ifdef DOSTATS ! 486: ndepth--; ! 487: #endif ! 488: return(0); ! 489: } ! 490: ! 491: do { ! 492: if (advance(lp, ep)){ ! 493: #ifdef DOSTATS ! 494: ndepth--; ! 495: #endif ! 496: return(1); ! 497: } ! 498: } while (lp-- > curlp); ! 499: #ifdef DOSTATS ! 500: ndepth--; ! 501: #endif ! 502: return(0); ! 503: ! 504: default: ! 505: errexit("grep RE botch\n", (char *)0); ! 506: } ! 507: } ! 508: ! 509: succeed(f, fd) ! 510: char *f; ! 511: int fd; ! 512: { ! 513: ! 514: nsucc = 1; ! 515: if (sflag){ ! 516: if(scanexit) exit(0); ! 517: return; ! 518: } ! 519: if (cflag) { ! 520: tln++; ! 521: return; ! 522: } ! 523: if (lflag) { ! 524: Fprint(1, "%s\n", f); ! 525: tln++; ! 526: return; ! 527: } ! 528: if (nfile > 1 && hflag) ! 529: Fprint(1, "%s:", f); ! 530: if (bflag) ! 531: Fprint(1, "%ld:", (FIOSEEK(fd)-FIOLINELEN(fd)-1)/1024); ! 532: if (nflag) ! 533: Fprint(1, "%ld:", lnum); ! 534: { ! 535: register x = FIOLINELEN(fd); ! 536: linebuf[x] = '\n'; ! 537: Fwrite(1, linebuf, x+1); ! 538: } ! 539: } ! 540: ! 541: ecmp(a, b, count) ! 542: char *a, *b; ! 543: { ! 544: register cc = count; ! 545: while(cc--) ! 546: if(*a++ != *b++) return(0); ! 547: return(1); ! 548: } ! 549: ! 550: errexit(s, f) ! 551: char *s, *f; ! 552: { ! 553: Fprint(2, s, f); ! 554: exit(2); ! 555: } ! 556: ! 557: #ifdef DOSTATS ! 558: #include <errno.h> ! 559: #define NAME "/tmp/grepdata" ! 560: dostats() ! 561: { ! 562: int mailfd; ! 563: ! 564: umask(0); ! 565: mailfd = open(NAME, 1); ! 566: if((mailfd < 0) && (errno != ECONC)){ ! 567: umask(0); ! 568: mailfd = creat(NAME, 03666); ! 569: } ! 570: if(mailfd >= 0){ ! 571: Finit(mailfd, (char *)0); ! 572: Fseek(mailfd, 0L, 2); ! 573: *statsfptr = 0; ! 574: Fprint(mailfd, "\321grep:%s:%d:%d:%d: %s\n", statsflags, nlines, nbytes, nmaxdepth, statsexpr); ! 575: Fflush(mailfd); ! 576: close(mailfd); ! 577: } ! 578: } ! 579: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.