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