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