|
|
1.1 ! root 1: static char *sccsid = "@(#)fgrep.c 4.1 (Berkeley) 10/1/80"; ! 2: /* ! 3: * fgrep -- print all lines containing any of a set of keywords ! 4: * ! 5: * status returns: ! 6: * 0 - ok, and some matches ! 7: * 1 - ok, but no matches ! 8: * 2 - some error ! 9: */ ! 10: /*#define DOSTATS /* define this to gather stats */ ! 11: #ifdef DOSTATS ! 12: char *statsexpr, *statspat; ! 13: long nlines, nbytes, nfail, ntrans0; ! 14: char statsflags[1024], *statsfptr = statsflags; ! 15: dostats(); ! 16: #endif ! 17: ! 18: #include "stdio.h" ! 19: # include "ctype.h" ! 20: ! 21: #define MAXSIZ 6000 ! 22: #define QSIZE 400 ! 23: struct words { ! 24: char inp; ! 25: char out; ! 26: struct words *nst; ! 27: struct words *link; ! 28: struct words *fail; ! 29: } w[MAXSIZ], *smax, *q; ! 30: ! 31: long lnum; ! 32: int bflag, cflag, fflag, lflag, nflag, vflag, xflag, iflag; ! 33: int hflag = 1; ! 34: int sflag; ! 35: int retcode = 0; ! 36: int nfile; ! 37: long blkno; ! 38: int nsucc; ! 39: long tln; ! 40: FILE *wordf; ! 41: char *argptr; ! 42: ! 43: /* ! 44: * preserve the interactive feel with stdio ! 45: */ ! 46: #define Read(f, b, s) (fflush(stdout), read(f, b, s)) ! 47: ! 48: main(argc, argv) ! 49: char **argv; ! 50: { ! 51: while (--argc > 0 && (++argv)[0][0]=='-'){ ! 52: #ifdef DOSTATS ! 53: *statsfptr++ = argv[0][1]; ! 54: #endif ! 55: switch (argv[0][1]) { ! 56: ! 57: case 's': ! 58: sflag++; ! 59: continue; ! 60: ! 61: case 'h': ! 62: hflag = 0; ! 63: continue; ! 64: ! 65: case 'b': ! 66: bflag++; ! 67: continue; ! 68: ! 69: case 'c': ! 70: cflag++; ! 71: continue; ! 72: ! 73: case 'e': ! 74: argc--; ! 75: argv++; ! 76: goto out; ! 77: ! 78: case 'f': ! 79: fflag++; ! 80: continue; ! 81: ! 82: case 'l': ! 83: lflag++; ! 84: continue; ! 85: ! 86: case 'n': ! 87: nflag++; ! 88: continue; ! 89: ! 90: case 'v': ! 91: vflag++; ! 92: continue; ! 93: ! 94: case 'x': ! 95: xflag++; ! 96: continue; ! 97: ! 98: case 'i': ! 99: iflag++; ! 100: continue; ! 101: default: ! 102: fprintf(stderr, "fgrep: unknown flag\n"); ! 103: continue; ! 104: } ! 105: } ! 106: out: ! 107: if (argc<=0) ! 108: exit(2); ! 109: if (fflag) { ! 110: wordf = fopen(*argv, "r"); ! 111: if (wordf==NULL) { ! 112: fprintf(stderr, "fgrep: can't open %s\n", *argv); ! 113: exit(2); ! 114: } ! 115: } ! 116: else argptr = *argv; ! 117: argc--; ! 118: argv++; ! 119: ! 120: #ifdef DOSTATS ! 121: statsexpr = statspat = (char *)malloc(MAXSIZ); ! 122: onexit(dostats); ! 123: #endif ! 124: cgotofn(); ! 125: cfail(); ! 126: nfile = argc; ! 127: if (argc<=0) { ! 128: if (lflag) exit(1); ! 129: execute((char *)NULL); ! 130: } ! 131: else while (--argc >= 0) { ! 132: execute(*argv); ! 133: argv++; ! 134: } ! 135: exit(retcode != 0 ? retcode : nsucc == 0); ! 136: } ! 137: ! 138: # define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b) ! 139: # define lca(x) (isupper(x) ? ((x)+'a'-'A') : x) ! 140: execute(file) ! 141: char *file; ! 142: { ! 143: register struct words *c; ! 144: register ccount; ! 145: register char ch; ! 146: register char *p; ! 147: char buf[2*BUFSIZ]; ! 148: int f; ! 149: int failed; ! 150: char *nlp; ! 151: if (file) { ! 152: if ((f = open(file, 0)) < 0) { ! 153: fprintf(stderr, "fgrep: can't open %s\n", file); ! 154: retcode = 2; ! 155: return; ! 156: } ! 157: } ! 158: else f = 0; ! 159: ccount = 0; ! 160: failed = 0; ! 161: lnum = 1; ! 162: tln = 0; ! 163: blkno = 0; ! 164: p = buf; ! 165: nlp = p; ! 166: c = w; ! 167: for (;;) { ! 168: if (--ccount <= 0) { ! 169: if (p == &buf[2*BUFSIZ]) p = buf; ! 170: if (p > &buf[BUFSIZ]) { ! 171: if ((ccount = Read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; ! 172: } ! 173: else if ((ccount = Read(f, p, BUFSIZ)) <= 0) break; ! 174: blkno += ccount; ! 175: } ! 176: nstate: ! 177: if (ccomp(c->inp, *p)) { ! 178: #ifdef DOSTATS ! 179: if(c == w) ntrans0++; ! 180: #endif ! 181: c = c->nst; ! 182: } ! 183: else if (c->link != 0) { ! 184: c = c->link; ! 185: goto nstate; ! 186: } ! 187: else { ! 188: #ifdef DOSTATS ! 189: nfail++; ! 190: #endif ! 191: c = c->fail; ! 192: failed = 1; ! 193: if (c==0) { ! 194: c = w; ! 195: istate: ! 196: if (ccomp(c->inp , *p)) { ! 197: c = c->nst; ! 198: } ! 199: else if (c->link != 0) { ! 200: c = c->link; ! 201: goto istate; ! 202: } ! 203: } ! 204: else goto nstate; ! 205: } ! 206: if (c->out) { ! 207: while (*p++ != '\n') { ! 208: if (--ccount <= 0) { ! 209: if (p == &buf[2*BUFSIZ]) p = buf; ! 210: if (p > &buf[BUFSIZ]) { ! 211: if ((ccount = Read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; ! 212: } ! 213: else if ((ccount = Read(f, p, BUFSIZ)) <= 0) break; ! 214: blkno += ccount; ! 215: } ! 216: } ! 217: if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) ) ! 218: goto nomatch; ! 219: succeed: nsucc = 1; ! 220: if (cflag) tln++; ! 221: else if (sflag) ! 222: ; /* ugh */ ! 223: else if (lflag) { ! 224: printf("%s\n", file); ! 225: close(f); ! 226: return; ! 227: } ! 228: else { ! 229: if (nfile > 1 && hflag) printf("%s:", file); ! 230: if (bflag) printf("%ld:", (blkno-ccount-1)/1024); ! 231: if (nflag) printf("%ld:", lnum); ! 232: if (p <= nlp) { ! 233: while (nlp < &buf[2*BUFSIZ]) putchar(*nlp++); ! 234: nlp = buf; ! 235: } ! 236: while (nlp < p) putchar(*nlp++); ! 237: } ! 238: nomatch: lnum++; ! 239: nlp = p; ! 240: c = w; ! 241: failed = 0; ! 242: continue; ! 243: } ! 244: if (*p++ == '\n') ! 245: if (vflag) goto succeed; ! 246: else { ! 247: lnum++; ! 248: nlp = p; ! 249: c = w; ! 250: failed = 0; ! 251: } ! 252: } ! 253: close(f); ! 254: if (cflag) { ! 255: if (nfile > 1) ! 256: printf("%s:", file); ! 257: printf("%ld\n", tln); ! 258: } ! 259: #ifdef DOSTATS ! 260: nbytes += blkno; ! 261: nlines += lnum-1; ! 262: #endif ! 263: } ! 264: ! 265: static int mailfd = -1; ! 266: ! 267: getargc() ! 268: { ! 269: register c; ! 270: if (wordf) ! 271: c = getc(wordf); ! 272: else if ((c = *argptr++) == '\0') ! 273: c = EOF; ! 274: #ifdef DOSTATS ! 275: if(c != EOF) *statsexpr++ = c; ! 276: #endif ! 277: return(c); ! 278: } ! 279: ! 280: cgotofn() { ! 281: register c; ! 282: register struct words *s; ! 283: ! 284: s = smax = w; ! 285: nword: for(;;) { ! 286: c = getargc(); ! 287: if (c==EOF) ! 288: return; ! 289: if (c == '\n') { ! 290: if (xflag) { ! 291: for(;;) { ! 292: if (s->inp == c) { ! 293: s = s->nst; ! 294: break; ! 295: } ! 296: if (s->inp == 0) goto nenter; ! 297: if (s->link == 0) { ! 298: if (smax >= &w[MAXSIZ -1]) overflo(); ! 299: s->link = ++smax; ! 300: s = smax; ! 301: goto nenter; ! 302: } ! 303: s = s->link; ! 304: } ! 305: } ! 306: s->out = 1; ! 307: s = w; ! 308: } else { ! 309: loop: if (s->inp == c) { ! 310: s = s->nst; ! 311: continue; ! 312: } ! 313: if (s->inp == 0) goto enter; ! 314: if (s->link == 0) { ! 315: if (smax >= &w[MAXSIZ - 1]) overflo(); ! 316: s->link = ++smax; ! 317: s = smax; ! 318: goto enter; ! 319: } ! 320: s = s->link; ! 321: goto loop; ! 322: } ! 323: } ! 324: ! 325: enter: ! 326: do { ! 327: s->inp = c; ! 328: if (smax >= &w[MAXSIZ - 1]) overflo(); ! 329: s->nst = ++smax; ! 330: s = smax; ! 331: } while ((c = getargc()) != '\n' && c!=EOF); ! 332: if (xflag) { ! 333: nenter: s->inp = '\n'; ! 334: if (smax >= &w[MAXSIZ -1]) overflo(); ! 335: s->nst = ++smax; ! 336: } ! 337: smax->out = 1; ! 338: s = w; ! 339: if (c != EOF) ! 340: goto nword; ! 341: } ! 342: ! 343: overflo() { ! 344: fprintf(stderr, "wordlist too large\n"); ! 345: exit(2); ! 346: } ! 347: cfail() { ! 348: struct words *queue[QSIZE]; ! 349: struct words **front, **rear; ! 350: struct words *state; ! 351: register char c; ! 352: register struct words *s; ! 353: s = w; ! 354: front = rear = queue; ! 355: init: if ((s->inp) != 0) { ! 356: *rear++ = s->nst; ! 357: if (rear >= &queue[QSIZE - 1]) overflo(); ! 358: } ! 359: if ((s = s->link) != 0) { ! 360: goto init; ! 361: } ! 362: ! 363: while (rear!=front) { ! 364: s = *front; /* s is next state in queue */ ! 365: if (front == &queue[QSIZE-1]) ! 366: front = queue; ! 367: else front++; ! 368: cloop: if ((c = s->inp) != 0) { /* g(s,c) != 0 */ ! 369: *rear = (q = s->nst); /* add q = g(s,c) to queue */ ! 370: if (front < rear) ! 371: if (rear >= &queue[QSIZE-1]) ! 372: if (front == queue) overflo(); ! 373: else rear = queue; ! 374: else rear++; ! 375: else ! 376: if (++rear == front) overflo(); ! 377: state = s->fail; /* state = f(s) */ ! 378: floop: if (state == 0) ! 379: state = w; ! 380: if (state->inp == c) ! 381: do { /* f(q) = g(state,c) for all q links */ ! 382: q->fail = state->nst; ! 383: if ((state->nst)->out == 1) q->out = 1; ! 384: } while ((q = q->link) != 0); ! 385: else if (state->link != 0) { ! 386: state = state->link; ! 387: goto floop; ! 388: } ! 389: else if ((state = state->fail) != 0) ! 390: goto floop; /* state = f(state) */ ! 391: } ! 392: if ((s = s->link) != 0) ! 393: goto cloop; ! 394: } ! 395: } ! 396: ! 397: #ifdef DOSTATS ! 398: #include <errno.h> ! 399: #define NAME "/tmp/grepdata" ! 400: dostats() ! 401: { ! 402: umask(0); ! 403: mailfd = open(NAME, 1); ! 404: if((mailfd < 0) && (errno != ECONC)){ ! 405: umask(0); ! 406: mailfd = creat(NAME, 03666); ! 407: } ! 408: if(mailfd >= 0){ ! 409: Finit(mailfd, (char *)0); ! 410: Fseek(mailfd, 0L, 2); ! 411: *statsexpr = 0; ! 412: *statsfptr = 0; ! 413: Fprint(mailfd, "\321fgrep:%s:%d:%d:%d:%d: %s\n", statsflags, nlines, nbytes, ntrans0, nfail, statspat); ! 414: } ! 415: Fflush(mailfd); ! 416: } ! 417: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.