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