source: trunk/minix/commands/elle/eemake.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.9 KB
RevLine 
[9]1/* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
2 * This software is quasi-public; it may be used freely with
3 * like software, but may NOT be sold or made part of licensed
4 * products without permission of the author.
5 */
6/* EEMAKE - IMAGEN configuration functions for interfacing to "make".
7 * Written by (I think) Chris Ryland at IMAGEN, who also
8 * wrote other functions scattered through ELLE. These are either
9 * conditionalized or are commented as being derived from the IMAGEN
10 * configuration.
11 *
12 * KLH: An attempt has been made to keep these routines updated as ELLE
13 * changed, but their workings cannot be guaranteed.
14 */
15
16
17/*
18 * eemake: "make" (and other program) support
19 *
20 * Next-error depends on programs writing error messages of the form:
21 * "file", line n: message
22 * which is a de facto standard, at least in some worlds.
23 */
24
25#include "elle.h"
26
27#if !(IMAGEN) /* Only with IMAGEN config for now */
28f_xucmd() {}
29f_make() {}
30f_nxterr() {}
31#else
32
33#include <stdio.h>
34
35struct buffer *exec_buf; /* Ptr to "Execution" buffer */
36 /* Only external ref is from e_buff.c */
37
38#define MSGLENGTH (scr_wid - 11) /* Max length of message */
39int fresh_make = 1; /* Fresh Execution buffer contents */
40chroff last_error_BOL; /* Dot for last-error's BOL */
41
42/* EFUN: "Execute Unix Command" */
43f_xucmd()
44{
45 make_or_unix_cmd(0);
46}
47
48/* EFUN: "Execute Make" */
49f_make()
50{
51 make_or_unix_cmd(1);
52}
53
54/* EFUN: "Find Next Error" */
55f_nxterr()
56{
57 register struct sbstr *sb;
58 register char *cp;
59 register int c;
60 char file[64], line[32];
61#ifdef ONEWINDOW
62 char msg[512];
63#endif
64 chroff linedot;
65 int lineno;
66 register int len;
67
68 sel_execbuf();
69 if (! fresh_make)
70 { e_go(last_error_BOL);
71 e_gonl();
72 }
73 else
74 { fresh_make = 0;
75 e_gobob();
76 last_error_BOL = e_dot();
77 }
78
79 /* Looking for `"file", line n: msg' */
80 if (! e_search("\", line ", 8, 0))
81 goto failed;
82 linedot = e_dot();
83 e_gobol(); /* Found something, get to BOL */
84 if (e_getc() != '"')
85 goto failed; /* Insist on beginning "file" */
86 cp = file; /* Pick up filename */
87 while ((c = e_getc()) != '"')
88 *cp++ = c;
89 *cp = 0;
90 e_go(linedot); /* Back to after "line " */
91 cp = line;
92 while ((c = e_getc()) >= '0' && c <= '9')
93 *cp++ = c;
94 *cp = 0;
95 lineno = atoi(line); /* Pick up line number */
96#ifdef ONEWINDOW
97 cp = msg; /* Now get rest of line to msg */
98 len = 0; /* But keep length <= MSGLENGTH */
99 e_getc(); /* Go past purported space */
100 while ((c = e_getc()) != LF && c != EOF && len <= MSGLENGTH)
101 { if (c == '\t')
102 len = (len + 8) & ~07;
103 else if (c < ' ' || c > 0176)
104 len += 2;
105 else
106 ++len;
107 *cp++ = c;
108 }
109 *cp = 0;
110 if (len > MSGLENGTH)
111 strcat(msg, "...");
112#ifdef DEBUG
113 say("file ");
114 saytoo(file);
115 saytoo(", line ");
116 saytoo(line);
117 saytoo(", msg: ");
118 sayntoo(msg);
119#else
120 say(line);
121 saytoo(": ");
122 sayntoo(msg);
123#endif /*DEBUG*/
124#else /* -ONEWINDOW */
125 f_begline(); /* Get to start of line */
126 last_error_BOL = e_dot(); /* Remember this position */
127 exp_p = 1; /* Make this the new top line */
128 exp = 0;
129 f_newwin();
130 upd_wind(0);
131#endif /*ONEWINDOW*/
132
133 /* Now, visit the given file and line */
134#ifdef ONEWINDOW
135#else
136 f_othwind(); /* To other window */
137#endif
138 find_file(file);
139 f_gobeg();
140 down_line(lineno - 1);
141#ifdef READJUST /* NAW */
142 exp_p = 1;
143 exp = cur_win->w_ht / 4; /* Adjust how we look at "error" */
144 f_newwin();
145#endif /*READJUST*/
146 return;
147
148failed: ding("No more errors!");
149 fresh_make = 1; /* Fake-out: pretend starting over */
150 return;
151}
152
153
154
155/* Do the "cmd" and put its output in the Execution buffer */
156do_exec(cmd, nicely)
157char *cmd;
158int nicely;
159{
160 register int n;
161 int status, res, pid, fd[2];
162 char nicecmd[256];
163 char pipebuff[512];
164 struct buffer *b;
165
166 b = cur_buf;
167 sel_execbuf(); /* Get our execution buffer up */
168 ed_reset(); /* Clear it out */
169 fresh_make = 1;
170 upd_wind(0);
171 if (nicely)
172 sayntoo(" ...starting up...");
173 else
174 sayntoo(" ...starting up (nasty person)...");
175 pipe(fd);
176 switch (pid = fork())
177 {
178 case -1:
179 /* Fork failed, in parent */
180 ding("Cannot fork!?!");
181 break;
182
183 case 0: /* In child */
184 for (n = 0; n < 20; ++n)
185 if (n != fd[0] && n != fd[1])
186 close(n);
187 open("/dev/null", 0); /* Give ourselves empty stdin */
188 dup(fd[1]);
189 dup(fd[1]); /* stdout, stderr out to pipe */
190 close(fd[1]); /* Close the pipe itself */
191 close(fd[0]);
192 if (nicely)
193 { strcpy(nicecmd, "nice -4 ");
194 strcat(nicecmd, cmd);
195 execl("/bin/sh", "sh", "-c", nicecmd, 0);
196 }
197 else
198 execl("/bin/sh", "sh", "-c", cmd, 0);
199 write(1, "Cannot execute!", 15);
200 _exit(-1);
201 break;
202
203 default:
204 /* Parent */
205 close(fd[1]); /* Close the output direction */
206 while ((n = read(fd[0], pipebuff, sizeof(pipebuff))) > 0)
207 { ed_nsins(pipebuff, n);
208 upd_wind(0);
209 saynow("Chugging along...");
210 }
211 close(fd[0]);
212 while ((res = wait(&status)) != pid && res != -1)
213 ; /* Wait for this fork to die */
214 f_bufnotmod(); /* Buffer is fresh */
215 saynow("Done!");
216 break;
217 }
218 f_othwind(); /* Back to other window */
219 chg_buf(b); /* Back to original buffer */
220}
221
222char last_make_cmd[256]; /* Last Unix/make command */
223int have_last_make_cmd = 0;
224
225make_or_unix_cmd(domake)
226int domake;
227{
228#if APOLLO
229 register int nicely = exp == 16; /* modification for apollo */
230#else
231 register int nicely = exp != 16;
232#endif /*-APOLLO*/
233 register char *reply, *cmd = 0;
234
235 if (domake) /* If "make"-style, */
236 { int savp = exp_p;
237 exp_p = 1;
238 f_savefiles(); /* write modified files quietly */
239 exp_p = savp;
240 }
241 if (exp_p || ! domake)
242 { /* Arg given make, or Unix command */
243 reply = ask((! domake) ? "Unix command: " : "Command: ");
244 if (! reply)
245 return;
246 if (*reply == 0)
247 { if (have_last_make_cmd)
248 cmd = &last_make_cmd[0];
249 else
250 { chkfree(reply);
251 ding("No previous command!");
252 return;
253 }
254 }
255 else
256 cmd = reply;
257 if (cmd != &last_make_cmd[0]) /* Update last command */
258 strcpy(last_make_cmd, cmd);
259 have_last_make_cmd = 1;
260 say("Command: ");
261 sayntoo(cmd);
262 do_exec(cmd, nicely);
263 chkfree(reply);
264 }
265 else if (have_last_make_cmd)
266 { say("Command: ");
267 sayntoo(last_make_cmd);
268 do_exec(last_make_cmd, nicely);
269 }
270 else
271 { saynow("Command: make");
272 do_exec("make", nicely);
273 }
274}
275
276
277sel_execbuf()
278{ if(!exec_buf)
279 { /* Make execution buffer; don't let anyone kill it */
280 exec_buf = make_buf("Execution");
281 exec_buf->b_flags |= B_PERMANENT;
282 }
283 popto_buf(exec_buf);
284}
285
286/* Utility: pop the given buffer to a window, getting into 2-window mode */
287popto_buf(b)
288register struct buffer *b;
289{
290 /* See if we already have this buffer in a visible window */
291 if (b == cur_win->w_buf)
292 { if (oth_win == 0)
293 { f_2winds();
294 f_othwind(); /* Get back to our window */
295 }
296 }
297 else if (oth_win != 0 && b == oth_win->w_buf)
298 f_othwind();
299 else if (oth_win == 0)
300 { /* One window mode */
301 f_2winds(); /* Get two, get into second */
302 sel_buf(b); /* Select our new buffer */
303 }
304 else
305 { f_othwind(); /* Get to other window */
306 sel_buf(b); /* and select our buffer */
307 }
308}
309
310#endif /*IMAGEN*/
Note: See TracBrowser for help on using the repository browser.