Annotation of coherent/b/bin/cgrep.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * To compile use
        !             3:  * cc cgrep.c -lmisc
        !             4:  * This uses libmisc.a and the misc.h header from libmisc.a.Z
        !             5:  */
        !             6: 
        !             7: /*
        !             8:  * cgrep is egrep for c source programs.
        !             9:  *     cgrep [-r new] [-clnsA] [pattern] [file ...]
        !            10:  *
        !            11:  * cgrep checks all c identifiers (cgrep considers if, etc to be
        !            12:  * identifiers) against an egrep type pattern for a full match.
        !            13:  *
        !            14:  *     cgrep tmp *.c
        !            15:  * will find tmp as an identifier, but not tmpname, or tmp in a string or
        !            16:  * comment.
        !            17:  *     cgrep "x|abc|d" *.c
        !            18:  * will find x, ab, or d. Note these are egrep style patterns with a
        !            19:  * surrounding ^( )$ Thus "reg*" will not match register but "reg.*"
        !            20:  * will.
        !            21:  *
        !            22:  * cgrep accumulates names with included . and -> for testing against the
        !            23:  * egrep pattern. Thus you can look for ptr->val with
        !            24:  *     cgrep "ptr->val" x.c
        !            25:  * This will find ptr->val even if it contains spaces, comments or is
        !            26:  * spread across lines. If it is spread across lines it will be reported
        !            27:  * on the line containing the last token unless the -A option is used
        !            28:  * in which case it will be reported on the line containing the first
        !            29:  * token.
        !            30:  *
        !            31:  * For structure.member use
        !            32:  *     cgrep "structure\.member" x.c
        !            33:  * because . has the egrep meaning any character. Do not include spaces
        !            34:  * in any pattern. Only identifiers and . or -> between identifiers are
        !            35:  * included in the tokens checked for pattern match.
        !            36:  *
        !            37:  * Where no files are given cgrep will read stdin. Options -lA require
        !            38:  * a file name. Where stdin is used with option -r a new file is written
        !            39:  * out stdout.
        !            40:  *
        !            41:  * Options.
        !            42:  *
        !            43:  * -l lists the files with hits not the lines.
        !            44:  *
        !            45:  * -n puts a line number on found lines.
        !            46:  *
        !            47:  * -s List all strings. This form takes no pattern.
        !            48:  *
        !            49:  * -c List all comments. This form takes no pattern.
        !            50:  *
        !            51:  * -A builds a tmp file and calls 'me' to process the file with the tmp file
        !            52:  *    as an "error" list like the -A option of cc. Each line of this list
        !            53:  *    shows the found pattern and where multiple patterns are found on a
        !            54:  *    line there are multiple lines, just like cc -A showing multiple
        !            55:  *    errors on a line. This is to allow emacs scripts to make systematic
        !            56:  *    changes. Where a patttern is split across multiple lines -A causes
        !            57:  *    it to be reported on the line with the first token, also to
        !            58:  *    simplify emacs scripts.
        !            59:  *
        !            60:  *    If cgrep -A is used to process a number of files it will search each
        !            61:  *    file for patttern matches and call 'me' only if the file has a hit. To
        !            62:  *    stop the process exit 'me' with <ctl-u><ctl-x><ctl-c>. See the new emacs
        !            63:  *    initialization macro feature for a way to process these files
        !            64:  *    automatically.
        !            65:  *
        !            66:  * -r Replaces all occurances of the pattern with "new". This form only matches
        !            67:  *    simple tokens, not things like "ptr->val". -r is incompatible with all
        !            68:  *    other options.
        !            69:  *
        !            70:  * -R Replaces all occurances of the pattern with a new after the following
        !            71:  *    substitutions. & is the whole pattern found. \1 is the first
        !            72:  *    parenthesized subexpression, \2 the second etc.
        !            73:  *
        !            74:  * -d token. Take following string and comment. For documentation extraction.
        !            75:  *    use the first char of the token as an output delimeter.
        !            76:  *
        !            77:  * -C token. Use token as delimeter -c option.
        !            78:  */
        !            79: #include <ctype.h>
        !            80: #include <stdio.h>
        !            81: #include <misc.h>
        !            82: 
        !            83: /*
        !            84:  * Cgrep never runs out of room on lines or buffers until malloc fails
        !            85:  * these are buffer expanders.
        !            86:  */
        !            87: #define TROOM(buf, has, needs) while ((needs) >= has) \
        !            88:  if (NULL == (buf = realloc(buf, sizeof(*buf) * (has += 10)))) \
        !            89:   fatal(outSpace)
        !            90: 
        !            91: #define ROOM(buf, has, needs)  while ((needs) >= has) \
        !            92:  if (NULL == (buf = realloc(buf, has += 512))) \
        !            93:   fatal(outSpace)
        !            94: 
        !            95: extern char *realloc();
        !            96: static char outSpace[] = "cgrep: out of space";
        !            97: 
        !            98: struct token { /* collected token array */
        !            99:        int start;      /* token index on buff */
        !           100:        int atline;     /* line number where token spotted */
        !           101: };
        !           102: 
        !           103: enum fstate {  /* lexical processing state */
        !           104:        start,
        !           105:        slash,          /* slash encountered in normal state */
        !           106:        comment,        /* in comment */
        !           107:        cppcom,         /* in cpp comment */
        !           108:        star,           /* * in comment */
        !           109:        bsl,            /* back slash */
        !           110:        dquote,         /* double quote */
        !           111:        squote,         /* single quote */
        !           112:        token,          /* c word */
        !           113:        minus           /* - maybe -> */
        !           114: };
        !           115: 
        !           116: enum wstate { /* word processing states */
        !           117:        word,   /* some c identifier */
        !           118:        dot,    /* . or -> */
        !           119:        other   /* anything else */
        !           120: };
        !           121: 
        !           122: /* cgrep has no fixed size arrays only growable buffers */
        !           123: static char *buff = NULL;      /* accumulate stuff */
        !           124: static int buffLen;            /* buffer length */
        !           125: 
        !           126: static struct token *tokens = NULL; /* token array */
        !           127: static int tokenLen;           /* size of token array */
        !           128: 
        !           129: static char *line;             /* expandable input line */
        !           130: static int  lineLen;           /* current length of input line */
        !           131: 
        !           132: static char lswitch;           /* list files found */
        !           133: static char aswitch;           /* call emacs with line list */
        !           134: static char dswitch;           /* special for docs */
        !           135: static char dtoken[80];                /* token copy for dswitch */
        !           136: static char nswitch;           /* print line number */
        !           137: static char sswitch;           /* print all strings */
        !           138: static char cswitch;           /* print all comments */
        !           139: static char rswitch;           /* replace found pattern */
        !           140: static char Rswitch;           /* do substition magic */
        !           141: 
        !           142: static regexp *pat;            /* a compiled regular expression */
        !           143: 
        !           144: static char *newstr;           /* The new string with rswitch */
        !           145: 
        !           146: static char *filen = NULL;     /* the file currently being processed */
        !           147: static char *tname = NULL;     /* temp file name */
        !           148: static FILE *tfp;              /* tmp file pointer */
        !           149: 
        !           150: static int lineno;             /* current line number */
        !           151: static int marked;             /* 1 if pattern found on line. */
        !           152: 
        !           153: static int matched;            /* 1 if any match found. */
        !           154: 
        !           155: /*
        !           156:  * Character types table
        !           157:  * for the ASCII character set modified to see _ as alpha.
        !           158:  * _ctype[0] is for EOF, the rest if indexed
        !           159:  * by the ascii values of the characters.
        !           160:  */
        !           161: static unsigned char _ctype[] = {
        !           162:        0,      /* EOF */
        !           163:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           164:        _C, _S|_C, _S|_C, _S|_C, _S|_C, _S|_C, _C, _C,
        !           165:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           166:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           167:        _S|_X, _P, _P, _P, _P, _P, _P, _P,
        !           168:        _P, _P, _P, _P, _P, _P, _P, _P,
        !           169:        _N, _N, _N, _N, _N, _N, _N, _N,
        !           170:        _N, _N, _P, _P, _P, _P, _P, _P,
        !           171:        _P, _U, _U, _U, _U, _U, _U, _U,
        !           172:        _U, _U, _U, _U, _U, _U, _U, _U,
        !           173:        _U, _U, _U, _U, _U, _U, _U, _U,
        !           174:        _U, _U, _U, _P, _P, _P, _P, _L,
        !           175:        _P, _L, _L, _L, _L, _L, _L, _L,
        !           176:        _L, _L, _L, _L, _L, _L, _L, _L,
        !           177:        _L, _L, _L, _L, _L, _L, _L, _L,
        !           178:        _L, _L, _L, _P, _P, _P, _P, _C,
        !           179:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           180:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           181:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           182:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           183:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           184:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           185:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           186:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           187:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           188:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           189:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           190:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           191:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           192:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           193:        _C, _C, _C, _C, _C, _C, _C, _C,
        !           194:        _C, _C, _C, _C, _C, _C, _C, _C
        !           195: };
        !           196: 
        !           197: /*
        !           198:  * Report errors for public domain regexp package.
        !           199:  */
        !           200: void
        !           201: regerror(s)
        !           202: char *s;
        !           203: {
        !           204:        fatal("cgrep: pattern error %s\n", s);
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Pattern found with -A mode. It is assumed that users of
        !           209:  * this mode will want to know about all hits on a line.
        !           210:  */
        !           211: static void
        !           212: emacsLine(found, atline)
        !           213: char *found;
        !           214: {
        !           215:        extern char *tempnam();
        !           216: 
        !           217:        /* if tmp file not opened open it. */
        !           218:        if ((NULL == tname) &&
        !           219:            ((NULL == (tname = tempnam(NULL, "cgr"))) ||
        !           220:              (NULL == (tfp = fopen(tname, "w")))))
        !           221:                fatal("cgrep: Cannot open tmp file");
        !           222:        fprintf(tfp, "%d: %s: found '%s'\n", atline, filen, found);
        !           223: }
        !           224: 
        !           225: /*
        !           226:  * When we get a word, dot, arrow or other we come here.
        !           227:  *
        !           228:  * cgrep accumulates things like ptr->memb.x in buff.
        !           229:  * as these are accumulated it is nessisary to match buff
        !           230:  * against the regular expression one slice at a time
        !           231:  * that is when the x in ptr->memb.x was found cgrep would check
        !           232:  * ptr->memb.x then memb.x then x
        !           233:  * against the pattern. Thus memb.x matches ptr->memb.x
        !           234:  */
        !           235: static void
        !           236: gota(got, what)
        !           237: register enum wstate got;      /* what we have */
        !           238: char *what;            /* the string we have or NULL */
        !           239: {
        !           240:        static int tokenCt;         /* number of tokens */
        !           241:        static enum wstate state;   /* current word processing state */
        !           242:        static int wlen, blen;      /* strlen(what) and strlen(buff) + 1 */
        !           243:        int i;
        !           244: 
        !           245:        if (sswitch || cswitch)
        !           246:                return;
        !           247: 
        !           248:        if (rswitch) {  /* replace mode works on tokens only */
        !           249:                marked = (word == got) && regexec(pat, what);
        !           250:                matched |= marked;
        !           251:                return;
        !           252:        }
        !           253: 
        !           254:        switch (got) {
        !           255:        case word:
        !           256:                wlen = strlen(what);
        !           257:                switch (state) {
        !           258:                case other:
        !           259:                case word:
        !           260:                        /* store start and line number of token */
        !           261:                        tokenCt = 1;
        !           262:                        TROOM(tokens, tokenLen, tokenCt);
        !           263:                        tokens[0].start = 0;
        !           264:                        tokens[0].atline = lineno;
        !           265: 
        !           266:                        /* store token */
        !           267:                        blen = wlen;
        !           268:                        ROOM(buff, buffLen, blen);
        !           269:                        strcpy(buff, what);
        !           270:                        break;
        !           271:                case dot:
        !           272:                        /* store start and line number of token */
        !           273:                        TROOM(tokens, tokenLen, tokenCt);
        !           274:                        tokens[tokenCt].start = blen;
        !           275:                        tokens[tokenCt++].atline = lineno;
        !           276: 
        !           277:                        /* store token */
        !           278:                        blen += wlen;
        !           279:                        ROOM(buff, buffLen, blen);
        !           280:                        strcat(buff, what);
        !           281:                }
        !           282: 
        !           283:                /* Check the accumulated token for matches */
        !           284:                for (i = 0; i < tokenCt; i++) {
        !           285:                        char *p;
        !           286: 
        !           287:                        if (regexec(pat, p = buff + tokens[i].start)) {
        !           288:                                if (aswitch)
        !           289:                                        emacsLine(p, tokens[i].atline);
        !           290:                                else {
        !           291:                                        marked = 1;
        !           292:                                        matched = 1;
        !           293:                                        if (dswitch) {
        !           294:                                                strcpy(dtoken, p);
        !           295:                                                cswitch = sswitch = 1;
        !           296:                                        }
        !           297:                                        break;
        !           298:                                }
        !           299:                        }
        !           300:                }
        !           301: 
        !           302:                state = got;
        !           303:                break;
        !           304: 
        !           305:        case dot:
        !           306:                if (word == state) {
        !           307:                        blen += strlen(what);
        !           308:                        ROOM(buff, buffLen, blen);
        !           309:                        strcat(buff, what);
        !           310:                        state = got;
        !           311:                        break;
        !           312:                }
        !           313:        case other:
        !           314:                state = other;
        !           315:        }
        !           316: }
        !           317: 
        !           318: /*
        !           319:  * call emacs with file and tmpfile.
        !           320:  */
        !           321: static void
        !           322: callEmacs()
        !           323: {
        !           324: #ifdef GEMDOS
        !           325: #include <path.h>
        !           326:        extern  char *path(), *getenv();
        !           327:        extern char **environ;
        !           328:        static char* cmda[5] = { NULL, "-e", NULL, NULL, NULL };
        !           329: #endif
        !           330:        int quit;
        !           331: 
        !           332:        fclose(tfp);
        !           333: #ifdef MSDOS
        !           334:        sprintf(line, "-e %s %s", tname, filen);
        !           335:        if (0x7f == (quit = execall("me", line)))
        !           336: #endif
        !           337: #ifdef COHERENT
        !           338:        sprintf(line, "me -e %s %s ", tname, filen);
        !           339:        if (0x7f == (quit = system(line)))
        !           340: #endif
        !           341: #ifdef GEMDOS
        !           342:        cmda[2] = tname;
        !           343:        cmda[3] = filen;
        !           344:        if ((NULL == cmda[0]) &&
        !           345:           (NULL == (cmda[0] = path(getenv("PATH"), "me.tos", 1))))
        !           346:                fatal("cgrep: Cannot locate me.tos\n");
        !           347:        else if ((quit = execve(cmda[0], cmda, environ)) < 0)
        !           348: #endif
        !           349:                fatal("cgrep: cannot execute 'me'");
        !           350:        unlink(tname);
        !           351:        free(tname);
        !           352:        tname = NULL;
        !           353:        if (quit)
        !           354:                exit(0);
        !           355: }
        !           356: 
        !           357: /*
        !           358:  * find first word in a string excluding printf % constructs.
        !           359:  * make it lower case and return it.
        !           360:  */
        !           361: static char *
        !           362: firstWord(p)
        !           363: char *p;
        !           364: {
        !           365:        static char buf[80];
        !           366:        char *out, c;
        !           367:        enum state { start, pct, name } state;
        !           368: 
        !           369:        out = NULL;
        !           370:        for (state = start; c = *p++;) {
        !           371:                switch(state) {
        !           372:                case start:
        !           373:                        if (isalpha(c)) {
        !           374:                                state = name;
        !           375:                                out = buf;
        !           376:                                *out++ = tolower(c);
        !           377:                                continue;
        !           378:                        }
        !           379:                        if ('%' == c)
        !           380:                                state = pct;
        !           381:                        continue;
        !           382: 
        !           383:                case pct:
        !           384:                        if (isalpha(c) && 'l' != c)
        !           385:                                state = start;
        !           386:                        continue;
        !           387: 
        !           388:                case name:
        !           389:                        if (isalnum(c)) {
        !           390:                                *out++ = tolower(c);
        !           391:                                continue;
        !           392:                        }
        !           393:                        *out = '\0'; 
        !           394:                        return (buf);
        !           395:                }
        !           396:        }                       
        !           397:        if (NULL == out)
        !           398:                return ("???");
        !           399:        *out = '\0';
        !           400:        return (buf);
        !           401: }
        !           402: 
        !           403: /*
        !           404:  * print a hit for options -s or -c. Option -d creates -s and -c.
        !           405:  */
        !           406: static void
        !           407: printx(s, sw)
        !           408: register char *s;
        !           409: {
        !           410:        register char c, *p;
        !           411: 
        !           412:        if (aswitch)
        !           413:                emacsLine(s, lineno);
        !           414:        else if (cswitch > 1) {
        !           415:                for (p = s; (c = *p) && isspace(c); p++)
        !           416:                        ;
        !           417:                if ('*' == c)
        !           418:                        s = p + 1;
        !           419: 
        !           420:                printf("%s", s);
        !           421:                putchar(sw ? cswitch : '\n');
        !           422:        }
        !           423:        else if (dswitch) {
        !           424:                for (p = s; (c = *p) && isspace(c); p++)
        !           425:                        ;
        !           426:                if ('*' == c)
        !           427:                        s = p + 1;
        !           428: 
        !           429:                if (dtoken[0]) {
        !           430:                        printf("%s%c%s%c%s",
        !           431:                                firstWord(s), dswitch, s, dswitch, dtoken);
        !           432:                        dtoken[0] = '\0';
        !           433:                }
        !           434:                else
        !           435:                        printf("%s", s);
        !           436:                putchar(cswitch ? dswitch : '\n');
        !           437:        }
        !           438:        else {
        !           439:                if (NULL != filen)
        !           440:                        printf("%s: ", filen);
        !           441:                if (nswitch)
        !           442:                        printf("%4d: ", lineno);
        !           443:                printf("%s\n", s);
        !           444:        }
        !           445: }
        !           446: 
        !           447: /*
        !           448:  * Lexically process a file.
        !           449:  */
        !           450: static void
        !           451: lex()
        !           452: {
        !           453:        int  c, i;
        !           454:        enum fstate state, pstate;
        !           455:        char *w, changed;
        !           456:        FILE *ifp, *tfp;
        !           457: 
        !           458:        if (NULL == filen)
        !           459:                ifp = stdin;
        !           460:        else if (NULL == (ifp = fopen(filen, "r"))) {
        !           461:                fprintf(stderr, "cgrep: warning cannot open %s\n", filen);
        !           462:                return;
        !           463:        }
        !           464: 
        !           465:        if (rswitch) {
        !           466:                changed = 0;    /* no changes so far */
        !           467: 
        !           468:                if (NULL == filen)
        !           469:                        tfp = stdout;
        !           470:                else if ((NULL == (tname = tempnam(NULL, "cse"))) ||
        !           471:                         (NULL == (tfp = fopen(tname, "w"))))
        !           472:                        fatal("cgrep: Cannot open tmp file");
        !           473:        }
        !           474: 
        !           475:        lineno = 1;
        !           476:        i = marked = 0;
        !           477:        gota(other, NULL);      /* initialize word machine */
        !           478: 
        !           479:        for (state = start; ; ) {
        !           480:                line[i] = '\0';
        !           481:                c = fgetc(ifp);
        !           482: 
        !           483:                switch (state) {
        !           484:                case minus:
        !           485:                        if ('>' == c) {
        !           486:                                gota(dot, "->");
        !           487:                                state = start;
        !           488:                                break;
        !           489:                        }
        !           490:                        goto isstart;
        !           491:                case token:
        !           492:                        if (isalnum(c))
        !           493:                                break;
        !           494:                        gota(word, w);
        !           495: 
        !           496:                        /* we have a word to replace */
        !           497:                        if (rswitch && marked) {
        !           498:                                if(Rswitch) {
        !           499:                                        char buf[80];
        !           500: 
        !           501:                                        regsub(pat, newstr, buf);
        !           502:                                        i += strlen(buf) - strlen(w);
        !           503:                                        ROOM(line, lineLen, i);
        !           504:                                        strcpy(w, buf);
        !           505:                                } else {
        !           506:                                        i += strlen(newstr) - strlen(w);
        !           507:                                        ROOM(line, lineLen, i);
        !           508:                                        strcpy(w, newstr);
        !           509:                                }
        !           510:                                changed = 1;
        !           511:                        }
        !           512: isstart:               state = start;
        !           513:                case start:
        !           514:                        switch (c) {
        !           515:                        case '.':
        !           516:                                gota(dot, ".");
        !           517:                                break;
        !           518:                        case '-':
        !           519:                                state = minus;
        !           520:                                break;
        !           521:                        case '/':
        !           522:                                state = slash;
        !           523:                                break;
        !           524:                        case '\\':
        !           525:                                pstate = state;
        !           526:                                state = bsl;
        !           527:                                break;
        !           528:                        case '"':
        !           529:                                w = line + i;
        !           530:                                state = dquote;
        !           531:                                break;
        !           532:                        case '\'':
        !           533:                                state = squote;
        !           534:                                break;
        !           535:                        default:
        !           536:                                if (isalpha(c)) {
        !           537:                                        w = line + i;
        !           538:                                        state = token;
        !           539:                                }
        !           540:                                else if (!isspace(c))
        !           541:                                        gota(other, NULL);
        !           542:                        }
        !           543:                        break;
        !           544: 
        !           545:                case slash:
        !           546:                        switch (c) {
        !           547:                        case '*':
        !           548:                                state = comment;
        !           549:                                w = line + i + 1;
        !           550:                                break;
        !           551:                        case '/':
        !           552:                                state = cppcom;
        !           553:                                w = line + i + 1;
        !           554:                                break;
        !           555:                        default:
        !           556:                                goto isstart;
        !           557:                        }
        !           558:                        break;
        !           559: 
        !           560:                case cppcom:
        !           561:                        if ('\n' == c) {
        !           562:                                if (cswitch) { /* report comment */
        !           563:                                        if (dswitch)
        !           564:                                                cswitch = 0;
        !           565:                                        line[i] = '\0';
        !           566:                                        printx(w, 0);
        !           567:                                        line[i] = '\n';
        !           568:                                }
        !           569:                                state = start;
        !           570:                        }                               
        !           571:                        break;
        !           572: 
        !           573:                case star:
        !           574:                        if ('/' == c) {
        !           575:                                if (cswitch) { /* report comment */
        !           576:                                        if (dswitch)
        !           577:                                                cswitch = 0;
        !           578:                                        line[i - 1] = '\0';
        !           579:                                        printx(w, 0);
        !           580:                                        line[i - 1] = '*';
        !           581:                                }
        !           582:                                state = start;
        !           583:                                break;
        !           584:                        }
        !           585:                        state = comment;
        !           586:                case comment:
        !           587:                        if ('*' == c)
        !           588:                                state = star;
        !           589:                        break;
        !           590:                case bsl:
        !           591:                        state = pstate;
        !           592:                        break;
        !           593:                case dquote:
        !           594:                        switch (c) {
        !           595:                        case '"':
        !           596:                        case '\n':
        !           597:                                state = start;
        !           598:                                if (sswitch) {
        !           599:                                        if (dswitch)
        !           600:                                                sswitch = 0;
        !           601:                                        printx(w + 1, 0);
        !           602:                                }
        !           603:                                else
        !           604:                                        gota(other, NULL);
        !           605:                                break;
        !           606:                        case '\\':
        !           607:                                pstate = state;
        !           608:                                state  = bsl;
        !           609:                                break;
        !           610:                        }
        !           611:                        break;
        !           612:                case squote:
        !           613:                        switch (c) {
        !           614:                        case '\'':
        !           615:                        case '\n':
        !           616:                                gota(other, NULL);
        !           617:                                state = start;
        !           618:                                break;
        !           619:                        case '\\':
        !           620:                                pstate = state;
        !           621:                                state  = bsl;
        !           622:                                break;
        !           623:                        }
        !           624:                        break;
        !           625:                }
        !           626:                if (('\n' != c) && (EOF != c)) {
        !           627:                        line[i++] = c;
        !           628:                        ROOM(line, lineLen, i);
        !           629:                }
        !           630:                else {  /* end of line */
        !           631:                        if (rswitch) {
        !           632:                                if (EOF == c) {
        !           633:                                        if (!i) /* null line */
        !           634:                                                break;
        !           635:                                }
        !           636:                                else
        !           637:                                        line[i++] = c;
        !           638:                                ROOM(line, lineLen, i);
        !           639:                                line[i] = 0;
        !           640:                                fputs(line, tfp);
        !           641:                                marked = 0;
        !           642:                        }
        !           643: 
        !           644:                        if (cswitch && (comment == state)) {
        !           645:                                printx(w, 1);
        !           646:                                w = line;
        !           647:                        }
        !           648: 
        !           649:                        if (marked && !dswitch) {
        !           650:                                if (lswitch) {
        !           651:                                        printf("%s\n", filen);
        !           652:                                        break;
        !           653:                                }
        !           654:                                printx(line, 0);
        !           655:                        }
        !           656: 
        !           657:                        lineno++;
        !           658:                        marked = i = 0;
        !           659:                        if (EOF == c)
        !           660:                                break;
        !           661:                }
        !           662:        }
        !           663: 
        !           664:        fclose(ifp);
        !           665: 
        !           666:        if (rswitch) {
        !           667:                fclose(tfp);
        !           668: 
        !           669:                if (NULL != filen) {    /* tmp file used */
        !           670:                        if (changed) {
        !           671:                                unlink(filen);
        !           672:                                sprintf(line, "mv %s %s", tname, filen);
        !           673:                                system(line);
        !           674:                        }
        !           675:                        else
        !           676:                                unlink(tname);
        !           677:                }
        !           678:        }
        !           679: 
        !           680:        if (aswitch && (NULL != tname)) /* tmp file opened for -A option */
        !           681:                callEmacs();
        !           682: }
        !           683: 
        !           684: main(argc, argv)
        !           685: int argc;
        !           686: register char **argv;
        !           687: {
        !           688:        register char c;
        !           689:        int errsw = 0;
        !           690:        static char msg[] = 
        !           691:                "cgrep [-[rR] newStr] [-clnsA] [pattern] filename ...";
        !           692:        char *p, *q;
        !           693:        extern int optind;
        !           694:        extern char *optarg;
        !           695: 
        !           696:        if (1 == argc)
        !           697:                usage(msg);
        !           698: 
        !           699:        while (EOF != (c = getopt(argc, argv, "cC:d:slnA?r:R:V"))) {
        !           700:                switch (c) {
        !           701:                case 'V':
        !           702:                        printf("cgrep version 1.2\n");
        !           703:                        exit(0);
        !           704:                case 'C':
        !           705:                        cswitch = *optarg;      /* get delimiter */
        !           706:                        break;
        !           707:                case 'c':
        !           708:                        cswitch = 1;    /* comments only */
        !           709:                        break;
        !           710:                case 'd': /* report following string & comment */
        !           711:                        dswitch = *optarg;
        !           712:                        break;
        !           713:                case 's':
        !           714:                        sswitch = 1;    /* strings only */
        !           715:                        break;
        !           716:                case 'l':
        !           717:                        lswitch = 1;    /* print filenames only */
        !           718:                        break;
        !           719:                case 'n':
        !           720:                        nswitch = 1;    /* print line numbers */
        !           721:                        break;
        !           722:                case 'A':
        !           723:                        aswitch = 1;    /* interact with emacs */
        !           724:                        break;
        !           725:                case 'R':
        !           726:                        Rswitch = 1;    /* do substitution magic */
        !           727:                        for (p = optarg; *p; p++)
        !           728:                                if('\\' == *p && (p[1] <= '8') && (p[1] > '0'))
        !           729:                                        p[1]++;
        !           730:                case 'r':
        !           731:                        rswitch = 1;    /* replace hits */
        !           732:                        newstr = optarg;
        !           733:                        break;
        !           734:                default:
        !           735:                        errsw = 1;
        !           736:                }
        !           737:        }
        !           738: 
        !           739:        /* check unknown switches and rswitch goes with no other switches */
        !           740:        if (errsw || 
        !           741:            (rswitch && (aswitch | nswitch | lswitch | cswitch | sswitch)))
        !           742:                usage(msg);
        !           743: 
        !           744:        if (!sswitch && !cswitch) {     /* process pattern */
        !           745:                if (optind == argc)             /* no pattern */
        !           746:                        usage(msg);
        !           747: 
        !           748:                /* inclose pattern in ^(  )$ to force full match */
        !           749:                p = alloc(5 + strlen(q = argv[optind++]));
        !           750:                sprintf(p, "^(%s)$", q);
        !           751:                if (NULL == (pat = regcomp(p)))
        !           752:                        fatal("cgrep: Illegal pattern\n");
        !           753:        }
        !           754: 
        !           755:        ROOM(line, lineLen, 1); /* get input line started */
        !           756: 
        !           757:        if (optind == argc) {
        !           758:                if (aswitch | lswitch)
        !           759:                        fatal("cgrep: -A and -l require a filename");
        !           760:                lex();
        !           761:        }
        !           762:        else {
        !           763:                while (optind < argc) {
        !           764:                        filen = argv[optind++];
        !           765:                        lex();
        !           766:                }
        !           767:        }
        !           768:        exit(! matched);
        !           769: }

unix.superglobalmegacorp.com

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