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

Defined functions

cfail defined in line 330; used 1 times
cgotofn defined in line 263; used 1 times
execute defined in line 124; used 2 times
getargc defined in line 253; used 2 times
main defined in line 39; never used
overflo defined in line 326; used 7 times

Defined variables

argptr defined in line 37; used 2 times
bflag defined in line 28; used 2 times
blkno defined in line 33; used 4 times
cflag defined in line 28; used 3 times
fflag defined in line 28; used 2 times
hflag defined in line 29; used 2 times
lflag defined in line 28; used 3 times
lnum defined in line 27; used 4 times
nfile defined in line 32; used 3 times
nflag defined in line 28; used 2 times
nsucc defined in line 34; used 2 times
q defined in line 25; used 5 times
retcode defined in line 31; used 4 times
sccsid defined in line 1; never used
sflag defined in line 30; used 2 times
smax defined in line 25; used 13 times
tln defined in line 35; used 3 times
vflag defined in line 28; used 4 times
w defined in line 25; used 13 times
xflag defined in line 28; used 5 times
yflag defined in line 28; used 2 times

Defined struct's

words defined in line 19; used 18 times

Defined macros

BLKSIZE defined in line 16; used 1 times
MAXSIZ defined in line 17; used 5 times
QSIZE defined in line 18; used 4 times
ccomp defined in line 122; used 2 times
lca defined in line 123; used 2 times
  • in line 122(2)
Last modified: 1986-03-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1629
Valid CSS Valid XHTML 1.0 Strict