1*32365Sbostic static char *sccsid = "@(#)old.fgrep.c 4.4 (Berkeley) 10/07/87"; 21010Sbill /* 31010Sbill * fgrep -- print all lines containing any of a set of keywords 41010Sbill * 51010Sbill * status returns: 61010Sbill * 0 - ok, and some matches 71010Sbill * 1 - ok, but no matches 81010Sbill * 2 - some error 91010Sbill */ 101010Sbill 118726Smckusick #include <stdio.h> 128726Smckusick #include <ctype.h> 1321395Smckusick #include <sys/param.h> 1421395Smckusick #include <sys/stat.h> 151010Sbill 1621395Smckusick #define BLKSIZE 8192 171010Sbill #define MAXSIZ 6000 181010Sbill #define QSIZE 400 191010Sbill struct words { 201010Sbill char inp; 211010Sbill char out; 221010Sbill struct words *nst; 231010Sbill struct words *link; 241010Sbill struct words *fail; 251010Sbill } w[MAXSIZ], *smax, *q; 261010Sbill 271010Sbill long lnum; 281010Sbill int bflag, cflag, fflag, lflag, nflag, vflag, xflag, yflag; 291010Sbill int hflag = 1; 30*32365Sbostic int oflag; 311010Sbill int sflag; 321010Sbill int retcode = 0; 331010Sbill int nfile; 341010Sbill long blkno; 351010Sbill int nsucc; 361010Sbill long tln; 371010Sbill FILE *wordf; 381010Sbill char *argptr; 391010Sbill 401010Sbill main(argc, argv) 411010Sbill char **argv; 421010Sbill { 431010Sbill while (--argc > 0 && (++argv)[0][0]=='-') 441010Sbill switch (argv[0][1]) { 451010Sbill 461010Sbill case 's': 471010Sbill sflag++; 481010Sbill continue; 491010Sbill 501010Sbill case 'h': 511010Sbill hflag = 0; 521010Sbill continue; 531010Sbill 54*32365Sbostic case 'o': 55*32365Sbostic oflag++; 56*32365Sbostic continue; 57*32365Sbostic 581010Sbill case 'b': 591010Sbill bflag++; 601010Sbill continue; 611010Sbill 621010Sbill case 'c': 631010Sbill cflag++; 641010Sbill continue; 651010Sbill 661010Sbill case 'e': 671010Sbill argc--; 681010Sbill argv++; 691010Sbill goto out; 701010Sbill 711010Sbill case 'f': 721010Sbill fflag++; 731010Sbill continue; 741010Sbill 751010Sbill case 'l': 761010Sbill lflag++; 771010Sbill continue; 781010Sbill 791010Sbill case 'n': 801010Sbill nflag++; 811010Sbill continue; 821010Sbill 831010Sbill case 'v': 841010Sbill vflag++; 851010Sbill continue; 861010Sbill 871010Sbill case 'x': 881010Sbill xflag++; 891010Sbill continue; 901010Sbill 911010Sbill case 'i': /* Berkeley */ 921010Sbill case 'y': /* Btl */ 931010Sbill yflag++; 941010Sbill continue; 951010Sbill default: 961010Sbill fprintf(stderr, "fgrep: unknown flag\n"); 971010Sbill continue; 981010Sbill } 991010Sbill out: 1001010Sbill if (argc<=0) 1011010Sbill exit(2); 1021010Sbill if (fflag) { 1031010Sbill wordf = fopen(*argv, "r"); 1041010Sbill if (wordf==NULL) { 1051010Sbill fprintf(stderr, "fgrep: can't open %s\n", *argv); 1061010Sbill exit(2); 1071010Sbill } 1081010Sbill } 1091010Sbill else argptr = *argv; 1101010Sbill argc--; 1111010Sbill argv++; 1121010Sbill 1131010Sbill cgotofn(); 1141010Sbill cfail(); 1151010Sbill nfile = argc; 1161010Sbill if (argc<=0) { 1171010Sbill if (lflag) exit(1); 1181010Sbill execute((char *)NULL); 1191010Sbill } 1201010Sbill else while (--argc >= 0) { 1211010Sbill execute(*argv); 1221010Sbill argv++; 1231010Sbill } 1241010Sbill exit(retcode != 0 ? retcode : nsucc == 0); 1251010Sbill } 1261010Sbill 1271010Sbill # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b) 1281010Sbill # define lca(x) (isupper(x) ? tolower(x) : x) 1291010Sbill execute(file) 1301010Sbill char *file; 1311010Sbill { 1321010Sbill register struct words *c; 1331010Sbill register ccount; 1341010Sbill register char ch; 1351010Sbill register char *p; 13621395Smckusick static char *buf; 13721395Smckusick static int blksize; 13821395Smckusick struct stat stb; 1391010Sbill int f; 1401010Sbill int failed; 1411010Sbill char *nlp; 1421010Sbill if (file) { 1431010Sbill if ((f = open(file, 0)) < 0) { 1441010Sbill fprintf(stderr, "fgrep: can't open %s\n", file); 1451010Sbill retcode = 2; 1461010Sbill return; 1471010Sbill } 1481010Sbill } 1491010Sbill else f = 0; 15021395Smckusick if (buf == NULL) { 15121395Smckusick if (fstat(f, &stb) > 0 && stb.st_blksize > 0) 15221395Smckusick blksize = stb.st_blksize; 15321395Smckusick else 15421395Smckusick blksize = BLKSIZE; 15521395Smckusick buf = (char *)malloc(2*blksize); 15621395Smckusick if (buf == NULL) { 15721395Smckusick fprintf(stderr, "egrep: no memory for %s\n", file); 15821395Smckusick retcode = 2; 15921395Smckusick return; 16021395Smckusick } 16121395Smckusick } 1621010Sbill ccount = 0; 1631010Sbill failed = 0; 1641010Sbill lnum = 1; 1651010Sbill tln = 0; 1661010Sbill blkno = 0; 1671010Sbill p = buf; 1681010Sbill nlp = p; 1691010Sbill c = w; 1701010Sbill for (;;) { 1711010Sbill if (--ccount <= 0) { 17221395Smckusick if (p == &buf[2*blksize]) p = buf; 17321395Smckusick if (p > &buf[blksize]) { 17421395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 1751010Sbill } 17621395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 1771010Sbill blkno += ccount; 1781010Sbill } 1791010Sbill nstate: 1801010Sbill if (ccomp(c->inp, *p)) { 1811010Sbill c = c->nst; 1821010Sbill } 1831010Sbill else if (c->link != 0) { 1841010Sbill c = c->link; 1851010Sbill goto nstate; 1861010Sbill } 1871010Sbill else { 1881010Sbill c = c->fail; 1891010Sbill failed = 1; 1901010Sbill if (c==0) { 1911010Sbill c = w; 1921010Sbill istate: 1931010Sbill if (ccomp(c->inp , *p)) { 1941010Sbill c = c->nst; 1951010Sbill } 1961010Sbill else if (c->link != 0) { 1971010Sbill c = c->link; 1981010Sbill goto istate; 1991010Sbill } 2001010Sbill } 2011010Sbill else goto nstate; 2021010Sbill } 2031010Sbill if (c->out) { 2041010Sbill while (*p++ != '\n') { 2051010Sbill if (--ccount <= 0) { 20621395Smckusick if (p == &buf[2*blksize]) p = buf; 20721395Smckusick if (p > &buf[blksize]) { 20821395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 2091010Sbill } 21021395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 2111010Sbill blkno += ccount; 2121010Sbill } 2131010Sbill } 2141010Sbill if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) ) 2151010Sbill goto nomatch; 2161010Sbill succeed: nsucc = 1; 2171010Sbill if (cflag) tln++; 2181010Sbill else if (sflag) 2191010Sbill ; /* ugh */ 2201010Sbill else if (lflag) { 2211010Sbill printf("%s\n", file); 2221010Sbill close(f); 2231010Sbill return; 2241010Sbill } 2251010Sbill else { 226*32365Sbostic if (nfile > 1 && hflag || oflag) printf("%s:", file); 22721395Smckusick if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE); 2281010Sbill if (nflag) printf("%ld:", lnum); 2291010Sbill if (p <= nlp) { 23021395Smckusick while (nlp < &buf[2*blksize]) putchar(*nlp++); 2311010Sbill nlp = buf; 2321010Sbill } 2331010Sbill while (nlp < p) putchar(*nlp++); 2341010Sbill } 2351010Sbill nomatch: lnum++; 2361010Sbill nlp = p; 2371010Sbill c = w; 2381010Sbill failed = 0; 2391010Sbill continue; 2401010Sbill } 2411010Sbill if (*p++ == '\n') 2421010Sbill if (vflag) goto succeed; 2431010Sbill else { 2441010Sbill lnum++; 2451010Sbill nlp = p; 2461010Sbill c = w; 2471010Sbill failed = 0; 2481010Sbill } 2491010Sbill } 2501010Sbill close(f); 2511010Sbill if (cflag) { 2521010Sbill if (nfile > 1) 2531010Sbill printf("%s:", file); 2541010Sbill printf("%ld\n", tln); 2551010Sbill } 2561010Sbill } 2571010Sbill 2581010Sbill getargc() 2591010Sbill { 2601010Sbill register c; 2611010Sbill if (wordf) 2621010Sbill return(getc(wordf)); 2631010Sbill if ((c = *argptr++) == '\0') 2641010Sbill return(EOF); 2651010Sbill return(c); 2661010Sbill } 2671010Sbill 2681010Sbill cgotofn() { 2691010Sbill register c; 2701010Sbill register struct words *s; 2711010Sbill 2721010Sbill s = smax = w; 2731010Sbill nword: for(;;) { 2741010Sbill c = getargc(); 2751010Sbill if (c==EOF) 2761010Sbill return; 2771010Sbill if (c == '\n') { 2781010Sbill if (xflag) { 2791010Sbill for(;;) { 2801010Sbill if (s->inp == c) { 2811010Sbill s = s->nst; 2821010Sbill break; 2831010Sbill } 2841010Sbill if (s->inp == 0) goto nenter; 2851010Sbill if (s->link == 0) { 2861010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 2871010Sbill s->link = ++smax; 2881010Sbill s = smax; 2891010Sbill goto nenter; 2901010Sbill } 2911010Sbill s = s->link; 2921010Sbill } 2931010Sbill } 2941010Sbill s->out = 1; 2951010Sbill s = w; 2961010Sbill } else { 2971010Sbill loop: if (s->inp == c) { 2981010Sbill s = s->nst; 2991010Sbill continue; 3001010Sbill } 3011010Sbill if (s->inp == 0) goto enter; 3021010Sbill if (s->link == 0) { 3031010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 3041010Sbill s->link = ++smax; 3051010Sbill s = smax; 3061010Sbill goto enter; 3071010Sbill } 3081010Sbill s = s->link; 3091010Sbill goto loop; 3101010Sbill } 3111010Sbill } 3121010Sbill 3131010Sbill enter: 3141010Sbill do { 3151010Sbill s->inp = c; 3161010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 3171010Sbill s->nst = ++smax; 3181010Sbill s = smax; 3191010Sbill } while ((c = getargc()) != '\n' && c!=EOF); 3201010Sbill if (xflag) { 3211010Sbill nenter: s->inp = '\n'; 3221010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 3231010Sbill s->nst = ++smax; 3241010Sbill } 3251010Sbill smax->out = 1; 3261010Sbill s = w; 3271010Sbill if (c != EOF) 3281010Sbill goto nword; 3291010Sbill } 3301010Sbill 3311010Sbill overflo() { 3321010Sbill fprintf(stderr, "wordlist too large\n"); 3331010Sbill exit(2); 3341010Sbill } 3351010Sbill cfail() { 3361010Sbill struct words *queue[QSIZE]; 3371010Sbill struct words **front, **rear; 3381010Sbill struct words *state; 3391010Sbill int bstart; 3401010Sbill register char c; 3411010Sbill register struct words *s; 3421010Sbill s = w; 3431010Sbill front = rear = queue; 3441010Sbill init: if ((s->inp) != 0) { 3451010Sbill *rear++ = s->nst; 3461010Sbill if (rear >= &queue[QSIZE - 1]) overflo(); 3471010Sbill } 3481010Sbill if ((s = s->link) != 0) { 3491010Sbill goto init; 3501010Sbill } 3511010Sbill 3521010Sbill while (rear!=front) { 3531010Sbill s = *front; 3541010Sbill if (front == &queue[QSIZE-1]) 3551010Sbill front = queue; 3561010Sbill else front++; 3571010Sbill cloop: if ((c = s->inp) != 0) { 3581010Sbill bstart = 0; 3591010Sbill *rear = (q = s->nst); 3601010Sbill if (front < rear) 3611010Sbill if (rear >= &queue[QSIZE-1]) 3621010Sbill if (front == queue) overflo(); 3631010Sbill else rear = queue; 3641010Sbill else rear++; 3651010Sbill else 3661010Sbill if (++rear == front) overflo(); 3671010Sbill state = s->fail; 3681010Sbill floop: if (state == 0) { 3691010Sbill state = w; 3701010Sbill bstart = 1; 3711010Sbill } 3721010Sbill if (state->inp == c) { 3731010Sbill qloop: q->fail = state->nst; 3741010Sbill if ((state->nst)->out == 1) q->out = 1; 3751010Sbill if ((q = q->link) != 0) goto qloop; 3761010Sbill } 3771010Sbill else if ((state = state->link) != 0) 3781010Sbill goto floop; 3791010Sbill else if(bstart == 0){ 3801010Sbill state = 0; 3811010Sbill goto floop; 3821010Sbill } 3831010Sbill } 3841010Sbill if ((s = s->link) != 0) 3851010Sbill goto cloop; 3861010Sbill } 3871010Sbill } 388