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