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