1 /* $OpenBSD: grep.c,v 1.38 2009/06/04 23:39:37 kjell Exp $ */
3 /* This file is in the public domain */
15 static int compile_goto_error(int, int);
16 int next_error(int, int);
17 static int grep(int, int);
18 static int gid(int, int);
19 static struct buffer *compile_mode(const char *, const char *);
20 static int xlint(int, int);
23 static char compile_last_command[NFILEN] = "make ";
26 * Hints for next-error
28 * XXX - need some kind of callback to find out when those get killed.
30 struct mgwin *compile_win;
31 struct buffer *compile_buffer;
33 static PF compile_pf[] = {
37 static struct KEYMAPE (1 + IMAPEXT) compilemap = {
42 { CCHR('M'), CCHR('M'), compile_pf, NULL }
49 funmap_add(compile_goto_error, "compile-goto-error");
50 funmap_add(next_error, "next-error");
51 funmap_add(grep, "grep");
52 funmap_add(xlint, "lint");
53 funmap_add(compile, "compile");
54 funmap_add(gid, "gid");
55 maps_add((KEYMAP *)&compilemap, "compile");
62 char cprompt[NFILEN], *bufp;
66 (void)strlcpy(cprompt, "grep -n ", sizeof(cprompt));
67 if ((bufp = eread("Run grep: ", cprompt, NFILEN,
68 EFDEF | EFNEW | EFCR)) == NULL)
70 else if (bufp[0] == '\0')
72 if (strlcat(cprompt, " /dev/null", sizeof(cprompt)) >= sizeof(cprompt))
75 if ((bp = compile_mode("*grep*", cprompt)) == NULL)
77 if ((wp = popbuf(bp, WNONE)) == NULL)
80 compile_win = curwp = wp;
88 char cprompt[NFILEN], *bufp;
92 (void)strlcpy(cprompt, "make lint ", sizeof(cprompt));
93 if ((bufp = eread("Run lint: ", cprompt, NFILEN,
94 EFDEF | EFNEW | EFCR)) == NULL)
96 else if (bufp[0] == '\0')
99 if ((bp = compile_mode("*lint*", cprompt)) == NULL)
101 if ((wp = popbuf(bp, WNONE)) == NULL)
104 compile_win = curwp = wp;
110 compile(int f, int n)
112 char cprompt[NFILEN], *bufp;
116 (void)strlcpy(cprompt, compile_last_command, sizeof(cprompt));
117 if ((bufp = eread("Compile command: ", cprompt, NFILEN,
118 EFDEF | EFNEW | EFCR)) == NULL)
120 else if (bufp[0] == '\0')
122 if (savebuffers(f, n) == ABORT)
124 (void)strlcpy(compile_last_command, bufp, sizeof(compile_last_command));
126 if ((bp = compile_mode("*compile*", cprompt)) == NULL)
128 if ((wp = popbuf(bp, WNONE)) == NULL)
131 compile_win = curwp = wp;
141 char command[NFILEN];
142 char cprompt[NFILEN], c, *bufp;
147 /* catch ([^\s(){}]+)[\s(){}]* */
150 /* Skip backwards over delimiters we are currently on */
152 c = lgetc(curwp->w_dotp, i);
153 if (isalnum(c) || c == '_')
159 /* Skip the symbol itself */
161 c = lgetc(curwp->w_dotp, i - 1);
162 if (!isalnum(c) && c != '_')
165 /* Fill the symbol in cprompt[] */
166 for (j = 0; j < sizeof(cprompt) - 1 && i < llength(curwp->w_dotp);
168 c = lgetc(curwp->w_dotp, i);
169 if (!isalnum(c) && c != '_')
175 if ((bufp = eread("Run gid (with args): ", cprompt, NFILEN,
176 (j ? EFDEF : 0) | EFNEW | EFCR)) == NULL)
178 else if (bufp[0] == '\0')
180 len = snprintf(command, sizeof(command), "gid %s", cprompt);
181 if (len < 0 || len >= sizeof(command))
184 if ((bp = compile_mode("*gid*", command)) == NULL)
186 if ((wp = popbuf(bp, WNONE)) == NULL)
189 compile_win = curwp = wp;
194 compile_mode(const char *name, const char *command)
201 char cwd[NFILEN], qcmd[NFILEN];
205 n = snprintf(qcmd, sizeof(qcmd), "%s 2>&1", command);
206 if (n < 0 || n >= sizeof(qcmd))
209 bp = bfind(name, TRUE);
210 if (bclear(bp) != TRUE)
213 if (getbufcwd(bp->b_cwd, sizeof(bp->b_cwd)) != TRUE)
215 addlinef(bp, "cd %s", bp->b_cwd);
219 if (getcwd(cwd, sizeof(cwd)) == NULL)
220 panic("Can't get current directory!");
221 if (chdir(bp->b_cwd) == -1) {
222 ewprintf("Can't change dir to %s", bp->b_cwd);
225 if ((fpipe = popen(qcmd, "r")) == NULL) {
226 ewprintf("Problem opening pipe");
230 * We know that our commands are nice and the last line will end with
231 * a \n, so we don't need to try to deal with the last line problem
234 while ((buf = fgetln(fpipe, &len)) != NULL) {
240 strftime(timestr, sizeof(timestr), "%a %b %e %T %Y", localtime(&t));
243 addlinef(bp, "Command exited abnormally with code %d"
244 " at %s", ret, timestr);
246 addlinef(bp, "Command finished at %s", timestr);
248 bp->b_dotp = bfirstlp(bp);
249 bp->b_modes[0] = name_mode("fundamental");
250 bp->b_modes[1] = name_mode("compile");
255 if (chdir(cwd) == -1) {
256 ewprintf("Can't change dir back to %s", cwd);
264 compile_goto_error(int f, int n)
268 char *fname, *line, *lp, *ln;
270 char *adjf, path[NFILEN];
275 compile_buffer = curbp;
276 last = blastlp(compile_buffer);
279 /* last line is compilation result */
280 if (curwp->w_dotp == last)
283 if ((line = linetostr(curwp->w_dotp)) == NULL)
286 if ((fname = strsep(&lp, ":")) == NULL || *fname == '\0')
288 if ((ln = strsep(&lp, ":")) == NULL || *ln == '\0')
290 lineno = (int)strtonum(ln, INT_MIN, INT_MAX, &errstr);
294 if (fname && fname[0] != '/') {
295 if (getbufcwd(path, sizeof(path)) == FALSE)
297 if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
301 adjf = adjustname(fname, TRUE);
308 if ((bp = findbuffer(adjf)) == NULL)
310 if ((wp = popbuf(bp, WNONE)) == NULL)
314 if (bp->b_fname[0] == '\0')
316 gotoline(FFARG, lineno);
320 if (curwp->w_dotp != blastlp(curbp)) {
321 curwp->w_dotp = lforw(curwp->w_dotp);
322 curwp->w_rflag |= WFMOVE;
325 ewprintf("No more hits");
331 next_error(int f, int n)
333 if (compile_win == NULL || compile_buffer == NULL) {
334 ewprintf("No compilation active");
338 curbp = compile_buffer;
339 if (curwp->w_dotp == blastlp(curbp)) {
340 ewprintf("No more hits");
343 curwp->w_dotp = lforw(curwp->w_dotp);
344 curwp->w_rflag |= WFMOVE;
346 return (compile_goto_error(f, n));
350 * Since we don't have variables (we probably should) these are command
351 * processors for changing the values of mode flags.
355 globalwdtoggle(int f, int n)
360 globalwd = !globalwd;