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