Home | History | Annotate | Line # | Download | only in libedit
el.c revision 1.12.2.1
      1  1.12.2.1        he /*	$NetBSD: el.c,v 1.12.2.1 2000/06/29 16:09:42 he Exp $	*/
      2       1.2     lukem 
      3       1.1       cgd /*-
      4       1.1       cgd  * Copyright (c) 1992, 1993
      5       1.1       cgd  *	The Regents of the University of California.  All rights reserved.
      6       1.1       cgd  *
      7       1.1       cgd  * This code is derived from software contributed to Berkeley by
      8       1.1       cgd  * Christos Zoulas of Cornell University.
      9       1.1       cgd  *
     10       1.1       cgd  * Redistribution and use in source and binary forms, with or without
     11       1.1       cgd  * modification, are permitted provided that the following conditions
     12       1.1       cgd  * are met:
     13       1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     14       1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     15       1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     17       1.1       cgd  *    documentation and/or other materials provided with the distribution.
     18       1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     19       1.1       cgd  *    must display the following acknowledgement:
     20       1.1       cgd  *	This product includes software developed by the University of
     21       1.1       cgd  *	California, Berkeley and its contributors.
     22       1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     23       1.1       cgd  *    may be used to endorse or promote products derived from this software
     24       1.1       cgd  *    without specific prior written permission.
     25       1.1       cgd  *
     26       1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27       1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28       1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29       1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30       1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31       1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32       1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33       1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34       1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35       1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36       1.1       cgd  * SUCH DAMAGE.
     37       1.1       cgd  */
     38       1.1       cgd 
     39       1.7  christos #include <sys/cdefs.h>
     40       1.1       cgd #if !defined(lint) && !defined(SCCSID)
     41       1.2     lukem #if 0
     42       1.1       cgd static char sccsid[] = "@(#)el.c	8.2 (Berkeley) 1/3/94";
     43       1.2     lukem #else
     44  1.12.2.1        he __RCSID("$NetBSD: el.c,v 1.12.2.1 2000/06/29 16:09:42 he Exp $");
     45       1.2     lukem #endif
     46       1.1       cgd #endif /* not lint && not SCCSID */
     47       1.1       cgd 
     48       1.1       cgd /*
     49       1.1       cgd  * el.c: EditLine interface functions
     50       1.1       cgd  */
     51       1.1       cgd #include "sys.h"
     52       1.1       cgd 
     53       1.1       cgd #include <sys/types.h>
     54       1.1       cgd #include <sys/param.h>
     55       1.1       cgd #include <string.h>
     56       1.1       cgd #include <stdlib.h>
     57       1.5  christos #ifdef __STDC__
     58       1.1       cgd # include <stdarg.h>
     59       1.1       cgd #else
     60       1.1       cgd # include <varargs.h>
     61       1.1       cgd #endif
     62       1.1       cgd #include "el.h"
     63       1.1       cgd 
     64       1.1       cgd /* el_init():
     65       1.1       cgd  *	Initialize editline and set default parameters.
     66       1.1       cgd  */
     67       1.1       cgd public EditLine *
     68       1.9  christos el_init(prog, fin, fout, ferr)
     69       1.1       cgd     const char *prog;
     70       1.9  christos     FILE *fin, *fout, *ferr;
     71       1.1       cgd {
     72       1.1       cgd     EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
     73       1.1       cgd #ifdef DEBUG
     74       1.1       cgd     char *tty;
     75       1.1       cgd #endif
     76       1.1       cgd 
     77       1.1       cgd     if (el == NULL)
     78       1.1       cgd 	return NULL;
     79       1.1       cgd 
     80       1.1       cgd     memset(el, 0, sizeof(EditLine));
     81       1.1       cgd 
     82       1.1       cgd     el->el_infd  = fileno(fin);
     83       1.1       cgd     el->el_outfile = fout;
     84       1.9  christos     el->el_errfile = ferr;
     85       1.1       cgd     el->el_prog = strdup(prog);
     86       1.1       cgd 
     87       1.1       cgd     /*
     88       1.1       cgd      * Initialize all the modules. Order is important!!!
     89       1.1       cgd      */
     90       1.8  christos     el->el_flags = 0;
     91       1.1       cgd     (void) term_init(el);
     92      1.11  christos     (void) key_init(el);
     93      1.11  christos     (void) map_init(el);
     94       1.8  christos     if (tty_init(el) == -1)
     95       1.8  christos 	el->el_flags |= NO_TTY;
     96       1.1       cgd     (void) ch_init(el);
     97       1.1       cgd     (void) search_init(el);
     98       1.1       cgd     (void) hist_init(el);
     99       1.1       cgd     (void) prompt_init(el);
    100       1.1       cgd     (void) sig_init(el);
    101       1.1       cgd 
    102       1.1       cgd     return el;
    103       1.1       cgd } /* end el_init */
    104       1.1       cgd 
    105       1.1       cgd 
    106       1.1       cgd /* el_end():
    107       1.1       cgd  *	Clean up.
    108       1.1       cgd  */
    109       1.1       cgd public void
    110       1.1       cgd el_end(el)
    111       1.1       cgd     EditLine *el;
    112       1.1       cgd {
    113       1.1       cgd     if (el == NULL)
    114       1.1       cgd 	return;
    115       1.1       cgd 
    116       1.1       cgd     el_reset(el);
    117       1.1       cgd 
    118       1.1       cgd     term_end(el);
    119       1.1       cgd     key_end(el);
    120       1.1       cgd     map_end(el);
    121      1.11  christos     tty_end(el);
    122       1.1       cgd     ch_end(el);
    123       1.1       cgd     search_end(el);
    124       1.1       cgd     hist_end(el);
    125       1.1       cgd     prompt_end(el);
    126       1.1       cgd     sig_end(el);
    127       1.1       cgd 
    128       1.1       cgd     el_free((ptr_t) el->el_prog);
    129       1.1       cgd     el_free((ptr_t) el);
    130       1.1       cgd } /* end el_end */
    131       1.1       cgd 
    132       1.1       cgd 
    133       1.1       cgd /* el_reset():
    134       1.1       cgd  *	Reset the tty and the parser
    135       1.1       cgd  */
    136       1.1       cgd public void
    137       1.1       cgd el_reset(el)
    138       1.1       cgd     EditLine *el;
    139       1.1       cgd {
    140       1.1       cgd     tty_cookedmode(el);
    141       1.1       cgd     ch_reset(el);	/* XXX: Do we want that? */
    142       1.1       cgd }
    143       1.1       cgd 
    144       1.1       cgd 
    145       1.1       cgd /* el_set():
    146       1.1       cgd  *	set the editline parameters
    147       1.1       cgd  */
    148       1.1       cgd public int
    149       1.5  christos #ifdef __STDC__
    150       1.1       cgd el_set(EditLine *el, int op, ...)
    151       1.1       cgd #else
    152       1.1       cgd el_set(va_alist)
    153       1.1       cgd     va_dcl
    154       1.1       cgd #endif
    155       1.1       cgd {
    156       1.1       cgd     va_list va;
    157       1.1       cgd     int rv;
    158       1.5  christos #ifdef __STDC__
    159       1.1       cgd     va_start(va, op);
    160       1.1       cgd #else
    161       1.1       cgd     EditLine *el;
    162       1.1       cgd     int op;
    163       1.1       cgd 
    164       1.1       cgd     va_start(va);
    165       1.1       cgd     el = va_arg(va, EditLine *);
    166       1.1       cgd     op = va_arg(va, int);
    167       1.1       cgd #endif
    168       1.1       cgd 
    169      1.10     lukem     if (el == NULL)
    170      1.10     lukem 	return -1;
    171       1.1       cgd     switch (op) {
    172       1.1       cgd     case EL_PROMPT:
    173       1.1       cgd 	rv = prompt_set(el, va_arg(va, el_pfunc_t));
    174       1.1       cgd 	break;
    175       1.1       cgd 
    176       1.1       cgd     case EL_TERMINAL:
    177       1.1       cgd 	rv = term_set(el, va_arg(va, char *));
    178       1.1       cgd 	break;
    179       1.1       cgd 
    180       1.1       cgd     case EL_EDITOR:
    181       1.1       cgd 	rv = map_set_editor(el, va_arg(va, char *));
    182       1.1       cgd 	break;
    183       1.1       cgd 
    184       1.1       cgd     case EL_SIGNAL:
    185       1.1       cgd 	if (va_arg(va, int))
    186       1.1       cgd 	    el->el_flags |= HANDLE_SIGNALS;
    187       1.1       cgd 	else
    188       1.1       cgd 	    el->el_flags &= ~HANDLE_SIGNALS;
    189       1.1       cgd 	rv = 0;
    190       1.1       cgd 	break;
    191       1.1       cgd 
    192       1.1       cgd     case EL_BIND:
    193       1.1       cgd     case EL_TELLTC:
    194       1.1       cgd     case EL_SETTC:
    195       1.1       cgd     case EL_ECHOTC:
    196       1.1       cgd     case EL_SETTY:
    197       1.1       cgd 	{
    198       1.1       cgd 	    char *argv[20];
    199       1.1       cgd 	    int i;
    200       1.1       cgd 	    for (i = 1; i < 20; i++)
    201       1.1       cgd 		if ((argv[i] = va_arg(va, char *)) == NULL)
    202       1.1       cgd 		     break;
    203       1.1       cgd 
    204       1.1       cgd 	    switch (op) {
    205       1.1       cgd 	    case EL_BIND:
    206       1.1       cgd 		argv[0] = "bind";
    207       1.1       cgd 		rv = map_bind(el, i, argv);
    208       1.1       cgd 		break;
    209       1.1       cgd 
    210       1.1       cgd 	    case EL_TELLTC:
    211       1.1       cgd 		argv[0] = "telltc";
    212       1.1       cgd 		rv = term_telltc(el, i, argv);
    213       1.1       cgd 		break;
    214       1.1       cgd 
    215       1.1       cgd 	    case EL_SETTC:
    216       1.1       cgd 		argv[0] = "settc";
    217       1.1       cgd 		rv = term_settc(el, i, argv);
    218       1.1       cgd 		break;
    219       1.1       cgd 
    220       1.1       cgd 	    case EL_ECHOTC:
    221       1.1       cgd 		argv[0] = "echotc";
    222       1.1       cgd 		rv = term_echotc(el, i, argv);
    223       1.1       cgd 		break;
    224       1.1       cgd 
    225       1.1       cgd 	    case EL_SETTY:
    226       1.1       cgd 		argv[0] = "setty";
    227       1.1       cgd 		rv = tty_stty(el, i, argv);
    228       1.1       cgd 		break;
    229       1.1       cgd 
    230       1.1       cgd 	    default:
    231       1.1       cgd 		rv = -1;
    232       1.1       cgd 		abort();
    233       1.1       cgd 		break;
    234       1.1       cgd 	    }
    235       1.1       cgd 	}
    236       1.1       cgd 	break;
    237       1.1       cgd 
    238       1.1       cgd     case EL_ADDFN:
    239       1.1       cgd 	{
    240       1.1       cgd 	    char 	*name = va_arg(va, char *);
    241       1.1       cgd 	    char 	*help = va_arg(va, char *);
    242       1.1       cgd 	    el_func_t    func = va_arg(va, el_func_t);
    243       1.1       cgd 	    rv = map_addfunc(el, name, help, func);
    244       1.1       cgd 	}
    245       1.1       cgd 	break;
    246       1.1       cgd 
    247       1.1       cgd     case EL_HIST:
    248       1.1       cgd 	{
    249       1.1       cgd 	    hist_fun_t func = va_arg(va, hist_fun_t);
    250       1.1       cgd 	    ptr_t      ptr = va_arg(va, char *);
    251       1.1       cgd 	    rv = hist_set(el, func, ptr);
    252       1.1       cgd 	}
    253       1.1       cgd 	break;
    254       1.1       cgd 
    255      1.10     lukem     case EL_EDITMODE:
    256      1.10     lukem 	if (va_arg(va, int))
    257      1.10     lukem 	    el->el_flags &= ~EDIT_DISABLED;
    258      1.10     lukem 	else
    259      1.10     lukem 	    el->el_flags |= EDIT_DISABLED;
    260      1.10     lukem 	rv = 0;
    261      1.10     lukem 	break;
    262      1.10     lukem 
    263       1.1       cgd     default:
    264       1.1       cgd 	rv = -1;
    265       1.1       cgd     }
    266       1.1       cgd 
    267       1.1       cgd     va_end(va);
    268       1.1       cgd     return rv;
    269       1.1       cgd } /* end el_set */
    270       1.1       cgd 
    271       1.1       cgd 
    272      1.10     lukem /* el_get():
    273      1.10     lukem  *	retrieve the editline parameters
    274      1.10     lukem  */
    275      1.10     lukem public int
    276      1.10     lukem el_get(el, op, ret)
    277      1.10     lukem     EditLine *el;
    278      1.10     lukem     int op;
    279      1.10     lukem     void *ret;
    280      1.10     lukem {
    281      1.10     lukem     int rv;
    282      1.10     lukem 
    283      1.10     lukem     if (el == NULL || ret == NULL)
    284      1.10     lukem 	return -1;
    285      1.10     lukem     switch (op) {
    286      1.10     lukem     case EL_PROMPT:
    287      1.10     lukem 	rv = prompt_get(el, (el_pfunc_t *)&ret);
    288      1.10     lukem 	break;
    289      1.10     lukem 
    290      1.10     lukem     case EL_EDITOR:
    291      1.10     lukem 	rv = map_get_editor(el, (const char **)&ret);
    292      1.10     lukem 	break;
    293      1.10     lukem 
    294      1.10     lukem     case EL_SIGNAL:
    295      1.10     lukem 	*((int *)ret) = (el->el_flags & HANDLE_SIGNALS);
    296      1.10     lukem 	rv = 0;
    297      1.10     lukem 	break;
    298      1.10     lukem 
    299      1.10     lukem     case EL_EDITMODE:
    300      1.10     lukem 	*((int *)ret) = (!(el->el_flags & EDIT_DISABLED));
    301      1.10     lukem 	rv = 0;
    302      1.10     lukem 	break;
    303      1.10     lukem 
    304      1.10     lukem #if 0 /*XXX*/
    305      1.10     lukem     case EL_TERMINAL:
    306      1.10     lukem 	rv = term_get(el, (const char *)&ret);
    307      1.10     lukem 	break;
    308      1.10     lukem 
    309      1.10     lukem     case EL_BIND:
    310      1.10     lukem     case EL_TELLTC:
    311      1.10     lukem     case EL_SETTC:
    312      1.10     lukem     case EL_ECHOTC:
    313      1.10     lukem     case EL_SETTY:
    314      1.10     lukem 	{
    315      1.10     lukem 	    char *argv[20];
    316      1.10     lukem 	    int i;
    317      1.10     lukem 	    for (i = 1; i < 20; i++)
    318      1.10     lukem 		if ((argv[i] = va_arg(va, char *)) == NULL)
    319      1.10     lukem 		     break;
    320      1.10     lukem 
    321      1.10     lukem 	    switch (op) {
    322      1.10     lukem 	    case EL_BIND:
    323      1.10     lukem 		argv[0] = "bind";
    324      1.10     lukem 		rv = map_bind(el, i, argv);
    325      1.10     lukem 		break;
    326      1.10     lukem 
    327      1.10     lukem 	    case EL_TELLTC:
    328      1.10     lukem 		argv[0] = "telltc";
    329      1.10     lukem 		rv = term_telltc(el, i, argv);
    330      1.10     lukem 		break;
    331      1.10     lukem 
    332      1.10     lukem 	    case EL_SETTC:
    333      1.10     lukem 		argv[0] = "settc";
    334      1.10     lukem 		rv = term_settc(el, i, argv);
    335      1.10     lukem 		break;
    336      1.10     lukem 
    337      1.10     lukem 	    case EL_ECHOTC:
    338      1.10     lukem 		argv[0] = "echotc";
    339      1.10     lukem 		rv = term_echotc(el, i, argv);
    340      1.10     lukem 		break;
    341      1.10     lukem 
    342      1.10     lukem 	    case EL_SETTY:
    343      1.10     lukem 		argv[0] = "setty";
    344      1.10     lukem 		rv = tty_stty(el, i, argv);
    345      1.10     lukem 		break;
    346      1.10     lukem 
    347      1.10     lukem 	    default:
    348      1.10     lukem 		rv = -1;
    349      1.10     lukem 		abort();
    350      1.10     lukem 		break;
    351      1.10     lukem 	    }
    352      1.10     lukem 	}
    353      1.10     lukem 	break;
    354      1.10     lukem 
    355      1.10     lukem     case EL_ADDFN:
    356      1.10     lukem 	{
    357      1.10     lukem 	    char 	*name = va_arg(va, char *);
    358      1.10     lukem 	    char 	*help = va_arg(va, char *);
    359      1.10     lukem 	    el_func_t    func = va_arg(va, el_func_t);
    360      1.10     lukem 	    rv = map_addfunc(el, name, help, func);
    361      1.10     lukem 	}
    362      1.10     lukem 	break;
    363      1.10     lukem 
    364      1.10     lukem     case EL_HIST:
    365      1.10     lukem 	{
    366      1.10     lukem 	    hist_fun_t func = va_arg(va, hist_fun_t);
    367      1.10     lukem 	    ptr_t      ptr = va_arg(va, char *);
    368      1.10     lukem 	    rv = hist_set(el, func, ptr);
    369      1.10     lukem 	}
    370      1.10     lukem 	break;
    371      1.10     lukem #endif /*XXX*/
    372      1.10     lukem 
    373      1.10     lukem     default:
    374      1.10     lukem 	rv = -1;
    375      1.10     lukem     }
    376      1.10     lukem 
    377      1.10     lukem     return rv;
    378      1.10     lukem } /* end el_get */
    379      1.10     lukem 
    380      1.10     lukem 
    381       1.1       cgd /* el_line():
    382       1.1       cgd  *	Return editing info
    383       1.1       cgd  */
    384       1.1       cgd public const LineInfo *
    385       1.1       cgd el_line(el)
    386       1.1       cgd     EditLine *el;
    387       1.1       cgd {
    388      1.12  christos     return (const LineInfo *)(void *)&el->el_line;
    389       1.1       cgd }
    390       1.1       cgd 
    391       1.1       cgd static const char elpath[] = "/.editrc";
    392       1.1       cgd 
    393       1.1       cgd /* el_source():
    394       1.1       cgd  *	Source a file
    395       1.1       cgd  */
    396       1.1       cgd public int
    397       1.1       cgd el_source(el, fname)
    398       1.1       cgd     EditLine *el;
    399       1.1       cgd     const char *fname;
    400       1.1       cgd {
    401       1.1       cgd     FILE *fp;
    402       1.1       cgd     size_t len;
    403       1.1       cgd     char *ptr, path[MAXPATHLEN];
    404       1.1       cgd 
    405       1.1       cgd     if (fname == NULL) {
    406  1.12.2.1        he 	if ((ptr = getenv("HOME")) == NULL)
    407  1.12.2.1        he 	    return -1;
    408  1.12.2.1        he 	(void)snprintf(path, sizeof(path), "%s%s", ptr, elpath);
    409  1.12.2.1        he 	fname = path;
    410       1.1       cgd     }
    411       1.1       cgd 
    412       1.1       cgd     if ((fp = fopen(fname, "r")) == NULL)
    413       1.1       cgd 	return -1;
    414       1.1       cgd 
    415       1.3     lukem     while ((ptr = fgetln(fp, &len)) != NULL) {
    416       1.6  christos 	if (ptr[len - 1] == '\n')
    417       1.6  christos 	    --len;
    418       1.6  christos 	ptr[len] = '\0';
    419       1.1       cgd 	if (parse_line(el, ptr) == -1) {
    420       1.1       cgd 	    (void) fclose(fp);
    421       1.1       cgd 	    return -1;
    422       1.1       cgd 	}
    423       1.3     lukem     }
    424       1.1       cgd 
    425       1.1       cgd     (void) fclose(fp);
    426       1.1       cgd     return 0;
    427       1.1       cgd }
    428       1.1       cgd 
    429       1.1       cgd 
    430       1.1       cgd /* el_resize():
    431       1.1       cgd  *	Called from program when terminal is resized
    432       1.1       cgd  */
    433       1.1       cgd public void
    434       1.1       cgd el_resize(el)
    435       1.1       cgd     EditLine *el;
    436       1.1       cgd {
    437       1.1       cgd     int lins, cols;
    438       1.1       cgd     sigset_t oset, nset;
    439       1.1       cgd     (void) sigemptyset(&nset);
    440       1.1       cgd     (void) sigaddset(&nset, SIGWINCH);
    441       1.1       cgd     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
    442       1.1       cgd 
    443       1.1       cgd     /* get the correct window size */
    444       1.1       cgd     if (term_get_size(el, &lins, &cols))
    445       1.1       cgd 	term_change_size(el, lins, cols);
    446       1.1       cgd 
    447       1.1       cgd     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
    448       1.9  christos }
    449       1.9  christos 
    450       1.9  christos /* el_beep():
    451       1.9  christos  *	Called from the program to beep
    452       1.9  christos  */
    453       1.9  christos public void
    454       1.9  christos el_beep(el)
    455       1.9  christos     EditLine *el;
    456       1.9  christos {
    457       1.9  christos     term_beep(el);
    458       1.1       cgd }
    459      1.10     lukem 
    460      1.10     lukem 
    461      1.10     lukem /* el_editmode()
    462      1.10     lukem  *	Set the state of EDIT_DISABLED from the `edit' command.
    463      1.10     lukem  */
    464      1.10     lukem protected int
    465      1.10     lukem /*ARGSUSED*/
    466      1.10     lukem el_editmode(el, argc, argv)
    467      1.10     lukem     EditLine *el;
    468      1.10     lukem     int argc;
    469      1.10     lukem     char **argv;
    470      1.10     lukem {
    471      1.10     lukem     const char *how;
    472      1.10     lukem 
    473      1.10     lukem     if (argv == NULL || argc != 2 || argv[1] == NULL)
    474      1.10     lukem 	return -1;
    475      1.10     lukem 
    476      1.10     lukem     how = argv[1];
    477      1.10     lukem     if (strcmp(how, "on") == 0)
    478      1.10     lukem 	    el->el_flags &= ~EDIT_DISABLED;
    479      1.10     lukem     else if (strcmp(how, "off") == 0)
    480      1.10     lukem 	    el->el_flags |= EDIT_DISABLED;
    481      1.10     lukem     else {
    482      1.10     lukem 	(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
    483      1.10     lukem 	return -1;
    484      1.10     lukem     }
    485      1.10     lukem     return 0;
    486      1.10     lukem } /* end el_editmode */
    487