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

Defined functions

cfail defined in line 336; used 1 times
cgotofn defined in line 269; used 1 times
execute defined in line 130; used 2 times
getargc defined in line 259; used 2 times
main defined in line 45; never used
overflo defined in line 332; used 7 times

Defined variables

argptr defined in line 43; used 2 times
bflag defined in line 34; used 2 times
blkno defined in line 39; used 4 times
cflag defined in line 34; used 3 times
fflag defined in line 34; used 2 times
hflag defined in line 35; used 2 times
lflag defined in line 34; used 3 times
lnum defined in line 33; used 4 times
nfile defined in line 38; used 3 times
nflag defined in line 34; used 2 times
nsucc defined in line 40; used 2 times
q defined in line 31; used 5 times
retcode defined in line 37; used 4 times
sccsid defined in line 2; never used
sflag defined in line 36; used 2 times
smax defined in line 31; used 13 times
tln defined in line 41; used 3 times
vflag defined in line 34; used 4 times
w defined in line 31; used 13 times
xflag defined in line 34; used 5 times
yflag defined in line 34; used 2 times

Defined struct's

words defined in line 25; used 18 times

Defined macros

BLKSIZE defined in line 21; used 1 times
MAXSIZ defined in line 23; used 5 times
QSIZE defined in line 24; used 4 times
ccomp defined in line 128; used 2 times
lca defined in line 129; used 2 times
  • in line 128(2)
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3783
Valid CSS Valid XHTML 1.0 Strict