1: /*
   2:  * grep -- print lines matching (or not matching) a pattern
   3:  *
   4:  *	status returns:
   5:  *		0 - ok, and some matches
   6:  *		1 - ok, but no matches
   7:  *		2 - some error
   8:  */
   9: 
  10: #include <stdio.h>
  11: #include <ctype.h>
  12: #include <sys/param.h>
  13: 
  14: #define CBRA    1
  15: #define CCHR    2
  16: #define CDOT    4
  17: #define CCL 6
  18: #define NCCL    8
  19: #define CDOL    10
  20: #define CEOF    11
  21: #define CKET    12
  22: #define CBACK   18
  23: 
  24: #define STAR    01
  25: 
  26: #define LBSIZE  BUFSIZ
  27: #define ESIZE   256
  28: #define NBRA    9
  29: 
  30: char    expbuf[ESIZE];
  31: long    lnum;
  32: char    linebuf[LBSIZE+1];
  33: char    ybuf[ESIZE];
  34: int bflag;
  35: int lflag;
  36: int nflag;
  37: int cflag;
  38: int vflag;
  39: int nfile;
  40: int hflag   = 1;
  41: int sflag;
  42: int yflag;
  43: int circf;
  44: long    tln;
  45: int nsucc;
  46: char    *braslist[NBRA];
  47: char    *braelist[NBRA];
  48: char    bittab[] = {
  49:     1,
  50:     2,
  51:     4,
  52:     8,
  53:     16,
  54:     32,
  55:     64,
  56:     128
  57: };
  58: long    ftell();
  59: 
  60: main(argc, argv)
  61: char **argv;
  62: {
  63:     extern char _sobuf[];
  64: 
  65:     setbuf(stdout, _sobuf);
  66:     while (--argc > 0 && (++argv)[0][0]=='-')
  67:         switch (argv[0][1]) {
  68: 
  69:         case 'y':
  70:             yflag++;
  71:             continue;
  72: 
  73:         case 'h':
  74:             hflag = 0;
  75:             continue;
  76: 
  77:         case 's':
  78:             sflag++;
  79:             continue;
  80: 
  81:         case 'v':
  82:             vflag++;
  83:             continue;
  84: 
  85:         case 'b':
  86:             bflag++;
  87:             continue;
  88: 
  89:         case 'l':
  90:             lflag++;
  91:             continue;
  92: 
  93:         case 'c':
  94:             cflag++;
  95:             continue;
  96: 
  97:         case 'n':
  98:             nflag++;
  99:             continue;
 100: 
 101:         case 'e':
 102:             --argc;
 103:             ++argv;
 104:             goto out;
 105: 
 106:         default:
 107:             errexit("grep: unknown flag\n", (char *)NULL);
 108:             continue;
 109:         }
 110: out:
 111:     if (argc<=0)
 112:         exit(2);
 113:     if (yflag) {
 114:         register char *p, *s;
 115:         for (s = ybuf, p = *argv; *p; ) {
 116:             if (*p == '\\') {
 117:                 *s++ = *p++;
 118:                 if (*p)
 119:                     *s++ = *p++;
 120:             } else if (*p == '[') {
 121:                 while (*p != '\0' && *p != ']')
 122:                     *s++ = *p++;
 123:             } else if (islower(*p)) {
 124:                 *s++ = '[';
 125:                 *s++ = toupper(*p);
 126:                 *s++ = *p++;
 127:                 *s++ = ']';
 128:             } else
 129:                 *s++ = *p++;
 130:             if (s >= ybuf+ESIZE-5)
 131:                 errexit("grep: argument too long\n", (char *)NULL);
 132:         }
 133:         *s = '\0';
 134:         *argv = ybuf;
 135:     }
 136:     compile(*argv);
 137:     nfile = --argc;
 138:     if (argc<=0) {
 139:         if (lflag)
 140:             exit(1);
 141:         execute((char *)NULL);
 142:     } else while (--argc >= 0) {
 143:         argv++;
 144:         execute(*argv);
 145:     }
 146:     exit(nsucc == 0);
 147: }
 148: 
 149: compile(astr)
 150: char *astr;
 151: {
 152:     register c;
 153:     register char *ep, *sp;
 154:     char *cstart;
 155:     char *lastep;
 156:     int cclcnt;
 157:     char bracket[NBRA], *bracketp;
 158:     int closed;
 159:     char numbra;
 160:     char neg;
 161: 
 162:     ep = expbuf;
 163:     sp = astr;
 164:     lastep = 0;
 165:     bracketp = bracket;
 166:     closed = numbra = 0;
 167:     if (*sp == '^') {
 168:         circf++;
 169:         sp++;
 170:     }
 171:     for (;;) {
 172:         if (ep >= &expbuf[ESIZE])
 173:             goto cerror;
 174:         if ((c = *sp++) != '*')
 175:             lastep = ep;
 176:         switch (c) {
 177: 
 178:         case '\0':
 179:             *ep++ = CEOF;
 180:             return;
 181: 
 182:         case '.':
 183:             *ep++ = CDOT;
 184:             continue;
 185: 
 186:         case '*':
 187:             if (lastep==0 || *lastep==CBRA || *lastep==CKET)
 188:                 goto defchar;
 189:             *lastep |= STAR;
 190:             continue;
 191: 
 192:         case '$':
 193:             if (*sp != '\0')
 194:                 goto defchar;
 195:             *ep++ = CDOL;
 196:             continue;
 197: 
 198:         case '[':
 199:             if(&ep[17] >= &expbuf[ESIZE])
 200:                 goto cerror;
 201:             *ep++ = CCL;
 202:             neg = 0;
 203:             if((c = *sp++) == '^') {
 204:                 neg = 1;
 205:                 c = *sp++;
 206:             }
 207:             cstart = sp;
 208:             do {
 209:                 if (c=='\0')
 210:                     goto cerror;
 211:                 if (c=='-' && sp>cstart && *sp!=']') {
 212:                     for (c = sp[-2]; c<*sp; c++)
 213:                         ep[c>>3] |= bittab[c&07];
 214:                     sp++;
 215:                 }
 216:                 ep[c>>3] |= bittab[c&07];
 217:             } while((c = *sp++) != ']');
 218:             if(neg) {
 219:                 for(cclcnt = 0; cclcnt < 16; cclcnt++)
 220:                     ep[cclcnt] ^= -1;
 221:                 ep[0] &= 0376;
 222:             }
 223: 
 224:             ep += 16;
 225: 
 226:             continue;
 227: 
 228:         case '\\':
 229:             if((c = *sp++) == '(') {
 230:                 if(numbra >= NBRA) {
 231:                     goto cerror;
 232:                 }
 233:                 *bracketp++ = numbra;
 234:                 *ep++ = CBRA;
 235:                 *ep++ = numbra++;
 236:                 continue;
 237:             }
 238:             if(c == ')') {
 239:                 if(bracketp <= bracket) {
 240:                     goto cerror;
 241:                 }
 242:                 *ep++ = CKET;
 243:                 *ep++ = *--bracketp;
 244:                 closed++;
 245:                 continue;
 246:             }
 247: 
 248:             if(c >= '1' && c <= '9') {
 249:                 if((c -= '1') >= closed)
 250:                     goto cerror;
 251:                 *ep++ = CBACK;
 252:                 *ep++ = c;
 253:                 continue;
 254:             }
 255: 
 256:         defchar:
 257:         default:
 258:             *ep++ = CCHR;
 259:             *ep++ = c;
 260:         }
 261:     }
 262:     cerror:
 263:     errexit("grep: RE error\n", (char *)NULL);
 264: }
 265: 
 266: execute(file)
 267: char *file;
 268: {
 269:     register char *p1, *p2;
 270:     register c;
 271: 
 272:     if (file) {
 273:         if (freopen(file, "r", stdin) == NULL)
 274:             errexit("grep: can't open %s\n", file);
 275:     }
 276:     lnum = 0;
 277:     tln = 0;
 278:     for (;;) {
 279:         lnum++;
 280:         p1 = linebuf;
 281:         while ((c = getchar()) != '\n') {
 282:             if (c == EOF) {
 283:                 if (cflag) {
 284:                     if (nfile>1)
 285:                         printf("%s:", file);
 286:                     printf("%D\n", tln);
 287:                     fflush(stdout);
 288:                 }
 289:                 return;
 290:             }
 291:             *p1++ = c;
 292:             if (p1 >= &linebuf[LBSIZE-1])
 293:                 break;
 294:         }
 295:         *p1++ = '\0';
 296:         p1 = linebuf;
 297:         p2 = expbuf;
 298:         if (circf) {
 299:             if (advance(p1, p2))
 300:                 goto found;
 301:             goto nfound;
 302:         }
 303:         /* fast check for first character */
 304:         if (*p2==CCHR) {
 305:             c = p2[1];
 306:             do {
 307:                 if (*p1!=c)
 308:                     continue;
 309:                 if (advance(p1, p2))
 310:                     goto found;
 311:             } while (*p1++);
 312:             goto nfound;
 313:         }
 314:         /* regular algorithm */
 315:         do {
 316:             if (advance(p1, p2))
 317:                 goto found;
 318:         } while (*p1++);
 319:     nfound:
 320:         if (vflag)
 321:             succeed(file);
 322:         continue;
 323:     found:
 324:         if (vflag==0)
 325:             succeed(file);
 326:     }
 327: }
 328: 
 329: advance(lp, ep)
 330: register char *lp, *ep;
 331: {
 332:     register char *curlp;
 333:     char c;
 334:     char *bbeg;
 335:     int ct;
 336: 
 337:     for (;;) switch (*ep++) {
 338: 
 339:     case CCHR:
 340:         if (*ep++ == *lp++)
 341:             continue;
 342:         return(0);
 343: 
 344:     case CDOT:
 345:         if (*lp++)
 346:             continue;
 347:         return(0);
 348: 
 349:     case CDOL:
 350:         if (*lp==0)
 351:             continue;
 352:         return(0);
 353: 
 354:     case CEOF:
 355:         return(1);
 356: 
 357:     case CCL:
 358:         c = *lp++ & 0177;
 359:         if(ep[c>>3] & bittab[c & 07]) {
 360:             ep += 16;
 361:             continue;
 362:         }
 363:         return(0);
 364:     case CBRA:
 365:         braslist[*ep++] = lp;
 366:         continue;
 367: 
 368:     case CKET:
 369:         braelist[*ep++] = lp;
 370:         continue;
 371: 
 372:     case CBACK:
 373:         bbeg = braslist[*ep];
 374:         if (braelist[*ep]==0)
 375:             return(0);
 376:         ct = braelist[*ep++] - bbeg;
 377:         if(ecmp(bbeg, lp, ct)) {
 378:             lp += ct;
 379:             continue;
 380:         }
 381:         return(0);
 382: 
 383:     case CBACK|STAR:
 384:         bbeg = braslist[*ep];
 385:         if (braelist[*ep]==0)
 386:             return(0);
 387:         ct = braelist[*ep++] - bbeg;
 388:         curlp = lp;
 389:         while(ecmp(bbeg, lp, ct))
 390:             lp += ct;
 391:         while(lp >= curlp) {
 392:             if(advance(lp, ep)) return(1);
 393:             lp -= ct;
 394:         }
 395:         return(0);
 396: 
 397: 
 398:     case CDOT|STAR:
 399:         curlp = lp;
 400:         while (*lp++);
 401:         goto star;
 402: 
 403:     case CCHR|STAR:
 404:         curlp = lp;
 405:         while (*lp++ == *ep);
 406:         ep++;
 407:         goto star;
 408: 
 409:     case CCL|STAR:
 410:         curlp = lp;
 411:         do {
 412:             c = *lp++ & 0177;
 413:         } while(ep[c>>3] & bittab[c & 07]);
 414:         ep += 16;
 415:         goto star;
 416: 
 417:     star:
 418:         if(--lp == curlp) {
 419:             continue;
 420:         }
 421: 
 422:         if(*ep == CCHR) {
 423:             c = ep[1];
 424:             do {
 425:                 if(*lp != c)
 426:                     continue;
 427:                 if(advance(lp, ep))
 428:                     return(1);
 429:             } while(lp-- > curlp);
 430:             return(0);
 431:         }
 432: 
 433:         do {
 434:             if (advance(lp, ep))
 435:                 return(1);
 436:         } while (lp-- > curlp);
 437:         return(0);
 438: 
 439:     default:
 440:         errexit("grep RE botch\n", (char *)NULL);
 441:     }
 442: }
 443: 
 444: succeed(f)
 445: char *f;
 446: {
 447:     nsucc = 1;
 448:     if (sflag)
 449:         return;
 450:     if (cflag) {
 451:         tln++;
 452:         return;
 453:     }
 454:     if (lflag) {
 455:         printf("%s\n", f);
 456:         fflush(stdout);
 457:         fseek(stdin, 0l, 2);
 458:         return;
 459:     }
 460:     if (nfile > 1 && hflag)
 461:         printf("%s:", f);
 462:     if (bflag)
 463:         printf("%ld:", (ftell(stdin)-1)/BSIZE);
 464:     if (nflag)
 465:         printf("%ld:", lnum);
 466:     printf("%s\n", linebuf);
 467:     fflush(stdout);
 468: }
 469: 
 470: ecmp(a, b, count)
 471: char    *a, *b;
 472: {
 473:     register cc = count;
 474:     while(cc--)
 475:         if(*a++ != *b++)    return(0);
 476:     return(1);
 477: }
 478: 
 479: errexit(s, f)
 480: char *s, *f;
 481: {
 482:     fprintf(stderr, s, f);
 483:     exit(2);
 484: }

