diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-05-24 10:58:35 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-05-24 10:58:35 +0000 |
commit | b0c4fceee63c1d87854c7694b89defccc4f68cc8 (patch) | |
tree | 7f4390f4f11778cd7523ad53cffd918224c1438d | |
parent | 34c69f8db5fe77fc261e9c72a705772a95659680 (diff) |
Add a compile/grep/id-utils mode.
The only pollution this code introduces in the rest of thed code is a call to
an init function in main(). In the future we might want to load extensions
like this dynamically.
Of course I did the test compile in the compile mode.
-rw-r--r-- | usr.bin/mg/Makefile | 7 | ||||
-rw-r--r-- | usr.bin/mg/grep.c | 254 | ||||
-rw-r--r-- | usr.bin/mg/main.c | 12 |
3 files changed, 271 insertions, 2 deletions
diff --git a/usr.bin/mg/Makefile b/usr.bin/mg/Makefile index 8eee50f5e20..c5eba2bf9cd 100644 --- a/usr.bin/mg/Makefile +++ b/usr.bin/mg/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 2001/05/24 09:47:33 art Exp $ +# $OpenBSD: Makefile,v 1.8 2001/05/24 10:58:33 art Exp $ PROG= mg @@ -24,4 +24,9 @@ SRCS= cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c \ buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \ macro.c main.c modes.c re_search.c funmap.c +# +# More or less standalone extensions. +# +SRCS+= grep.c + .include <bsd.prog.mk> diff --git a/usr.bin/mg/grep.c b/usr.bin/mg/grep.c new file mode 100644 index 00000000000..b4310cd2f2d --- /dev/null +++ b/usr.bin/mg/grep.c @@ -0,0 +1,254 @@ +/* $OpenBSD: grep.c,v 1.1 2001/05/24 10:58:34 art Exp $ */ +/* + * Copyright (c) 2001 Artur Grabowski <art@openbsd.org>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "def.h" +#include "kbd.h" +#include "funmap.h" + +static int compile_goto_error(int f, int n); +static int next_error(int f, int n); +static int grep(int, int); +static int compile(int, int); +static int gid(int, int); +static BUFFER *compile_mode(char *name, char *command); + + +void grep_init(void); + +/* + * Hints for next-error + * + * XXX - need some kind of callback to find out when those get killed. + */ +MGWIN *compile_win; +BUFFER *compile_buffer; + +static PF compile_pf[] = { + compile_goto_error, +}; + +static struct KEYMAPE (1 + IMAPEXT) compilemap = { + 1, + 1 + IMAPEXT, + rescan, + { + { CCHR('M'), CCHR('M'), compile_pf, NULL }, + } +}; + +void +grep_init(void) +{ + funmap_add(compile_goto_error, "compile-goto-error"); + funmap_add(next_error, "next-error"); + funmap_add(grep, "grep"); + funmap_add(compile, "compile"); + funmap_add(gid, "gid"); + maps_add((KEYMAP *)&compilemap, "compile"); +} + +static int +grep(int f, int n) +{ + char command[NFILEN + 20]; + char prompt[NFILEN]; + BUFFER *bp; + MGWIN *wp; + + strcpy(prompt, "grep -n "); + if (eread("Run grep: ", prompt, NFILEN, EFDEF|EFNEW|EFCR) == ABORT) + return ABORT; + + sprintf(command, "%s /dev/null", prompt); + + if ((bp = compile_mode("*grep*", command)) == NULL) + return FALSE; + if ((wp = popbuf(bp)) == NULL) + return FALSE; + curbp = bp; + compile_win = curwp = wp; + return TRUE; +} + +static int +compile(int f, int n) +{ + char command[NFILEN + 20]; + char prompt[NFILEN]; + BUFFER *bp; + MGWIN *wp; + + strcpy(prompt, "make "); + if (eread("Compile command: ", prompt, NFILEN, EFDEF|EFNEW|EFCR) == ABORT) + return ABORT; + + sprintf(command, "%s 2>&1", prompt); + + if ((bp = compile_mode("*compile*", command)) == NULL) + return FALSE; + if ((wp = popbuf(bp)) == NULL) + return FALSE; + curbp = bp; + compile_win = curwp = wp; + return TRUE; +} + +/* id-utils foo. */ +static int +gid(int f, int n) +{ + char command[NFILEN + 20]; + char prompt[NFILEN]; + BUFFER *bp; + MGWIN *wp; + + if (eread("Run gid (with args): ", prompt, NFILEN, EFNEW|EFCR) == ABORT) + return ABORT; + + sprintf(command, "gid %s", prompt); + + if ((bp = compile_mode("*gid*", command)) == NULL) + return FALSE; + if ((wp = popbuf(bp)) == NULL) + return FALSE; + curbp = bp; + compile_win = curwp = wp; + return TRUE; +} + +BUFFER * +compile_mode(char *name, char *command) +{ + BUFFER *bp; + FILE *pipe; + char *buf; + size_t len; + int ret; + + bp = bfind(name, TRUE); + if (bclear(bp) != TRUE) + return NULL; + + addlinef(bp, "Running (%s).", command); + addline(bp, ""); + + if ((pipe = popen(command, "r")) == NULL) { + ewprintf("Problem opening pipe"); + return NULL; + } + /* + * We know that our commands are nice and the last line will end with + * a \n, so we don't need to try to deal with the last line problem + * in fgetln. + */ + while ((buf = fgetln(pipe, &len)) != NULL) { + buf[len - 1] = '\0'; + addline(bp, buf); + } + ret = pclose(pipe); + addline(bp, ""); + addlinef(bp, "Command (%s) completed %s.", command, + ret == 0 ? "successfully" : "with errors"); + bp->b_dotp = lforw(bp->b_linep); /* go to first line */ + bp->b_modes[0] = name_mode("fundamental"); + bp->b_modes[1] = name_mode("compile"); + bp->b_nmodes = 1; + + compile_buffer = bp; + + return bp; +} + +static int +compile_goto_error(int f, int n) +{ + BUFFER *bp; + MGWIN *wp; + char *fname, *line, *lp, *ln, *lp1; + int lineno, len; + char *adjf; + + compile_win = curwp; + compile_buffer = curbp; + +retry: + len = llength(curwp->w_dotp); + + if ((line = malloc(len + 1)) == NULL) + return FALSE; + + memcpy(line, curwp->w_dotp->l_text, len); + line[len] = '\0'; + + lp = line; + if ((fname = strsep(&lp, ":")) == NULL) + goto fail; + if ((ln = strsep(&lp, ":")) == NULL) + goto fail; + lineno = strtol(ln, &lp1, 10); + if (lp != lp1 + 1) + goto fail; + free(line); + + adjf = adjustname(fname); + if ((bp = findbuffer(adjf)) == NULL) + return FALSE; + if ((wp = popbuf(bp)) == NULL) + return FALSE; + curbp = bp; + curwp = wp; + if (bp->b_fname[0] == 0) + readin(adjf); + gotoline(FFARG, lineno); + return TRUE; +fail: + free(line); + if (curwp->w_dotp != lback(curbp->b_linep)) { + curwp->w_dotp = lforw(curwp->w_dotp); + curwp->w_flag |= WFMOVE; + goto retry; + } + ewprintf("No more hits"); + return FALSE; +} + +static int +next_error(int f, int n) +{ + if (compile_win == NULL || compile_buffer == NULL) { + ewprintf("No compilation active"); + return FALSE; + } + curwp = compile_win; + curbp = compile_buffer; + if (curwp->w_dotp == lback(curbp->b_linep)) { + ewprintf("No more hits"); + return FALSE; + } + curwp->w_dotp = lforw(curwp->w_dotp); + curwp->w_flag |= WFMOVE; + + return compile_goto_error(f, n); +} diff --git a/usr.bin/mg/main.c b/usr.bin/mg/main.c index 9f3c7ca3f4d..5f9981392b1 100644 --- a/usr.bin/mg/main.c +++ b/usr.bin/mg/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.12 2001/05/24 10:43:19 art Exp $ */ +/* $OpenBSD: main.c,v 1.13 2001/05/24 10:58:34 art Exp $ */ /* * Mainline. @@ -43,6 +43,16 @@ main(argc, argv) ttykeymapinit(); /* Symbols, bindings. */ /* + * This is where we initialize standalone extensions that should + * be loaded dynamically sometime in the future. + */ + { + extern void grep_init(void); + + grep_init(); + } + + /* * doing update() before reading files causes the error messages from * the file I/O show up on the screen. (and also an extra display of * the mode line if there are files specified on the command line.) |