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