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

Defined functions

advance defined in line 301; used 4 times
cclass defined in line 389; used 3 times
compile defined in line 111; used 1 times
  • in line 94
digit defined in line 430; used 3 times
execute defined in line 213; used 2 times
letter defined in line 202; used 5 times
main defined in line 40; never used
same defined in line 195; used 2 times
succeed defined in line 411; used 2 times

Defined variables

bflag defined in line 24; used 2 times
blkno defined in line 35; used 3 times
cantopen defined in line 38; used 2 times
cflag defined in line 26; used 3 times
circf defined in line 34; used 2 times
expbuf defined in line 21; used 5 times
ibuf defined in line 36; used 5 times
iflag defined in line 29; used 3 times
lflag defined in line 30; used 3 times
linebuf defined in line 23; used 4 times
lnum defined in line 22; used 4 times
nfile defined in line 28; used 3 times
nflag defined in line 25; used 2 times
nsucc defined in line 33; used 2 times
sflag defined in line 32; used 2 times
tln defined in line 37; used 4 times
vflag defined in line 27; used 3 times
wflag defined in line 31; used 3 times

Defined macros

CBRC defined in line 14; used 2 times
CCHR defined in line 7; used 3 times
CCL defined in line 9; used 3 times
CDOL defined in line 11; used 1 times
CDOT defined in line 8; used 2 times
CEOF defined in line 12; used 1 times
CLET defined in line 15; used 2 times
ESIZE defined in line 19; used 3 times
LBSIZE defined in line 18; used 2 times
NCCL defined in line 10; used 2 times
STAR defined in line 16; used 2 times
uletter defined in line 374; used 3 times
Last modified: 1983-07-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1210
Valid CSS Valid XHTML 1.0 Strict