el.c revision 1.2 1 /* $NetBSD: el.c,v 1.2 1997/01/11 06:47:53 lukem 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 #if !defined(lint) && !defined(SCCSID)
40 #if 0
41 static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
42 #else
43 static char rcsid[] = "$NetBSD: el.c,v 1.2 1997/01/11 06:47:53 lukem Exp $";
44 #endif
45 #endif /* not lint && not SCCSID */
46
47 /*
48 * el.c: EditLine interface functions
49 */
50 #include "sys.h"
51
52 #include <sys/types.h>
53 #include <sys/param.h>
54 #include <string.h>
55 #include <stdlib.h>
56 #if __STDC__
57 # include <stdarg.h>
58 #else
59 # include <varargs.h>
60 #endif
61 #include "el.h"
62
63 /* el_init():
64 * Initialize editline and set default parameters.
65 */
66 public EditLine *
67 el_init(prog, fin, fout)
68 const char *prog;
69 FILE *fin, *fout;
70 {
71 EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
72 #ifdef DEBUG
73 char *tty;
74 #endif
75
76 if (el == NULL)
77 return NULL;
78
79 memset(el, 0, sizeof(EditLine));
80
81 el->el_infd = fileno(fin);
82 el->el_outfile = fout;
83 el->el_prog = strdup(prog);
84
85 #ifdef DEBUG
86 if ((tty = getenv("DEBUGTTY")) != NULL) {
87 el->el_errfile = fopen(tty, "w");
88 if (el->el_errfile == NULL) {
89 extern errno;
90 (void) fprintf(stderr, "Cannot open %s (%s).\n",
91 tty, strerror(errno));
92 return NULL;
93 }
94 }
95 else
96 #endif
97 el->el_errfile = stderr;
98
99 /*
100 * Initialize all the modules. Order is important!!!
101 */
102 (void) term_init(el);
103 (void) tty_init(el);
104 (void) key_init(el);
105 (void) map_init(el);
106 (void) ch_init(el);
107 (void) search_init(el);
108 (void) hist_init(el);
109 (void) prompt_init(el);
110 (void) sig_init(el);
111 el->el_flags = 0;
112
113 return el;
114 } /* end el_init */
115
116
117 /* el_end():
118 * Clean up.
119 */
120 public void
121 el_end(el)
122 EditLine *el;
123 {
124 if (el == NULL)
125 return;
126
127 el_reset(el);
128
129 term_end(el);
130 tty_end(el);
131 key_end(el);
132 map_end(el);
133 ch_end(el);
134 search_end(el);
135 hist_end(el);
136 prompt_end(el);
137 sig_end(el);
138
139 el_free((ptr_t) el->el_prog);
140 el_free((ptr_t) el);
141 } /* end el_end */
142
143
144 /* el_reset():
145 * Reset the tty and the parser
146 */
147 public void
148 el_reset(el)
149 EditLine *el;
150 {
151 tty_cookedmode(el);
152 ch_reset(el); /* XXX: Do we want that? */
153 }
154
155
156 /* el_set():
157 * set the editline parameters
158 */
159 public int
160 #if __STDC__
161 el_set(EditLine *el, int op, ...)
162 #else
163 el_set(va_alist)
164 va_dcl
165 #endif
166 {
167 va_list va;
168 int rv;
169 #if __STDC__
170 va_start(va, op);
171 #else
172 EditLine *el;
173 int op;
174
175 va_start(va);
176 el = va_arg(va, EditLine *);
177 op = va_arg(va, int);
178 #endif
179
180 switch (op) {
181 case EL_PROMPT:
182 rv = prompt_set(el, va_arg(va, el_pfunc_t));
183 break;
184
185 case EL_TERMINAL:
186 rv = term_set(el, va_arg(va, char *));
187 break;
188
189 case EL_EDITOR:
190 rv = map_set_editor(el, va_arg(va, char *));
191 break;
192
193 case EL_SIGNAL:
194 if (va_arg(va, int))
195 el->el_flags |= HANDLE_SIGNALS;
196 else
197 el->el_flags &= ~HANDLE_SIGNALS;
198 rv = 0;
199 break;
200
201 case EL_BIND:
202 case EL_TELLTC:
203 case EL_SETTC:
204 case EL_ECHOTC:
205 case EL_SETTY:
206 {
207 char *argv[20];
208 int i;
209 for (i = 1; i < 20; i++)
210 if ((argv[i] = va_arg(va, char *)) == NULL)
211 break;
212
213 switch (op) {
214 case EL_BIND:
215 argv[0] = "bind";
216 rv = map_bind(el, i, argv);
217 break;
218
219 case EL_TELLTC:
220 argv[0] = "telltc";
221 rv = term_telltc(el, i, argv);
222 break;
223
224 case EL_SETTC:
225 argv[0] = "settc";
226 rv = term_settc(el, i, argv);
227 break;
228
229 case EL_ECHOTC:
230 argv[0] = "echotc";
231 rv = term_echotc(el, i, argv);
232 break;
233
234 case EL_SETTY:
235 argv[0] = "setty";
236 rv = tty_stty(el, i, argv);
237 break;
238
239 default:
240 rv = -1;
241 abort();
242 break;
243 }
244 }
245 break;
246
247 case EL_ADDFN:
248 {
249 char *name = va_arg(va, char *);
250 char *help = va_arg(va, char *);
251 el_func_t func = va_arg(va, el_func_t);
252 rv = map_addfunc(el, name, help, func);
253 }
254 break;
255
256 case EL_HIST:
257 {
258 hist_fun_t func = va_arg(va, hist_fun_t);
259 ptr_t ptr = va_arg(va, char *);
260 rv = hist_set(el, func, ptr);
261 }
262 break;
263
264 default:
265 rv = -1;
266 }
267
268 va_end(va);
269 return rv;
270 } /* end el_set */
271
272
273 /* el_line():
274 * Return editing info
275 */
276 public const LineInfo *
277 el_line(el)
278 EditLine *el;
279 {
280 return (const LineInfo *) &el->el_line;
281 }
282
283 static const char elpath[] = "/.editrc";
284
285 /* el_source():
286 * Source a file
287 */
288 public int
289 el_source(el, fname)
290 EditLine *el;
291 const char *fname;
292 {
293 FILE *fp;
294 size_t len;
295 char *ptr, path[MAXPATHLEN];
296
297 if (fname == NULL) {
298 fname = &elpath[1];
299 if ((fp = fopen(fname, "r")) == NULL) {
300 if ((ptr = getenv("HOME")) == NULL)
301 return -1;
302 fname = strncpy(path, ptr, MAXPATHLEN);
303 (void) strncat(path, elpath, MAXPATHLEN);
304 path[MAXPATHLEN-1] = '\0';
305 }
306 }
307
308 if ((fp = fopen(fname, "r")) == NULL)
309 return -1;
310
311 while ((ptr = fgetln(fp, &len)) != NULL)
312 ptr[len - 1] = '\0';
313 if (parse_line(el, ptr) == -1) {
314 (void) fclose(fp);
315 return -1;
316 }
317
318 (void) fclose(fp);
319 return 0;
320 }
321
322
323 /* el_resize():
324 * Called from program when terminal is resized
325 */
326 public void
327 el_resize(el)
328 EditLine *el;
329 {
330 int lins, cols;
331 sigset_t oset, nset;
332 (void) sigemptyset(&nset);
333 (void) sigaddset(&nset, SIGWINCH);
334 (void) sigprocmask(SIG_BLOCK, &nset, &oset);
335
336 /* get the correct window size */
337 if (term_get_size(el, &lins, &cols))
338 term_change_size(el, lins, cols);
339
340 (void) sigprocmask(SIG_SETMASK, &oset, NULL);
341 }
342