[BACK]Return to grep.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/grep.c, Revision 1.16

1.16    ! kjell       1: /*     $OpenBSD: grep.c,v 1.15 2005/06/03 23:39:55 cloder Exp $        */
1.1       art         2: /*
                      3:  * Copyright (c) 2001 Artur Grabowski <art@openbsd.org>.  All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     16:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     17:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     18:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     19:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     20:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     21:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     22:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     23:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     24:  */
                     25:
                     26: #include "def.h"
                     27: #include "kbd.h"
                     28: #include "funmap.h"
                     29:
1.11      vincent    30: #include <ctype.h>
                     31:
1.13      db         32: static int      compile_goto_error(int, int);
                     33: static int      next_error(int, int);
                     34: static int      grep(int, int);
                     35: static int      compile(int, int);
                     36: static int      gid(int, int);
1.9       vincent    37: static BUFFER  *compile_mode(char *, char *);
1.1       art        38:
                     39:
                     40: void grep_init(void);
                     41:
1.8       vincent    42: static char compile_last_command[NFILEN] = "make ";
                     43:
1.1       art        44: /*
                     45:  * Hints for next-error
                     46:  *
                     47:  * XXX - need some kind of callback to find out when those get killed.
                     48:  */
1.13      db         49: MGWIN  *compile_win;
                     50: BUFFER *compile_buffer;
