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