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