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