|
|
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 <fio.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; ! 33: char ybuf[sizeof(Fbuffer)+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: fprintf(stderr, "panic: lflag\n"); ! 120: exit(1); ! 121: } ! 122: execute("/dev/stdin"); ! 123: } else while (--argc >= 0) { ! 124: argv++; ! 125: execute(*argv); ! 126: } ! 127: exit (retcode != 0 ? retcode : nsucc == 0); ! 128: } ! 129: ! 130: compile(astr) ! 131: char *astr; ! 132: { ! 133: register c; ! 134: register char *ep, *sp; ! 135: char *cstart; ! 136: char *lastep; ! 137: int cclcnt; ! 138: char bracket[NBRA], *bracketp; ! 139: int closed; ! 140: char numbra; ! 141: char neg; ! 142: ! 143: ep = expbuf; ! 144: sp = astr; ! 145: lastep = 0; ! 146: bracketp = bracket; ! 147: closed = numbra = 0; ! 148: if (*sp == '^') { ! 149: circf++; ! 150: sp++; ! 151: } ! 152: for (;;) { ! 153: if (ep >= &expbuf[ESIZE]) ! 154: goto cerror; ! 155: if ((c = *sp++) != '*') ! 156: lastep = ep; ! 157: switch (c) { ! 158: ! 159: case '\0': ! 160: *ep++ = CEOF; ! 161: return; ! 162: ! 163: case '.': ! 164: *ep++ = CDOT; ! 165: continue; ! 166: ! 167: case '*': ! 168: if (lastep==0 || *lastep==CBRA || *lastep==CKET) ! 169: goto defchar; ! 170: *lastep |= STAR; ! 171: continue; ! 172: ! 173: case '$': ! 174: if (*sp != '\0') ! 175: goto defchar; ! 176: *ep++ = CDOL; ! 177: continue; ! 178: ! 179: case '[': ! 180: if(&ep[17] >= &expbuf[ESIZE]) ! 181: goto cerror; ! 182: *ep++ = CCL; ! 183: neg = 0; ! 184: if((c = *sp++) == '^') { ! 185: neg = 1; ! 186: c = *sp++; ! 187: } ! 188: cstart = sp; ! 189: do { ! 190: if (c=='\0') ! 191: goto cerror; ! 192: if (c=='-' && sp>cstart && *sp!=']') { ! 193: for (c = sp[-2]; c<*sp; c++) ! 194: ep[c>>3] |= bittab[c&07]; ! 195: sp++; ! 196: } ! 197: ep[c>>3] |= bittab[c&07]; ! 198: } while((c = *sp++) != ']'); ! 199: if(neg) { ! 200: for(cclcnt = 0; cclcnt < 16; cclcnt++) ! 201: ep[cclcnt] ^= -1; ! 202: ep[0] &= 0376; ! 203: } ! 204: ! 205: ep += 16; ! 206: ! 207: continue; ! 208: ! 209: case '\\': ! 210: if((c = *sp++) == '(') { ! 211: if(numbra >= NBRA) { ! 212: goto cerror; ! 213: } ! 214: *bracketp++ = numbra; ! 215: *ep++ = CBRA; ! 216: *ep++ = numbra++; ! 217: continue; ! 218: } ! 219: if(c == ')') { ! 220: if(bracketp <= bracket) { ! 221: goto cerror; ! 222: } ! 223: *ep++ = CKET; ! 224: *ep++ = *--bracketp; ! 225: closed++; ! 226: continue; ! 227: } ! 228: ! 229: if(c >= '1' && c <= '9') { ! 230: if((c -= '1') >= closed) ! 231: goto cerror; ! 232: *ep++ = CBACK; ! 233: *ep++ = c; ! 234: continue; ! 235: } ! 236: ! 237: defchar: ! 238: default: ! 239: *ep++ = CCHR; ! 240: *ep++ = c; ! 241: } ! 242: } ! 243: cerror: ! 244: errexit("grep: RE error\n", (char *)NULL); ! 245: } ! 246: ! 247: execute(file) ! 248: char *file; ! 249: { ! 250: register char *p1, *p2; ! 251: register c; ! 252: register fd; ! 253: ! 254: if ((fd = open(file, 0)) < 0) { ! 255: fprintf(stderr, "grep: can't open %s\n", file); ! 256: retcode = 2; ! 257: return; ! 258: } ! 259: Finit(fd, (char *)0); ! 260: lnum = 0; ! 261: tln = 0; ! 262: for (;;) { ! 263: if (tln && lflag) { ! 264: close(fd); ! 265: return; ! 266: } ! 267: lnum++; ! 268: if((p1 = linebuf = Frdline(fd)) == 0) { ! 269: if (cflag) { ! 270: if (nfile>1) ! 271: printf("%s:", file); ! 272: printf("%ld\n", tln); ! 273: } ! 274: close(fd); ! 275: return; ! 276: } ! 277: if (iflag) { ! 278: char *s = p1; ! 279: char *t = ybuf; ! 280: do { ! 281: *t++ = tolower(*s); ! 282: } while (*s++); ! 283: p1 = ybuf; ! 284: } ! 285: p2 = expbuf; ! 286: if (circf) { ! 287: if (advance(p1, p2)) ! 288: goto found; ! 289: goto nfound; ! 290: } ! 291: /* fast check for first character */ ! 292: if (*p2==CCHR) { ! 293: c = p2[1]; ! 294: do { ! 295: if (*p1!=c) ! 296: continue; ! 297: if (advance(p1, p2)) ! 298: goto found; ! 299: } while (*p1++); ! 300: goto nfound; ! 301: } ! 302: /* regular algorithm */ ! 303: do { ! 304: if (advance(p1, p2)) ! 305: goto found; ! 306: } while (*p1++); ! 307: nfound: ! 308: if (vflag) ! 309: succeed(file, fd); ! 310: continue; ! 311: found: ! 312: if (vflag==0) ! 313: succeed(file, fd); ! 314: } ! 315: } ! 316: ! 317: advance(lp, ep) ! 318: register char *lp, *ep; ! 319: { ! 320: register char *curlp; ! 321: char c; ! 322: char *bbeg; ! 323: int ct; ! 324: ! 325: for (;;) switch (*ep++) { ! 326: ! 327: case CCHR: ! 328: if (*ep++ == *lp++) ! 329: continue; ! 330: return(0); ! 331: ! 332: case CDOT: ! 333: if (*lp++) ! 334: continue; ! 335: return(0); ! 336: ! 337: case CDOL: ! 338: if (*lp==0) ! 339: continue; ! 340: return(0); ! 341: ! 342: case CEOF: ! 343: return(1); ! 344: ! 345: case CCL: ! 346: c = *lp++ & 0177; ! 347: if(ep[c>>3] & bittab[c & 07]) { ! 348: ep += 16; ! 349: continue; ! 350: } ! 351: return(0); ! 352: case CBRA: ! 353: braslist[*ep++] = lp; ! 354: continue; ! 355: ! 356: case CKET: ! 357: braelist[*ep++] = lp; ! 358: continue; ! 359: ! 360: case CBACK: ! 361: bbeg = braslist[*ep]; ! 362: if (braelist[*ep]==0) ! 363: return(0); ! 364: ct = braelist[*ep++] - bbeg; ! 365: if(ecmp(bbeg, lp, ct)) { ! 366: lp += ct; ! 367: continue; ! 368: } ! 369: return(0); ! 370: ! 371: case CBACK|STAR: ! 372: bbeg = braslist[*ep]; ! 373: if (braelist[*ep]==0) ! 374: return(0); ! 375: ct = braelist[*ep++] - bbeg; ! 376: curlp = lp; ! 377: while(ecmp(bbeg, lp, ct)) ! 378: lp += ct; ! 379: while(lp >= curlp) { ! 380: if(advance(lp, ep)) return(1); ! 381: lp -= ct; ! 382: } ! 383: return(0); ! 384: ! 385: ! 386: case CDOT|STAR: ! 387: curlp = lp; ! 388: while (*lp++); ! 389: goto star; ! 390: ! 391: case CCHR|STAR: ! 392: curlp = lp; ! 393: while (*lp++ == *ep); ! 394: ep++; ! 395: goto star; ! 396: ! 397: case CCL|STAR: ! 398: curlp = lp; ! 399: do { ! 400: c = *lp++ & 0177; ! 401: } while(ep[c>>3] & bittab[c & 07]); ! 402: ep += 16; ! 403: goto star; ! 404: ! 405: star: ! 406: if(--lp == curlp) { ! 407: continue; ! 408: } ! 409: ! 410: if(*ep == CCHR) { ! 411: c = ep[1]; ! 412: do { ! 413: if(*lp != c) ! 414: continue; ! 415: if(advance(lp, ep)) ! 416: return(1); ! 417: } while(lp-- > curlp); ! 418: return(0); ! 419: } ! 420: ! 421: do { ! 422: if (advance(lp, ep)) ! 423: return(1); ! 424: } while (lp-- > curlp); ! 425: return(0); ! 426: ! 427: default: ! 428: errexit("grep RE botch\n", (char *)NULL); ! 429: } ! 430: } ! 431: ! 432: succeed(f, fd) ! 433: char *f; ! 434: { ! 435: long ftell(); ! 436: ! 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: tln++; ! 447: return; ! 448: } ! 449: if (nfile > 1 && hflag) ! 450: printf("%s:", f); ! 451: if (bflag) ! 452: printf("%ld:", (FIOSEEK(fd)-1)/1024); ! 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.