1*0a6a1f1dSLionel Sambuc /* $NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $ */
23e1db26aSLionel Sambuc
33e1db26aSLionel Sambuc /*-
43e1db26aSLionel Sambuc * Copyright (c) 1992, 1993
53e1db26aSLionel Sambuc * The Regents of the University of California. All rights reserved.
63e1db26aSLionel Sambuc *
73e1db26aSLionel Sambuc * This code is derived from software contributed to Berkeley by
83e1db26aSLionel Sambuc * Christos Zoulas of Cornell University.
93e1db26aSLionel Sambuc *
103e1db26aSLionel Sambuc * Redistribution and use in source and binary forms, with or without
113e1db26aSLionel Sambuc * modification, are permitted provided that the following conditions
123e1db26aSLionel Sambuc * are met:
133e1db26aSLionel Sambuc * 1. Redistributions of source code must retain the above copyright
143e1db26aSLionel Sambuc * notice, this list of conditions and the following disclaimer.
153e1db26aSLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
163e1db26aSLionel Sambuc * notice, this list of conditions and the following disclaimer in the
173e1db26aSLionel Sambuc * documentation and/or other materials provided with the distribution.
183e1db26aSLionel Sambuc * 3. Neither the name of the University nor the names of its contributors
193e1db26aSLionel Sambuc * may be used to endorse or promote products derived from this software
203e1db26aSLionel Sambuc * without specific prior written permission.
213e1db26aSLionel Sambuc *
223e1db26aSLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233e1db26aSLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243e1db26aSLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253e1db26aSLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263e1db26aSLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273e1db26aSLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283e1db26aSLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293e1db26aSLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303e1db26aSLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313e1db26aSLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323e1db26aSLionel Sambuc * SUCH DAMAGE.
333e1db26aSLionel Sambuc */
343e1db26aSLionel Sambuc
353e1db26aSLionel Sambuc #include "config.h"
363e1db26aSLionel Sambuc #if !defined(lint) && !defined(SCCSID)
373e1db26aSLionel Sambuc #if 0
383e1db26aSLionel Sambuc static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
393e1db26aSLionel Sambuc #else
40*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $");
413e1db26aSLionel Sambuc #endif
423e1db26aSLionel Sambuc #endif /* not lint && not SCCSID */
433e1db26aSLionel Sambuc
443e1db26aSLionel Sambuc /*
453e1db26aSLionel Sambuc * el.c: EditLine interface functions
463e1db26aSLionel Sambuc */
473e1db26aSLionel Sambuc #include <sys/types.h>
483e1db26aSLionel Sambuc #include <sys/param.h>
493e1db26aSLionel Sambuc #include <string.h>
503e1db26aSLionel Sambuc #include <stdlib.h>
513e1db26aSLionel Sambuc #include <stdarg.h>
523e1db26aSLionel Sambuc #include <ctype.h>
533e1db26aSLionel Sambuc #include <locale.h>
543e1db26aSLionel Sambuc #include <langinfo.h>
553e1db26aSLionel Sambuc #include "el.h"
563e1db26aSLionel Sambuc
573e1db26aSLionel Sambuc /* el_init():
583e1db26aSLionel Sambuc * Initialize editline and set default parameters.
593e1db26aSLionel Sambuc */
603e1db26aSLionel Sambuc public EditLine *
el_init(const char * prog,FILE * fin,FILE * fout,FILE * ferr)613e1db26aSLionel Sambuc el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
623e1db26aSLionel Sambuc {
6384d9c625SLionel Sambuc return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
6484d9c625SLionel Sambuc fileno(ferr));
6584d9c625SLionel Sambuc }
6684d9c625SLionel Sambuc
6784d9c625SLionel Sambuc public EditLine *
el_init_fd(const char * prog,FILE * fin,FILE * fout,FILE * ferr,int fdin,int fdout,int fderr)6884d9c625SLionel Sambuc el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
6984d9c625SLionel Sambuc int fdin, int fdout, int fderr)
7084d9c625SLionel Sambuc {
713e1db26aSLionel Sambuc EditLine *el = el_malloc(sizeof(*el));
723e1db26aSLionel Sambuc
733e1db26aSLionel Sambuc if (el == NULL)
743e1db26aSLionel Sambuc return NULL;
753e1db26aSLionel Sambuc
763e1db26aSLionel Sambuc memset(el, 0, sizeof(EditLine));
773e1db26aSLionel Sambuc
783e1db26aSLionel Sambuc el->el_infile = fin;
793e1db26aSLionel Sambuc el->el_outfile = fout;
803e1db26aSLionel Sambuc el->el_errfile = ferr;
813e1db26aSLionel Sambuc
8284d9c625SLionel Sambuc el->el_infd = fdin;
8384d9c625SLionel Sambuc el->el_outfd = fdout;
8484d9c625SLionel Sambuc el->el_errfd = fderr;
853e1db26aSLionel Sambuc
863e1db26aSLionel Sambuc el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
873e1db26aSLionel Sambuc if (el->el_prog == NULL) {
883e1db26aSLionel Sambuc el_free(el);
893e1db26aSLionel Sambuc return NULL;
903e1db26aSLionel Sambuc }
913e1db26aSLionel Sambuc
923e1db26aSLionel Sambuc /*
933e1db26aSLionel Sambuc * Initialize all the modules. Order is important!!!
943e1db26aSLionel Sambuc */
953e1db26aSLionel Sambuc el->el_flags = 0;
963e1db26aSLionel Sambuc #ifdef WIDECHAR
973e1db26aSLionel Sambuc if (setlocale(LC_CTYPE, NULL) != NULL){
983e1db26aSLionel Sambuc if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
993e1db26aSLionel Sambuc el->el_flags |= CHARSET_IS_UTF8;
1003e1db26aSLionel Sambuc }
1013e1db26aSLionel Sambuc #endif
1023e1db26aSLionel Sambuc
1033e1db26aSLionel Sambuc if (terminal_init(el) == -1) {
1043e1db26aSLionel Sambuc el_free(el->el_prog);
1053e1db26aSLionel Sambuc el_free(el);
1063e1db26aSLionel Sambuc return NULL;
1073e1db26aSLionel Sambuc }
1083e1db26aSLionel Sambuc (void) keymacro_init(el);
1093e1db26aSLionel Sambuc (void) map_init(el);
1103e1db26aSLionel Sambuc if (tty_init(el) == -1)
1113e1db26aSLionel Sambuc el->el_flags |= NO_TTY;
1123e1db26aSLionel Sambuc (void) ch_init(el);
1133e1db26aSLionel Sambuc (void) search_init(el);
1143e1db26aSLionel Sambuc (void) hist_init(el);
1153e1db26aSLionel Sambuc (void) prompt_init(el);
1163e1db26aSLionel Sambuc (void) sig_init(el);
1173e1db26aSLionel Sambuc (void) read_init(el);
1183e1db26aSLionel Sambuc
1193e1db26aSLionel Sambuc return el;
1203e1db26aSLionel Sambuc }
1213e1db26aSLionel Sambuc
1223e1db26aSLionel Sambuc
1233e1db26aSLionel Sambuc /* el_end():
1243e1db26aSLionel Sambuc * Clean up.
1253e1db26aSLionel Sambuc */
1263e1db26aSLionel Sambuc public void
el_end(EditLine * el)1273e1db26aSLionel Sambuc el_end(EditLine *el)
1283e1db26aSLionel Sambuc {
1293e1db26aSLionel Sambuc
1303e1db26aSLionel Sambuc if (el == NULL)
1313e1db26aSLionel Sambuc return;
1323e1db26aSLionel Sambuc
1333e1db26aSLionel Sambuc el_reset(el);
1343e1db26aSLionel Sambuc
1353e1db26aSLionel Sambuc terminal_end(el);
1363e1db26aSLionel Sambuc keymacro_end(el);
1373e1db26aSLionel Sambuc map_end(el);
1383e1db26aSLionel Sambuc tty_end(el);
1393e1db26aSLionel Sambuc ch_end(el);
1403e1db26aSLionel Sambuc search_end(el);
1413e1db26aSLionel Sambuc hist_end(el);
1423e1db26aSLionel Sambuc prompt_end(el);
1433e1db26aSLionel Sambuc sig_end(el);
1443e1db26aSLionel Sambuc
1453e1db26aSLionel Sambuc el_free(el->el_prog);
1463e1db26aSLionel Sambuc #ifdef WIDECHAR
1473e1db26aSLionel Sambuc el_free(el->el_scratch.cbuff);
1483e1db26aSLionel Sambuc el_free(el->el_scratch.wbuff);
1493e1db26aSLionel Sambuc el_free(el->el_lgcyconv.cbuff);
1503e1db26aSLionel Sambuc el_free(el->el_lgcyconv.wbuff);
1513e1db26aSLionel Sambuc #endif
1523e1db26aSLionel Sambuc el_free(el);
1533e1db26aSLionel Sambuc }
1543e1db26aSLionel Sambuc
1553e1db26aSLionel Sambuc
1563e1db26aSLionel Sambuc /* el_reset():
1573e1db26aSLionel Sambuc * Reset the tty and the parser
1583e1db26aSLionel Sambuc */
1593e1db26aSLionel Sambuc public void
el_reset(EditLine * el)1603e1db26aSLionel Sambuc el_reset(EditLine *el)
1613e1db26aSLionel Sambuc {
1623e1db26aSLionel Sambuc
1633e1db26aSLionel Sambuc tty_cookedmode(el);
1643e1db26aSLionel Sambuc ch_reset(el, 0); /* XXX: Do we want that? */
1653e1db26aSLionel Sambuc }
1663e1db26aSLionel Sambuc
1673e1db26aSLionel Sambuc
1683e1db26aSLionel Sambuc /* el_set():
1693e1db26aSLionel Sambuc * set the editline parameters
1703e1db26aSLionel Sambuc */
1713e1db26aSLionel Sambuc public int
FUN(el,set)1723e1db26aSLionel Sambuc FUN(el,set)(EditLine *el, int op, ...)
1733e1db26aSLionel Sambuc {
1743e1db26aSLionel Sambuc va_list ap;
1753e1db26aSLionel Sambuc int rv = 0;
1763e1db26aSLionel Sambuc
1773e1db26aSLionel Sambuc if (el == NULL)
1783e1db26aSLionel Sambuc return -1;
1793e1db26aSLionel Sambuc va_start(ap, op);
1803e1db26aSLionel Sambuc
1813e1db26aSLionel Sambuc switch (op) {
1823e1db26aSLionel Sambuc case EL_PROMPT:
1833e1db26aSLionel Sambuc case EL_RPROMPT: {
1843e1db26aSLionel Sambuc el_pfunc_t p = va_arg(ap, el_pfunc_t);
1853e1db26aSLionel Sambuc
1863e1db26aSLionel Sambuc rv = prompt_set(el, p, 0, op, 1);
1873e1db26aSLionel Sambuc break;
1883e1db26aSLionel Sambuc }
1893e1db26aSLionel Sambuc
1903e1db26aSLionel Sambuc case EL_RESIZE: {
1913e1db26aSLionel Sambuc el_zfunc_t p = va_arg(ap, el_zfunc_t);
1923e1db26aSLionel Sambuc void *arg = va_arg(ap, void *);
1933e1db26aSLionel Sambuc rv = ch_resizefun(el, p, arg);
1943e1db26aSLionel Sambuc break;
1953e1db26aSLionel Sambuc }
1963e1db26aSLionel Sambuc
197*0a6a1f1dSLionel Sambuc case EL_ALIAS_TEXT: {
198*0a6a1f1dSLionel Sambuc el_afunc_t p = va_arg(ap, el_afunc_t);
199*0a6a1f1dSLionel Sambuc void *arg = va_arg(ap, void *);
200*0a6a1f1dSLionel Sambuc rv = ch_aliasfun(el, p, arg);
201*0a6a1f1dSLionel Sambuc break;
202*0a6a1f1dSLionel Sambuc }
203*0a6a1f1dSLionel Sambuc
2043e1db26aSLionel Sambuc case EL_PROMPT_ESC:
2053e1db26aSLionel Sambuc case EL_RPROMPT_ESC: {
2063e1db26aSLionel Sambuc el_pfunc_t p = va_arg(ap, el_pfunc_t);
2073e1db26aSLionel Sambuc int c = va_arg(ap, int);
2083e1db26aSLionel Sambuc
2093e1db26aSLionel Sambuc rv = prompt_set(el, p, c, op, 1);
2103e1db26aSLionel Sambuc break;
2113e1db26aSLionel Sambuc }
2123e1db26aSLionel Sambuc
2133e1db26aSLionel Sambuc case EL_TERMINAL:
2143e1db26aSLionel Sambuc rv = terminal_set(el, va_arg(ap, char *));
2153e1db26aSLionel Sambuc break;
2163e1db26aSLionel Sambuc
2173e1db26aSLionel Sambuc case EL_EDITOR:
2183e1db26aSLionel Sambuc rv = map_set_editor(el, va_arg(ap, Char *));
2193e1db26aSLionel Sambuc break;
2203e1db26aSLionel Sambuc
2213e1db26aSLionel Sambuc case EL_SIGNAL:
2223e1db26aSLionel Sambuc if (va_arg(ap, int))
2233e1db26aSLionel Sambuc el->el_flags |= HANDLE_SIGNALS;
2243e1db26aSLionel Sambuc else
2253e1db26aSLionel Sambuc el->el_flags &= ~HANDLE_SIGNALS;
2263e1db26aSLionel Sambuc break;
2273e1db26aSLionel Sambuc
2283e1db26aSLionel Sambuc case EL_BIND:
2293e1db26aSLionel Sambuc case EL_TELLTC:
2303e1db26aSLionel Sambuc case EL_SETTC:
2313e1db26aSLionel Sambuc case EL_ECHOTC:
2323e1db26aSLionel Sambuc case EL_SETTY:
2333e1db26aSLionel Sambuc {
2343e1db26aSLionel Sambuc const Char *argv[20];
2353e1db26aSLionel Sambuc int i;
2363e1db26aSLionel Sambuc
2373e1db26aSLionel Sambuc for (i = 1; i < (int)__arraycount(argv); i++)
2383e1db26aSLionel Sambuc if ((argv[i] = va_arg(ap, Char *)) == NULL)
2393e1db26aSLionel Sambuc break;
2403e1db26aSLionel Sambuc
2413e1db26aSLionel Sambuc switch (op) {
2423e1db26aSLionel Sambuc case EL_BIND:
2433e1db26aSLionel Sambuc argv[0] = STR("bind");
2443e1db26aSLionel Sambuc rv = map_bind(el, i, argv);
2453e1db26aSLionel Sambuc break;
2463e1db26aSLionel Sambuc
2473e1db26aSLionel Sambuc case EL_TELLTC:
2483e1db26aSLionel Sambuc argv[0] = STR("telltc");
2493e1db26aSLionel Sambuc rv = terminal_telltc(el, i, argv);
2503e1db26aSLionel Sambuc break;
2513e1db26aSLionel Sambuc
2523e1db26aSLionel Sambuc case EL_SETTC:
2533e1db26aSLionel Sambuc argv[0] = STR("settc");
2543e1db26aSLionel Sambuc rv = terminal_settc(el, i, argv);
2553e1db26aSLionel Sambuc break;
2563e1db26aSLionel Sambuc
2573e1db26aSLionel Sambuc case EL_ECHOTC:
2583e1db26aSLionel Sambuc argv[0] = STR("echotc");
2593e1db26aSLionel Sambuc rv = terminal_echotc(el, i, argv);
2603e1db26aSLionel Sambuc break;
2613e1db26aSLionel Sambuc
2623e1db26aSLionel Sambuc case EL_SETTY:
2633e1db26aSLionel Sambuc argv[0] = STR("setty");
2643e1db26aSLionel Sambuc rv = tty_stty(el, i, argv);
2653e1db26aSLionel Sambuc break;
2663e1db26aSLionel Sambuc
2673e1db26aSLionel Sambuc default:
2683e1db26aSLionel Sambuc rv = -1;
2693e1db26aSLionel Sambuc EL_ABORT((el->el_errfile, "Bad op %d\n", op));
2703e1db26aSLionel Sambuc break;
2713e1db26aSLionel Sambuc }
2723e1db26aSLionel Sambuc break;
2733e1db26aSLionel Sambuc }
2743e1db26aSLionel Sambuc
2753e1db26aSLionel Sambuc case EL_ADDFN:
2763e1db26aSLionel Sambuc {
2773e1db26aSLionel Sambuc Char *name = va_arg(ap, Char *);
2783e1db26aSLionel Sambuc Char *help = va_arg(ap, Char *);
2793e1db26aSLionel Sambuc el_func_t func = va_arg(ap, el_func_t);
2803e1db26aSLionel Sambuc
2813e1db26aSLionel Sambuc rv = map_addfunc(el, name, help, func);
2823e1db26aSLionel Sambuc break;
2833e1db26aSLionel Sambuc }
2843e1db26aSLionel Sambuc
2853e1db26aSLionel Sambuc case EL_HIST:
2863e1db26aSLionel Sambuc {
2873e1db26aSLionel Sambuc hist_fun_t func = va_arg(ap, hist_fun_t);
2883e1db26aSLionel Sambuc void *ptr = va_arg(ap, void *);
2893e1db26aSLionel Sambuc
2903e1db26aSLionel Sambuc rv = hist_set(el, func, ptr);
2913e1db26aSLionel Sambuc if (!(el->el_flags & CHARSET_IS_UTF8))
2923e1db26aSLionel Sambuc el->el_flags &= ~NARROW_HISTORY;
2933e1db26aSLionel Sambuc break;
2943e1db26aSLionel Sambuc }
2953e1db26aSLionel Sambuc
2963e1db26aSLionel Sambuc case EL_EDITMODE:
2973e1db26aSLionel Sambuc if (va_arg(ap, int))
2983e1db26aSLionel Sambuc el->el_flags &= ~EDIT_DISABLED;
2993e1db26aSLionel Sambuc else
3003e1db26aSLionel Sambuc el->el_flags |= EDIT_DISABLED;
3013e1db26aSLionel Sambuc rv = 0;
3023e1db26aSLionel Sambuc break;
3033e1db26aSLionel Sambuc
3043e1db26aSLionel Sambuc case EL_GETCFN:
3053e1db26aSLionel Sambuc {
3063e1db26aSLionel Sambuc el_rfunc_t rc = va_arg(ap, el_rfunc_t);
3073e1db26aSLionel Sambuc rv = el_read_setfn(el, rc);
3083e1db26aSLionel Sambuc el->el_flags &= ~NARROW_READ;
3093e1db26aSLionel Sambuc break;
3103e1db26aSLionel Sambuc }
3113e1db26aSLionel Sambuc
3123e1db26aSLionel Sambuc case EL_CLIENTDATA:
3133e1db26aSLionel Sambuc el->el_data = va_arg(ap, void *);
3143e1db26aSLionel Sambuc break;
3153e1db26aSLionel Sambuc
3163e1db26aSLionel Sambuc case EL_UNBUFFERED:
3173e1db26aSLionel Sambuc rv = va_arg(ap, int);
3183e1db26aSLionel Sambuc if (rv && !(el->el_flags & UNBUFFERED)) {
3193e1db26aSLionel Sambuc el->el_flags |= UNBUFFERED;
3203e1db26aSLionel Sambuc read_prepare(el);
3213e1db26aSLionel Sambuc } else if (!rv && (el->el_flags & UNBUFFERED)) {
3223e1db26aSLionel Sambuc el->el_flags &= ~UNBUFFERED;
3233e1db26aSLionel Sambuc read_finish(el);
3243e1db26aSLionel Sambuc }
3253e1db26aSLionel Sambuc rv = 0;
3263e1db26aSLionel Sambuc break;
3273e1db26aSLionel Sambuc
3283e1db26aSLionel Sambuc case EL_PREP_TERM:
3293e1db26aSLionel Sambuc rv = va_arg(ap, int);
3303e1db26aSLionel Sambuc if (rv)
3313e1db26aSLionel Sambuc (void) tty_rawmode(el);
3323e1db26aSLionel Sambuc else
3333e1db26aSLionel Sambuc (void) tty_cookedmode(el);
3343e1db26aSLionel Sambuc rv = 0;
3353e1db26aSLionel Sambuc break;
3363e1db26aSLionel Sambuc
3373e1db26aSLionel Sambuc case EL_SETFP:
3383e1db26aSLionel Sambuc {
3393e1db26aSLionel Sambuc FILE *fp;
3403e1db26aSLionel Sambuc int what;
3413e1db26aSLionel Sambuc
3423e1db26aSLionel Sambuc what = va_arg(ap, int);
3433e1db26aSLionel Sambuc fp = va_arg(ap, FILE *);
3443e1db26aSLionel Sambuc
3453e1db26aSLionel Sambuc rv = 0;
3463e1db26aSLionel Sambuc switch (what) {
3473e1db26aSLionel Sambuc case 0:
3483e1db26aSLionel Sambuc el->el_infile = fp;
3493e1db26aSLionel Sambuc el->el_infd = fileno(fp);
3503e1db26aSLionel Sambuc break;
3513e1db26aSLionel Sambuc case 1:
3523e1db26aSLionel Sambuc el->el_outfile = fp;
3533e1db26aSLionel Sambuc el->el_outfd = fileno(fp);
3543e1db26aSLionel Sambuc break;
3553e1db26aSLionel Sambuc case 2:
3563e1db26aSLionel Sambuc el->el_errfile = fp;
3573e1db26aSLionel Sambuc el->el_errfd = fileno(fp);
3583e1db26aSLionel Sambuc break;
3593e1db26aSLionel Sambuc default:
3603e1db26aSLionel Sambuc rv = -1;
3613e1db26aSLionel Sambuc break;
3623e1db26aSLionel Sambuc }
3633e1db26aSLionel Sambuc break;
3643e1db26aSLionel Sambuc }
3653e1db26aSLionel Sambuc
3663e1db26aSLionel Sambuc case EL_REFRESH:
3673e1db26aSLionel Sambuc re_clear_display(el);
3683e1db26aSLionel Sambuc re_refresh(el);
3693e1db26aSLionel Sambuc terminal__flush(el);
3703e1db26aSLionel Sambuc break;
3713e1db26aSLionel Sambuc
3723e1db26aSLionel Sambuc default:
3733e1db26aSLionel Sambuc rv = -1;
3743e1db26aSLionel Sambuc break;
3753e1db26aSLionel Sambuc }
3763e1db26aSLionel Sambuc
3773e1db26aSLionel Sambuc va_end(ap);
3783e1db26aSLionel Sambuc return rv;
3793e1db26aSLionel Sambuc }
3803e1db26aSLionel Sambuc
3813e1db26aSLionel Sambuc
3823e1db26aSLionel Sambuc /* el_get():
3833e1db26aSLionel Sambuc * retrieve the editline parameters
3843e1db26aSLionel Sambuc */
3853e1db26aSLionel Sambuc public int
FUN(el,get)3863e1db26aSLionel Sambuc FUN(el,get)(EditLine *el, int op, ...)
3873e1db26aSLionel Sambuc {
3883e1db26aSLionel Sambuc va_list ap;
3893e1db26aSLionel Sambuc int rv;
3903e1db26aSLionel Sambuc
3913e1db26aSLionel Sambuc if (el == NULL)
3923e1db26aSLionel Sambuc return -1;
3933e1db26aSLionel Sambuc
3943e1db26aSLionel Sambuc va_start(ap, op);
3953e1db26aSLionel Sambuc
3963e1db26aSLionel Sambuc switch (op) {
3973e1db26aSLionel Sambuc case EL_PROMPT:
3983e1db26aSLionel Sambuc case EL_RPROMPT: {
3993e1db26aSLionel Sambuc el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
4003e1db26aSLionel Sambuc rv = prompt_get(el, p, 0, op);
4013e1db26aSLionel Sambuc break;
4023e1db26aSLionel Sambuc }
4033e1db26aSLionel Sambuc case EL_PROMPT_ESC:
4043e1db26aSLionel Sambuc case EL_RPROMPT_ESC: {
4053e1db26aSLionel Sambuc el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
4063e1db26aSLionel Sambuc Char *c = va_arg(ap, Char *);
4073e1db26aSLionel Sambuc
4083e1db26aSLionel Sambuc rv = prompt_get(el, p, c, op);
4093e1db26aSLionel Sambuc break;
4103e1db26aSLionel Sambuc }
4113e1db26aSLionel Sambuc
4123e1db26aSLionel Sambuc case EL_EDITOR:
4133e1db26aSLionel Sambuc rv = map_get_editor(el, va_arg(ap, const Char **));
4143e1db26aSLionel Sambuc break;
4153e1db26aSLionel Sambuc
4163e1db26aSLionel Sambuc case EL_SIGNAL:
4173e1db26aSLionel Sambuc *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
4183e1db26aSLionel Sambuc rv = 0;
4193e1db26aSLionel Sambuc break;
4203e1db26aSLionel Sambuc
4213e1db26aSLionel Sambuc case EL_EDITMODE:
4223e1db26aSLionel Sambuc *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
4233e1db26aSLionel Sambuc rv = 0;
4243e1db26aSLionel Sambuc break;
4253e1db26aSLionel Sambuc
4263e1db26aSLionel Sambuc case EL_TERMINAL:
4273e1db26aSLionel Sambuc terminal_get(el, va_arg(ap, const char **));
4283e1db26aSLionel Sambuc rv = 0;
4293e1db26aSLionel Sambuc break;
4303e1db26aSLionel Sambuc
4313e1db26aSLionel Sambuc case EL_GETTC:
4323e1db26aSLionel Sambuc {
4333e1db26aSLionel Sambuc static char name[] = "gettc";
4343e1db26aSLionel Sambuc char *argv[20];
4353e1db26aSLionel Sambuc int i;
4363e1db26aSLionel Sambuc
4373e1db26aSLionel Sambuc for (i = 1; i < (int)__arraycount(argv); i++)
4383e1db26aSLionel Sambuc if ((argv[i] = va_arg(ap, char *)) == NULL)
4393e1db26aSLionel Sambuc break;
4403e1db26aSLionel Sambuc
4413e1db26aSLionel Sambuc argv[0] = name;
4423e1db26aSLionel Sambuc rv = terminal_gettc(el, i, argv);
4433e1db26aSLionel Sambuc break;
4443e1db26aSLionel Sambuc }
4453e1db26aSLionel Sambuc
4463e1db26aSLionel Sambuc case EL_GETCFN:
4473e1db26aSLionel Sambuc *va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
4483e1db26aSLionel Sambuc rv = 0;
4493e1db26aSLionel Sambuc break;
4503e1db26aSLionel Sambuc
4513e1db26aSLionel Sambuc case EL_CLIENTDATA:
4523e1db26aSLionel Sambuc *va_arg(ap, void **) = el->el_data;
4533e1db26aSLionel Sambuc rv = 0;
4543e1db26aSLionel Sambuc break;
4553e1db26aSLionel Sambuc
4563e1db26aSLionel Sambuc case EL_UNBUFFERED:
4573e1db26aSLionel Sambuc *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
4583e1db26aSLionel Sambuc rv = 0;
4593e1db26aSLionel Sambuc break;
4603e1db26aSLionel Sambuc
4613e1db26aSLionel Sambuc case EL_GETFP:
4623e1db26aSLionel Sambuc {
4633e1db26aSLionel Sambuc int what;
4643e1db26aSLionel Sambuc FILE **fpp;
4653e1db26aSLionel Sambuc
4663e1db26aSLionel Sambuc what = va_arg(ap, int);
4673e1db26aSLionel Sambuc fpp = va_arg(ap, FILE **);
4683e1db26aSLionel Sambuc rv = 0;
4693e1db26aSLionel Sambuc switch (what) {
4703e1db26aSLionel Sambuc case 0:
4713e1db26aSLionel Sambuc *fpp = el->el_infile;
4723e1db26aSLionel Sambuc break;
4733e1db26aSLionel Sambuc case 1:
4743e1db26aSLionel Sambuc *fpp = el->el_outfile;
4753e1db26aSLionel Sambuc break;
4763e1db26aSLionel Sambuc case 2:
4773e1db26aSLionel Sambuc *fpp = el->el_errfile;
4783e1db26aSLionel Sambuc break;
4793e1db26aSLionel Sambuc default:
4803e1db26aSLionel Sambuc rv = -1;
4813e1db26aSLionel Sambuc break;
4823e1db26aSLionel Sambuc }
4833e1db26aSLionel Sambuc break;
4843e1db26aSLionel Sambuc }
4853e1db26aSLionel Sambuc default:
4863e1db26aSLionel Sambuc rv = -1;
4873e1db26aSLionel Sambuc break;
4883e1db26aSLionel Sambuc }
4893e1db26aSLionel Sambuc va_end(ap);
4903e1db26aSLionel Sambuc
4913e1db26aSLionel Sambuc return rv;
4923e1db26aSLionel Sambuc }
4933e1db26aSLionel Sambuc
4943e1db26aSLionel Sambuc
4953e1db26aSLionel Sambuc /* el_line():
4963e1db26aSLionel Sambuc * Return editing info
4973e1db26aSLionel Sambuc */
TYPE(LineInfo)4983e1db26aSLionel Sambuc public const TYPE(LineInfo) *
4993e1db26aSLionel Sambuc FUN(el,line)(EditLine *el)
5003e1db26aSLionel Sambuc {
5013e1db26aSLionel Sambuc
5023e1db26aSLionel Sambuc return (const TYPE(LineInfo) *)(void *)&el->el_line;
5033e1db26aSLionel Sambuc }
5043e1db26aSLionel Sambuc
5053e1db26aSLionel Sambuc
5063e1db26aSLionel Sambuc /* el_source():
5073e1db26aSLionel Sambuc * Source a file
5083e1db26aSLionel Sambuc */
5093e1db26aSLionel Sambuc public int
el_source(EditLine * el,const char * fname)5103e1db26aSLionel Sambuc el_source(EditLine *el, const char *fname)
5113e1db26aSLionel Sambuc {
5123e1db26aSLionel Sambuc FILE *fp;
5133e1db26aSLionel Sambuc size_t len;
5143e1db26aSLionel Sambuc char *ptr;
5153e1db26aSLionel Sambuc char *path = NULL;
5163e1db26aSLionel Sambuc const Char *dptr;
5173e1db26aSLionel Sambuc int error = 0;
5183e1db26aSLionel Sambuc
5193e1db26aSLionel Sambuc fp = NULL;
5203e1db26aSLionel Sambuc if (fname == NULL) {
5213e1db26aSLionel Sambuc #ifdef HAVE_ISSETUGID
5223e1db26aSLionel Sambuc static const char elpath[] = "/.editrc";
5233e1db26aSLionel Sambuc size_t plen = sizeof(elpath);
5243e1db26aSLionel Sambuc
5253e1db26aSLionel Sambuc if (issetugid())
5263e1db26aSLionel Sambuc return -1;
5273e1db26aSLionel Sambuc if ((ptr = getenv("HOME")) == NULL)
5283e1db26aSLionel Sambuc return -1;
5293e1db26aSLionel Sambuc plen += strlen(ptr);
5303e1db26aSLionel Sambuc if ((path = el_malloc(plen * sizeof(*path))) == NULL)
5313e1db26aSLionel Sambuc return -1;
5323e1db26aSLionel Sambuc (void)snprintf(path, plen, "%s%s", ptr, elpath);
5333e1db26aSLionel Sambuc fname = path;
5343e1db26aSLionel Sambuc #else
5353e1db26aSLionel Sambuc /*
5363e1db26aSLionel Sambuc * If issetugid() is missing, always return an error, in order
5373e1db26aSLionel Sambuc * to keep from inadvertently opening up the user to a security
5383e1db26aSLionel Sambuc * hole.
5393e1db26aSLionel Sambuc */
5403e1db26aSLionel Sambuc return -1;
5413e1db26aSLionel Sambuc #endif
5423e1db26aSLionel Sambuc }
5433e1db26aSLionel Sambuc if (fp == NULL)
5443e1db26aSLionel Sambuc fp = fopen(fname, "r");
5453e1db26aSLionel Sambuc if (fp == NULL) {
5463e1db26aSLionel Sambuc el_free(path);
5473e1db26aSLionel Sambuc return -1;
5483e1db26aSLionel Sambuc }
5493e1db26aSLionel Sambuc
5503e1db26aSLionel Sambuc while ((ptr = fgetln(fp, &len)) != NULL) {
5513e1db26aSLionel Sambuc if (*ptr == '\n')
5523e1db26aSLionel Sambuc continue; /* Empty line. */
5533e1db26aSLionel Sambuc dptr = ct_decode_string(ptr, &el->el_scratch);
5543e1db26aSLionel Sambuc if (!dptr)
5553e1db26aSLionel Sambuc continue;
5563e1db26aSLionel Sambuc if (len > 0 && dptr[len - 1] == '\n')
5573e1db26aSLionel Sambuc --len;
5583e1db26aSLionel Sambuc
5593e1db26aSLionel Sambuc /* loop until first non-space char or EOL */
5603e1db26aSLionel Sambuc while (*dptr != '\0' && Isspace(*dptr))
5613e1db26aSLionel Sambuc dptr++;
5623e1db26aSLionel Sambuc if (*dptr == '#')
5633e1db26aSLionel Sambuc continue; /* ignore, this is a comment line */
5643e1db26aSLionel Sambuc if ((error = parse_line(el, dptr)) == -1)
5653e1db26aSLionel Sambuc break;
5663e1db26aSLionel Sambuc }
5673e1db26aSLionel Sambuc
5683e1db26aSLionel Sambuc el_free(path);
5693e1db26aSLionel Sambuc (void) fclose(fp);
5703e1db26aSLionel Sambuc return error;
5713e1db26aSLionel Sambuc }
5723e1db26aSLionel Sambuc
5733e1db26aSLionel Sambuc
5743e1db26aSLionel Sambuc /* el_resize():
5753e1db26aSLionel Sambuc * Called from program when terminal is resized
5763e1db26aSLionel Sambuc */
5773e1db26aSLionel Sambuc public void
el_resize(EditLine * el)5783e1db26aSLionel Sambuc el_resize(EditLine *el)
5793e1db26aSLionel Sambuc {
5803e1db26aSLionel Sambuc int lins, cols;
5813e1db26aSLionel Sambuc sigset_t oset, nset;
5823e1db26aSLionel Sambuc
5833e1db26aSLionel Sambuc (void) sigemptyset(&nset);
5843e1db26aSLionel Sambuc (void) sigaddset(&nset, SIGWINCH);
5853e1db26aSLionel Sambuc (void) sigprocmask(SIG_BLOCK, &nset, &oset);
5863e1db26aSLionel Sambuc
5873e1db26aSLionel Sambuc /* get the correct window size */
5883e1db26aSLionel Sambuc if (terminal_get_size(el, &lins, &cols))
5893e1db26aSLionel Sambuc terminal_change_size(el, lins, cols);
5903e1db26aSLionel Sambuc
5913e1db26aSLionel Sambuc (void) sigprocmask(SIG_SETMASK, &oset, NULL);
5923e1db26aSLionel Sambuc }
5933e1db26aSLionel Sambuc
5943e1db26aSLionel Sambuc
5953e1db26aSLionel Sambuc /* el_beep():
5963e1db26aSLionel Sambuc * Called from the program to beep
5973e1db26aSLionel Sambuc */
5983e1db26aSLionel Sambuc public void
el_beep(EditLine * el)5993e1db26aSLionel Sambuc el_beep(EditLine *el)
6003e1db26aSLionel Sambuc {
6013e1db26aSLionel Sambuc
6023e1db26aSLionel Sambuc terminal_beep(el);
6033e1db26aSLionel Sambuc }
6043e1db26aSLionel Sambuc
6053e1db26aSLionel Sambuc
6063e1db26aSLionel Sambuc /* el_editmode()
6073e1db26aSLionel Sambuc * Set the state of EDIT_DISABLED from the `edit' command.
6083e1db26aSLionel Sambuc */
6093e1db26aSLionel Sambuc protected int
6103e1db26aSLionel Sambuc /*ARGSUSED*/
el_editmode(EditLine * el,int argc,const Char ** argv)6113e1db26aSLionel Sambuc el_editmode(EditLine *el, int argc, const Char **argv)
6123e1db26aSLionel Sambuc {
6133e1db26aSLionel Sambuc const Char *how;
6143e1db26aSLionel Sambuc
6153e1db26aSLionel Sambuc if (argv == NULL || argc != 2 || argv[1] == NULL)
6163e1db26aSLionel Sambuc return -1;
6173e1db26aSLionel Sambuc
6183e1db26aSLionel Sambuc how = argv[1];
6193e1db26aSLionel Sambuc if (Strcmp(how, STR("on")) == 0) {
6203e1db26aSLionel Sambuc el->el_flags &= ~EDIT_DISABLED;
6213e1db26aSLionel Sambuc tty_rawmode(el);
6223e1db26aSLionel Sambuc } else if (Strcmp(how, STR("off")) == 0) {
6233e1db26aSLionel Sambuc tty_cookedmode(el);
6243e1db26aSLionel Sambuc el->el_flags |= EDIT_DISABLED;
6253e1db26aSLionel Sambuc }
6263e1db26aSLionel Sambuc else {
6273e1db26aSLionel Sambuc (void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
6283e1db26aSLionel Sambuc how);
6293e1db26aSLionel Sambuc return -1;
6303e1db26aSLionel Sambuc }
6313e1db26aSLionel Sambuc return 0;
6323e1db26aSLionel Sambuc }
633