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