el.c revision 1.7 1 /* $NetBSD: el.c,v 1.7 1997/07/06 18:25:24 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 #if !defined(lint) && !defined(SCCSID)
41 #if 0
42 static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
43 #else
44 __RCSID("$NetBSD: el.c,v 1.7 1997/07/06 18:25:24 christos Exp $");
45 #endif
46 #endif /* not lint && not SCCSID */
47
48 /*
49 * el.c: EditLine interface functions
50 */
51 #include "sys.h"
52
53 #include <sys/types.h>
54 #include <sys/param.h>
55 #include <string.h>
56 #include <stdlib.h>
57 #ifdef __STDC__
58 # include <stdarg.h>
59 #else
60 # include <varargs.h>
61 #endif
62 #include "el.h"
63
64 /* el_init():
65 * Initialize editline and set default parameters.
66 */
67 public EditLine *
68 el_init(prog, fin, fout)
69 const char *prog;
70 FILE *fin, *fout;
71 {
72 EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
73 #ifdef DEBUG
74 char *tty;
75 #endif
76
77 if (el == NULL)
78 return NULL;
79
80 memset(el, 0, sizeof(EditLine));
81
82 el->el_infd = fileno(fin);
83 el->el_outfile = fout;
84 el->el_prog = strdup(prog);
85
86 #ifdef DEBUG
87 if ((tty = getenv("DEBUGTTY")) != NULL) {
88 el->el_errfile = fopen(tty, "w");
89 if (el->el_errfile == NULL) {
90 extern errno;
91 (void) fprintf(stderr, "Cannot open %s (%s).\n",
92 tty, strerror(errno));
93 return NULL;
94 }
95 }
96 else
97 #endif
98 el->el_errfile = stderr;
99
100 /*
101 * Initialize all the modules. Order is important!!!
102 */
103 (void) term_init(el);
104 (void) tty_init(el);
105 (void) key_init(el);
106 (void) map_init(el);
107 (void) ch_init(el);
108 (void) search_init(el);
109 (void) hist_init(el);
110 (void) prompt_init(el);
111 (void) sig_init(el);
112 el->el_flags = 0;
113
114 return el;
115 } /* end el_init */
116
117
118 /* el_end():
119 * Clean up.
120 */
121 public void
122 el_end(el)
123 EditLine *el;
124 {
125 if (el == NULL)
126 return;
127
128 el_reset(el);
129
130 term_end(el);
131 tty_end(el);
132 key_end(el);
133 map_end(el);
134 ch_end(el);
135 search_end(el);
136 hist_end(el);
137 prompt_end(el);
138 sig_end(el);
139
140 el_free((ptr_t) el->el_prog);
141 el_free((ptr_t) el);
142 } /* end el_end */
143
144
145 /* el_reset():
146 * Reset the tty and the parser
147 */
148 public void
149 el_reset(el)
150 EditLine *el;
151 {
152 tty_cookedmode(el);
153 ch_reset(el); /* XXX: Do we want that? */
154 }
155
156
157 /* el_set():
158 * set the editline parameters
159 */
160 public int
161 #ifdef __STDC__
162 el_set(EditLine *el, int op, ...)
163 #else
164 el_set(va_alist)
165 va_dcl
166 #endif
167 {
168 va_list va;
169 int rv;
170 #ifdef __STDC__
171 va_start(va, op);
172 #else
173 EditLine *el;
174 int op;
175
176 va_start(va);
177 el = va_arg(va, EditLine *);
178 op = va_arg(va, int);
179 #endif
180
181 switch (op) {
182 case EL_PROMPT:
183 rv = prompt_set(el, va_arg(va, el_pfunc_t));
184 break;
185
186 case EL_TERMINAL:
187 rv = term_set(el, va_arg(va, char *));
188 break;
189
190 case EL_EDITOR:
191 rv = map_set_editor(el, va_arg(va, char *));
192 break;
193
194 case EL_SIGNAL:
195 if (va_arg(va, int))
196 el->el_flags |= HANDLE_SIGNALS;
197 else
198 el->el_flags &= ~HANDLE_SIGNALS;
199 rv = 0;
200 break;
201
202 case EL_BIND:
203 case EL_TELLTC:
204 case EL_SETTC:
205 case EL_ECHOTC:
206 case EL_SETTY:
207 {
208 char *argv[20];
209 int i;
210 for (i = 1; i < 20; i++)
211 if ((argv[i] = va_arg(va, char *)) == NULL)
212 break;
213
214 switch (op) {
215 case EL_BIND:
216 argv[0] = "bind";
217 rv = map_bind(el, i, argv);
218 break;
219
220 case EL_TELLTC:
221 argv[0] = "telltc";
222 rv = term_telltc(el, i, argv);
223 break;
224
225 case EL_SETTC:
226 argv[0] = "settc";
227 rv = term_settc(el, i, argv);
228 break;
229
230 case EL_ECHOTC:
231 argv[0] = "echotc";
232 rv = term_echotc(el, i, argv);
233 break;
234
235 case EL_SETTY:
236 argv[0] = "setty";
237 rv = tty_stty(el, i, argv);
238 break;
239
240 default:
241 rv = -1;
242 abort();
243 break;
244 }
245 }
246 break;
247
248 case EL_ADDFN:
249 {
250 char *name = va_arg(va, char *);
251 char *help = va_arg(va, char *);
252 el_func_t func = va_arg(va, el_func_t);
253 rv = map_addfunc(el, name, help, func);
254 }
255 break;
256
257 case EL_HIST:
258 {
259 hist_fun_t func = va_arg(va, hist_fun_t);
260 ptr_t ptr = va_arg(va, char *);
261 rv = hist_set(el, func, ptr);
262 }
263 break;
264
265 default:
266 rv = -1;
267 }
268
269 va_end(va);
270 return rv;
271 } /* end el_set */
272
273
274 /* el_line():
275 * Return editing info
276 */
277 public const LineInfo *
278 el_line(el)
279 EditLine *el;
280 {
281 return (const LineInfo *) &el->el_line;
282 }
283
284 static const char elpath[] = "/.editrc";
285
286 /* el_source():
287 * Source a file
288 */
289 public int
290 el_source(el, fname)
291 EditLine *el;
292 const char *fname;
293 {
294 FILE *fp;
295 size_t len;
296 char *ptr, path[MAXPATHLEN];
297
298 if (fname == NULL) {
299 fname = &elpath[1];
300 if ((fp = fopen(fname, "r")) == NULL) {
301 if ((ptr = getenv("HOME")) == NULL)
302 return -1;
303 (void)snprintf(path, sizeof(path), "%s%s", ptr, elpath);
304 fname = path;
305 }
306 }
307
308 if ((fp = fopen(fname, "r")) == NULL)
309 return -1;
310
311 while ((ptr = fgetln(fp, &len)) != NULL) {
312 if (ptr[len - 1] == '\n')
313 --len;
314 ptr[len] = '\0';
315 if (parse_line(el, ptr) == -1) {
316 (void) fclose(fp);
317 return -1;
318 }
319 }
320
321 (void) fclose(fp);
322 return 0;
323 }
324
325
326 /* el_resize():
327 * Called from program when terminal is resized
328 */
329 public void
330 el_resize(el)
331 EditLine *el;
332 {
333 int lins, cols;
334 sigset_t oset, nset;
335 (void) sigemptyset(&nset);
336 (void) sigaddset(&nset, SIGWINCH);
337 (void) sigprocmask(SIG_BLOCK, &nset, &oset);
338
339 /* get the correct window size */
340 if (term_get_size(el, &lins, &cols))
341 term_change_size(el, lins, cols);
342
343 (void) sigprocmask(SIG_SETMASK, &oset, NULL);
344 }
345