Annotation of coherent/d/bin/grep/grep1.c, revision 1.1.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.