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