1.1       art        51:
                     52: static PF compile_pf[] = {
1.13      db         53:        compile_goto_error
1.1       art        54: };
                     55:
                     56: static struct KEYMAPE (1 + IMAPEXT) compilemap = {
                     57:        1,
                     58:        1 + IMAPEXT,
                     59:        rescan,
                     60:        {
1.13      db         61:                { CCHR('M'), CCHR('M'), compile_pf, NULL }
1.1       art        62:        }
                     63: };
                     64:
                     65: void
                     66: grep_init(void)
                     67: {
                     68:        funmap_add(compile_goto_error, "compile-goto-error");
                     69:        funmap_add(next_error, "next-error");
                     70:        funmap_add(grep, "grep");
                     71:        funmap_add(compile, "compile");
                     72:        funmap_add(gid, "gid");
                     73:        maps_add((KEYMAP *)&compilemap, "compile");
                     74: }
                     75:
                     76: static int
                     77: grep(int f, int n)
                     78: {
1.13      db         79:        char     command[NFILEN + 20];
                     80:        char     prompt[NFILEN], *bufp;
                     81:        BUFFER  *bp;
                     82:        MGWIN   *wp;
1.1       art        83:
1.13      db         84:        (void)strlcpy(prompt, "grep -n ", sizeof(prompt));
1.16    ! kjell      85:        if ((bufp = eread("Run grep: ", prompt, NFILEN,
        !            86:            EFDEF | EFNEW | EFCR)) == NULL)
1.13      db         87:                return (ABORT);
1.16    ! kjell      88:        else if (bufp[0] == '\0')
        !            89:                return (FALSE);
1.13      db         90:        (void)snprintf(command, sizeof(command), "%s /dev/null", bufp);
1.1       art        91:
                     92:        if ((bp = compile_mode("*grep*", command)) == NULL)
1.13      db         93:                return (FALSE);
1.1       art        94:        if ((wp = popbuf(bp)) == NULL)
1.13      db         95:                return (FALSE);
1.1       art        96:        curbp = bp;
                     97:        compile_win = curwp = wp;
1.13      db         98:        return (TRUE);
1.1       art        99: }
                    100:
                    101: static int
                    102: compile(int f, int n)
                    103: {
1.13      db        104:        char     command[NFILEN + 20];
                    105:        char     prompt[NFILEN], *bufp;
                    106:        BUFFER  *bp;
                    107:        MGWIN   *wp;
1.1       art       108:
1.13      db        109:        (void)strlcpy(prompt, compile_last_command, sizeof(prompt));
1.16    ! kjell     110:        if ((bufp = eread("Compile command: ", prompt, NFILEN,
        !           111:            EFDEF | EFNEW | EFCR)) == NULL)
1.14      jason     112:                return (ABORT);
1.16    ! kjell     113:        else if (bufp[0] == '\0')
        !           114:                return (FALSE);
1.14      jason     115:        if (savebuffers(f, n) == ABORT)
1.13      db        116:                return (ABORT);
                    117:        (void)strlcpy(compile_last_command, bufp, sizeof(compile_last_command));
1.1       art       118:
1.13      db        119:        (void)snprintf(command, sizeof(command), "%s 2>&1", bufp);
1.1       art       120:
                    121:        if ((bp = compile_mode("*compile*", command)) == NULL)
1.13      db        122:                return (FALSE);
1.1       art       123:        if ((wp = popbuf(bp)) == NULL)
1.13      db        124:                return (FALSE);
1.1       art       125:        curbp = bp;
                    126:        compile_win = curwp = wp;
1.13      db        127:        return (TRUE);
1.1       art       128: }
                    129:
                    130: /* id-utils foo. */
                    131: static int
                    132: gid(int f, int n)
                    133: {
1.13      db        134:        char     command[NFILEN + 20];
                    135:        char     prompt[NFILEN], c, *bufp;
                    136:        BUFFER  *bp;
                    137:        MGWIN   *wp;
                    138:        int      i, j;
1.1       art       139:
1.11      vincent   140:        /* catch ([^\s(){}]+)[\s(){}]* */
                    141:
                    142:        i = curwp->w_doto;
1.15      cloder    143:        /* Skip backwards over delimiters we are currently on */
                    144:        while (i > 0) {
                    145:                c = lgetc(curwp->w_dotp, i);
                    146:                if (isalnum(c) || c == '_')
                    147:                        break;
                    148:
1.11      vincent   149:                i--;
1.15      cloder    150:        }
                    151:
1.11      vincent   152:        /* Skip the symbol itself */
                    153:        for (; i > 0; i--) {
                    154:                c = lgetc(curwp->w_dotp, i - 1);
1.15      cloder    155:                if (!isalnum(c) && c != '_')
1.11      vincent   156:                        break;
                    157:        }
                    158:        /* Fill the symbol in prompt[] */
                    159:        for (j = 0; j < sizeof(prompt) - 1 && i < llength(curwp->w_dotp);
                    160:            j++, i++) {
                    161:                c = lgetc(curwp->w_dotp, i);
1.15      cloder    162:                if (!isalnum(c) && c != '_')
1.11      vincent   163:                        break;
                    164:                prompt[j] = c;
                    165:        }
                    166:        prompt[j] = '\0';
                    167:
1.12      vincent   168:        if ((bufp = eread("Run gid (with args): ", prompt, NFILEN,
1.16    ! kjell     169:            (j ? EFDEF : 0) | EFNEW | EFCR)) == NULL)
1.13      db        170:                return (ABORT);
1.16    ! kjell     171:        else if (bufp[0] == '\0')
        !           172:                return (FALSE);
1.13      db        173:        (void)snprintf(command, sizeof(command), "gid %s", prompt);
1.1       art       174:
                    175:        if ((bp = compile_mode("*gid*", command)) == NULL)
1.13      db        176:                return (FALSE);
1.1       art       177:        if ((wp = popbuf(bp)) == NULL)
1.13      db        178:                return (FALSE);
1.1       art       179:        curbp = bp;
                    180:        compile_win = curwp = wp;
1.13      db        181:        return (TRUE);
1.1       art       182: }
                    183:
                    184: BUFFER *
                    185: compile_mode(char *name, char *command)
                    186: {
1.13      db        187:        BUFFER  *bp;
                    188:        FILE    *pipe;
                    189:        char    *buf;
                    190:        size_t   len;
                    191:        int      ret;
1.1       art       192:
                    193:        bp = bfind(name, TRUE);
                    194:        if (bclear(bp) != TRUE)
1.13      db        195:                return (NULL);
1.1       art       196:
1.3       deraadt   197:        addlinef(bp, "Running (%s).", command);
1.1       art       198:        addline(bp, "");
                    199:
                    200:        if ((pipe = popen(command, "r")) == NULL) {
                    201:                ewprintf("Problem opening pipe");
1.13      db        202:                return (NULL);
1.1       art       203:        }
                    204:        /*
                    205:         * We know that our commands are nice and the last line will end with
                    206:         * a \n, so we don't need to try to deal with the last line problem
                    207:         * in fgetln.
                    208:         */
                    209:        while ((buf = fgetln(pipe, &len)) != NULL) {
                    210:                buf[len - 1] = '\0';
                    211:                addline(bp, buf);
                    212:        }
                    213:        ret = pclose(pipe);
                    214:        addline(bp, "");
                    215:        addlinef(bp, "Command (%s) completed %s.", command,
                    216:                ret == 0 ? "successfully" : "with errors");
                    217:        bp->b_dotp = lforw(bp->b_linep);        /* go to first line */
                    218:        bp->b_modes[0] = name_mode("fundamental");
                    219:        bp->b_modes[1] = name_mode("compile");
                    220:        bp->b_nmodes = 1;
                    221:
                    222:        compile_buffer = bp;
                    223:
1.13      db        224:        return (bp);
1.1       art       225: }
                    226:
                    227: static int
                    228: compile_goto_error(int f, int n)
                    229: {
1.13      db        230:        BUFFER  *bp;
                    231:        MGWIN   *wp;
                    232:        char    *fname, *line, *lp, *ln, *lp1;
                    233:        int      lineno, len;
                    234:        char    *adjf;
1.1       art       235:
                    236:        compile_win = curwp;
                    237:        compile_buffer = curbp;
                    238:
                    239: retry:
                    240:        len = llength(curwp->w_dotp);
                    241:
                    242:        if ((line = malloc(len + 1)) == NULL)
1.13      db        243:                return (FALSE);
1.1       art       244:
1.6       vincent   245:        (void)memcpy(line, curwp->w_dotp->l_text, len);
1.1       art       246:        line[len] = '\0';
                    247:
                    248:        lp = line;
                    249:        if ((fname = strsep(&lp, ":")) == NULL)
                    250:                goto fail;
                    251:        if ((ln = strsep(&lp, ":")) == NULL)
                    252:                goto fail;
                    253:        lineno = strtol(ln, &lp1, 10);
                    254:        if (lp != lp1 + 1)
                    255:                goto fail;
1.10      vincent   256:
                    257:        adjf = adjustname(fname);
1.1       art       258:        free(line);
                    259:
1.7       vincent   260:        if (adjf == NULL)
                    261:                return (FALSE);
1.10      vincent   262:
1.1       art       263:        if ((bp = findbuffer(adjf)) == NULL)
1.13      db        264:                return (FALSE);
1.1       art       265:        if ((wp = popbuf(bp)) == NULL)
1.13      db        266:                return (FALSE);
1.1       art       267:        curbp = bp;
                    268:        curwp = wp;
                    269:        if (bp->b_fname[0] == 0)
                    270:                readin(adjf);
                    271:        gotoline(FFARG, lineno);
1.13      db        272:        return (TRUE);
1.1       art       273: fail:
1.3       deraadt   274:        free(line);
1.1       art       275:        if (curwp->w_dotp != lback(curbp->b_linep)) {
                    276:                curwp->w_dotp = lforw(curwp->w_dotp);
                    277:                curwp->w_flag |= WFMOVE;
                    278:                goto retry;
                    279:        }
                    280:        ewprintf("No more hits");
1.13      db        281:        return (FALSE);
1.1       art       282: }
                    283:
                    284: static int
                    285: next_error(int f, int n)
                    286: {
                    287:        if (compile_win == NULL || compile_buffer == NULL) {
                    288:                ewprintf("No compilation active");
1.13      db        289:                return (FALSE);
1.1       art       290:        }
                    291:        curwp = compile_win;
                    292:        curbp = compile_buffer;
                    293:        if (curwp->w_dotp == lback(curbp->b_linep)) {
                    294:                ewprintf("No more hits");
1.13      db        295:                return (FALSE);
1.1       art       296:        }
                    297:        curwp->w_dotp = lforw(curwp->w_dotp);
                    298:        curwp->w_flag |= WFMOVE;
                    299:
1.13      db        300:        return (compile_goto_error(f, n));
1.1       art       301: }