Annotation of coherent/d/bin/grep/grep1.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Grep - search a file for a pattern
        !             3:  * This code uses the regexp.c code which is
        !             4:  * also used by AWK.
        !             5:  */
        !             6: 
        !             7: #include <stdio.h>
        !             8: #include <ctype.h>
        !             9: #include "grep.h"
        !            10: 
        !            11: #define        MAXLINE 400             /* Maximum input line length */
        !            12: #define        NEXP    50              /* Maximum number of regular expressions */
        !            13: #define        BSIZE   BUFSIZ          /* Assume block size if buffer size */
        !            14: 
        !            15: char   line[MAXLINE];
        !            16: struct exps {
        !            17:        union {
        !            18:                char    *u_cp;
        !            19:                RE      *u_re;
        !            20:        }       e_un;
        !            21:        int     (*e_mfun)();
        !            22: }      exps[NEXP+1];
        !            23: char   usage[] =
        !            24:        "Usage: grep [-abchlnsvxy] [-e exp] [-f efile] [expression] [file ...]";
        !            25: char   mre[] = "Missing regular expression";
        !            26: char   nospace[] = "Out of space for regular expressions";
        !            27: char   *fname;         /* Current filename */
        !            28: 
        !            29: int    vflag;          /* Reverse sense of match */
        !            30: int    cflag;          /* Print only count of lines */
        !            31: int    lflag;          /* Only filenames with matching lines */
        !            32: int    nflag;          /* precede lines by line number in file */
        !            33: int    bflag;          /* print block number of match */
        !            34: int    sflag;          /* No output, only status */
        !            35: int    hflag;          /* Never print filenames */
        !            36: int    xflag;          /* Exact match only */
        !            37: int    some;           /* non-zero if some matches */
        !            38: int    outfile;        /* Output filename if match flag */
        !            39: int    lineno;         /* Input line # */
        !            40: unsigned blkno;                /* Block number for `-b' */
        !            41: long   lmatch;         /* Lines matching */
        !            42: int    yflag;          /* Dual case comparisons */
        !            43: 
        !            44: int    (*mfun)();      /* Match function */
        !            45: int    rematch();
        !            46: int    dirmatch();
        !            47: int    reinterp();
        !            48: int    ematch();
        !            49: int    yematch();
        !            50: 
        !            51: main(argc, argv)
        !            52: char *argv[];
        !            53: {
        !            54:        register RE *rp;
        !            55:        register char *cp;
        !            56:        register i;
        !            57:        struct exps *epp;
        !            58:        FILE *fp;
        !            59: 
        !            60:        mfun = rematch;
        !            61:        while (argc>1 && *argv[1]=='-') {
        !            62:                for (cp = &argv[1][1]; *cp; cp++)
        !            63:                        switch (*cp) {
        !            64:                        case 'a':
        !            65:                                refull = 1;
        !            66:                                break;
        !            67: 
        !            68:                        case 'b':
        !            69:                                bflag = 1;
        !            70:                                break;
        !            71: 
        !            72:                        case 'c':
        !            73:                                cflag = 1;
        !            74:                                break;
        !            75: 
        !            76:                        case 'e':
        !            77:                                if (argc < 3)
        !            78:                                        err(mre);
        !            79:                                expsave(argv[2]);
        !            80:                                argc--;
        !            81:                                argv++;
        !            82:                                break;
        !            83: 
        !            84:                        case 'f':
        !            85:                                if (argc < 3)
        !            86:                                        err("Missing expression filename");
        !            87:                                if ((fp = fopen(argv[2], "r")) == NULL)
        !            88:                                        err("Cannot open %s", argv[2]);
        !            89:                                argv++;
        !            90:                                argc--;
        !            91:                                while (fgets(line, MAXLINE, fp) != NULL) {
        !            92:                                        i = strlen(line);
        !            93:                                        line[i-1] = '\0';
        !            94:                                        expsave(line);
        !            95:                                }
        !            96:                                fclose(fp);
        !            97:                                break;
        !            98: 
        !            99:                        case 'h':
        !           100:                                hflag = 1;
        !           101:                                break;
        !           102: 
        !           103:                        case 'l':
        !           104:                                lflag = 1;
        !           105:                                break;
        !           106: 
        !           107:                        case 'n':
        !           108:                                nflag = 1;
        !           109:                                break;
        !           110: 
        !           111:                        case 's':
        !           112:                                sflag = 1;
        !           113:                                break;
        !           114: 
        !           115:                        case 'v':
        !           116:                                vflag = 1;
        !           117:                                break;
        !           118: 
        !           119:                        case 'x':
        !           120:                                xflag = 1;
        !           121:                                mfun = dirmatch;
        !           122:                                break;
        !           123: 
        !           124:                        case 'i':
        !           125:                        case 'y':
        !           126:                                redual = 1;
        !           127:                                yflag = 1;
        !           128:                                break;
        !           129: 
        !           130:                        default:
        !           131:                                err(usage);
        !           132:                        }
        !           133:                argv++;
        !           134:                argc--;
        !           135:        }
        !           136:        if (exps[0].e_un.u_cp == NULL) {
        !           137:                if (argc-- < 2)
        !           138:                        err(usage);
        !           139:                expsave(argv[1]);
        !           140:                argv++;
        !           141:        }
        !           142:        expsave(NULL);
        !           143:        if (!xflag)
        !           144:                for (epp = &exps[0]; (cp = epp->e_un.u_cp) != NULL; epp++) {
        !           145:                        rp = epp->e_un.u_re = reparse(cp, '\0');
        !           146:                        if (reerror != NULL)
        !           147:                                err(reerror);
        !           148:                        for (; rp != NULL; rp = rp->r_next)
        !           149:                                if (rp->r_op != CONC)
        !           150:                                        break;
        !           151:                        if (rp != NULL) {       /* hard RE */
        !           152:                                free(cp);
        !           153:                                epp->e_mfun = reinterp;
        !           154:                        } else {
        !           155:                                rp = epp->e_un.u_re;
        !           156:                                epp->e_un.u_cp = cp;
        !           157:                                epp->e_mfun = yflag ? yematch : ematch;
        !           158:                                for ( ; rp!=NULL; rp = rp->r_next) {
        !           159:                                        *cp = rp->r_left.u_ival;
        !           160:                                        cp++;
        !           161:                                }
        !           162:                                *cp = '\0';
        !           163:                        }
        !           164:                }
        !           165:        if (argc < 3)                   /* Fewer than 2 files? */
        !           166:                hflag = 1;
        !           167:        if (argc == 1) {
        !           168:                fname = "(stdin)";
        !           169:                grep(stdin);
        !           170:        } else
        !           171:                for (i=1; i<argc; i++) {
        !           172:                        if ((fp = fopen(argv[i], "r")) == NULL)
        !           173:                                err("Cannot open %s", argv[i]);
        !           174:                        fname = argv[i];
        !           175:                        grep(fp);
        !           176:                        fclose(fp);
        !           177:                }
        !           178:        if (cflag)
        !           179:                printf("%ld\n", lmatch);
        !           180:        exit(!some);
        !           181: }
        !           182: 
        !           183: /*
        !           184:  * Save regular expression.
        !           185:  */
        !           186: expsave(s)
        !           187: register char *s;
        !           188: {
        !           189:        static struct exps *epp;
        !           190: 
        !           191:        if (epp == NULL)
        !           192:                epp = &exps[0];
        !           193:        if (epp >= &exps[NEXP-1])
        !           194:                err("Too many regular expressions");
        !           195:        if (s == NULL)
        !           196:                epp->e_un.u_cp = NULL;
        !           197:        else {
        !           198:                if ((epp->e_un.u_cp = malloc(strlen(s)+1)) == NULL)
        !           199:                        err(nospace);
        !           200:                strcpy(epp->e_un.u_cp, s);
        !           201:        }
        !           202:        epp++;
        !           203: }
        !           204: 
        !           205: /*
        !           206:  * Called for each input file
        !           207:  * to drive the pattern matches.
        !           208:  */
        !           209: grep(ifp)
        !           210: FILE *ifp;
        !           211: {
        !           212:        register unsigned n;
        !           213:        register c;
        !           214:        register char *cp;
        !           215: 
        !           216:        outfile = 0;
        !           217:        blkno = 0;
        !           218:        n = BSIZE;
        !           219:        lineno = 0;
        !           220:        for (cp = line; (c = getc(ifp)) != EOF; ) {
        !           221:                if (n-- == 0) {
        !           222:                        n = BSIZE;
        !           223:                        blkno++;
        !           224:                }
        !           225:                if (c=='\n' || cp>=&line[MAXLINE-1]) {
        !           226:                        *cp = '\0';
        !           227:                        lineno++;
        !           228:                        (*mfun)(cp = line);
        !           229:                } else
        !           230:                        *cp++ = c;
        !           231:        }
        !           232:        if (outfile)
        !           233:                printf("%s\n", fname);
        !           234: }
        !           235: 
        !           236: /*
        !           237:  * Called when a match occurred in input
        !           238:  */
        !           239: amatch(s)
        !           240: char *s;
        !           241: {
        !           242:        some = 1;
        !           243:        if (sflag)
        !           244:                return;
        !           245:        if (!lflag && !cflag) {
        !           246:                if (!hflag)
        !           247:                        printf("%s:", fname);
        !           248:                if (bflag)
        !           249:                        printf("%d:", blkno);
        !           250:                else if (nflag)
        !           251:                        printf("%d:", lineno);
        !           252:                printf("%s\n", s);
        !           253:        } else if (lflag)
        !           254:                outfile = 1;
        !           255:        else if (cflag)
        !           256:                lmatch++;
        !           257: }
        !           258: 
        !           259: /*
        !           260:  * try to match each line with all the
        !           261:  * regular expressions.
        !           262:  * An attempt is made to make expressions
        !           263:  * with no metacharacters run faster.
        !           264:  */
        !           265: rematch(s)
        !           266: char *s;
        !           267: {
        !           268:        register struct exps *epp;
        !           269:        register int m;
        !           270: 
        !           271:        m = 0;
        !           272:        for (epp = &exps[0]; epp->e_un.u_re!=NULL && m==0; epp++)
        !           273:                if ((*epp->e_mfun)(epp->e_un.u_re, s) != 0)
        !           274:                        m = 1;
        !           275:        if (vflag)
        !           276:                m = !m;
        !           277:        if (m)
        !           278:                amatch(s);
        !           279:        return (m);
        !           280: }
        !           281: 
        !           282: /*
        !           283:  * Direct match function (for `-x' option)
        !           284:  */
        !           285: dirmatch(s)
        !           286: char *s;
        !           287: {
        !           288:        register struct exps *epp;
        !           289:        register m;
        !           290: 
        !           291:        m = 0;
        !           292:        for (epp = &exps[0]; epp->e_un.u_cp!=NULL && !m; epp++)
        !           293:                m = yflag ? yseq(epp->e_un.u_cp, s) : seq(epp->e_un.u_cp, s);
        !           294:        if (vflag)
        !           295:                m = !m;
        !           296:        if (m)
        !           297:                amatch(s);
        !           298:        return (m);
        !           299: }
        !           300: 
        !           301: /*
        !           302:  * Easy match
        !           303:  * For non -y grep.
        !           304:  */
        !           305: ematch(p, s)
        !           306: char *p;
        !           307: register char *s;
        !           308: {
        !           309:        register char *xp, *xs;
        !           310: 
        !           311:        do {
        !           312:                xp = p;
        !           313:                xs = s;
        !           314:                while (*xp != '\0') {
        !           315:                        if (*xs == '\0')
        !           316:                                return (0);
        !           317:                        if (*xp != *xs++)
        !           318:                                break;
        !           319:                        xp++;
        !           320:                }
        !           321:                if (*xp == '\0')
        !           322:                        return (1);
        !           323:        } while (*s++ != '\0');
        !           324:        return (0);
        !           325: }
        !           326: 
        !           327: /*
        !           328:  * Version of `ematch' for `-y' option
        !           329:  * of grep.
        !           330:  */
        !           331: yematch(p, s)
        !           332: char *p;
        !           333: register char *s;
        !           334: {
        !           335:        register char *xp, *xs;
        !           336:        register int c;
        !           337: 
        !           338:        do {
        !           339:                xp = p;
        !           340:                xs = s;
        !           341:                while (*xp != '\0') {
        !           342:                        if (*xs == '\0')
        !           343:                                return (0);
        !           344:                        if (islower(*xp) && isupper(*xs))
        !           345:                                c = tolower(*xs++); else
        !           346:                                c = *xs++;
        !           347:                        if (*xp != c)
        !           348:                                break;
        !           349:                        xp++;
        !           350:                }
        !           351:                if (*xp == '\0')
        !           352:                        return (1);
        !           353:        } while (*s++ != '\0');
        !           354:        return (0);
        !           355: }
        !           356: 
        !           357: /*
        !           358:  * String comparison for `-x' option
        !           359:  * without `-y' (dual) flag.
        !           360:  */
        !           361: seq(p, s)
        !           362: register char *p;
        !           363: register char *s;
        !           364: {
        !           365:        while (*s == *p++)
        !           366:                if (*s++ == '\0')
        !           367:                        return (1);
        !           368:        return (0);
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * Version of `seq' for the `-y' option.
        !           373:  * First argument is the pattern, the second
        !           374:  * is the input string.
        !           375:  */
        !           376: yseq(p, s)
        !           377: register char *p;
        !           378: register char *s;
        !           379: {
        !           380:        register int c;
        !           381: 
        !           382:        while ((c = *s++) != '\0') {
        !           383:                if (islower(*p) && isupper(c))
        !           384:                        c = tolower(c);
        !           385:                if (c != *p++)
        !           386:                        return (0);
        !           387:        }
        !           388:        if (*p != '\0')
        !           389:                return (0);
        !           390:        return (1);
        !           391: }
        !           392: 
        !           393: err(s)
        !           394: {
        !           395:        if (!sflag)
        !           396:                fprintf(stderr, "grep: %r\n", &s);
        !           397:        exit(2);
        !           398: }

unix.superglobalmegacorp.com

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