1*21395Smckusick static char *sccsid = "@(#)old.fgrep.c 4.3 (Berkeley) 05/30/85"; 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> 13*21395Smckusick #include <sys/param.h> 14*21395Smckusick #include <sys/stat.h> 151010Sbill 16*21395Smckusick #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; 301010Sbill int sflag; 311010Sbill int retcode = 0; 321010Sbill int nfile; 331010Sbill long blkno; 341010Sbill int nsucc; 351010Sbill long tln; 361010Sbill FILE *wordf; 371010Sbill char *argptr; 381010Sbill 391010Sbill main(argc, argv) 401010Sbill char **argv; 411010Sbill { 421010Sbill while (--argc > 0 && (++argv)[0][0]=='-') 431010Sbill switch (argv[0][1]) { 441010Sbill 451010Sbill case 's': 461010Sbill sflag++; 471010Sbill continue; 481010Sbill 491010Sbill case 'h': 501010Sbill hflag = 0; 511010Sbill continue; 521010Sbill 531010Sbill case 'b': 541010Sbill bflag++; 551010Sbill continue; 561010Sbill 571010Sbill case 'c': 581010Sbill cflag++; 591010Sbill continue; 601010Sbill 611010Sbill case 'e': 621010Sbill argc--; 631010Sbill argv++; 641010Sbill goto out; 651010Sbill 661010Sbill case 'f': 671010Sbill fflag++; 681010Sbill continue; 691010Sbill 701010Sbill case 'l': 711010Sbill lflag++; 721010Sbill continue; 731010Sbill 741010Sbill case 'n': 751010Sbill nflag++; 761010Sbill continue; 771010Sbill 781010Sbill case 'v': 791010Sbill vflag++; 801010Sbill continue; 811010Sbill 821010Sbill case 'x': 831010Sbill xflag++; 841010Sbill continue; 851010Sbill 861010Sbill case 'i': /* Berkeley */ 871010Sbill case 'y': /* Btl */ 881010Sbill yflag++; 891010Sbill continue; 901010Sbill default: 911010Sbill fprintf(stderr, "fgrep: unknown flag\n"); 921010Sbill continue; 931010Sbill } 941010Sbill out: 951010Sbill if (argc<=0) 961010Sbill exit(2); 971010Sbill if (fflag) { 981010Sbill wordf = fopen(*argv, "r"); 991010Sbill if (wordf==NULL) { 1001010Sbill fprintf(stderr, "fgrep: can't open %s\n", *argv); 1011010Sbill exit(2); 1021010Sbill } 1031010Sbill } 1041010Sbill else argptr = *argv; 1051010Sbill argc--; 1061010Sbill argv++; 1071010Sbill 1081010Sbill cgotofn(); 1091010Sbill cfail(); 1101010Sbill nfile = argc; 1111010Sbill if (argc<=0) { 1121010Sbill if (lflag) exit(1); 1131010Sbill execute((char *)NULL); 1141010Sbill } 1151010Sbill else while (--argc >= 0) { 1161010Sbill execute(*argv); 1171010Sbill argv++; 1181010Sbill } 1191010Sbill exit(retcode != 0 ? retcode : nsucc == 0); 1201010Sbill } 1211010Sbill 1221010Sbill # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b) 1231010Sbill # define lca(x) (isupper(x) ? tolower(x) : x) 1241010Sbill execute(file) 1251010Sbill char *file; 1261010Sbill { 1271010Sbill register struct words *c; 1281010Sbill register ccount; 1291010Sbill register char ch; 1301010Sbill register char *p; 131*21395Smckusick static char *buf; 132*21395Smckusick static int blksize; 133*21395Smckusick struct stat stb; 1341010Sbill int f; 1351010Sbill int failed; 1361010Sbill char *nlp; 1371010Sbill if (file) { 1381010Sbill if ((f = open(file, 0)) < 0) { 1391010Sbill fprintf(stderr, "fgrep: can't open %s\n", file); 1401010Sbill retcode = 2; 1411010Sbill return; 1421010Sbill } 1431010Sbill } 1441010Sbill else f = 0; 145*21395Smckusick if (buf == NULL) { 146*21395Smckusick if (fstat(f, &stb) > 0 && stb.st_blksize > 0) 147*21395Smckusick blksize = stb.st_blksize; 148*21395Smckusick else 149*21395Smckusick blksize = BLKSIZE; 150*21395Smckusick buf = (char *)malloc(2*blksize); 151*21395Smckusick if (buf == NULL) { 152*21395Smckusick fprintf(stderr, "egrep: no memory for %s\n", file); 153*21395Smckusick retcode = 2; 154*21395Smckusick return; 155*21395Smckusick } 156*21395Smckusick } 1571010Sbill ccount = 0; 1581010Sbill failed = 0; 1591010Sbill lnum = 1; 1601010Sbill tln = 0; 1611010Sbill blkno = 0; 1621010Sbill p = buf; 1631010Sbill nlp = p; 1641010Sbill c = w; 1651010Sbill for (;;) { 1661010Sbill if (--ccount <= 0) { 167*21395Smckusick if (p == &buf[2*blksize]) p = buf; 168*21395Smckusick if (p > &buf[blksize]) { 169*21395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 1701010Sbill } 171*21395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 1721010Sbill blkno += ccount; 1731010Sbill } 1741010Sbill nstate: 1751010Sbill if (ccomp(c->inp, *p)) { 1761010Sbill c = c->nst; 1771010Sbill } 1781010Sbill else if (c->link != 0) { 1791010Sbill c = c->link; 1801010Sbill goto nstate; 1811010Sbill } 1821010Sbill else { 1831010Sbill c = c->fail; 1841010Sbill failed = 1; 1851010Sbill if (c==0) { 1861010Sbill c = w; 1871010Sbill istate: 1881010Sbill if (ccomp(c->inp , *p)) { 1891010Sbill c = c->nst; 1901010Sbill } 1911010Sbill else if (c->link != 0) { 1921010Sbill c = c->link; 1931010Sbill goto istate; 1941010Sbill } 1951010Sbill } 1961010Sbill else goto nstate; 1971010Sbill } 1981010Sbill if (c->out) { 1991010Sbill while (*p++ != '\n') { 2001010Sbill if (--ccount <= 0) { 201*21395Smckusick if (p == &buf[2*blksize]) p = buf; 202*21395Smckusick if (p > &buf[blksize]) { 203*21395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 2041010Sbill } 205*21395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 2061010Sbill blkno += ccount; 2071010Sbill } 2081010Sbill } 2091010Sbill if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) ) 2101010Sbill goto nomatch; 2111010Sbill succeed: nsucc = 1; 2121010Sbill if (cflag) tln++; 2131010Sbill else if (sflag) 2141010Sbill ; /* ugh */ 2151010Sbill else if (lflag) { 2161010Sbill printf("%s\n", file); 2171010Sbill close(f); 2181010Sbill return; 2191010Sbill } 2201010Sbill else { 2211010Sbill if (nfile > 1 && hflag) printf("%s:", file); 222*21395Smckusick if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE); 2231010Sbill if (nflag) printf("%ld:", lnum); 2241010Sbill if (p <= nlp) { 225*21395Smckusick while (nlp < &buf[2*blksize]) putchar(*nlp++); 2261010Sbill nlp = buf; 2271010Sbill } 2281010Sbill while (nlp < p) putchar(*nlp++); 2291010Sbill } 2301010Sbill nomatch: lnum++; 2311010Sbill nlp = p; 2321010Sbill c = w; 2331010Sbill failed = 0; 2341010Sbill continue; 2351010Sbill } 2361010Sbill if (*p++ == '\n') 2371010Sbill if (vflag) goto succeed; 2381010Sbill else { 2391010Sbill lnum++; 2401010Sbill nlp = p; 2411010Sbill c = w; 2421010Sbill failed = 0; 2431010Sbill } 2441010Sbill } 2451010Sbill close(f); 2461010Sbill if (cflag) { 2471010Sbill if (nfile > 1) 2481010Sbill printf("%s:", file); 2491010Sbill printf("%ld\n", tln); 2501010Sbill } 2511010Sbill } 2521010Sbill 2531010Sbill getargc() 2541010Sbill { 2551010Sbill register c; 2561010Sbill if (wordf) 2571010Sbill return(getc(wordf)); 2581010Sbill if ((c = *argptr++) == '\0') 2591010Sbill return(EOF); 2601010Sbill return(c); 2611010Sbill } 2621010Sbill 2631010Sbill cgotofn() { 2641010Sbill register c; 2651010Sbill register struct words *s; 2661010Sbill 2671010Sbill s = smax = w; 2681010Sbill nword: for(;;) { 2691010Sbill c = getargc(); 2701010Sbill if (c==EOF) 2711010Sbill return; 2721010Sbill if (c == '\n') { 2731010Sbill if (xflag) { 2741010Sbill for(;;) { 2751010Sbill if (s->inp == c) { 2761010Sbill s = s->nst; 2771010Sbill break; 2781010Sbill } 2791010Sbill if (s->inp == 0) goto nenter; 2801010Sbill if (s->link == 0) { 2811010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 2821010Sbill s->link = ++smax; 2831010Sbill s = smax; 2841010Sbill goto nenter; 2851010Sbill } 2861010Sbill s = s->link; 2871010Sbill } 2881010Sbill } 2891010Sbill s->out = 1; 2901010Sbill s = w; 2911010Sbill } else { 2921010Sbill loop: if (s->inp == c) { 2931010Sbill s = s->nst; 2941010Sbill continue; 2951010Sbill } 2961010Sbill if (s->inp == 0) goto enter; 2971010Sbill if (s->link == 0) { 2981010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 2991010Sbill s->link = ++smax; 3001010Sbill s = smax; 3011010Sbill goto enter; 3021010Sbill } 3031010Sbill s = s->link; 3041010Sbill goto loop; 3051010Sbill } 3061010Sbill } 3071010Sbill 3081010Sbill enter: 3091010Sbill do { 3101010Sbill s->inp = c; 3111010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 3121010Sbill s->nst = ++smax; 3131010Sbill s = smax; 3141010Sbill } while ((c = getargc()) != '\n' && c!=EOF); 3151010Sbill if (xflag) { 3161010Sbill nenter: s->inp = '\n'; 3171010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 3181010Sbill s->nst = ++smax; 3191010Sbill } 3201010Sbill smax->out = 1; 3211010Sbill s = w; 3221010Sbill if (c != EOF) 3231010Sbill goto nword; 3241010Sbill } 3251010Sbill 3261010Sbill overflo() { 3271010Sbill fprintf(stderr, "wordlist too large\n"); 3281010Sbill exit(2); 3291010Sbill } 3301010Sbill cfail() { 3311010Sbill struct words *queue[QSIZE]; 3321010Sbill struct words **front, **rear; 3331010Sbill struct words *state; 3341010Sbill int bstart; 3351010Sbill register char c; 3361010Sbill register struct words *s; 3371010Sbill s = w; 3381010Sbill front = rear = queue; 3391010Sbill init: if ((s->inp) != 0) { 3401010Sbill *rear++ = s->nst; 3411010Sbill if (rear >= &queue[QSIZE - 1]) overflo(); 3421010Sbill } 3431010Sbill if ((s = s->link) != 0) { 3441010Sbill goto init; 3451010Sbill } 3461010Sbill 3471010Sbill while (rear!=front) { 3481010Sbill s = *front; 3491010Sbill if (front == &queue[QSIZE-1]) 3501010Sbill front = queue; 3511010Sbill else front++; 3521010Sbill cloop: if ((c = s->inp) != 0) { 3531010Sbill bstart = 0; 3541010Sbill *rear = (q = s->nst); 3551010Sbill if (front < rear) 3561010Sbill if (rear >= &queue[QSIZE-1]) 3571010Sbill if (front == queue) overflo(); 3581010Sbill else rear = queue; 3591010Sbill else rear++; 3601010Sbill else 3611010Sbill if (++rear == front) overflo(); 3621010Sbill state = s->fail; 3631010Sbill floop: if (state == 0) { 3641010Sbill state = w; 3651010Sbill bstart = 1; 3661010Sbill } 3671010Sbill if (state->inp == c) { 3681010Sbill qloop: q->fail = state->nst; 3691010Sbill if ((state->nst)->out == 1) q->out = 1; 3701010Sbill if ((q = q->link) != 0) goto qloop; 3711010Sbill } 3721010Sbill else if ((state = state->link) != 0) 3731010Sbill goto floop; 3741010Sbill else if(bstart == 0){ 3751010Sbill state = 0; 3761010Sbill goto floop; 3771010Sbill } 3781010Sbill } 3791010Sbill if ((s = s->link) != 0) 3801010Sbill goto cloop; 3811010Sbill } 3821010Sbill } 383