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