1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)grep.c	5.2 (Berkeley) 3/4/86";
  15: #endif not lint
  16: 
  17: #include <stdio.h>
  18: #include <sys/types.h>
  19: #include <sys/stat.h>
  20: /*
  21:  * grep -- print lines matching (or not matching) a pattern
  22:  */
  23: 
  24: #define BLKSIZE 8192
  25: #define CCHR    2
  26: #define CDOT    4
  27: #define CCL 6
  28: #define NCCL    8
  29: #define CDOL    10
  30: #define CEOF    11
  31: 
  32: #define CBRC    14
  33: #define CLET    15
  34: #define STAR    01
  35: 
  36: #define ESIZE   256
  37: 
  38: char    expbuf[ESIZE];
  39: long    lnum;
  40: char    linebuf[BUFSIZ+1];
  41: int bflag;
  42: int nflag;
  43: int cflag;
  44: int vflag;
  45: int nfile;
  46: int iflag;
  47: int lflag;
  48: int wflag;
  49: int sflag;
  50: int nsucc;
  51: int circf;
  52: long    blkno;
  53: long    tln;
  54: int retcode = 0;
  55: 
  56: main(argc, argv)
  57: char **argv;
  58: {
  59: 
  60:     while (--argc > 0 && (++argv)[0][0]=='-') {
  61:         char *cp = argv[0] + 1;
  62:         while (*cp) switch (*cp++) {
  63: 
  64:         case 'v':
  65:             vflag++;
  66:             continue;
  67: 
  68:         case 'b':
  69:             bflag++;
  70:             continue;
  71: 
  72:         case 'i':
  73:         case 'y':   /* -y for compatibility with btl grep */
  74:             iflag++;
  75:             continue;
  76: 
  77:         case 'l':
  78:             lflag++;
  79:         case 'c':
  80:             cflag++;
  81:             continue;
  82: 
  83:         case 'w':
  84:             wflag++;
  85:             continue;
  86: 
  87:         case 's':
  88:             sflag++;
  89:             continue;
  90: 
  91:         case 'n':
  92:             nflag++;
  93:             continue;
  94: 
  95:         case 'e':
  96:             --argc;
  97:             ++argv;
  98:             goto out;
  99: 
 100:         default:
 101:             fprintf(stderr, "grep: unknown flag\n");
 102:             continue;
 103:         }
 104:     }
 105: out:
 106:     if (argc<=0)
 107:         exit(2);
 108:     compile(*argv);
 109:     nfile = --argc;
 110:     if (argc<=0) {
 111:         if (lflag)
 112:             exit(1);
 113:         execute(0);
 114:     }
 115:     else while (--argc >= 0) {
 116:         argv++;
 117:         execute(*argv);
 118:     }
 119:     exit(retcode != 0 ? retcode : nsucc == 0);
 120: }
 121: 
 122: compile(astr)
 123: char *astr;
 124: {
 125:     register c;
 126:     register char *ep, *sp;
 127:     char *lastep;
 128:     int cclcnt;
 129: 
 130:     ep = expbuf;
 131:     sp = astr;
 132:     if (*sp == '^') {
 133:         circf++;
 134:         sp++;
 135:     }
 136:     if (wflag)
 137:         *ep++ = CBRC;
 138:     for (;;) {
 139:         if (ep >= &expbuf[ESIZE])
 140:             goto cerror;
 141:         if ((c = *sp++) != '*')
 142:             lastep = ep;
 143:         switch (c) {
 144: 
 145:         case '\0':
 146:             if (wflag)
 147:                 *ep++ = CLET;
 148:             *ep++ = CEOF;
 149:             return;
 150: 
 151:         case '.':
 152:             *ep++ = CDOT;
 153:             continue;
 154: 
 155:         case '*':
 156:             if (lastep==0)
 157:                 goto defchar;
 158:             *lastep |= STAR;
 159:             continue;
 160: 
 161:         case '$':
 162:             if (*sp != '\0')
 163:                 goto defchar;
 164:             *ep++ = CDOL;
 165:             continue;
 166: 
 167:         case '[':
 168:             *ep++ = CCL;
 169:             *ep++ = 0;
 170:             cclcnt = 1;
 171:             if ((c = *sp++) == '^') {
 172:                 c = *sp++;
 173:                 ep[-2] = NCCL;
 174:             }
 175:             do {
 176:                 *ep++ = c;
 177:                 cclcnt++;
 178:                 if (c=='\0' || ep >= &expbuf[ESIZE])
 179:                     goto cerror;
 180:             } while ((c = *sp++) != ']');
 181:             lastep[1] = cclcnt;
 182:             continue;
 183: 
 184:         case '\\':
 185:             if ((c = *sp++) == '\0')
 186:                 goto cerror;
 187:             if (c == '<') {
 188:                 *ep++ = CBRC;
 189:                 continue;
 190:             }
 191:             if (c == '>') {
 192:                 *ep++ = CLET;
 193:                 continue;
 194:             }
 195:         defchar:
 196:         default:
 197:             *ep++ = CCHR;
 198:             *ep++ = c;
 199:         }
 200:     }
 201:     cerror:
 202:     fprintf(stderr, "grep: RE error\n");
 203:     exit(2);
 204: }
 205: 
 206: same(a, b)
 207:     register int a, b;
 208: {
 209: 
 210:     return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b));
 211: }
 212: 
 213: letter(c)
 214:     register int c;
 215: {
 216: 
 217:     if (c >= 'a' && c <= 'z')
 218:         return (c);
 219:     if (c >= 'A' && c <= 'Z')
 220:         return (c + 'a' - 'A');
 221:     return (0);
 222: }
 223: 
 224: execute(file)
 225: {
 226:     register char *p1, *p2;
 227:     register c;
 228:     int f;
 229:     char *ebp, *cbp;
 230:     static char *buf;
 231:     static int blksize;
 232:     struct stat stb;
 233: 
 234:     if (file) {
 235:         if ((f = open(file, 0)) < 0) {
 236:             perror(file);
 237:             retcode = 2;
 238:         }
 239:     } else
 240:         f = 0;
 241:     if (buf == NULL) {
 242:         if (fstat(f, &stb) > 0 && stb.st_blksize > 0)
 243:             blksize = stb.st_blksize;
 244:         else
 245:             blksize = BLKSIZE;
 246:         buf = (char *)malloc(blksize);
 247:         if (buf == NULL) {
 248:             fprintf(stderr, "grep: no memory for %s\n", file);
 249:             retcode = 2;
 250:             return;
 251:         }
 252:     }
 253:     ebp = buf;
 254:     cbp = buf;
 255:     lnum = 0;
 256:     tln = 0;
 257:     blkno = -1;
 258:     for (;;) {
 259:         lnum++;
 260:         if((lnum&0377) == 0)
 261:             fflush(stdout);
 262:         p1 = linebuf;
 263:         p2 = cbp;
 264:         for (;;) {
 265:             if (p2 >= ebp) {
 266:                 if ((c = read(f, buf, blksize)) <= 0) {
 267:                     close(f);
 268:                     if (cflag) {
 269:                         if (lflag) {
 270:                             if (tln)
 271:                             printf("%s\n", file);
 272:                         } else {
 273:                             if (nfile > 1)
 274:                                 printf("%s:", file);
 275:                             printf("%ld\n", tln);
 276:                         }
 277:                     }
 278:                     return;
 279:                 }
 280:                 blkno++;
 281:                 p2 = buf;
 282:                 ebp = buf+c;
 283:             }
 284:             if ((c = *p2++) == '\n')
 285:                 break;
 286:             if(c)
 287:             if (p1 < &linebuf[BUFSIZ-1])
 288:                 *p1++ = c;
 289:         }
 290:         *p1++ = 0;
 291:         cbp = p2;
 292:         p1 = linebuf;
 293:         p2 = expbuf;
 294:         if (circf) {
 295:             if (advance(p1, p2))
 296:                 goto found;
 297:             goto nfound;
 298:         }
 299:         /* fast check for first character */
 300:         if (*p2==CCHR) {
 301:             c = p2[1];
 302:             do {
 303:                 if (*p1!=c && (!iflag || (c ^ *p1) != ' '
 304:                     || letter(c) != letter(*p1)))
 305:                     continue;
 306:                 if (advance(p1, p2))
 307:                     goto found;
 308:             } while (*p1++);
 309:             goto nfound;
 310:         }
 311:         /* regular algorithm */
 312:         do {
 313:             if (advance(p1, p2))
 314:                 goto found;
 315:         } while (*p1++);
 316:     nfound:
 317:         if (vflag)
 318:             succeed(file);
 319:         continue;
 320:     found:
 321:         if (vflag==0)
 322:             succeed(file);
 323:     }
 324: }
 325: 
 326: advance(alp, aep)
 327:     char *alp, *aep;
 328: {
 329:     register char *lp, *ep, *curlp;
 330:     char *nextep;
 331: 
 332:     lp = alp;
 333:     ep = aep;
 334:     for (;;) switch (*ep++) {
 335: 
 336:     case CCHR:
 337:         if (!same(*ep, *lp))
 338:             return (0);
 339:         ep++, lp++;
 340:         continue;
 341: 
 342:     case CDOT:
 343:         if (*lp++)
 344:             continue;
 345:         return(0);
 346: 
 347:     case CDOL:
 348:         if (*lp==0)
 349:             continue;
 350:         return(0);
 351: 
 352:     case CEOF:
 353:         return(1);
 354: 
 355:     case CCL:
 356:         if (cclass(ep, *lp++, 1)) {
 357:             ep += *ep;
 358:             continue;
 359:         }
 360:         return(0);
 361: 
 362:     case NCCL:
 363:         if (cclass(ep, *lp++, 0)) {
 364:             ep += *ep;
 365:             continue;
 366:         }
 367:         return(0);
 368: 
 369:     case CDOT|STAR:
 370:         curlp = lp;
 371:         while (*lp++);
 372:         goto star;
 373: 
 374:     case CCHR|STAR:
 375:         curlp = lp;
 376:         while (same(*lp, *ep))
 377:             lp++;
 378:         lp++;
 379:         ep++;
 380:         goto star;
 381: 
 382:     case CCL|STAR:
 383:     case NCCL|STAR:
 384:         curlp = lp;
 385:         while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
 386:         ep += *ep;
 387:         goto star;
 388: 
 389:     star:
 390:         do {
 391:             lp--;
 392:             if (advance(lp, ep))
 393:                 return(1);
 394:         } while (lp > curlp);
 395:         return(0);
 396: 
 397:     case CBRC:
 398:         if (lp == expbuf)
 399:             continue;
 400: #define uletter(c)  (letter(c) || c == '_')
 401:         if ( ( uletter(*lp) || digit ( * lp ) )  && !uletter(lp[-1]) && !digit(lp[-1]))
 402:             continue;
 403:         return (0);
 404: 
 405:     case CLET:
 406:         if (!uletter(*lp) && !digit(*lp))
 407:             continue;
 408:         return (0);
 409: 
 410:     default:
 411:         fprintf(stderr, "grep: RE botch\n");
 412:         exit(2);
 413:     }
 414: }
 415: 
 416: cclass(aset, ac, af)
 417:     char *aset;
 418: {
 419:     register char *set, c;
 420:     register n;
 421: 
 422:     set = aset;
 423:     if ((c = ac) == 0)
 424:         return(0);
 425:     n = *set++;
 426:     while (--n)
 427:         if (n > 2 && set[1] == '-') {
 428:             if (c >= (set[0] & 0177) && c <= (set[2] & 0177))
 429:                 return (af);
 430:             set += 3;
 431:             n -= 2;
 432:         } else
 433:             if ((*set++ & 0177) == c)
 434:                 return(af);
 435:     return(!af);
 436: }
 437: 
 438: succeed(f)
 439: {
 440:     nsucc = 1;
 441:     if (sflag)
 442:         return;
 443:     if (cflag) {
 444:         tln++;
 445:         return;
 446:     }
 447:     if (nfile > 1)
 448:         printf("%s:", f);
 449:     if (bflag)
 450:         printf("%ld:", blkno);
 451:     if (nflag)
 452:         printf("%ld:", lnum);
 453:     printf("%s\n", linebuf);
 454: }
 455: 
 456: digit(c)
 457:     char c;
 458: {
 459:     return (c>='0' && c<='9');
 460: }

