[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.45

1.45    ! florian     1: /*     $OpenBSD: grep.c,v 1.44 2015/03/19 21:48:05 bcallah Exp $       */
1.35      kjell       2:
                      3: /* This file is in the public domain */
1.1       art         4:
1.43      bcallah     5: #include <sys/queue.h>
1.18      kjell       6: #include <sys/types.h>
1.11      vincent     7: #include <ctype.h>
1.18      kjell       8: #include <libgen.h>
1.42      guenther    9: #include <limits.h>
1.43      bcallah    10: #include <signal.h>
                     11: #include <stdio.h>
                     12: #include <stdlib.h>
                     13: #include <string.h>
1.18      kjell      14: #include <time.h>
1.43      bcallah    15: #include <unistd.h>
                     16:
                     17: #include "def.h"
                     18: #include "kbd.h"
                     19: #include "funmap.h"
1.11      vincent    20:
1.34      kjell      21: int     globalwd = FALSE;
1.13      db         22: static int      compile_goto_error(int, int);
1.17      kjell      23: int             next_error(int, int);
1.13      db         24: static int      grep(int, int);
                     25: static int      gid(int, int);
1.28      kjell      26: static struct buffer   *compile_mode(const char *, const char *);
1.1       art        27: void grep_init(void);
                     28:
1.8       vincent    29: static char compile_last_command[NFILEN] = "make ";
                     30:
1.1       art        31: /*
                     32:  * Hints for next-error
                     33:  *
                     34:  * XXX - need some kind of callback to find out when those get killed.
                     35:  */
1.24      deraadt    36: struct mgwin   *compile_win;
                     37: struct buffer  *compile_buffer;
1.1       art        38:
                     39: static PF compile_pf[] = {
1.13      db         40:        compile_goto_error
1.1       art        41: };
                     42:
1.44      bcallah    43: static struct KEYMAPE (1) compilemap = {
                     44:        1,
1.1       art        45:        1,
                     46:        rescan,
                     47:        {
1.13      db         48:                { CCHR('M'), CCHR('M'), compile_pf, NULL }
1.1       art        49:        }
                     50: };
                     51:
                     52: void
                     53: grep_init(void)
                     54: {
                     55:        funmap_add(compile_goto_error, "compile-goto-error");
                     56:        funmap_add(next_error, "next-error");
                     57:        funmap_add(grep, "grep");
                     58:        funmap_add(compile, "compile");
                     59:        funmap_add(gid, "gid");
                     60:        maps_add((KEYMAP *)&compilemap, "compile");
                     61: }
                     62:
1.20      kjell      63: /* ARGSUSED */
1.1       art        64: static int
                     65: grep(int f, int n)
                     66: {
1.25      kjell      67:        char     cprompt[NFILEN], *bufp;
1.24      deraadt    68:        struct buffer   *bp;
                     69:        struct mgwin    *wp;
1.1       art        70:
1.25      kjell      71:        (void)strlcpy(cprompt, "grep -n ", sizeof(cprompt));
                     72:        if ((bufp = eread("Run grep: ", cprompt, NFILEN,
1.16      kjell      73:            EFDEF | EFNEW | EFCR)) == NULL)
1.13      db         74:                return (ABORT);
1.16      kjell      75:        else if (bufp[0] == '\0')
                     76:                return (FALSE);
1.29      kjell      77:        if (strlcat(cprompt, " /dev/null", sizeof(cprompt)) >= sizeof(cprompt))
                     78:                return (FALSE);
1.1       art        79:
1.29      kjell      80:        if ((bp = compile_mode("*grep*", cprompt)) == NULL)
1.25      kjell      81:                return (FALSE);
1.38      kjell      82:        if ((wp = popbuf(bp, WNONE)) == NULL)
1.25      kjell      83:                return (FALSE);
                     84:        curbp = bp;
                     85:        compile_win = curwp = wp;
                     86:        return (TRUE);
                     87: }
                     88:
                     89: /* ARGSUSED */
1.36      kjell      90: int
1.1       art        91: compile(int f, int n)
                     92: {
1.25      kjell      93:        char     cprompt[NFILEN], *bufp;
1.24      deraadt    94:        struct buffer   *bp;
                     95:        struct mgwin    *wp;
1.1       art        96:
1.25      kjell      97:        (void)strlcpy(cprompt, compile_last_command, sizeof(cprompt));
                     98:        if ((bufp = eread("Compile command: ", cprompt, NFILEN,
1.16      kjell      99:            EFDEF | EFNEW | EFCR)) == NULL)
1.14      jason     100:                return (ABORT);
1.16      kjell     101:        else if (bufp[0] == '\0')
                    102:                return (FALSE);
1.14      jason     103:        if (savebuffers(f, n) == ABORT)
1.13      db        104:                return (ABORT);
                    105:        (void)strlcpy(compile_last_command, bufp, sizeof(compile_last_command));
1.1       art       106:
1.29      kjell     107:        if ((bp = compile_mode("*compile*", cprompt)) == NULL)
1.13      db        108:                return (FALSE);
1.38      kjell     109:        if ((wp = popbuf(bp, WNONE)) == NULL)
1.13      db        110:                return (FALSE);
1.1       art       111:        curbp = bp;
                    112:        compile_win = curwp = wp;
1.27      kjell     113:        gotoline(FFARG, 0);
1.13      db        114:        return (TRUE);
1.1       art       115: }
                    116:
                    117: /* id-utils foo. */
1.20      kjell     118: /* ARGSUSED */
1.1       art       119: static int
                    120: gid(int f, int n)
                    121: {
1.29      kjell     122:        char     command[NFILEN];
1.41      guenther  123:        char     cprompt[NFILEN], *bufp;
                    124:        int     c;
1.24      deraadt   125:        struct buffer   *bp;
                    126:        struct mgwin    *wp;
1.29      kjell     127:        int      i, j, len;
1.1       art       128:
1.11      vincent   129:        /* catch ([^\s(){}]+)[\s(){}]* */
                    130:
                    131:        i = curwp->w_doto;
1.15      cloder    132:        /* Skip backwards over delimiters we are currently on */
                    133:        while (i > 0) {
                    134:                c = lgetc(curwp->w_dotp, i);
                    135:                if (isalnum(c) || c == '_')
                    136:                        break;
                    137:
1.11      vincent   138:                i--;
1.15      cloder    139:        }
                    140:
1.11      vincent   141:        /* Skip the symbol itself */
                    142:        for (; i > 0; i--) {
                    143:                c = lgetc(curwp->w_dotp, i - 1);
1.15      cloder    144:                if (!isalnum(c) && c != '_')
1.11      vincent   145:                        break;
                    146:        }
1.25      kjell     147:        /* Fill the symbol in cprompt[] */
                    148:        for (j = 0; j < sizeof(cprompt) - 1 && i < llength(curwp->w_dotp);
1.11      vincent   149:            j++, i++) {
                    150:                c = lgetc(curwp->w_dotp, i);
1.15      cloder    151:                if (!isalnum(c) && c != '_')
1.11      vincent   152:                        break;
1.25      kjell     153:                cprompt[j] = c;
1.11      vincent   154:        }
1.25      kjell     155:        cprompt[j] = '\0';
1.11      vincent   156:
1.25      kjell     157:        if ((bufp = eread("Run gid (with args): ", cprompt, NFILEN,
1.16      kjell     158:            (j ? EFDEF : 0) | EFNEW | EFCR)) == NULL)
1.13      db        159:                return (ABORT);
1.16      kjell     160:        else if (bufp[0] == '\0')
                    161:                return (FALSE);
1.29      kjell     162:        len = snprintf(command, sizeof(command), "gid %s", cprompt);
                    163:        if (len < 0 || len >= sizeof(command))
                    164:                return (FALSE);
1.1       art       165:
1.28      kjell     166:        if ((bp = compile_mode("*gid*", command)) == NULL)
1.13      db        167:                return (FALSE);
1.38      kjell     168:        if ((wp = popbuf(bp, WNONE)) == NULL)
1.13      db        169:                return (FALSE);
1.1       art       170:        curbp = bp;
                    171:        compile_win = curwp = wp;
1.13      db        172:        return (TRUE);
1.1       art       173: }
                    174:
1.24      deraadt   175: struct buffer *
1.28      kjell     176: compile_mode(const char *name, const char *command)
1.1       art       177: {
1.24      deraadt   178:        struct buffer   *bp;
1.26      kjell     179:        FILE    *fpipe;
1.13      db        180:        char    *buf;
1.45    ! florian   181:        size_t   sz;
        !           182:        ssize_t  len;
1.29      kjell     183:        int      ret, n;
                    184:        char     cwd[NFILEN], qcmd[NFILEN];
1.18      kjell     185:        char     timestr[NTIME];
                    186:        time_t   t;
1.1       art       187:
1.45    ! florian   188:        buf = NULL;
        !           189:        sz = 0;
        !           190:
1.29      kjell     191:        n = snprintf(qcmd, sizeof(qcmd), "%s 2>&1", command);
                    192:        if (n < 0 || n >= sizeof(qcmd))
                    193:                return (NULL);
                    194:
1.1       art       195:        bp = bfind(name, TRUE);
                    196:        if (bclear(bp) != TRUE)
1.13      db        197:                return (NULL);
1.1       art       198:
1.28      kjell     199:        if (getbufcwd(bp->b_cwd, sizeof(bp->b_cwd)) != TRUE)
                    200:                return (NULL);
                    201:        addlinef(bp, "cd %s", bp->b_cwd);
1.29      kjell     202:        addline(bp, qcmd);
1.1       art       203:        addline(bp, "");
                    204:
1.23      deraadt   205:        if (getcwd(cwd, sizeof(cwd)) == NULL)
1.18      kjell     206:                panic("Can't get current directory!");
1.28      kjell     207:        if (chdir(bp->b_cwd) == -1) {
1.40      lum       208:                dobeep();
1.28      kjell     209:                ewprintf("Can't change dir to %s", bp->b_cwd);
1.18      kjell     210:                return (NULL);
1.19      deraadt   211:        }
1.29      kjell     212:        if ((fpipe = popen(qcmd, "r")) == NULL) {
1.40      lum       213:                dobeep();
1.1       art       214:                ewprintf("Problem opening pipe");
1.13      db        215:                return (NULL);
1.1       art       216:        }
1.45    ! florian   217:        while ((len = getline(&buf, &sz, fpipe)) != -1) {
        !           218:                if (buf[len - 1] == '\n')
        !           219:                        buf[len - 1] = '\0';
1.1       art       220:                addline(bp, buf);
                    221:        }
1.45    ! florian   222:        free(buf);
        !           223:        if (ferror(fpipe))
        !           224:                ewprintf("Problem reading pipe");
1.26      kjell     225:        ret = pclose(fpipe);
1.18      kjell     226:        t = time(NULL);
                    227:        strftime(timestr, sizeof(timestr), "%a %b %e %T %Y", localtime(&t));
1.1       art       228:        addline(bp, "");
1.18      kjell     229:        if (ret != 0)
                    230:                addlinef(bp, "Command exited abnormally with code %d"
                    231:                    " at %s", ret, timestr);
                    232:        else
                    233:                addlinef(bp, "Command finished at %s", timestr);
                    234:
1.32      kjell     235:        bp->b_dotp = bfirstlp(bp);
1.1       art       236:        bp->b_modes[0] = name_mode("fundamental");
                    237:        bp->b_modes[1] = name_mode("compile");
                    238:        bp->b_nmodes = 1;
                    239:
                    240:        compile_buffer = bp;
                    241:
1.18      kjell     242:        if (chdir(cwd) == -1) {
1.40      lum       243:                dobeep();
1.18      kjell     244:                ewprintf("Can't change dir back to %s", cwd);
                    245:                return (NULL);
1.19      deraadt   246:        }
1.13      db        247:        return (bp);
1.1       art       248: }
                    249:
1.20      kjell     250: /* ARGSUSED */
1.1       art       251: static int
                    252: compile_goto_error(int f, int n)
                    253: {
1.24      deraadt   254:        struct buffer   *bp;
                    255:        struct mgwin    *wp;
1.21      kjell     256:        char    *fname, *line, *lp, *ln;
1.29      kjell     257:        int      lineno;
1.28      kjell     258:        char    *adjf, path[NFILEN];
1.21      kjell     259:        const char *errstr;
1.24      deraadt   260:        struct line     *last;
1.1       art       261:
                    262:        compile_win = curwp;
                    263:        compile_buffer = curbp;
1.32      kjell     264:        last = blastlp(compile_buffer);
1.22      deraadt   265:
1.21      kjell     266:  retry:
                    267:        /* last line is compilation result */
                    268:        if (curwp->w_dotp == last)
                    269:                return (FALSE);
1.33      deraadt   270:
1.29      kjell     271:        if ((line = linetostr(curwp->w_dotp)) == NULL)
1.13      db        272:                return (FALSE);
1.1       art       273:        lp = line;
1.21      kjell     274:        if ((fname = strsep(&lp, ":")) == NULL || *fname == '\0')
1.1       art       275:                goto fail;
1.21      kjell     276:        if ((ln = strsep(&lp, ":")) == NULL || *ln == '\0')
1.1       art       277:                goto fail;
1.24      deraadt   278:        lineno = (int)strtonum(ln, INT_MIN, INT_MAX, &errstr);
1.21      kjell     279:        if (errstr)
1.1       art       280:                goto fail;
1.33      deraadt   281:
1.28      kjell     282:        if (fname && fname[0] != '/') {
1.34      kjell     283:                if (getbufcwd(path, sizeof(path)) == FALSE)
                    284:                        goto fail;
1.28      kjell     285:                if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
                    286:                        goto fail;
                    287:                adjf = path;
                    288:        } else {
1.30      jason     289:                adjf = adjustname(fname, TRUE);
1.28      kjell     290:        }
1.1       art       291:        free(line);
                    292:
1.7       vincent   293:        if (adjf == NULL)
                    294:                return (FALSE);
1.10      vincent   295:
1.1       art       296:        if ((bp = findbuffer(adjf)) == NULL)
1.13      db        297:                return (FALSE);
1.38      kjell     298:        if ((wp = popbuf(bp, WNONE)) == NULL)
1.13      db        299:                return (FALSE);
1.1       art       300:        curbp = bp;
                    301:        curwp = wp;
1.27      kjell     302:        if (bp->b_fname[0] == '\0')
1.1       art       303:                readin(adjf);
                    304:        gotoline(FFARG, lineno);
1.13      db        305:        return (TRUE);
1.1       art       306: fail:
1.3       deraadt   307:        free(line);
1.32      kjell     308:        if (curwp->w_dotp != blastlp(curbp)) {
1.1       art       309:                curwp->w_dotp = lforw(curwp->w_dotp);
1.37      kjell     310:                curwp->w_rflag |= WFMOVE;
1.1       art       311:                goto retry;
                    312:        }
1.40      lum       313:        dobeep();
1.1       art       314:        ewprintf("No more hits");
1.13      db        315:        return (FALSE);
1.1       art       316: }
                    317:
1.20      kjell     318: /* ARGSUSED */
1.17      kjell     319: int
1.1       art       320: next_error(int f, int n)
                    321: {
                    322:        if (compile_win == NULL || compile_buffer == NULL) {
1.40      lum       323:                dobeep();
1.1       art       324:                ewprintf("No compilation active");
1.13      db        325:                return (FALSE);
1.1       art       326:        }
                    327:        curwp = compile_win;
                    328:        curbp = compile_buffer;
1.32      kjell     329:        if (curwp->w_dotp == blastlp(curbp)) {
1.40      lum       330:                dobeep();
1.1       art       331:                ewprintf("No more hits");
1.13      db        332:                return (FALSE);
1.1       art       333:        }
                    334:        curwp->w_dotp = lforw(curwp->w_dotp);
1.37      kjell     335:        curwp->w_rflag |= WFMOVE;
1.1       art       336:
1.13      db        337:        return (compile_goto_error(f, n));
1.34      kjell     338: }
                    339:
                    340: /*
                    341:  * Since we don't have variables (we probably should) these are command
                    342:  * processors for changing the values of mode flags.
                    343:  */
                    344: /* ARGSUSED */
                    345: int
                    346: globalwdtoggle(int f, int n)
                    347: {
                    348:        if (f & FFARG)
                    349:                globalwd = n > 0;
                    350:        else
                    351:                globalwd = !globalwd;
                    352:
                    353:        sgarbf = TRUE;
                    354:
                    355:        return (TRUE);
1.1       art       356: }