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