1*48266Sbostic /*- 2*48266Sbostic * Copyright (c) 1991 The Regents of the University of California. 3*48266Sbostic * All rights reserved. 4*48266Sbostic * 5*48266Sbostic * %sccs.include.proprietary.c% 6*48266Sbostic */ 7*48266Sbostic 8*48266Sbostic #ifndef lint 9*48266Sbostic char copyright[] = 10*48266Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 11*48266Sbostic All rights reserved.\n"; 12*48266Sbostic #endif /* not lint */ 13*48266Sbostic 14*48266Sbostic #ifndef lint 15*48266Sbostic static char sccsid[] = "@(#)old.fgrep.c 4.5 (Berkeley) 04/17/91"; 16*48266Sbostic #endif /* not lint */ 17*48266Sbostic 181010Sbill /* 191010Sbill * fgrep -- print all lines containing any of a set of keywords 201010Sbill * 211010Sbill * status returns: 221010Sbill * 0 - ok, and some matches 231010Sbill * 1 - ok, but no matches 241010Sbill * 2 - some error 251010Sbill */ 261010Sbill 278726Smckusick #include <stdio.h> 288726Smckusick #include <ctype.h> 2921395Smckusick #include <sys/param.h> 3021395Smckusick #include <sys/stat.h> 311010Sbill 3221395Smckusick #define BLKSIZE 8192 331010Sbill #define MAXSIZ 6000 341010Sbill #define QSIZE 400 351010Sbill struct words { 361010Sbill char inp; 371010Sbill char out; 381010Sbill struct words *nst; 391010Sbill struct words *link; 401010Sbill struct words *fail; 411010Sbill } w[MAXSIZ], *smax, *q; 421010Sbill 431010Sbill long lnum; 441010Sbill int bflag, cflag, fflag, lflag, nflag, vflag, xflag, yflag; 451010Sbill int hflag = 1; 4632365Sbostic int oflag; 471010Sbill int sflag; 481010Sbill int retcode = 0; 491010Sbill int nfile; 501010Sbill long blkno; 511010Sbill int nsucc; 521010Sbill long tln; 531010Sbill FILE *wordf; 541010Sbill char *argptr; 551010Sbill 561010Sbill main(argc, argv) 571010Sbill char **argv; 581010Sbill { 591010Sbill while (--argc > 0 && (++argv)[0][0]=='-') 601010Sbill switch (argv[0][1]) { 611010Sbill 621010Sbill case 's': 631010Sbill sflag++; 641010Sbill continue; 651010Sbill 661010Sbill case 'h': 671010Sbill hflag = 0; 681010Sbill continue; 691010Sbill 7032365Sbostic case 'o': 7132365Sbostic oflag++; 7232365Sbostic continue; 7332365Sbostic 741010Sbill case 'b': 751010Sbill bflag++; 761010Sbill continue; 771010Sbill 781010Sbill case 'c': 791010Sbill cflag++; 801010Sbill continue; 811010Sbill 821010Sbill case 'e': 831010Sbill argc--; 841010Sbill argv++; 851010Sbill goto out; 861010Sbill 871010Sbill case 'f': 881010Sbill fflag++; 891010Sbill continue; 901010Sbill 911010Sbill case 'l': 921010Sbill lflag++; 931010Sbill continue; 941010Sbill 951010Sbill case 'n': 961010Sbill nflag++; 971010Sbill continue; 981010Sbill 991010Sbill case 'v': 1001010Sbill vflag++; 1011010Sbill continue; 1021010Sbill 1031010Sbill case 'x': 1041010Sbill xflag++; 1051010Sbill continue; 1061010Sbill 1071010Sbill case 'i': /* Berkeley */ 1081010Sbill case 'y': /* Btl */ 1091010Sbill yflag++; 1101010Sbill continue; 1111010Sbill default: 1121010Sbill fprintf(stderr, "fgrep: unknown flag\n"); 1131010Sbill continue; 1141010Sbill } 1151010Sbill out: 1161010Sbill if (argc<=0) 1171010Sbill exit(2); 1181010Sbill if (fflag) { 1191010Sbill wordf = fopen(*argv, "r"); 1201010Sbill if (wordf==NULL) { 1211010Sbill fprintf(stderr, "fgrep: can't open %s\n", *argv); 1221010Sbill exit(2); 1231010Sbill } 1241010Sbill } 1251010Sbill else argptr = *argv; 1261010Sbill argc--; 1271010Sbill argv++; 1281010Sbill 1291010Sbill cgotofn(); 1301010Sbill cfail(); 1311010Sbill nfile = argc; 1321010Sbill if (argc<=0) { 1331010Sbill if (lflag) exit(1); 1341010Sbill execute((char *)NULL); 1351010Sbill } 1361010Sbill else while (--argc >= 0) { 1371010Sbill execute(*argv); 1381010Sbill argv++; 1391010Sbill } 1401010Sbill exit(retcode != 0 ? retcode : nsucc == 0); 1411010Sbill } 1421010Sbill 1431010Sbill # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b) 1441010Sbill # define lca(x) (isupper(x) ? tolower(x) : x) 1451010Sbill execute(file) 1461010Sbill char *file; 1471010Sbill { 1481010Sbill register struct words *c; 1491010Sbill register ccount; 1501010Sbill register char ch; 1511010Sbill register char *p; 15221395Smckusick static char *buf; 15321395Smckusick static int blksize; 15421395Smckusick struct stat stb; 1551010Sbill int f; 1561010Sbill int failed; 1571010Sbill char *nlp; 1581010Sbill if (file) { 1591010Sbill if ((f = open(file, 0)) < 0) { 1601010Sbill fprintf(stderr, "fgrep: can't open %s\n", file); 1611010Sbill retcode = 2; 1621010Sbill return; 1631010Sbill } 1641010Sbill } 1651010Sbill else f = 0; 16621395Smckusick if (buf == NULL) { 16721395Smckusick if (fstat(f, &stb) > 0 && stb.st_blksize > 0) 16821395Smckusick blksize = stb.st_blksize; 16921395Smckusick else 17021395Smckusick blksize = BLKSIZE; 17121395Smckusick buf = (char *)malloc(2*blksize); 17221395Smckusick if (buf == NULL) { 17321395Smckusick fprintf(stderr, "egrep: no memory for %s\n", file); 17421395Smckusick retcode = 2; 17521395Smckusick return; 17621395Smckusick } 17721395Smckusick } 1781010Sbill ccount = 0; 1791010Sbill failed = 0; 1801010Sbill lnum = 1; 1811010Sbill tln = 0; 1821010Sbill blkno = 0; 1831010Sbill p = buf; 1841010Sbill nlp = p; 1851010Sbill c = w; 1861010Sbill for (;;) { 1871010Sbill if (--ccount <= 0) { 18821395Smckusick if (p == &buf[2*blksize]) p = buf; 18921395Smckusick if (p > &buf[blksize]) { 19021395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 1911010Sbill } 19221395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 1931010Sbill blkno += ccount; 1941010Sbill } 1951010Sbill nstate: 1961010Sbill if (ccomp(c->inp, *p)) { 1971010Sbill c = c->nst; 1981010Sbill } 1991010Sbill else if (c->link != 0) { 2001010Sbill c = c->link; 2011010Sbill goto nstate; 2021010Sbill } 2031010Sbill else { 2041010Sbill c = c->fail; 2051010Sbill failed = 1; 2061010Sbill if (c==0) { 2071010Sbill c = w; 2081010Sbill istate: 2091010Sbill if (ccomp(c->inp , *p)) { 2101010Sbill c = c->nst; 2111010Sbill } 2121010Sbill else if (c->link != 0) { 2131010Sbill c = c->link; 2141010Sbill goto istate; 2151010Sbill } 2161010Sbill } 2171010Sbill else goto nstate; 2181010Sbill } 2191010Sbill if (c->out) { 2201010Sbill while (*p++ != '\n') { 2211010Sbill if (--ccount <= 0) { 22221395Smckusick if (p == &buf[2*blksize]) p = buf; 22321395Smckusick if (p > &buf[blksize]) { 22421395Smckusick if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 2251010Sbill } 22621395Smckusick else if ((ccount = read(f, p, blksize)) <= 0) break; 2271010Sbill blkno += ccount; 2281010Sbill } 2291010Sbill } 2301010Sbill if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) ) 2311010Sbill goto nomatch; 2321010Sbill succeed: nsucc = 1; 2331010Sbill if (cflag) tln++; 2341010Sbill else if (sflag) 2351010Sbill ; /* ugh */ 2361010Sbill else if (lflag) { 2371010Sbill printf("%s\n", file); 2381010Sbill close(f); 2391010Sbill return; 2401010Sbill } 2411010Sbill else { 24232365Sbostic if (nfile > 1 && hflag || oflag) printf("%s:", file); 24321395Smckusick if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE); 2441010Sbill if (nflag) printf("%ld:", lnum); 2451010Sbill if (p <= nlp) { 24621395Smckusick while (nlp < &buf[2*blksize]) putchar(*nlp++); 2471010Sbill nlp = buf; 2481010Sbill } 2491010Sbill while (nlp < p) putchar(*nlp++); 2501010Sbill } 2511010Sbill nomatch: lnum++; 2521010Sbill nlp = p; 2531010Sbill c = w; 2541010Sbill failed = 0; 2551010Sbill continue; 2561010Sbill } 2571010Sbill if (*p++ == '\n') 2581010Sbill if (vflag) goto succeed; 2591010Sbill else { 2601010Sbill lnum++; 2611010Sbill nlp = p; 2621010Sbill c = w; 2631010Sbill failed = 0; 2641010Sbill } 2651010Sbill } 2661010Sbill close(f); 2671010Sbill if (cflag) { 2681010Sbill if (nfile > 1) 2691010Sbill printf("%s:", file); 2701010Sbill printf("%ld\n", tln); 2711010Sbill } 2721010Sbill } 2731010Sbill 2741010Sbill getargc() 2751010Sbill { 2761010Sbill register c; 2771010Sbill if (wordf) 2781010Sbill return(getc(wordf)); 2791010Sbill if ((c = *argptr++) == '\0') 2801010Sbill return(EOF); 2811010Sbill return(c); 2821010Sbill } 2831010Sbill 2841010Sbill cgotofn() { 2851010Sbill register c; 2861010Sbill register struct words *s; 2871010Sbill 2881010Sbill s = smax = w; 2891010Sbill nword: for(;;) { 2901010Sbill c = getargc(); 2911010Sbill if (c==EOF) 2921010Sbill return; 2931010Sbill if (c == '\n') { 2941010Sbill if (xflag) { 2951010Sbill for(;;) { 2961010Sbill if (s->inp == c) { 2971010Sbill s = s->nst; 2981010Sbill break; 2991010Sbill } 3001010Sbill if (s->inp == 0) goto nenter; 3011010Sbill if (s->link == 0) { 3021010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 3031010Sbill s->link = ++smax; 3041010Sbill s = smax; 3051010Sbill goto nenter; 3061010Sbill } 3071010Sbill s = s->link; 3081010Sbill } 3091010Sbill } 3101010Sbill s->out = 1; 3111010Sbill s = w; 3121010Sbill } else { 3131010Sbill loop: if (s->inp == c) { 3141010Sbill s = s->nst; 3151010Sbill continue; 3161010Sbill } 3171010Sbill if (s->inp == 0) goto enter; 3181010Sbill if (s->link == 0) { 3191010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 3201010Sbill s->link = ++smax; 3211010Sbill s = smax; 3221010Sbill goto enter; 3231010Sbill } 3241010Sbill s = s->link; 3251010Sbill goto loop; 3261010Sbill } 3271010Sbill } 3281010Sbill 3291010Sbill enter: 3301010Sbill do { 3311010Sbill s->inp = c; 3321010Sbill if (smax >= &w[MAXSIZ - 1]) overflo(); 3331010Sbill s->nst = ++smax; 3341010Sbill s = smax; 3351010Sbill } while ((c = getargc()) != '\n' && c!=EOF); 3361010Sbill if (xflag) { 3371010Sbill nenter: s->inp = '\n'; 3381010Sbill if (smax >= &w[MAXSIZ -1]) overflo(); 3391010Sbill s->nst = ++smax; 3401010Sbill } 3411010Sbill smax->out = 1; 3421010Sbill s = w; 3431010Sbill if (c != EOF) 3441010Sbill goto nword; 3451010Sbill } 3461010Sbill 3471010Sbill overflo() { 3481010Sbill fprintf(stderr, "wordlist too large\n"); 3491010Sbill exit(2); 3501010Sbill } 3511010Sbill cfail() { 3521010Sbill struct words *queue[QSIZE]; 3531010Sbill struct words **front, **rear; 3541010Sbill struct words *state; 3551010Sbill int bstart; 3561010Sbill register char c; 3571010Sbill register struct words *s; 3581010Sbill s = w; 3591010Sbill front = rear = queue; 3601010Sbill init: if ((s->inp) != 0) { 3611010Sbill *rear++ = s->nst; 3621010Sbill if (rear >= &queue[QSIZE - 1]) overflo(); 3631010Sbill } 3641010Sbill if ((s = s->link) != 0) { 3651010Sbill goto init; 3661010Sbill } 3671010Sbill 3681010Sbill while (rear!=front) { 3691010Sbill s = *front; 3701010Sbill if (front == &queue[QSIZE-1]) 3711010Sbill front = queue; 3721010Sbill else front++; 3731010Sbill cloop: if ((c = s->inp) != 0) { 3741010Sbill bstart = 0; 3751010Sbill *rear = (q = s->nst); 3761010Sbill if (front < rear) 3771010Sbill if (rear >= &queue[QSIZE-1]) 3781010Sbill if (front == queue) overflo(); 3791010Sbill else rear = queue; 3801010Sbill else rear++; 3811010Sbill else 3821010Sbill if (++rear == front) overflo(); 3831010Sbill state = s->fail; 3841010Sbill floop: if (state == 0) { 3851010Sbill state = w; 3861010Sbill bstart = 1; 3871010Sbill } 3881010Sbill if (state->inp == c) { 3891010Sbill qloop: q->fail = state->nst; 3901010Sbill if ((state->nst)->out == 1) q->out = 1; 3911010Sbill if ((q = q->link) != 0) goto qloop; 3921010Sbill } 3931010Sbill else if ((state = state->link) != 0) 3941010Sbill goto floop; 3951010Sbill else if(bstart == 0){ 3961010Sbill state = 0; 3971010Sbill goto floop; 3981010Sbill } 3991010Sbill } 4001010Sbill if ((s = s->link) != 0) 4011010Sbill goto cloop; 4021010Sbill } 4031010Sbill } 404