|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)grep.c 4.3 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: #include <stdio.h> ! 6: /* ! 7: * grep -- print lines matching (or not matching) a pattern ! 8: */ ! 9: ! 10: #define CCHR 2 ! 11: #define CDOT 4 ! 12: #define CCL 6 ! 13: #define NCCL 8 ! 14: #define CDOL 10 ! 15: #define CEOF 11 ! 16: ! 17: #define CBRC 14 ! 18: #define CLET 15 ! 19: #define STAR 01 ! 20: ! 21: #define LBSIZE BUFSIZ ! 22: #define ESIZE 256 ! 23: ! 24: char expbuf[ESIZE]; ! 25: long lnum; ! 26: char linebuf[LBSIZE+1]; ! 27: int bflag; ! 28: int nflag; ! 29: int cflag; ! 30: int vflag; ! 31: int nfile; ! 32: int iflag; ! 33: int lflag; ! 34: int wflag; ! 35: int sflag; ! 36: int nsucc; ! 37: int circf; ! 38: int blkno; ! 39: char ibuf[BUFSIZ]; ! 40: long tln; ! 41: ! 42: main(argc, argv) ! 43: char **argv; ! 44: { ! 45: char obuf[BUFSIZ]; ! 46: ! 47: setbuf(stdout, obuf); ! 48: while (--argc > 0 && (++argv)[0][0]=='-') { ! 49: char *cp = argv[0] + 1; ! 50: while (*cp) switch (*cp++) { ! 51: ! 52: case 'v': ! 53: vflag++; ! 54: continue; ! 55: ! 56: case 'b': ! 57: bflag++; ! 58: continue; ! 59: ! 60: case 'i': ! 61: case 'y': /* -y for compatibility with btl grep */ ! 62: iflag++; ! 63: continue; ! 64: ! 65: case 'l': ! 66: lflag++; ! 67: case 'c': ! 68: cflag++; ! 69: continue; ! 70: ! 71: case 'w': ! 72: wflag++; ! 73: continue; ! 74: ! 75: case 's': ! 76: sflag++; ! 77: continue; ! 78: ! 79: case 'n': ! 80: nflag++; ! 81: continue; ! 82: ! 83: case 'e': ! 84: --argc; ! 85: ++argv; ! 86: goto out; ! 87: ! 88: default: ! 89: fprintf(stderr, "Unknown flag\n"); ! 90: continue; ! 91: } ! 92: } ! 93: out: ! 94: if (argc<=0) ! 95: exit(2); ! 96: compile(*argv); ! 97: nfile = --argc; ! 98: if (argc<=0) { ! 99: if (lflag) ! 100: exit(1); ! 101: execute(0); ! 102: } ! 103: else while (--argc >= 0) { ! 104: argv++; ! 105: execute(*argv); ! 106: } ! 107: exit(nsucc == 0); ! 108: } ! 109: ! 110: compile(astr) ! 111: char *astr; ! 112: { ! 113: register c; ! 114: register char *ep, *sp; ! 115: char *lastep; ! 116: int cclcnt; ! 117: ! 118: ep = expbuf; ! 119: sp = astr; ! 120: if (*sp == '^') { ! 121: circf++; ! 122: sp++; ! 123: } ! 124: if (wflag) ! 125: *ep++ = CBRC; ! 126: for (;;) { ! 127: if (ep >= &expbuf[ESIZE]) ! 128: goto cerror; ! 129: if ((c = *sp++) != '*') ! 130: lastep = ep; ! 131: switch (c) { ! 132: ! 133: case '\0': ! 134: if (wflag) ! 135: *ep++ = CLET; ! 136: *ep++ = CEOF; ! 137: return; ! 138: ! 139: case '.': ! 140: *ep++ = CDOT; ! 141: continue; ! 142: ! 143: case '*': ! 144: if (lastep==0) ! 145: goto defchar; ! 146: *lastep |= STAR; ! 147: continue; ! 148: ! 149: case '$': ! 150: if (*sp != '\0') ! 151: goto defchar; ! 152: *ep++ = CDOL; ! 153: continue; ! 154: ! 155: case '[': ! 156: *ep++ = CCL; ! 157: *ep++ = 0; ! 158: cclcnt = 1; ! 159: if ((c = *sp++) == '^') { ! 160: c = *sp++; ! 161: ep[-2] = NCCL; ! 162: } ! 163: do { ! 164: *ep++ = c; ! 165: cclcnt++; ! 166: if (c=='\0' || ep >= &expbuf[ESIZE]) ! 167: goto cerror; ! 168: } while ((c = *sp++) != ']'); ! 169: lastep[1] = cclcnt; ! 170: continue; ! 171: ! 172: case '\\': ! 173: if ((c = *sp++) == '\0') ! 174: goto cerror; ! 175: if (c == '<') { ! 176: *ep++ = CBRC; ! 177: continue; ! 178: } ! 179: if (c == '>') { ! 180: *ep++ = CLET; ! 181: continue; ! 182: } ! 183: defchar: ! 184: default: ! 185: *ep++ = CCHR; ! 186: *ep++ = c; ! 187: } ! 188: } ! 189: cerror: ! 190: fprintf(stderr, "RE error\n"); ! 191: } ! 192: ! 193: same(a, b) ! 194: register int a, b; ! 195: { ! 196: ! 197: return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b)); ! 198: } ! 199: ! 200: letter(c) ! 201: register int c; ! 202: { ! 203: ! 204: if (c >= 'a' && c <= 'z') ! 205: return (c); ! 206: if (c >= 'A' && c <= 'Z') ! 207: return (c + 'a' - 'A'); ! 208: return (0); ! 209: } ! 210: ! 211: execute(file) ! 212: { ! 213: register char *p1, *p2; ! 214: register c; ! 215: int f; ! 216: char *ebp, *cbp; ! 217: ! 218: if (file) { ! 219: if ((f = open(file, 0)) < 0) { ! 220: perror(file); ! 221: } ! 222: } else ! 223: f = 0; ! 224: ebp = ibuf; ! 225: cbp = ibuf; ! 226: lnum = 0; ! 227: tln = 0; ! 228: blkno = -1; ! 229: for (;;) { ! 230: lnum++; ! 231: if((lnum&0377) == 0) ! 232: fflush(stdout); ! 233: p1 = linebuf; ! 234: p2 = cbp; ! 235: for (;;) { ! 236: if (p2 >= ebp) { ! 237: if ((c = read(f, ibuf, BUFSIZ)) <= 0) { ! 238: close(f); ! 239: if (cflag) { ! 240: if (lflag) { ! 241: if (tln) ! 242: printf("%s\n", file); ! 243: } else { ! 244: if (nfile > 1) ! 245: printf("%s:", file); ! 246: printf("%ld\n", tln); ! 247: } ! 248: } ! 249: return; ! 250: } ! 251: blkno++; ! 252: p2 = ibuf; ! 253: ebp = ibuf+c; ! 254: } ! 255: if ((c = *p2++) == '\n') ! 256: break; ! 257: if(c) ! 258: if (p1 < &linebuf[LBSIZE-1]) ! 259: *p1++ = c; ! 260: } ! 261: *p1++ = 0; ! 262: cbp = p2; ! 263: p1 = linebuf; ! 264: p2 = expbuf; ! 265: if (circf) { ! 266: if (advance(p1, p2)) ! 267: goto found; ! 268: goto nfound; ! 269: } ! 270: /* fast check for first character */ ! 271: if (*p2==CCHR) { ! 272: c = p2[1]; ! 273: do { ! 274: if (*p1!=c && (!iflag || (c ^ *p1) != ' ' ! 275: || letter(c) != letter(*p1))) ! 276: continue; ! 277: if (advance(p1, p2)) ! 278: goto found; ! 279: } while (*p1++); ! 280: goto nfound; ! 281: } ! 282: /* regular algorithm */ ! 283: do { ! 284: if (advance(p1, p2)) ! 285: goto found; ! 286: } while (*p1++); ! 287: nfound: ! 288: if (vflag) ! 289: succeed(file); ! 290: continue; ! 291: found: ! 292: if (vflag==0) ! 293: succeed(file); ! 294: } ! 295: } ! 296: ! 297: advance(alp, aep) ! 298: char *alp, *aep; ! 299: { ! 300: register char *lp, *ep, *curlp; ! 301: char *nextep; ! 302: ! 303: lp = alp; ! 304: ep = aep; ! 305: for (;;) switch (*ep++) { ! 306: ! 307: case CCHR: ! 308: if (!same(*ep, *lp)) ! 309: return (0); ! 310: ep++, lp++; ! 311: continue; ! 312: ! 313: case CDOT: ! 314: if (*lp++) ! 315: continue; ! 316: return(0); ! 317: ! 318: case CDOL: ! 319: if (*lp==0) ! 320: continue; ! 321: return(0); ! 322: ! 323: case CEOF: ! 324: return(1); ! 325: ! 326: case CCL: ! 327: if (cclass(ep, *lp++, 1)) { ! 328: ep += *ep; ! 329: continue; ! 330: } ! 331: return(0); ! 332: ! 333: case NCCL: ! 334: if (cclass(ep, *lp++, 0)) { ! 335: ep += *ep; ! 336: continue; ! 337: } ! 338: return(0); ! 339: ! 340: case CDOT|STAR: ! 341: curlp = lp; ! 342: while (*lp++); ! 343: goto star; ! 344: ! 345: case CCHR|STAR: ! 346: curlp = lp; ! 347: while (same(*lp, *ep)) ! 348: lp++; ! 349: lp++; ! 350: ep++; ! 351: goto star; ! 352: ! 353: case CCL|STAR: ! 354: case NCCL|STAR: ! 355: curlp = lp; ! 356: while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); ! 357: ep += *ep; ! 358: goto star; ! 359: ! 360: star: ! 361: do { ! 362: lp--; ! 363: if (advance(lp, ep)) ! 364: return(1); ! 365: } while (lp > curlp); ! 366: return(0); ! 367: ! 368: case CBRC: ! 369: if (lp == expbuf) ! 370: continue; ! 371: #define uletter(c) (letter(c) || c == '_') ! 372: if ( ( uletter(*lp) || digit ( * lp ) ) && !uletter(lp[-1]) && !digit(lp[-1])) ! 373: continue; ! 374: return (0); ! 375: ! 376: case CLET: ! 377: if (!uletter(*lp) && !digit(*lp)) ! 378: continue; ! 379: return (0); ! 380: ! 381: default: ! 382: fprintf(stderr, "RE botch\n"); ! 383: } ! 384: } ! 385: ! 386: cclass(aset, ac, af) ! 387: char *aset; ! 388: { ! 389: register char *set, c; ! 390: register n; ! 391: ! 392: set = aset; ! 393: if ((c = ac) == 0) ! 394: return(0); ! 395: n = *set++; ! 396: while (--n) ! 397: if (n > 2 && set[1] == '-') { ! 398: if (c >= (set[0] & 0177) && c <= (set[2] & 0177)) ! 399: return (af); ! 400: set += 3; ! 401: n -= 2; ! 402: } else ! 403: if ((*set++ & 0177) == c) ! 404: return(af); ! 405: return(!af); ! 406: } ! 407: ! 408: succeed(f) ! 409: { ! 410: nsucc = 1; ! 411: if (sflag) ! 412: return; ! 413: if (cflag) { ! 414: tln++; ! 415: return; ! 416: } ! 417: if (nfile > 1) ! 418: printf("%s:", f); ! 419: if (bflag) ! 420: printf("%d:", blkno); ! 421: if (nflag) ! 422: printf("%ld:", lnum); ! 423: printf("%s\n", linebuf); ! 424: } ! 425: ! 426: digit(c) ! 427: char c; ! 428: { ! 429: return (c>='0' && c<='9'); ! 430: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.