Annotation of src/usr.bin/mg/grep.c, Revision 1.4
1.4 ! vincent 1: /* $OpenBSD: grep.c,v 1.3 2002/02/14 14:24:21 deraadt 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:
30: static int compile_goto_error(int f, int n);
31: static int next_error(int f, int n);
32: static int grep(int, int);
33: static int compile(int, int);
34: static int gid(int, int);
35: static BUFFER *compile_mode(char *name, char *command);
36:
37:
38: void grep_init(void);
39:
40: /*
41: * Hints for next-error
42: *
43: * XXX - need some kind of callback to find out when those get killed.
44: */
45: MGWIN *compile_win;
46: BUFFER *compile_buffer;
47:
48: static PF compile_pf[] = {
49: compile_goto_error,
50: };
51:
52: static struct KEYMAPE (1 + IMAPEXT) compilemap = {
53: 1,
54: 1 + IMAPEXT,
55: rescan,
56: {
57: { CCHR('M'), CCHR('M'), compile_pf, NULL },
58: }
59: };
60:
61: void
62: grep_init(void)
63: {
64: funmap_add(compile_goto_error, "compile-goto-error");
65: funmap_add(next_error, "next-error");
66: funmap_add(grep, "grep");
67: funmap_add(compile, "compile");
68: funmap_add(gid, "gid");
69: maps_add((KEYMAP *)&compilemap, "compile");
70: }
71:
72: static int
73: grep(int f, int n)
74: {
75: char command[NFILEN + 20];
76: char prompt[NFILEN];
77: BUFFER *bp;
78: MGWIN *wp;
79:
1.2 deraadt 80: strlcpy(prompt, "grep -n ", sizeof prompt);
1.1 art 81: if (eread("Run grep: ", prompt, NFILEN, EFDEF|EFNEW|EFCR) == ABORT)
82: return ABORT;
83:
1.2 deraadt 84: snprintf(command, sizeof command, "%s /dev/null", prompt);
1.1 art 85:
86: if ((bp = compile_mode("*grep*", command)) == NULL)
87: return FALSE;
88: if ((wp = popbuf(bp)) == NULL)
89: return FALSE;
90: curbp = bp;
91: compile_win = curwp = wp;
92: return TRUE;
93: }
94:
95: static int
96: compile(int f, int n)
97: {
98: char command[NFILEN + 20];
99: char prompt[NFILEN];
100: BUFFER *bp;
101: MGWIN *wp;
102:
1.3 deraadt 103: strlcpy(prompt, "make ", sizeof prompt);
1.1 art 104: if (eread("Compile command: ", prompt, NFILEN, EFDEF|EFNEW|EFCR) == ABORT)
105: return ABORT;
106:
1.2 deraadt 107: snprintf(command, sizeof command, "%s 2>&1", prompt);
1.1 art 108:
109: if ((bp = compile_mode("*compile*", command)) == NULL)
110: return FALSE;
111: if ((wp = popbuf(bp)) == NULL)
112: return FALSE;
113: curbp = bp;
114: compile_win = curwp = wp;
115: return TRUE;
116: }
117:
118: /* id-utils foo. */
119: static int
120: gid(int f, int n)
121: {
122: char command[NFILEN + 20];
123: char prompt[NFILEN];
124: BUFFER *bp;
125: MGWIN *wp;
126:
127: if (eread("Run gid (with args): ", prompt, NFILEN, EFNEW|EFCR) == ABORT)
128: return ABORT;
129:
1.2 deraadt 130: snprintf(command, sizeof command, "gid %s", prompt);
1.1 art 131:
132: if ((bp = compile_mode("*gid*", command)) == NULL)
133: return FALSE;
134: if ((wp = popbuf(bp)) == NULL)
135: return FALSE;
136: curbp = bp;
137: compile_win = curwp = wp;
138: return TRUE;
139: }
140:
141: BUFFER *
142: compile_mode(char *name, char *command)
143: {
144: BUFFER *bp;
145: FILE *pipe;
146: char *buf;
147: size_t len;
148: int ret;
149:
150: bp = bfind(name, TRUE);
151: if (bclear(bp) != TRUE)
152: return NULL;
1.4 ! vincent 153: bp->b_flag |= BFREADONLY;
1.1 art 154:
1.3 deraadt 155: addlinef(bp, "Running (%s).", command);
1.1 art 156: addline(bp, "");
157:
158: if ((pipe = popen(command, "r")) == NULL) {
159: ewprintf("Problem opening pipe");
160: return NULL;
161: }
162: /*
163: * We know that our commands are nice and the last line will end with
164: * a \n, so we don't need to try to deal with the last line problem
165: * in fgetln.
166: */
167: while ((buf = fgetln(pipe, &len)) != NULL) {
168: buf[len - 1] = '\0';
169: addline(bp, buf);
170: }
171: ret = pclose(pipe);
172: addline(bp, "");
173: addlinef(bp, "Command (%s) completed %s.", command,
174: ret == 0 ? "successfully" : "with errors");
175: bp->b_dotp = lforw(bp->b_linep); /* go to first line */
176: bp->b_modes[0] = name_mode("fundamental");
177: bp->b_modes[1] = name_mode("compile");
178: bp->b_nmodes = 1;
179:
180: compile_buffer = bp;
181:
182: return bp;
183: }
184:
185: static int
186: compile_goto_error(int f, int n)
187: {
188: BUFFER *bp;
189: MGWIN *wp;
190: char *fname, *line, *lp, *ln, *lp1;
191: int lineno, len;
192: char *adjf;
193:
194: compile_win = curwp;
195: compile_buffer = curbp;
196:
197: retry:
198: len = llength(curwp->w_dotp);
199:
200: if ((line = malloc(len + 1)) == NULL)
201: return FALSE;
202:
203: memcpy(line, curwp->w_dotp->l_text, len);
204: line[len] = '\0';
205:
206: lp = line;
207: if ((fname = strsep(&lp, ":")) == NULL)
208: goto fail;
209: if ((ln = strsep(&lp, ":")) == NULL)
210: goto fail;
211: lineno = strtol(ln, &lp1, 10);
212: if (lp != lp1 + 1)
213: goto fail;
214: free(line);
215:
216: adjf = adjustname(fname);
217: if ((bp = findbuffer(adjf)) == NULL)
218: return FALSE;
219: if ((wp = popbuf(bp)) == NULL)
220: return FALSE;
221: curbp = bp;
222: curwp = wp;
223: if (bp->b_fname[0] == 0)
224: readin(adjf);
225: gotoline(FFARG, lineno);
226: return TRUE;
227: fail:
1.3 deraadt 228: free(line);
1.1 art 229: if (curwp->w_dotp != lback(curbp->b_linep)) {
230: curwp->w_dotp = lforw(curwp->w_dotp);
231: curwp->w_flag |= WFMOVE;
232: goto retry;
233: }
234: ewprintf("No more hits");
1.3 deraadt 235: return FALSE;
1.1 art 236: }
237:
238: static int
239: next_error(int f, int n)
240: {
241: if (compile_win == NULL || compile_buffer == NULL) {
242: ewprintf("No compilation active");
243: return FALSE;
244: }
245: curwp = compile_win;
246: curbp = compile_buffer;
247: if (curwp->w_dotp == lback(curbp->b_linep)) {
248: ewprintf("No more hits");
249: return FALSE;
250: }
251: curwp->w_dotp = lforw(curwp->w_dotp);
252: curwp->w_flag |= WFMOVE;
253:
254: return compile_goto_error(f, n);
255: }