Annotation of researchv10no/cmd/grep.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.