Annotation of 40BSD/cmd/grep/ucbgrep.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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