Annotation of src/usr.bin/mg/grep.c, Revision 1.5
1.5 ! vincent 1: /* $OpenBSD: grep.c,v 1.4 2002/03/16 19:30:29 vincent 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;
153:
1.3 deraadt 154: addlinef(bp, "Running (%s).", command);
1.1 art 155: addline(bp, "");
156:
157: if ((pipe = popen(command, "r")) == NULL) {
158: ewprintf("Problem opening pipe");
159: return NULL;
160: }
161: /*
162: * We know that our commands are nice and the last line will end with
163: * a \n, so we don't need to try to deal with the last line problem
164: * in fgetln.
165: */
166: while ((buf = fgetln(pipe, &len)) != NULL) {
167: buf[len - 1] = '\0';
168: addline(bp, buf);
169: }
170: ret = pclose(pipe);
171: addline(bp, "");
172: addlinef(bp, "Command (%s) completed %s.", command,
173: ret == 0 ? "successfully" : "with errors");
174: bp->b_dotp = lforw(bp->b_linep); /* go to first line */
175: bp->b_modes[0] = name_mode("fundamental");
176: bp->b_modes[1] = name_mode("compile");
177: bp->b_nmodes = 1;
178:
179: compile_buffer = bp;
180:
181: return bp;
182: }
183:
184: static int
185: compile_goto_error(int f, int n)
186: {
187: BUFFER *bp;
188: MGWIN *wp;
189: char *fname, *line, *lp, *ln, *lp1;
190: int lineno, len;
191: char *adjf;
192:
193: compile_win = curwp;
194: compile_buffer = curbp;
195:
196: retry:
197: len = llength(curwp->w_dotp);
198:
199: if ((line = malloc(len + 1)) == NULL)
200: return FALSE;
201:
202: memcpy(line, curwp->w_dotp->l_text, len);
203: line[len] = '\0';
204:
205: lp = line;
206: if ((fname = strsep(&lp, ":")) == NULL)
207: goto fail;
208: if ((ln = strsep(&lp, ":")) == NULL)
209: goto fail;
210: lineno = strtol(ln, &lp1, 10);
211: if (lp != lp1 + 1)
212: goto fail;
213: free(line);
214:
215: adjf = adjustname(fname);
216: if ((bp = findbuffer(adjf)) == NULL)
217: return FALSE;
218: if ((wp = popbuf(bp)) == NULL)
219: return FALSE;
220: curbp = bp;
221: curwp = wp;
222: if (bp->b_fname[0] == 0)
223: readin(adjf);
224: gotoline(FFARG, lineno);
225: return TRUE;
226: fail:
1.3 deraadt 227: free(line);
1.1 art 228: if (curwp->w_dotp != lback(curbp->b_linep)) {
229: curwp->w_dotp = lforw(curwp->w_dotp);
230: curwp->w_flag |= WFMOVE;
231: goto retry;
232: }
233: ewprintf("No more hits");
1.3 deraadt 234: return FALSE;
1.1 art 235: }
236:
237: static int
238: next_error(int f, int n)
239: {
240: if (compile_win == NULL || compile_buffer == NULL) {
241: ewprintf("No compilation active");
242: return FALSE;
243: }
244: curwp = compile_win;
245: curbp = compile_buffer;
246: if (curwp->w_dotp == lback(curbp->b_linep)) {
247: ewprintf("No more hits");
248: return FALSE;
249: }
250: curwp->w_dotp = lforw(curwp->w_dotp);
251: curwp->w_flag |= WFMOVE;
252:
253: return compile_goto_error(f, n);
254: }