Defined functions

advance defined in line 326; used 4 times
cclass defined in line 416; used 3 times
compile defined in line 122; used 1 times
digit defined in line 456; used 3 times
execute defined in line 224; used 2 times
letter defined in line 213; used 5 times
main defined in line 56; never used
same defined in line 206; used 2 times
succeed defined in line 438; used 2 times

Defined variables

bflag defined in line 41; used 2 times
blkno defined in line 52; used 3 times
cflag defined in line 43; used 3 times
circf defined in line 51; used 2 times
copyright defined in line 8; never used
expbuf defined in line 38; used 5 times
iflag defined in line 46; used 3 times
lflag defined in line 47; used 3 times
linebuf defined in line 40; used 4 times
lnum defined in line 39; used 4 times
nfile defined in line 45; used 3 times
nflag defined in line 42; used 2 times
nsucc defined in line 50; used 2 times
retcode defined in line 54; used 4 times
sccsid defined in line 14; never used
sflag defined in line 49; used 2 times
tln defined in line 53; used 4 times
vflag defined in line 44; used 3 times
wflag defined in line 48; used 3 times

Defined macros

BLKSIZE defined in line 24; used 1 times
CBRC defined in line 32; used 2 times
CCHR defined in line 25; used 3 times
CCL defined in line 27; used 3 times
CDOL defined in line 29; used 1 times
CDOT defined in line 26; used 2 times
CEOF defined in line 30; used 1 times
CLET defined in line 33; used 2 times
ESIZE defined in line 36; used 3 times
NCCL defined in line 28; used 2 times
STAR defined in line 34; used 2 times
uletter defined in line 400; used 3 times
Last modified: 1987-02-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3086
Valid CSS Valid XHTML 1.0 Strict