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 */
|
---|
28 | f_xucmd() {}
|
---|
29 | f_make() {}
|
---|
30 | f_nxterr() {}
|
---|
31 | #else
|
---|
32 |
|
---|
33 | #include <stdio.h>
|
---|
34 |
|
---|
35 | struct 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 */
|
---|
39 | int fresh_make = 1; /* Fresh Execution buffer contents */
|
---|
40 | chroff last_error_BOL; /* Dot for last-error's BOL */
|
---|
41 |
|
---|
42 | /* EFUN: "Execute Unix Command" */
|
---|
43 | f_xucmd()
|
---|
44 | {
|
---|
45 | make_or_unix_cmd(0);
|
---|
46 | }
|
---|
47 |
|
---|
48 | /* EFUN: "Execute Make" */
|
---|
49 | f_make()
|
---|
50 | {
|
---|
51 | make_or_unix_cmd(1);
|
---|
52 | }
|
---|
53 |
|
---|
54 | /* EFUN: "Find Next Error" */
|
---|
55 | f_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 |
|
---|
148 | failed: 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 */
|
---|
156 | do_exec(cmd, nicely)
|
---|
157 | char *cmd;
|
---|
158 | int 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 |
|
---|
222 | char last_make_cmd[256]; /* Last Unix/make command */
|
---|
223 | int have_last_make_cmd = 0;
|
---|
224 |
|
---|
225 | make_or_unix_cmd(domake)
|
---|
226 | int 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 |
|
---|
277 | sel_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 */
|
---|
287 | popto_buf(b)
|
---|
288 | register 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*/
|
---|