1*5b133f3fSguenther /* $OpenBSD: el.c,v 1.38 2023/03/08 04:43:05 guenther Exp $ */
25f805b19Sokan /* $NetBSD: el.c,v 1.61 2011/01/27 23:11:40 christos Exp $ */
3babb851aSmillert
4df930be7Sderaadt /*-
5df930be7Sderaadt * Copyright (c) 1992, 1993
6df930be7Sderaadt * The Regents of the University of California. All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt * Christos Zoulas of Cornell University.
10df930be7Sderaadt *
11df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt * modification, are permitted provided that the following conditions
13df930be7Sderaadt * are met:
14df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt * documentation and/or other materials provided with the distribution.
196580fee3Smillert * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt * may be used to endorse or promote products derived from this software
21df930be7Sderaadt * without specific prior written permission.
22df930be7Sderaadt *
23df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt * SUCH DAMAGE.
34df930be7Sderaadt */
35df930be7Sderaadt
36d484b7d0Sotto #include "config.h"
37df930be7Sderaadt
38df930be7Sderaadt /*
39df930be7Sderaadt * el.c: EditLine interface functions
40df930be7Sderaadt */
41df930be7Sderaadt #include <sys/types.h>
42aed0ee81Snicm #include <ctype.h>
4359aed043Sschwarze #include <langinfo.h>
44aea60beeSderaadt #include <limits.h>
4559aed043Sschwarze #include <locale.h>
467ccfa089Sschwarze #include <stdarg.h>
477ccfa089Sschwarze #include <stdlib.h>
487ccfa089Sschwarze #include <string.h>
49624bc356Sschwarze
50df930be7Sderaadt #include "el.h"
515564fb94Sschwarze #include "parse.h"
5204833be7Sschwarze #include "read.h"
53df930be7Sderaadt
54df930be7Sderaadt /* el_init():
55df930be7Sderaadt * Initialize editline and set default parameters.
56df930be7Sderaadt */
57ddc81437Sschwarze EditLine *
el_init(const char * prog,FILE * fin,FILE * fout,FILE * ferr)58d484b7d0Sotto el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
59df930be7Sderaadt {
607b6df1e2Stb EditLine *el = (EditLine *) calloc(1, sizeof(EditLine));
61df930be7Sderaadt
62df930be7Sderaadt if (el == NULL)
6328d54ee8Sschwarze return NULL;
64df930be7Sderaadt
65aed0ee81Snicm el->el_infile = fin;
66df930be7Sderaadt el->el_outfile = fout;
67d484b7d0Sotto el->el_errfile = ferr;
68aed0ee81Snicm
69aed0ee81Snicm el->el_infd = fileno(fin);
705f805b19Sokan el->el_outfd = fileno(fout);
715f805b19Sokan el->el_errfd = fileno(ferr);
72aed0ee81Snicm
735c93237dSschwarze el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
74aed0ee81Snicm if (el->el_prog == NULL) {
75014b1be8Sderaadt free(el);
766e02e073Sotto return NULL;
776e02e073Sotto }
78df930be7Sderaadt
79df930be7Sderaadt /*
80df930be7Sderaadt * Initialize all the modules. Order is important!!!
81df930be7Sderaadt */
82d484b7d0Sotto el->el_flags = 0;
83aed0ee81Snicm if (setlocale(LC_CTYPE, NULL) != NULL){
84aed0ee81Snicm if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
85aed0ee81Snicm el->el_flags |= CHARSET_IS_UTF8;
86aed0ee81Snicm }
87d484b7d0Sotto
88fd40972aSschwarze if (terminal_init(el) == -1) {
89014b1be8Sderaadt free(el->el_prog);
90014b1be8Sderaadt free(el);
91d484b7d0Sotto return NULL;
92d484b7d0Sotto }
9336facb13Sschwarze (void) keymacro_init(el);
94df930be7Sderaadt (void) map_init(el);
95d484b7d0Sotto if (tty_init(el) == -1)
96d484b7d0Sotto el->el_flags |= NO_TTY;
97df930be7Sderaadt (void) ch_init(el);
98df930be7Sderaadt (void) search_init(el);
99df930be7Sderaadt (void) hist_init(el);
100df930be7Sderaadt (void) prompt_init(el);
101df930be7Sderaadt (void) sig_init(el);
10204833be7Sschwarze if (read_init(el) == -1) {
10304833be7Sschwarze el_end(el);
10404833be7Sschwarze return NULL;
10504833be7Sschwarze }
10628d54ee8Sschwarze return el;
107d484b7d0Sotto }
108df930be7Sderaadt
109df930be7Sderaadt
110df930be7Sderaadt /* el_end():
111df930be7Sderaadt * Clean up.
112df930be7Sderaadt */
113ddc81437Sschwarze void
el_end(EditLine * el)114d484b7d0Sotto el_end(EditLine *el)
115df930be7Sderaadt {
116d484b7d0Sotto
117df930be7Sderaadt if (el == NULL)
118df930be7Sderaadt return;
119df930be7Sderaadt
120df930be7Sderaadt el_reset(el);
121df930be7Sderaadt
122fd40972aSschwarze terminal_end(el);
12336facb13Sschwarze keymacro_end(el);
124df930be7Sderaadt map_end(el);
125d484b7d0Sotto tty_end(el);
126df930be7Sderaadt ch_end(el);
1275161d913Sschwarze read_end(el->el_read);
128df930be7Sderaadt search_end(el);
129df930be7Sderaadt hist_end(el);
130df930be7Sderaadt prompt_end(el);
131df930be7Sderaadt sig_end(el);
132df930be7Sderaadt
1337b85e16bSschwarze free(el->el_prog);
1347b85e16bSschwarze free(el->el_scratch.cbuff);
1357b85e16bSschwarze free(el->el_scratch.wbuff);
1367b85e16bSschwarze free(el->el_lgcyconv.cbuff);
1377b85e16bSschwarze free(el->el_lgcyconv.wbuff);
1387b85e16bSschwarze free(el);
139d484b7d0Sotto }
140df930be7Sderaadt
141df930be7Sderaadt
142df930be7Sderaadt /* el_reset():
143df930be7Sderaadt * Reset the tty and the parser
144df930be7Sderaadt */
145ddc81437Sschwarze void
el_reset(EditLine * el)146d484b7d0Sotto el_reset(EditLine *el)
147df930be7Sderaadt {
148d484b7d0Sotto
149df930be7Sderaadt tty_cookedmode(el);
1505161d913Sschwarze ch_reset(el); /* XXX: Do we want that? */
151df930be7Sderaadt }
152df930be7Sderaadt
153df930be7Sderaadt
154df930be7Sderaadt /* el_set():
155df930be7Sderaadt * set the editline parameters
156df930be7Sderaadt */
157ddc81437Sschwarze int
el_wset(EditLine * el,int op,...)1585c93237dSschwarze el_wset(EditLine *el, int op, ...)
159df930be7Sderaadt {
160aed0ee81Snicm va_list ap;
161d484b7d0Sotto int rv = 0;
162df930be7Sderaadt
163d484b7d0Sotto if (el == NULL)
16428d54ee8Sschwarze return -1;
165aed0ee81Snicm va_start(ap, op);
166df930be7Sderaadt
167df930be7Sderaadt switch (op) {
168df930be7Sderaadt case EL_PROMPT:
169aed0ee81Snicm case EL_RPROMPT: {
170aed0ee81Snicm el_pfunc_t p = va_arg(ap, el_pfunc_t);
171aed0ee81Snicm
172aed0ee81Snicm rv = prompt_set(el, p, 0, op, 1);
173df930be7Sderaadt break;
174aed0ee81Snicm }
175aed0ee81Snicm
1765f805b19Sokan case EL_RESIZE: {
1775f805b19Sokan el_zfunc_t p = va_arg(ap, el_zfunc_t);
1785f805b19Sokan void *arg = va_arg(ap, void *);
1795f805b19Sokan rv = ch_resizefun(el, p, arg);
1805f805b19Sokan break;
1815f805b19Sokan }
1825f805b19Sokan
183aed0ee81Snicm case EL_PROMPT_ESC:
184aed0ee81Snicm case EL_RPROMPT_ESC: {
185aed0ee81Snicm el_pfunc_t p = va_arg(ap, el_pfunc_t);
186aed0ee81Snicm int c = va_arg(ap, int);
187aed0ee81Snicm
188aed0ee81Snicm rv = prompt_set(el, p, c, op, 1);
189aed0ee81Snicm break;
190aed0ee81Snicm }
191df930be7Sderaadt
192df930be7Sderaadt case EL_TERMINAL:
193fd40972aSschwarze rv = terminal_set(el, va_arg(ap, char *));
194df930be7Sderaadt break;
195df930be7Sderaadt
196df930be7Sderaadt case EL_EDITOR:
197e3191321Sschwarze rv = map_set_editor(el, va_arg(ap, wchar_t *));
198df930be7Sderaadt break;
199df930be7Sderaadt
200df930be7Sderaadt case EL_SIGNAL:
201aed0ee81Snicm if (va_arg(ap, int))
202df930be7Sderaadt el->el_flags |= HANDLE_SIGNALS;
203df930be7Sderaadt else
204df930be7Sderaadt el->el_flags &= ~HANDLE_SIGNALS;
205df930be7Sderaadt break;
206df930be7Sderaadt
207df930be7Sderaadt case EL_BIND:
208df930be7Sderaadt case EL_TELLTC:
209df930be7Sderaadt case EL_SETTC:
210df930be7Sderaadt case EL_ECHOTC:
211df930be7Sderaadt case EL_SETTY:
212df930be7Sderaadt {
213e3191321Sschwarze const wchar_t *argv[20];
214df930be7Sderaadt int i;
215d484b7d0Sotto
216df930be7Sderaadt for (i = 1; i < 20; i++)
217e3191321Sschwarze if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)
218df930be7Sderaadt break;
219df930be7Sderaadt
220df930be7Sderaadt switch (op) {
221df930be7Sderaadt case EL_BIND:
2225c93237dSschwarze argv[0] = L"bind";
223df930be7Sderaadt rv = map_bind(el, i, argv);
224df930be7Sderaadt break;
225df930be7Sderaadt
226df930be7Sderaadt case EL_TELLTC:
2275c93237dSschwarze argv[0] = L"telltc";
228fd40972aSschwarze rv = terminal_telltc(el, i, argv);
229df930be7Sderaadt break;
230df930be7Sderaadt
231df930be7Sderaadt case EL_SETTC:
2325c93237dSschwarze argv[0] = L"settc";
233fd40972aSschwarze rv = terminal_settc(el, i, argv);
234df930be7Sderaadt break;
235df930be7Sderaadt
236df930be7Sderaadt case EL_ECHOTC:
2375c93237dSschwarze argv[0] = L"echotc";
238fd40972aSschwarze rv = terminal_echotc(el, i, argv);
239df930be7Sderaadt break;
240df930be7Sderaadt
241df930be7Sderaadt case EL_SETTY:
2425c93237dSschwarze argv[0] = L"setty";
243df930be7Sderaadt rv = tty_stty(el, i, argv);
244df930be7Sderaadt break;
245df930be7Sderaadt
246df930be7Sderaadt default:
247df930be7Sderaadt rv = -1;
248d484b7d0Sotto EL_ABORT((el->el_errfile, "Bad op %d\n", op));
249df930be7Sderaadt break;
250df930be7Sderaadt }
251df930be7Sderaadt break;
252d484b7d0Sotto }
253df930be7Sderaadt
254df930be7Sderaadt case EL_ADDFN:
255df930be7Sderaadt {
256e3191321Sschwarze wchar_t *name = va_arg(ap, wchar_t *);
257e3191321Sschwarze wchar_t *help = va_arg(ap, wchar_t *);
258aed0ee81Snicm el_func_t func = va_arg(ap, el_func_t);
259d484b7d0Sotto
260df930be7Sderaadt rv = map_addfunc(el, name, help, func);
261d484b7d0Sotto break;
262d484b7d0Sotto }
263d484b7d0Sotto
264d484b7d0Sotto case EL_HIST:
265d484b7d0Sotto {
266aed0ee81Snicm hist_fun_t func = va_arg(ap, hist_fun_t);
2677b85e16bSschwarze void *ptr = va_arg(ap, void *);
268d484b7d0Sotto
269d484b7d0Sotto rv = hist_set(el, func, ptr);
270aed0ee81Snicm if (!(el->el_flags & CHARSET_IS_UTF8))
271aed0ee81Snicm el->el_flags &= ~NARROW_HISTORY;
272d484b7d0Sotto break;
273d484b7d0Sotto }
274d484b7d0Sotto
275d484b7d0Sotto case EL_EDITMODE:
276aed0ee81Snicm if (va_arg(ap, int))
277d484b7d0Sotto el->el_flags &= ~EDIT_DISABLED;
278d484b7d0Sotto else
279d484b7d0Sotto el->el_flags |= EDIT_DISABLED;
280d484b7d0Sotto rv = 0;
281d484b7d0Sotto break;
282d484b7d0Sotto
283d484b7d0Sotto case EL_GETCFN:
284d484b7d0Sotto {
285aed0ee81Snicm el_rfunc_t rc = va_arg(ap, el_rfunc_t);
28604833be7Sschwarze rv = el_read_setfn(el->el_read, rc);
287d484b7d0Sotto break;
288d484b7d0Sotto }
289d484b7d0Sotto
290d484b7d0Sotto case EL_CLIENTDATA:
291aed0ee81Snicm el->el_data = va_arg(ap, void *);
292d484b7d0Sotto break;
293d484b7d0Sotto
294d484b7d0Sotto case EL_UNBUFFERED:
295aed0ee81Snicm rv = va_arg(ap, int);
296d484b7d0Sotto if (rv && !(el->el_flags & UNBUFFERED)) {
297d484b7d0Sotto el->el_flags |= UNBUFFERED;
298d484b7d0Sotto read_prepare(el);
299d484b7d0Sotto } else if (!rv && (el->el_flags & UNBUFFERED)) {
300d484b7d0Sotto el->el_flags &= ~UNBUFFERED;
301d484b7d0Sotto read_finish(el);
302d484b7d0Sotto }
303d484b7d0Sotto rv = 0;
304d484b7d0Sotto break;
305d484b7d0Sotto
3066e02e073Sotto case EL_PREP_TERM:
307aed0ee81Snicm rv = va_arg(ap, int);
3086e02e073Sotto if (rv)
309aed0ee81Snicm (void) tty_rawmode(el);
3106e02e073Sotto else
311aed0ee81Snicm (void) tty_cookedmode(el);
3126e02e073Sotto rv = 0;
3136e02e073Sotto break;
3146e02e073Sotto
315aed0ee81Snicm case EL_SETFP:
316aed0ee81Snicm {
317aed0ee81Snicm FILE *fp;
318aed0ee81Snicm int what;
319aed0ee81Snicm
320aed0ee81Snicm what = va_arg(ap, int);
321aed0ee81Snicm fp = va_arg(ap, FILE *);
322aed0ee81Snicm
323aed0ee81Snicm rv = 0;
324aed0ee81Snicm switch (what) {
325aed0ee81Snicm case 0:
326aed0ee81Snicm el->el_infile = fp;
327aed0ee81Snicm el->el_infd = fileno(fp);
328aed0ee81Snicm break;
329aed0ee81Snicm case 1:
330aed0ee81Snicm el->el_outfile = fp;
3315f805b19Sokan el->el_outfd = fileno(fp);
332aed0ee81Snicm break;
333aed0ee81Snicm case 2:
334aed0ee81Snicm el->el_errfile = fp;
3355f805b19Sokan el->el_errfd = fileno(fp);
336aed0ee81Snicm break;
337aed0ee81Snicm default:
338aed0ee81Snicm rv = -1;
339aed0ee81Snicm break;
340aed0ee81Snicm }
341aed0ee81Snicm break;
342aed0ee81Snicm }
343aed0ee81Snicm
344aed0ee81Snicm case EL_REFRESH:
345aed0ee81Snicm re_clear_display(el);
346aed0ee81Snicm re_refresh(el);
347fd40972aSschwarze terminal__flush(el);
348aed0ee81Snicm break;
349aed0ee81Snicm
350d484b7d0Sotto default:
351d484b7d0Sotto rv = -1;
352d484b7d0Sotto break;
353d484b7d0Sotto }
354d484b7d0Sotto
355aed0ee81Snicm va_end(ap);
35628d54ee8Sschwarze return rv;
357d484b7d0Sotto }
358d484b7d0Sotto
359d484b7d0Sotto
360d484b7d0Sotto /* el_get():
361d484b7d0Sotto * retrieve the editline parameters
362d484b7d0Sotto */
363ddc81437Sschwarze int
el_wget(EditLine * el,int op,...)3645c93237dSschwarze el_wget(EditLine *el, int op, ...)
365d484b7d0Sotto {
366aed0ee81Snicm va_list ap;
367d484b7d0Sotto int rv;
368d484b7d0Sotto
369aed0ee81Snicm if (el == NULL)
370aed0ee81Snicm return -1;
371aed0ee81Snicm
372aed0ee81Snicm va_start(ap, op);
373aed0ee81Snicm
374d484b7d0Sotto switch (op) {
375d484b7d0Sotto case EL_PROMPT:
376aed0ee81Snicm case EL_RPROMPT: {
377aed0ee81Snicm el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
378aed0ee81Snicm rv = prompt_get(el, p, 0, op);
379d484b7d0Sotto break;
380aed0ee81Snicm }
381aed0ee81Snicm case EL_PROMPT_ESC:
382aed0ee81Snicm case EL_RPROMPT_ESC: {
383aed0ee81Snicm el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
384e3191321Sschwarze wchar_t *c = va_arg(ap, wchar_t *);
385aed0ee81Snicm
386aed0ee81Snicm rv = prompt_get(el, p, c, op);
387aed0ee81Snicm break;
388aed0ee81Snicm }
389d484b7d0Sotto
390d484b7d0Sotto case EL_EDITOR:
391e3191321Sschwarze rv = map_get_editor(el, va_arg(ap, const wchar_t **));
392d484b7d0Sotto break;
393d484b7d0Sotto
394d484b7d0Sotto case EL_SIGNAL:
395aed0ee81Snicm *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
396d484b7d0Sotto rv = 0;
397d484b7d0Sotto break;
398d484b7d0Sotto
399d484b7d0Sotto case EL_EDITMODE:
400aed0ee81Snicm *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
401d484b7d0Sotto rv = 0;
402d484b7d0Sotto break;
403d484b7d0Sotto
404d484b7d0Sotto case EL_TERMINAL:
405fd40972aSschwarze terminal_get(el, va_arg(ap, const char **));
406d484b7d0Sotto rv = 0;
407d484b7d0Sotto break;
408d484b7d0Sotto
409aed0ee81Snicm case EL_GETTC:
410d484b7d0Sotto {
411aed0ee81Snicm static char name[] = "gettc";
412aed0ee81Snicm char *argv[20];
413d484b7d0Sotto int i;
414d484b7d0Sotto
415aed0ee81Snicm for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
416aed0ee81Snicm if ((argv[i] = va_arg(ap, char *)) == NULL)
417d484b7d0Sotto break;
418d484b7d0Sotto
419d484b7d0Sotto switch (op) {
420aed0ee81Snicm case EL_GETTC:
421aed0ee81Snicm argv[0] = name;
422fd40972aSschwarze rv = terminal_gettc(el, i, argv);
423d484b7d0Sotto break;
424d484b7d0Sotto
425d484b7d0Sotto default:
426d484b7d0Sotto rv = -1;
427aed0ee81Snicm EL_ABORT((el->el_errfile, "Bad op %d\n", op));
428d484b7d0Sotto break;
429df930be7Sderaadt }
430df930be7Sderaadt break;
431d484b7d0Sotto }
432d484b7d0Sotto
433d484b7d0Sotto case EL_GETCFN:
43404833be7Sschwarze *va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
435d484b7d0Sotto rv = 0;
436d484b7d0Sotto break;
437d484b7d0Sotto
438d484b7d0Sotto case EL_CLIENTDATA:
439aed0ee81Snicm *va_arg(ap, void **) = el->el_data;
440d484b7d0Sotto rv = 0;
441d484b7d0Sotto break;
442d484b7d0Sotto
443d484b7d0Sotto case EL_UNBUFFERED:
444aed0ee81Snicm *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
445d484b7d0Sotto rv = 0;
446d484b7d0Sotto break;
447df930be7Sderaadt
448aed0ee81Snicm case EL_GETFP:
449aed0ee81Snicm {
450aed0ee81Snicm int what;
451aed0ee81Snicm FILE **fpp;
452aed0ee81Snicm
453aed0ee81Snicm what = va_arg(ap, int);
454aed0ee81Snicm fpp = va_arg(ap, FILE **);
455aed0ee81Snicm rv = 0;
456aed0ee81Snicm switch (what) {
457aed0ee81Snicm case 0:
458aed0ee81Snicm *fpp = el->el_infile;
459aed0ee81Snicm break;
460aed0ee81Snicm case 1:
461aed0ee81Snicm *fpp = el->el_outfile;
462aed0ee81Snicm break;
463aed0ee81Snicm case 2:
464aed0ee81Snicm *fpp = el->el_errfile;
465aed0ee81Snicm break;
466df930be7Sderaadt default:
467df930be7Sderaadt rv = -1;
468aed0ee81Snicm break;
469df930be7Sderaadt }
470aed0ee81Snicm break;
471aed0ee81Snicm }
472aed0ee81Snicm default:
473aed0ee81Snicm rv = -1;
474aed0ee81Snicm break;
475aed0ee81Snicm }
476aed0ee81Snicm va_end(ap);
477df930be7Sderaadt
47828d54ee8Sschwarze return rv;
479d484b7d0Sotto }
480df930be7Sderaadt
481df930be7Sderaadt
482df930be7Sderaadt /* el_line():
483df930be7Sderaadt * Return editing info
484df930be7Sderaadt */
485ddc81437Sschwarze const LineInfoW *
el_wline(EditLine * el)4865c93237dSschwarze el_wline(EditLine *el)
487df930be7Sderaadt {
488d484b7d0Sotto
4895c93237dSschwarze return (const LineInfoW *)(void *)&el->el_line;
490df930be7Sderaadt }
491df930be7Sderaadt
492df930be7Sderaadt
493df930be7Sderaadt /* el_source():
494df930be7Sderaadt * Source a file
495df930be7Sderaadt */
496ddc81437Sschwarze int
el_source(EditLine * el,const char * fname)497d484b7d0Sotto el_source(EditLine *el, const char *fname)
498df930be7Sderaadt {
499df930be7Sderaadt FILE *fp;
500df930be7Sderaadt size_t len;
501f3a50c9eSschwarze ssize_t slen;
502f3a50c9eSschwarze char *ptr;
503aed0ee81Snicm #ifdef HAVE_ISSETUGID
504aea60beeSderaadt char path[PATH_MAX];
505aed0ee81Snicm #endif
506e3191321Sschwarze const wchar_t *dptr;
507df930be7Sderaadt
508d484b7d0Sotto fp = NULL;
509df930be7Sderaadt if (fname == NULL) {
510d484b7d0Sotto #ifdef HAVE_ISSETUGID
511d484b7d0Sotto static const char elpath[] = "/.editrc";
512df930be7Sderaadt
513d484b7d0Sotto if (issetugid())
51428d54ee8Sschwarze return -1;
515d484b7d0Sotto if ((ptr = getenv("HOME")) == NULL)
51628d54ee8Sschwarze return -1;
517d484b7d0Sotto if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
51828d54ee8Sschwarze return -1;
519d484b7d0Sotto if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
52028d54ee8Sschwarze return -1;
521d484b7d0Sotto fname = path;
522d484b7d0Sotto #else
523d484b7d0Sotto /*
524d484b7d0Sotto * If issetugid() is missing, always return an error, in order
525d484b7d0Sotto * to keep from inadvertently opening up the user to a security
526d484b7d0Sotto * hole.
527d484b7d0Sotto */
52828d54ee8Sschwarze return -1;
529d484b7d0Sotto #endif
530d484b7d0Sotto }
531d484b7d0Sotto if (fp == NULL)
532d484b7d0Sotto fp = fopen(fname, "r");
533d484b7d0Sotto if (fp == NULL)
53428d54ee8Sschwarze return -1;
535df930be7Sderaadt
536f3a50c9eSschwarze ptr = NULL;
537f3a50c9eSschwarze len = 0;
538f3a50c9eSschwarze while ((slen = getline(&ptr, &len, fp)) != -1) {
539f3a50c9eSschwarze if (*ptr == '\n')
540f3a50c9eSschwarze continue; /* Empty line. */
541f3a50c9eSschwarze if (slen > 0 && ptr[--slen] == '\n')
542f3a50c9eSschwarze ptr[slen] = '\0';
543b51eafdaSotto
544aed0ee81Snicm dptr = ct_decode_string(ptr, &el->el_scratch);
545aed0ee81Snicm if (!dptr)
546aed0ee81Snicm continue;
547aed0ee81Snicm /* loop until first non-space char or EOL */
548565aa7e8Sschwarze while (*dptr != '\0' && iswspace(*dptr))
549aed0ee81Snicm dptr++;
550aed0ee81Snicm if (*dptr == '#')
551aed0ee81Snicm continue; /* ignore, this is a comment line */
552aed0ee81Snicm if (parse_line(el, dptr) == -1) {
553f3a50c9eSschwarze free(ptr);
554df930be7Sderaadt (void) fclose(fp);
55528d54ee8Sschwarze return -1;
556df930be7Sderaadt }
557f840f2e0Smillert }
558f3a50c9eSschwarze free(ptr);
559df930be7Sderaadt (void) fclose(fp);
56028d54ee8Sschwarze return 0;
561df930be7Sderaadt }
562df930be7Sderaadt
563df930be7Sderaadt
564df930be7Sderaadt /* el_resize():
565df930be7Sderaadt * Called from program when terminal is resized
566df930be7Sderaadt */
567ddc81437Sschwarze void
el_resize(EditLine * el)568d484b7d0Sotto el_resize(EditLine *el)
569df930be7Sderaadt {
570df930be7Sderaadt int lins, cols;
571df930be7Sderaadt sigset_t oset, nset;
572d484b7d0Sotto
573df930be7Sderaadt (void) sigemptyset(&nset);
574df930be7Sderaadt (void) sigaddset(&nset, SIGWINCH);
575df930be7Sderaadt (void) sigprocmask(SIG_BLOCK, &nset, &oset);
576df930be7Sderaadt
577df930be7Sderaadt /* get the correct window size */
578fd40972aSschwarze if (terminal_get_size(el, &lins, &cols))
579fd40972aSschwarze terminal_change_size(el, lins, cols);
580df930be7Sderaadt
581df930be7Sderaadt (void) sigprocmask(SIG_SETMASK, &oset, NULL);
582df930be7Sderaadt }
583d484b7d0Sotto
584d484b7d0Sotto
585d484b7d0Sotto /* el_beep():
586d484b7d0Sotto * Called from the program to beep
587d484b7d0Sotto */
588ddc81437Sschwarze void
el_beep(EditLine * el)589d484b7d0Sotto el_beep(EditLine *el)
590d484b7d0Sotto {
591d484b7d0Sotto
592fd40972aSschwarze terminal_beep(el);
593d484b7d0Sotto }
594d484b7d0Sotto
595d484b7d0Sotto
596d484b7d0Sotto /* el_editmode()
597d484b7d0Sotto * Set the state of EDIT_DISABLED from the `edit' command.
598d484b7d0Sotto */
599d484b7d0Sotto protected int
el_editmode(EditLine * el,int argc,const wchar_t ** argv)600e3191321Sschwarze el_editmode(EditLine *el, int argc, const wchar_t **argv)
601d484b7d0Sotto {
602e3191321Sschwarze const wchar_t *how;
603d484b7d0Sotto
604d484b7d0Sotto if (argv == NULL || argc != 2 || argv[1] == NULL)
60528d54ee8Sschwarze return -1;
606d484b7d0Sotto
607d484b7d0Sotto how = argv[1];
6085c93237dSschwarze if (wcscmp(how, L"on") == 0) {
609d484b7d0Sotto el->el_flags &= ~EDIT_DISABLED;
610aed0ee81Snicm tty_rawmode(el);
6115c93237dSschwarze } else if (wcscmp(how, L"off") == 0) {
612aed0ee81Snicm tty_cookedmode(el);
613d484b7d0Sotto el->el_flags |= EDIT_DISABLED;
614aed0ee81Snicm }
615d484b7d0Sotto else {
616565aa7e8Sschwarze (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
617aed0ee81Snicm how);
61828d54ee8Sschwarze return -1;
619d484b7d0Sotto }
62028d54ee8Sschwarze return 0;
621d484b7d0Sotto }
622