1*baff8195SBaptiste Daroussin /* $NetBSD: el.c,v 1.101 2022/10/30 19:11:31 christos Exp $ */
2d0ef721eSBaptiste Daroussin
3d0ef721eSBaptiste Daroussin /*-
4d0ef721eSBaptiste Daroussin * Copyright (c) 1992, 1993
5d0ef721eSBaptiste Daroussin * The Regents of the University of California. All rights reserved.
6d0ef721eSBaptiste Daroussin *
7d0ef721eSBaptiste Daroussin * This code is derived from software contributed to Berkeley by
8d0ef721eSBaptiste Daroussin * Christos Zoulas of Cornell University.
9d0ef721eSBaptiste Daroussin *
10d0ef721eSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without
11d0ef721eSBaptiste Daroussin * modification, are permitted provided that the following conditions
12d0ef721eSBaptiste Daroussin * are met:
13d0ef721eSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright
14d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer.
15d0ef721eSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright
16d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the
17d0ef721eSBaptiste Daroussin * documentation and/or other materials provided with the distribution.
18d0ef721eSBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors
19d0ef721eSBaptiste Daroussin * may be used to endorse or promote products derived from this software
20d0ef721eSBaptiste Daroussin * without specific prior written permission.
21d0ef721eSBaptiste Daroussin *
22d0ef721eSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23d0ef721eSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24d0ef721eSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25d0ef721eSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26d0ef721eSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27d0ef721eSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28d0ef721eSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29d0ef721eSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30d0ef721eSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31d0ef721eSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32d0ef721eSBaptiste Daroussin * SUCH DAMAGE.
33d0ef721eSBaptiste Daroussin */
34d0ef721eSBaptiste Daroussin
35d0ef721eSBaptiste Daroussin #include "config.h"
36d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID)
37d0ef721eSBaptiste Daroussin #if 0
38d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
39d0ef721eSBaptiste Daroussin #else
40*baff8195SBaptiste Daroussin __RCSID("$NetBSD: el.c,v 1.101 2022/10/30 19:11:31 christos Exp $");
41d0ef721eSBaptiste Daroussin #endif
42d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */
43d0ef721eSBaptiste Daroussin
44d0ef721eSBaptiste Daroussin /*
45d0ef721eSBaptiste Daroussin * el.c: EditLine interface functions
46d0ef721eSBaptiste Daroussin */
47d0ef721eSBaptiste Daroussin #include <sys/types.h>
48d0ef721eSBaptiste Daroussin #include <sys/param.h>
49d0ef721eSBaptiste Daroussin #include <ctype.h>
50d0ef721eSBaptiste Daroussin #include <langinfo.h>
51d0ef721eSBaptiste Daroussin #include <locale.h>
52d0ef721eSBaptiste Daroussin #include <stdarg.h>
53d0ef721eSBaptiste Daroussin #include <stdlib.h>
54d0ef721eSBaptiste Daroussin #include <string.h>
55d0ef721eSBaptiste Daroussin
56d0ef721eSBaptiste Daroussin #include "el.h"
57d0ef721eSBaptiste Daroussin #include "parse.h"
58d0ef721eSBaptiste Daroussin #include "read.h"
59d0ef721eSBaptiste Daroussin
60d0ef721eSBaptiste Daroussin /* el_init():
61d0ef721eSBaptiste Daroussin * Initialize editline and set default parameters.
62d0ef721eSBaptiste Daroussin */
63d0ef721eSBaptiste Daroussin EditLine *
el_init(const char * prog,FILE * fin,FILE * fout,FILE * ferr)64d0ef721eSBaptiste Daroussin el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
65d0ef721eSBaptiste Daroussin {
66d0ef721eSBaptiste Daroussin return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
67d0ef721eSBaptiste Daroussin fileno(ferr));
68d0ef721eSBaptiste Daroussin }
69d0ef721eSBaptiste Daroussin
70d0ef721eSBaptiste Daroussin libedit_private EditLine *
el_init_internal(const char * prog,FILE * fin,FILE * fout,FILE * ferr,int fdin,int fdout,int fderr,int flags)71d0ef721eSBaptiste Daroussin el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
72d0ef721eSBaptiste Daroussin int fdin, int fdout, int fderr, int flags)
73d0ef721eSBaptiste Daroussin {
74d0ef721eSBaptiste Daroussin EditLine *el = el_calloc(1, sizeof(*el));
75d0ef721eSBaptiste Daroussin
76d0ef721eSBaptiste Daroussin if (el == NULL)
77d0ef721eSBaptiste Daroussin return NULL;
78d0ef721eSBaptiste Daroussin
79d0ef721eSBaptiste Daroussin el->el_infile = fin;
80d0ef721eSBaptiste Daroussin el->el_outfile = fout;
81d0ef721eSBaptiste Daroussin el->el_errfile = ferr;
82d0ef721eSBaptiste Daroussin
83d0ef721eSBaptiste Daroussin el->el_infd = fdin;
84d0ef721eSBaptiste Daroussin el->el_outfd = fdout;
85d0ef721eSBaptiste Daroussin el->el_errfd = fderr;
86d0ef721eSBaptiste Daroussin
87d0ef721eSBaptiste Daroussin el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
88d0ef721eSBaptiste Daroussin if (el->el_prog == NULL) {
89d0ef721eSBaptiste Daroussin el_free(el);
90d0ef721eSBaptiste Daroussin return NULL;
91d0ef721eSBaptiste Daroussin }
92d0ef721eSBaptiste Daroussin
93d0ef721eSBaptiste Daroussin /*
94d0ef721eSBaptiste Daroussin * Initialize all the modules. Order is important!!!
95d0ef721eSBaptiste Daroussin */
96d0ef721eSBaptiste Daroussin el->el_flags = flags;
97d0ef721eSBaptiste Daroussin
98d0ef721eSBaptiste Daroussin if (terminal_init(el) == -1) {
99d0ef721eSBaptiste Daroussin el_free(el->el_prog);
100d0ef721eSBaptiste Daroussin el_free(el);
101d0ef721eSBaptiste Daroussin return NULL;
102d0ef721eSBaptiste Daroussin }
103d0ef721eSBaptiste Daroussin (void) keymacro_init(el);
104d0ef721eSBaptiste Daroussin (void) map_init(el);
105d0ef721eSBaptiste Daroussin if (tty_init(el) == -1)
106d0ef721eSBaptiste Daroussin el->el_flags |= NO_TTY;
107d0ef721eSBaptiste Daroussin (void) ch_init(el);
108d0ef721eSBaptiste Daroussin (void) search_init(el);
109d0ef721eSBaptiste Daroussin (void) hist_init(el);
110d0ef721eSBaptiste Daroussin (void) prompt_init(el);
111d0ef721eSBaptiste Daroussin (void) sig_init(el);
112d0ef721eSBaptiste Daroussin (void) literal_init(el);
113d0ef721eSBaptiste Daroussin if (read_init(el) == -1) {
114d0ef721eSBaptiste Daroussin el_end(el);
115d0ef721eSBaptiste Daroussin return NULL;
116d0ef721eSBaptiste Daroussin }
117d0ef721eSBaptiste Daroussin return el;
118d0ef721eSBaptiste Daroussin }
119d0ef721eSBaptiste Daroussin
120d0ef721eSBaptiste Daroussin EditLine *
el_init_fd(const char * prog,FILE * fin,FILE * fout,FILE * ferr,int fdin,int fdout,int fderr)121d0ef721eSBaptiste Daroussin el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
122d0ef721eSBaptiste Daroussin int fdin, int fdout, int fderr)
123d0ef721eSBaptiste Daroussin {
124d0ef721eSBaptiste Daroussin return el_init_internal(prog, fin, fout, ferr, fdin, fdout, fderr, 0);
125d0ef721eSBaptiste Daroussin }
126d0ef721eSBaptiste Daroussin
127d0ef721eSBaptiste Daroussin /* el_end():
128d0ef721eSBaptiste Daroussin * Clean up.
129d0ef721eSBaptiste Daroussin */
130d0ef721eSBaptiste Daroussin void
el_end(EditLine * el)131d0ef721eSBaptiste Daroussin el_end(EditLine *el)
132d0ef721eSBaptiste Daroussin {
133d0ef721eSBaptiste Daroussin
134d0ef721eSBaptiste Daroussin if (el == NULL)
135d0ef721eSBaptiste Daroussin return;
136d0ef721eSBaptiste Daroussin
137d0ef721eSBaptiste Daroussin el_reset(el);
138d0ef721eSBaptiste Daroussin
139d0ef721eSBaptiste Daroussin terminal_end(el);
140d0ef721eSBaptiste Daroussin keymacro_end(el);
141d0ef721eSBaptiste Daroussin map_end(el);
142d0ef721eSBaptiste Daroussin if (!(el->el_flags & NO_TTY))
143d0ef721eSBaptiste Daroussin tty_end(el, TCSAFLUSH);
144d0ef721eSBaptiste Daroussin ch_end(el);
145*baff8195SBaptiste Daroussin read_end(el);
146d0ef721eSBaptiste Daroussin search_end(el);
147d0ef721eSBaptiste Daroussin hist_end(el);
148d0ef721eSBaptiste Daroussin prompt_end(el);
149d0ef721eSBaptiste Daroussin sig_end(el);
150d0ef721eSBaptiste Daroussin literal_end(el);
151d0ef721eSBaptiste Daroussin
152d0ef721eSBaptiste Daroussin el_free(el->el_prog);
153d0ef721eSBaptiste Daroussin el_free(el->el_visual.cbuff);
154d0ef721eSBaptiste Daroussin el_free(el->el_visual.wbuff);
155d0ef721eSBaptiste Daroussin el_free(el->el_scratch.cbuff);
156d0ef721eSBaptiste Daroussin el_free(el->el_scratch.wbuff);
157d0ef721eSBaptiste Daroussin el_free(el->el_lgcyconv.cbuff);
158d0ef721eSBaptiste Daroussin el_free(el->el_lgcyconv.wbuff);
159d0ef721eSBaptiste Daroussin el_free(el);
160d0ef721eSBaptiste Daroussin }
161d0ef721eSBaptiste Daroussin
162d0ef721eSBaptiste Daroussin
163d0ef721eSBaptiste Daroussin /* el_reset():
164d0ef721eSBaptiste Daroussin * Reset the tty and the parser
165d0ef721eSBaptiste Daroussin */
166d0ef721eSBaptiste Daroussin void
el_reset(EditLine * el)167d0ef721eSBaptiste Daroussin el_reset(EditLine *el)
168d0ef721eSBaptiste Daroussin {
169d0ef721eSBaptiste Daroussin
170d0ef721eSBaptiste Daroussin tty_cookedmode(el);
171d0ef721eSBaptiste Daroussin ch_reset(el); /* XXX: Do we want that? */
172d0ef721eSBaptiste Daroussin }
173d0ef721eSBaptiste Daroussin
174d0ef721eSBaptiste Daroussin
175d0ef721eSBaptiste Daroussin /* el_set():
176d0ef721eSBaptiste Daroussin * set the editline parameters
177d0ef721eSBaptiste Daroussin */
178d0ef721eSBaptiste Daroussin int
el_wset(EditLine * el,int op,...)179d0ef721eSBaptiste Daroussin el_wset(EditLine *el, int op, ...)
180d0ef721eSBaptiste Daroussin {
181d0ef721eSBaptiste Daroussin va_list ap;
182d0ef721eSBaptiste Daroussin int rv = 0;
183d0ef721eSBaptiste Daroussin
184d0ef721eSBaptiste Daroussin if (el == NULL)
185d0ef721eSBaptiste Daroussin return -1;
186d0ef721eSBaptiste Daroussin va_start(ap, op);
187d0ef721eSBaptiste Daroussin
188d0ef721eSBaptiste Daroussin switch (op) {
189d0ef721eSBaptiste Daroussin case EL_PROMPT:
190d0ef721eSBaptiste Daroussin case EL_RPROMPT: {
191d0ef721eSBaptiste Daroussin el_pfunc_t p = va_arg(ap, el_pfunc_t);
192d0ef721eSBaptiste Daroussin
193d0ef721eSBaptiste Daroussin rv = prompt_set(el, p, 0, op, 1);
194d0ef721eSBaptiste Daroussin break;
195d0ef721eSBaptiste Daroussin }
196d0ef721eSBaptiste Daroussin
197d0ef721eSBaptiste Daroussin case EL_RESIZE: {
198d0ef721eSBaptiste Daroussin el_zfunc_t p = va_arg(ap, el_zfunc_t);
199d0ef721eSBaptiste Daroussin void *arg = va_arg(ap, void *);
200d0ef721eSBaptiste Daroussin rv = ch_resizefun(el, p, arg);
201d0ef721eSBaptiste Daroussin break;
202d0ef721eSBaptiste Daroussin }
203d0ef721eSBaptiste Daroussin
204d0ef721eSBaptiste Daroussin case EL_ALIAS_TEXT: {
205d0ef721eSBaptiste Daroussin el_afunc_t p = va_arg(ap, el_afunc_t);
206d0ef721eSBaptiste Daroussin void *arg = va_arg(ap, void *);
207d0ef721eSBaptiste Daroussin rv = ch_aliasfun(el, p, arg);
208d0ef721eSBaptiste Daroussin break;
209d0ef721eSBaptiste Daroussin }
210d0ef721eSBaptiste Daroussin
211d0ef721eSBaptiste Daroussin case EL_PROMPT_ESC:
212d0ef721eSBaptiste Daroussin case EL_RPROMPT_ESC: {
213d0ef721eSBaptiste Daroussin el_pfunc_t p = va_arg(ap, el_pfunc_t);
214d0ef721eSBaptiste Daroussin int c = va_arg(ap, int);
215d0ef721eSBaptiste Daroussin
216d0ef721eSBaptiste Daroussin rv = prompt_set(el, p, (wchar_t)c, op, 1);
217d0ef721eSBaptiste Daroussin break;
218d0ef721eSBaptiste Daroussin }
219d0ef721eSBaptiste Daroussin
220d0ef721eSBaptiste Daroussin case EL_TERMINAL:
221d0ef721eSBaptiste Daroussin rv = terminal_set(el, va_arg(ap, char *));
222d0ef721eSBaptiste Daroussin break;
223d0ef721eSBaptiste Daroussin
224d0ef721eSBaptiste Daroussin case EL_EDITOR:
225d0ef721eSBaptiste Daroussin rv = map_set_editor(el, va_arg(ap, wchar_t *));
226d0ef721eSBaptiste Daroussin break;
227d0ef721eSBaptiste Daroussin
228d0ef721eSBaptiste Daroussin case EL_SIGNAL:
229d0ef721eSBaptiste Daroussin if (va_arg(ap, int))
230d0ef721eSBaptiste Daroussin el->el_flags |= HANDLE_SIGNALS;
231d0ef721eSBaptiste Daroussin else
232d0ef721eSBaptiste Daroussin el->el_flags &= ~HANDLE_SIGNALS;
233d0ef721eSBaptiste Daroussin break;
234d0ef721eSBaptiste Daroussin
235d0ef721eSBaptiste Daroussin case EL_BIND:
236d0ef721eSBaptiste Daroussin case EL_TELLTC:
237d0ef721eSBaptiste Daroussin case EL_SETTC:
238d0ef721eSBaptiste Daroussin case EL_ECHOTC:
239d0ef721eSBaptiste Daroussin case EL_SETTY:
240d0ef721eSBaptiste Daroussin {
241d0ef721eSBaptiste Daroussin const wchar_t *argv[20];
242d0ef721eSBaptiste Daroussin int i;
243d0ef721eSBaptiste Daroussin
244d0ef721eSBaptiste Daroussin for (i = 1; i < (int)__arraycount(argv); i++)
245d0ef721eSBaptiste Daroussin if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)
246d0ef721eSBaptiste Daroussin break;
247d0ef721eSBaptiste Daroussin
248d0ef721eSBaptiste Daroussin switch (op) {
249d0ef721eSBaptiste Daroussin case EL_BIND:
250d0ef721eSBaptiste Daroussin argv[0] = L"bind";
251d0ef721eSBaptiste Daroussin rv = map_bind(el, i, argv);
252d0ef721eSBaptiste Daroussin break;
253d0ef721eSBaptiste Daroussin
254d0ef721eSBaptiste Daroussin case EL_TELLTC:
255d0ef721eSBaptiste Daroussin argv[0] = L"telltc";
256d0ef721eSBaptiste Daroussin rv = terminal_telltc(el, i, argv);
257d0ef721eSBaptiste Daroussin break;
258d0ef721eSBaptiste Daroussin
259d0ef721eSBaptiste Daroussin case EL_SETTC:
260d0ef721eSBaptiste Daroussin argv[0] = L"settc";
261d0ef721eSBaptiste Daroussin rv = terminal_settc(el, i, argv);
262d0ef721eSBaptiste Daroussin break;
263d0ef721eSBaptiste Daroussin
264d0ef721eSBaptiste Daroussin case EL_ECHOTC:
265d0ef721eSBaptiste Daroussin argv[0] = L"echotc";
266d0ef721eSBaptiste Daroussin rv = terminal_echotc(el, i, argv);
267d0ef721eSBaptiste Daroussin break;
268d0ef721eSBaptiste Daroussin
269d0ef721eSBaptiste Daroussin case EL_SETTY:
270d0ef721eSBaptiste Daroussin argv[0] = L"setty";
271d0ef721eSBaptiste Daroussin rv = tty_stty(el, i, argv);
272d0ef721eSBaptiste Daroussin break;
273d0ef721eSBaptiste Daroussin
274d0ef721eSBaptiste Daroussin default:
275d0ef721eSBaptiste Daroussin rv = -1;
276d0ef721eSBaptiste Daroussin EL_ABORT((el->el_errfile, "Bad op %d\n", op));
277d0ef721eSBaptiste Daroussin break;
278d0ef721eSBaptiste Daroussin }
279d0ef721eSBaptiste Daroussin break;
280d0ef721eSBaptiste Daroussin }
281d0ef721eSBaptiste Daroussin
282d0ef721eSBaptiste Daroussin case EL_ADDFN:
283d0ef721eSBaptiste Daroussin {
284d0ef721eSBaptiste Daroussin wchar_t *name = va_arg(ap, wchar_t *);
285d0ef721eSBaptiste Daroussin wchar_t *help = va_arg(ap, wchar_t *);
286d0ef721eSBaptiste Daroussin el_func_t func = va_arg(ap, el_func_t);
287d0ef721eSBaptiste Daroussin
288d0ef721eSBaptiste Daroussin rv = map_addfunc(el, name, help, func);
289d0ef721eSBaptiste Daroussin break;
290d0ef721eSBaptiste Daroussin }
291d0ef721eSBaptiste Daroussin
292d0ef721eSBaptiste Daroussin case EL_HIST:
293d0ef721eSBaptiste Daroussin {
294d0ef721eSBaptiste Daroussin hist_fun_t func = va_arg(ap, hist_fun_t);
295d0ef721eSBaptiste Daroussin void *ptr = va_arg(ap, void *);
296d0ef721eSBaptiste Daroussin
297d0ef721eSBaptiste Daroussin rv = hist_set(el, func, ptr);
298d0ef721eSBaptiste Daroussin if (MB_CUR_MAX == 1)
299d0ef721eSBaptiste Daroussin el->el_flags &= ~NARROW_HISTORY;
300d0ef721eSBaptiste Daroussin break;
301d0ef721eSBaptiste Daroussin }
302d0ef721eSBaptiste Daroussin
30391f76417SBaptiste Daroussin case EL_SAFEREAD:
30491f76417SBaptiste Daroussin if (va_arg(ap, int))
30591f76417SBaptiste Daroussin el->el_flags |= FIXIO;
30691f76417SBaptiste Daroussin else
30791f76417SBaptiste Daroussin el->el_flags &= ~FIXIO;
30891f76417SBaptiste Daroussin rv = 0;
30991f76417SBaptiste Daroussin break;
31091f76417SBaptiste Daroussin
311d0ef721eSBaptiste Daroussin case EL_EDITMODE:
312d0ef721eSBaptiste Daroussin if (va_arg(ap, int))
313d0ef721eSBaptiste Daroussin el->el_flags &= ~EDIT_DISABLED;
314d0ef721eSBaptiste Daroussin else
315d0ef721eSBaptiste Daroussin el->el_flags |= EDIT_DISABLED;
316d0ef721eSBaptiste Daroussin rv = 0;
317d0ef721eSBaptiste Daroussin break;
318d0ef721eSBaptiste Daroussin
319d0ef721eSBaptiste Daroussin case EL_GETCFN:
320d0ef721eSBaptiste Daroussin {
321d0ef721eSBaptiste Daroussin el_rfunc_t rc = va_arg(ap, el_rfunc_t);
322d0ef721eSBaptiste Daroussin rv = el_read_setfn(el->el_read, rc);
323d0ef721eSBaptiste Daroussin break;
324d0ef721eSBaptiste Daroussin }
325d0ef721eSBaptiste Daroussin
326d0ef721eSBaptiste Daroussin case EL_CLIENTDATA:
327d0ef721eSBaptiste Daroussin el->el_data = va_arg(ap, void *);
328d0ef721eSBaptiste Daroussin break;
329d0ef721eSBaptiste Daroussin
330d0ef721eSBaptiste Daroussin case EL_UNBUFFERED:
331d0ef721eSBaptiste Daroussin rv = va_arg(ap, int);
332d0ef721eSBaptiste Daroussin if (rv && !(el->el_flags & UNBUFFERED)) {
333d0ef721eSBaptiste Daroussin el->el_flags |= UNBUFFERED;
334d0ef721eSBaptiste Daroussin read_prepare(el);
335d0ef721eSBaptiste Daroussin } else if (!rv && (el->el_flags & UNBUFFERED)) {
336d0ef721eSBaptiste Daroussin el->el_flags &= ~UNBUFFERED;
337d0ef721eSBaptiste Daroussin read_finish(el);
338d0ef721eSBaptiste Daroussin }
339d0ef721eSBaptiste Daroussin rv = 0;
340d0ef721eSBaptiste Daroussin break;
341d0ef721eSBaptiste Daroussin
342d0ef721eSBaptiste Daroussin case EL_PREP_TERM:
343d0ef721eSBaptiste Daroussin rv = va_arg(ap, int);
344d0ef721eSBaptiste Daroussin if (rv)
345d0ef721eSBaptiste Daroussin (void) tty_rawmode(el);
346d0ef721eSBaptiste Daroussin else
347d0ef721eSBaptiste Daroussin (void) tty_cookedmode(el);
348d0ef721eSBaptiste Daroussin rv = 0;
349d0ef721eSBaptiste Daroussin break;
350d0ef721eSBaptiste Daroussin
351d0ef721eSBaptiste Daroussin case EL_SETFP:
352d0ef721eSBaptiste Daroussin {
353d0ef721eSBaptiste Daroussin FILE *fp;
354d0ef721eSBaptiste Daroussin int what;
355d0ef721eSBaptiste Daroussin
356d0ef721eSBaptiste Daroussin what = va_arg(ap, int);
357d0ef721eSBaptiste Daroussin fp = va_arg(ap, FILE *);
358d0ef721eSBaptiste Daroussin
359d0ef721eSBaptiste Daroussin rv = 0;
360d0ef721eSBaptiste Daroussin switch (what) {
361d0ef721eSBaptiste Daroussin case 0:
362d0ef721eSBaptiste Daroussin el->el_infile = fp;
363d0ef721eSBaptiste Daroussin el->el_infd = fileno(fp);
364d0ef721eSBaptiste Daroussin break;
365d0ef721eSBaptiste Daroussin case 1:
366d0ef721eSBaptiste Daroussin el->el_outfile = fp;
367d0ef721eSBaptiste Daroussin el->el_outfd = fileno(fp);
368d0ef721eSBaptiste Daroussin break;
369d0ef721eSBaptiste Daroussin case 2:
370d0ef721eSBaptiste Daroussin el->el_errfile = fp;
371d0ef721eSBaptiste Daroussin el->el_errfd = fileno(fp);
372d0ef721eSBaptiste Daroussin break;
373d0ef721eSBaptiste Daroussin default:
374d0ef721eSBaptiste Daroussin rv = -1;
375d0ef721eSBaptiste Daroussin break;
376d0ef721eSBaptiste Daroussin }
377d0ef721eSBaptiste Daroussin break;
378d0ef721eSBaptiste Daroussin }
379d0ef721eSBaptiste Daroussin
380d0ef721eSBaptiste Daroussin case EL_REFRESH:
381d0ef721eSBaptiste Daroussin re_clear_display(el);
382d0ef721eSBaptiste Daroussin re_refresh(el);
383d0ef721eSBaptiste Daroussin terminal__flush(el);
384d0ef721eSBaptiste Daroussin break;
385d0ef721eSBaptiste Daroussin
386d0ef721eSBaptiste Daroussin default:
387d0ef721eSBaptiste Daroussin rv = -1;
388d0ef721eSBaptiste Daroussin break;
389d0ef721eSBaptiste Daroussin }
390d0ef721eSBaptiste Daroussin
391d0ef721eSBaptiste Daroussin va_end(ap);
392d0ef721eSBaptiste Daroussin return rv;
393d0ef721eSBaptiste Daroussin }
394d0ef721eSBaptiste Daroussin
395d0ef721eSBaptiste Daroussin
396d0ef721eSBaptiste Daroussin /* el_get():
397d0ef721eSBaptiste Daroussin * retrieve the editline parameters
398d0ef721eSBaptiste Daroussin */
399d0ef721eSBaptiste Daroussin int
el_wget(EditLine * el,int op,...)400d0ef721eSBaptiste Daroussin el_wget(EditLine *el, int op, ...)
401d0ef721eSBaptiste Daroussin {
402d0ef721eSBaptiste Daroussin va_list ap;
403d0ef721eSBaptiste Daroussin int rv;
404d0ef721eSBaptiste Daroussin
405d0ef721eSBaptiste Daroussin if (el == NULL)
406d0ef721eSBaptiste Daroussin return -1;
407d0ef721eSBaptiste Daroussin
408d0ef721eSBaptiste Daroussin va_start(ap, op);
409d0ef721eSBaptiste Daroussin
410d0ef721eSBaptiste Daroussin switch (op) {
411d0ef721eSBaptiste Daroussin case EL_PROMPT:
412d0ef721eSBaptiste Daroussin case EL_RPROMPT: {
413d0ef721eSBaptiste Daroussin el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
414d0ef721eSBaptiste Daroussin rv = prompt_get(el, p, 0, op);
415d0ef721eSBaptiste Daroussin break;
416d0ef721eSBaptiste Daroussin }
417d0ef721eSBaptiste Daroussin case EL_PROMPT_ESC:
418d0ef721eSBaptiste Daroussin case EL_RPROMPT_ESC: {
419d0ef721eSBaptiste Daroussin el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
420d0ef721eSBaptiste Daroussin wchar_t *c = va_arg(ap, wchar_t *);
421d0ef721eSBaptiste Daroussin
422d0ef721eSBaptiste Daroussin rv = prompt_get(el, p, c, op);
423d0ef721eSBaptiste Daroussin break;
424d0ef721eSBaptiste Daroussin }
425d0ef721eSBaptiste Daroussin
426d0ef721eSBaptiste Daroussin case EL_EDITOR:
427d0ef721eSBaptiste Daroussin rv = map_get_editor(el, va_arg(ap, const wchar_t **));
428d0ef721eSBaptiste Daroussin break;
429d0ef721eSBaptiste Daroussin
430d0ef721eSBaptiste Daroussin case EL_SIGNAL:
431d0ef721eSBaptiste Daroussin *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
432d0ef721eSBaptiste Daroussin rv = 0;
433d0ef721eSBaptiste Daroussin break;
434d0ef721eSBaptiste Daroussin
435d0ef721eSBaptiste Daroussin case EL_EDITMODE:
436d0ef721eSBaptiste Daroussin *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
437d0ef721eSBaptiste Daroussin rv = 0;
438d0ef721eSBaptiste Daroussin break;
439d0ef721eSBaptiste Daroussin
44091f76417SBaptiste Daroussin case EL_SAFEREAD:
44191f76417SBaptiste Daroussin *va_arg(ap, int *) = (el->el_flags & FIXIO);
44291f76417SBaptiste Daroussin rv = 0;
44391f76417SBaptiste Daroussin break;
44491f76417SBaptiste Daroussin
445d0ef721eSBaptiste Daroussin case EL_TERMINAL:
446d0ef721eSBaptiste Daroussin terminal_get(el, va_arg(ap, const char **));
447d0ef721eSBaptiste Daroussin rv = 0;
448d0ef721eSBaptiste Daroussin break;
449d0ef721eSBaptiste Daroussin
450d0ef721eSBaptiste Daroussin case EL_GETTC:
451d0ef721eSBaptiste Daroussin {
452d0ef721eSBaptiste Daroussin static char name[] = "gettc";
453d0ef721eSBaptiste Daroussin char *argv[3];
454d0ef721eSBaptiste Daroussin argv[0] = name;
455d0ef721eSBaptiste Daroussin argv[1] = va_arg(ap, char *);
456d0ef721eSBaptiste Daroussin argv[2] = va_arg(ap, void *);
457d0ef721eSBaptiste Daroussin rv = terminal_gettc(el, 3, argv);
458d0ef721eSBaptiste Daroussin break;
459d0ef721eSBaptiste Daroussin }
460d0ef721eSBaptiste Daroussin
461d0ef721eSBaptiste Daroussin case EL_GETCFN:
462d0ef721eSBaptiste Daroussin *va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
463d0ef721eSBaptiste Daroussin rv = 0;
464d0ef721eSBaptiste Daroussin break;
465d0ef721eSBaptiste Daroussin
466d0ef721eSBaptiste Daroussin case EL_CLIENTDATA:
467d0ef721eSBaptiste Daroussin *va_arg(ap, void **) = el->el_data;
468d0ef721eSBaptiste Daroussin rv = 0;
469d0ef721eSBaptiste Daroussin break;
470d0ef721eSBaptiste Daroussin
471d0ef721eSBaptiste Daroussin case EL_UNBUFFERED:
472d0ef721eSBaptiste Daroussin *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
473d0ef721eSBaptiste Daroussin rv = 0;
474d0ef721eSBaptiste Daroussin break;
475d0ef721eSBaptiste Daroussin
476d0ef721eSBaptiste Daroussin case EL_GETFP:
477d0ef721eSBaptiste Daroussin {
478d0ef721eSBaptiste Daroussin int what;
479d0ef721eSBaptiste Daroussin FILE **fpp;
480d0ef721eSBaptiste Daroussin
481d0ef721eSBaptiste Daroussin what = va_arg(ap, int);
482d0ef721eSBaptiste Daroussin fpp = va_arg(ap, FILE **);
483d0ef721eSBaptiste Daroussin rv = 0;
484d0ef721eSBaptiste Daroussin switch (what) {
485d0ef721eSBaptiste Daroussin case 0:
486d0ef721eSBaptiste Daroussin *fpp = el->el_infile;
487d0ef721eSBaptiste Daroussin break;
488d0ef721eSBaptiste Daroussin case 1:
489d0ef721eSBaptiste Daroussin *fpp = el->el_outfile;
490d0ef721eSBaptiste Daroussin break;
491d0ef721eSBaptiste Daroussin case 2:
492d0ef721eSBaptiste Daroussin *fpp = el->el_errfile;
493d0ef721eSBaptiste Daroussin break;
494d0ef721eSBaptiste Daroussin default:
495d0ef721eSBaptiste Daroussin rv = -1;
496d0ef721eSBaptiste Daroussin break;
497d0ef721eSBaptiste Daroussin }
498d0ef721eSBaptiste Daroussin break;
499d0ef721eSBaptiste Daroussin }
500d0ef721eSBaptiste Daroussin default:
501d0ef721eSBaptiste Daroussin rv = -1;
502d0ef721eSBaptiste Daroussin break;
503d0ef721eSBaptiste Daroussin }
504d0ef721eSBaptiste Daroussin va_end(ap);
505d0ef721eSBaptiste Daroussin
506d0ef721eSBaptiste Daroussin return rv;
507d0ef721eSBaptiste Daroussin }
508d0ef721eSBaptiste Daroussin
509d0ef721eSBaptiste Daroussin
510d0ef721eSBaptiste Daroussin /* el_line():
511d0ef721eSBaptiste Daroussin * Return editing info
512d0ef721eSBaptiste Daroussin */
513d0ef721eSBaptiste Daroussin const LineInfoW *
el_wline(EditLine * el)514d0ef721eSBaptiste Daroussin el_wline(EditLine *el)
515d0ef721eSBaptiste Daroussin {
516d0ef721eSBaptiste Daroussin
517d0ef721eSBaptiste Daroussin return (const LineInfoW *)(void *)&el->el_line;
518d0ef721eSBaptiste Daroussin }
519d0ef721eSBaptiste Daroussin
520d0ef721eSBaptiste Daroussin
521d0ef721eSBaptiste Daroussin /* el_source():
522d0ef721eSBaptiste Daroussin * Source a file
523d0ef721eSBaptiste Daroussin */
524d0ef721eSBaptiste Daroussin int
el_source(EditLine * el,const char * fname)525d0ef721eSBaptiste Daroussin el_source(EditLine *el, const char *fname)
526d0ef721eSBaptiste Daroussin {
527d0ef721eSBaptiste Daroussin FILE *fp;
528d0ef721eSBaptiste Daroussin size_t len;
529d0ef721eSBaptiste Daroussin ssize_t slen;
530d0ef721eSBaptiste Daroussin char *ptr;
531d0ef721eSBaptiste Daroussin char *path = NULL;
532d0ef721eSBaptiste Daroussin const wchar_t *dptr;
533d0ef721eSBaptiste Daroussin int error = 0;
534d0ef721eSBaptiste Daroussin
535d0ef721eSBaptiste Daroussin fp = NULL;
536d0ef721eSBaptiste Daroussin if (fname == NULL) {
537d0ef721eSBaptiste Daroussin #ifdef HAVE_ISSETUGID
538d0ef721eSBaptiste Daroussin if (issetugid())
539d0ef721eSBaptiste Daroussin return -1;
540d0ef721eSBaptiste Daroussin
541d0ef721eSBaptiste Daroussin if ((fname = getenv("EDITRC")) == NULL) {
542d0ef721eSBaptiste Daroussin static const char elpath[] = "/.editrc";
543d0ef721eSBaptiste Daroussin size_t plen = sizeof(elpath);
544d0ef721eSBaptiste Daroussin
545d0ef721eSBaptiste Daroussin if ((ptr = getenv("HOME")) == NULL)
546d0ef721eSBaptiste Daroussin return -1;
547d0ef721eSBaptiste Daroussin plen += strlen(ptr);
548d0ef721eSBaptiste Daroussin if ((path = el_calloc(plen, sizeof(*path))) == NULL)
549d0ef721eSBaptiste Daroussin return -1;
550d0ef721eSBaptiste Daroussin (void)snprintf(path, plen, "%s%s", ptr,
551d0ef721eSBaptiste Daroussin elpath + (*ptr == '\0'));
552d0ef721eSBaptiste Daroussin fname = path;
553d0ef721eSBaptiste Daroussin }
554d0ef721eSBaptiste Daroussin #else
555d0ef721eSBaptiste Daroussin /*
556d0ef721eSBaptiste Daroussin * If issetugid() is missing, always return an error, in order
557d0ef721eSBaptiste Daroussin * to keep from inadvertently opening up the user to a security
558d0ef721eSBaptiste Daroussin * hole.
559d0ef721eSBaptiste Daroussin */
560d0ef721eSBaptiste Daroussin return -1;
561d0ef721eSBaptiste Daroussin #endif
562d0ef721eSBaptiste Daroussin }
563d0ef721eSBaptiste Daroussin if (fname[0] == '\0')
564d0ef721eSBaptiste Daroussin return -1;
565d0ef721eSBaptiste Daroussin
566d0ef721eSBaptiste Daroussin if (fp == NULL)
567d0ef721eSBaptiste Daroussin fp = fopen(fname, "r");
568d0ef721eSBaptiste Daroussin if (fp == NULL) {
569d0ef721eSBaptiste Daroussin el_free(path);
570d0ef721eSBaptiste Daroussin return -1;
571d0ef721eSBaptiste Daroussin }
572d0ef721eSBaptiste Daroussin
573d0ef721eSBaptiste Daroussin ptr = NULL;
574d0ef721eSBaptiste Daroussin len = 0;
575d0ef721eSBaptiste Daroussin while ((slen = getline(&ptr, &len, fp)) != -1) {
576d0ef721eSBaptiste Daroussin if (*ptr == '\n')
577d0ef721eSBaptiste Daroussin continue; /* Empty line. */
578d0ef721eSBaptiste Daroussin if (slen > 0 && ptr[--slen] == '\n')
579d0ef721eSBaptiste Daroussin ptr[slen] = '\0';
580d0ef721eSBaptiste Daroussin
581d0ef721eSBaptiste Daroussin dptr = ct_decode_string(ptr, &el->el_scratch);
582d0ef721eSBaptiste Daroussin if (!dptr)
583d0ef721eSBaptiste Daroussin continue;
584d0ef721eSBaptiste Daroussin /* loop until first non-space char or EOL */
585d0ef721eSBaptiste Daroussin while (*dptr != '\0' && iswspace(*dptr))
586d0ef721eSBaptiste Daroussin dptr++;
587d0ef721eSBaptiste Daroussin if (*dptr == '#')
588d0ef721eSBaptiste Daroussin continue; /* ignore, this is a comment line */
589d0ef721eSBaptiste Daroussin if ((error = parse_line(el, dptr)) == -1)
590d0ef721eSBaptiste Daroussin break;
591d0ef721eSBaptiste Daroussin }
592d0ef721eSBaptiste Daroussin free(ptr);
593d0ef721eSBaptiste Daroussin
594d0ef721eSBaptiste Daroussin el_free(path);
595d0ef721eSBaptiste Daroussin (void) fclose(fp);
596d0ef721eSBaptiste Daroussin return error;
597d0ef721eSBaptiste Daroussin }
598d0ef721eSBaptiste Daroussin
599d0ef721eSBaptiste Daroussin
600d0ef721eSBaptiste Daroussin /* el_resize():
601d0ef721eSBaptiste Daroussin * Called from program when terminal is resized
602d0ef721eSBaptiste Daroussin */
603d0ef721eSBaptiste Daroussin void
el_resize(EditLine * el)604d0ef721eSBaptiste Daroussin el_resize(EditLine *el)
605d0ef721eSBaptiste Daroussin {
606d0ef721eSBaptiste Daroussin int lins, cols;
607d0ef721eSBaptiste Daroussin sigset_t oset, nset;
608d0ef721eSBaptiste Daroussin
609d0ef721eSBaptiste Daroussin (void) sigemptyset(&nset);
610d0ef721eSBaptiste Daroussin (void) sigaddset(&nset, SIGWINCH);
611d0ef721eSBaptiste Daroussin (void) sigprocmask(SIG_BLOCK, &nset, &oset);
612d0ef721eSBaptiste Daroussin
613d0ef721eSBaptiste Daroussin /* get the correct window size */
614d0ef721eSBaptiste Daroussin if (terminal_get_size(el, &lins, &cols))
615d0ef721eSBaptiste Daroussin terminal_change_size(el, lins, cols);
616d0ef721eSBaptiste Daroussin
617d0ef721eSBaptiste Daroussin (void) sigprocmask(SIG_SETMASK, &oset, NULL);
618d0ef721eSBaptiste Daroussin }
619d0ef721eSBaptiste Daroussin
620d0ef721eSBaptiste Daroussin
621d0ef721eSBaptiste Daroussin /* el_beep():
622d0ef721eSBaptiste Daroussin * Called from the program to beep
623d0ef721eSBaptiste Daroussin */
624d0ef721eSBaptiste Daroussin void
el_beep(EditLine * el)625d0ef721eSBaptiste Daroussin el_beep(EditLine *el)
626d0ef721eSBaptiste Daroussin {
627d0ef721eSBaptiste Daroussin
628d0ef721eSBaptiste Daroussin terminal_beep(el);
629d0ef721eSBaptiste Daroussin }
630d0ef721eSBaptiste Daroussin
631d0ef721eSBaptiste Daroussin
632d0ef721eSBaptiste Daroussin /* el_editmode()
633d0ef721eSBaptiste Daroussin * Set the state of EDIT_DISABLED from the `edit' command.
634d0ef721eSBaptiste Daroussin */
635d0ef721eSBaptiste Daroussin libedit_private int
636d0ef721eSBaptiste Daroussin /*ARGSUSED*/
el_editmode(EditLine * el,int argc,const wchar_t ** argv)637d0ef721eSBaptiste Daroussin el_editmode(EditLine *el, int argc, const wchar_t **argv)
638d0ef721eSBaptiste Daroussin {
639d0ef721eSBaptiste Daroussin const wchar_t *how;
640d0ef721eSBaptiste Daroussin
641d0ef721eSBaptiste Daroussin if (argv == NULL || argc != 2 || argv[1] == NULL)
642d0ef721eSBaptiste Daroussin return -1;
643d0ef721eSBaptiste Daroussin
644d0ef721eSBaptiste Daroussin how = argv[1];
645d0ef721eSBaptiste Daroussin if (wcscmp(how, L"on") == 0) {
646d0ef721eSBaptiste Daroussin el->el_flags &= ~EDIT_DISABLED;
647d0ef721eSBaptiste Daroussin tty_rawmode(el);
648d0ef721eSBaptiste Daroussin } else if (wcscmp(how, L"off") == 0) {
649d0ef721eSBaptiste Daroussin tty_cookedmode(el);
650d0ef721eSBaptiste Daroussin el->el_flags |= EDIT_DISABLED;
651d0ef721eSBaptiste Daroussin }
652d0ef721eSBaptiste Daroussin else {
653d0ef721eSBaptiste Daroussin (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
654d0ef721eSBaptiste Daroussin how);
655d0ef721eSBaptiste Daroussin return -1;
656d0ef721eSBaptiste Daroussin }
657d0ef721eSBaptiste Daroussin return 0;
658d0ef721eSBaptiste Daroussin }
659