Annotation of 42BSD/ucb/grep.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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