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