Defined functions

advance defined in line 329; used 6 times
compile defined in line 149; used 1 times
ecmp defined in line 470; used 2 times
errexit defined in line 479; used 5 times
execute defined in line 266; used 2 times
main defined in line 60; never used
succeed defined in line 444; used 2 times

Defined variables

bflag defined in line 34; used 2 times
bittab defined in line 48; used 4 times
braelist defined in line 47; used 5 times
braslist defined in line 46; used 3 times
cflag defined in line 37; used 3 times
circf defined in line 43; used 2 times
expbuf defined in line 30; used 4 times
hflag defined in line 40; used 2 times
lflag defined in line 35; used 3 times
linebuf defined in line 32; used 4 times
lnum defined in line 31; used 3 times
nfile defined in line 39; used 3 times
nflag defined in line 36; used 2 times
nsucc defined in line 45; used 2 times
sflag defined in line 41; used 2 times
tln defined in line 44; used 3 times
vflag defined in line 38; used 3 times
ybuf defined in line 33; used 3 times
yflag defined in line 42; used 2 times

Defined macros

CBACK defined in line 22; used 2 times
CBRA defined in line 14; used 2 times
CCHR defined in line 15; used 4 times
CCL defined in line 17; used 2 times
CDOL defined in line 19; used 1 times
CDOT defined in line 16; used 2 times
CEOF defined in line 20; used 1 times
CKET defined in line 21; used 2 times
ESIZE defined in line 27; used 5 times
LBSIZE defined in line 26; used 2 times
NBRA defined in line 28; used 4 times
NCCL defined in line 18; never used
STAR defined in line 24; used 1 times
Last modified: 1982-11-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1645
Valid CSS Valid XHTML 1.0 Strict