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