# 2.11BSD#431 - /usr/src/bin/grep.c

##### Functions

    advance           X
    compile           X
    ecmp              X
    errexit           X
    execute           X
    main              X
    succeed           X

##### Variables

    bflag             X
    bittab            X
    blkno             X
    braelist          X
    braslist          X
    cflag             X
    circf             X
    expbuf            X
    hflag             X
    lflag             X
    linebuf           X
    lnum              X
    nfile             X
    nflag             X
    nsucc             X
    retcode           X
    sflag             X
    tln               X
    vflag             X
    wflag             X
    ybuf              X
    yflag             X

##### Macros

    CBACK             X
    CBRA              X
    CBRC              X
    CCHR              X
    CCL               X
    CDOL              X
    CDOT              X
    CEOF              X
    CKET              X
    CLET              X
    ESIZE             X
    LBSIZE            X
    NBRA              X
    NCCL              X
    STAR              X
    uletter           X

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

#### Defined functions

advance defined in line 355; used 6 times

- in line 325, 335, 342, 418, 453, 460

compile defined in line 158; used 1 times

- in line 145

ecmp defined in line 510; used 2 times

- in line 403, 415

errexit defined in line 519; used 4 times

- in line 116, 140, 287, 480

execute defined in line 290; used 2 times

- in line 150-153(2)

main defined in line 67; never used
succeed defined in line 484; used 2 times

- in line 347-351(2)

#### Defined variables

bflag defined in line 39; used 2 times

- in line 95, 502

bittab defined in line 56; used 4 times

- in line 227-230(2), 385, 439

blkno defined in line 51; used 1 times

- in line 503

braelist defined in line 55; used 5 times

- in line 395-402(3), 411-413(2)

braslist defined in line 54; used 3 times

- in line 391, 399, 410

cflag defined in line 42; used 3 times

- in line 103, 309, 490

circf defined in line 50; used 2 times

- in line 177, 324

expbuf defined in line 35; used 5 times

- in line 171, 183, 213, 323, 466

hflag defined in line 45; used 2 times

- in line 83, 500

lflag defined in line 40; used 3 times

- in line 99, 148, 494

linebuf defined in line 37; used 4 times

- in line 306, 318-322(2), 506

lnum defined in line 36; used 3 times

- in line 302-305(2), 505

nfile defined in line 44; used 3 times

- in line 146, 310, 500

nflag defined in line 41; used 2 times

- in line 107, 504

nsucc defined in line 53; used 2 times

- in line 155, 487

retcode defined in line 49; used 3 times

- in line 155(2), 299

sccsid defined in line 2; never used
sflag defined in line 46; used 2 times

- in line 87, 488

tln defined in line 52; used 3 times

- in line 303, 312, 491

vflag defined in line 43; used 3 times

- in line 91, 346-350(2)

wflag defined in line 48; used 3 times

- in line 79, 180, 190

ybuf defined in line 38; used 3 times

- in line 124, 139-143(2)

yflag defined in line 47; used 2 times

- in line 75, 122

#### Defined macros

CBACK defined in line 27; used 2 times

- in line 275, 409

CBRA defined in line 17; used 2 times

- in line 200, 258

CBRC defined in line 25; used 3 times

- in line 181, 201, 246

CCHR defined in line 18; used 4 times

- in line 282, 330, 429, 448

CCL defined in line 20; used 2 times

- in line 215, 435

CDOL defined in line 22; used 1 times

- in line 209

CDOT defined in line 19; used 2 times

- in line 196, 424

CEOF defined in line 23; used 1 times

- in line 192

CKET defined in line 24; used 2 times

- in line 200, 266

CLET defined in line 26; used 3 times

- in line 191, 201, 250

ESIZE defined in line 32; used 5 times

- in line 35-38(2), 139, 183, 213

LBSIZE defined in line 31; used 2 times

- in line 37, 318

NBRA defined in line 33; used 4 times

- in line 54-55(2), 166, 254

NCCL defined in line 21; never used
STAR defined in line 29; used 1 times

- in line 203

uletter defined in line 468; used 3 times

- in line 469-475(3)

Last modified: 1987-02-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1825 |