Home | History | Annotate | Line # | Download | only in libedit
el.c revision 1.7
      1 /*	$NetBSD: el.c,v 1.7 1997/07/06 18:25:24 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1992, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Christos Zoulas of Cornell University.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the University of
     21  *	California, Berkeley and its contributors.
     22  * 4. Neither the name of the University nor the names of its contributors
     23  *    may be used to endorse or promote products derived from this software
     24  *    without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36  * SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 #if !defined(lint) && !defined(SCCSID)
     41 #if 0
     42 static char sccsid[] = "@(#)el.c	8.2 (Berkeley) 1/3/94";
     43 #else
     44 __RCSID("$NetBSD: el.c,v 1.7 1997/07/06 18:25:24 christos Exp $");
     45 #endif
     46 #endif /* not lint && not SCCSID */
     47 
     48 /*
     49  * el.c: EditLine interface functions
     50  */
     51 #include "sys.h"
     52 
     53 #include <sys/types.h>
     54 #include <sys/param.h>
     55 #include <string.h>
     56 #include <stdlib.h>
     57 #ifdef __STDC__
     58 # include <stdarg.h>
     59 #else
     60 # include <varargs.h>
     61 #endif
     62 #include "el.h"
     63 
     64 /* el_init():
     65  *	Initialize editline and set default parameters.
     66  */
     67 public EditLine *
     68 el_init(prog, fin, fout)
     69     const char *prog;
     70     FILE *fin, *fout;
     71 {
     72     EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
     73 #ifdef DEBUG
     74     char *tty;
     75 #endif
     76 
     77     if (el == NULL)
     78 	return NULL;
     79 
     80     memset(el, 0, sizeof(EditLine));
     81 
     82     el->el_infd  = fileno(fin);
     83     el->el_outfile = fout;
     84     el->el_prog = strdup(prog);
     85 
     86 #ifdef DEBUG
     87     if ((tty = getenv("DEBUGTTY")) != NULL) {
     88 	el->el_errfile = fopen(tty, "w");
     89 	if (el->el_errfile == NULL) {
     90 		extern errno;
     91 		(void) fprintf(stderr, "Cannot open %s (%s).\n",
     92 			       tty, strerror(errno));
     93 		return NULL;
     94 	}
     95     }
     96     else
     97 #endif
     98 	el->el_errfile = stderr;
     99 
    100     /*
    101      * Initialize all the modules. Order is important!!!
    102      */
    103     (void) term_init(el);
    104     (void) tty_init(el);
    105     (void) key_init(el);
    106     (void) map_init(el);
    107     (void) ch_init(el);
    108     (void) search_init(el);
    109     (void) hist_init(el);
    110     (void) prompt_init(el);
    111     (void) sig_init(el);
    112     el->el_flags = 0;
    113 
    114     return el;
    115 } /* end el_init */
    116 
    117 
    118 /* el_end():
    119  *	Clean up.
    120  */
    121 public void
    122 el_end(el)
    123     EditLine *el;
    124 {
    125     if (el == NULL)
    126 	return;
    127 
    128     el_reset(el);
    129 
    130     term_end(el);
    131     tty_end(el);
    132     key_end(el);
    133     map_end(el);
    134     ch_end(el);
    135     search_end(el);
    136     hist_end(el);
    137     prompt_end(el);
    138     sig_end(el);
    139 
    140     el_free((ptr_t) el->el_prog);
    141     el_free((ptr_t) el);
    142 } /* end el_end */
    143 
    144 
    145 /* el_reset():
    146  *	Reset the tty and the parser
    147  */
    148 public void
    149 el_reset(el)
    150     EditLine *el;
    151 {
    152     tty_cookedmode(el);
    153     ch_reset(el);	/* XXX: Do we want that? */
    154 }
    155 
    156 
    157 /* el_set():
    158  *	set the editline parameters
    159  */
    160 public int
    161 #ifdef __STDC__
    162 el_set(EditLine *el, int op, ...)
    163 #else
    164 el_set(va_alist)
    165     va_dcl
    166 #endif
    167 {
    168     va_list va;
    169     int rv;
    170 #ifdef __STDC__
    171     va_start(va, op);
    172 #else
    173     EditLine *el;
    174     int op;
    175 
    176     va_start(va);
    177     el = va_arg(va, EditLine *);
    178     op = va_arg(va, int);
    179 #endif
    180 
    181     switch (op) {
    182     case EL_PROMPT:
    183 	rv = prompt_set(el, va_arg(va, el_pfunc_t));
    184 	break;
    185 
    186     case EL_TERMINAL:
    187 	rv = term_set(el, va_arg(va, char *));
    188 	break;
    189 
    190     case EL_EDITOR:
    191 	rv = map_set_editor(el, va_arg(va, char *));
    192 	break;
    193 
    194     case EL_SIGNAL:
    195 	if (va_arg(va, int))
    196 	    el->el_flags |= HANDLE_SIGNALS;
    197 	else
    198 	    el->el_flags &= ~HANDLE_SIGNALS;
    199 	rv = 0;
    200 	break;
    201 
    202     case EL_BIND:
    203     case EL_TELLTC:
    204     case EL_SETTC:
    205     case EL_ECHOTC:
    206     case EL_SETTY:
    207 	{
    208 	    char *argv[20];
    209 	    int i;
    210 	    for (i = 1; i < 20; i++)
    211 		if ((argv[i] = va_arg(va, char *)) == NULL)
    212 		     break;
    213 
    214 	    switch (op) {
    215 	    case EL_BIND:
    216 		argv[0] = "bind";
    217 		rv = map_bind(el, i, argv);
    218 		break;
    219 
    220 	    case EL_TELLTC:
    221 		argv[0] = "telltc";
    222 		rv = term_telltc(el, i, argv);
    223 		break;
    224 
    225 	    case EL_SETTC:
    226 		argv[0] = "settc";
    227 		rv = term_settc(el, i, argv);
    228 		break;
    229 
    230 	    case EL_ECHOTC:
    231 		argv[0] = "echotc";
    232 		rv = term_echotc(el, i, argv);
    233 		break;
    234 
    235 	    case EL_SETTY:
    236 		argv[0] = "setty";
    237 		rv = tty_stty(el, i, argv);
    238 		break;
    239 
    240 	    default:
    241 		rv = -1;
    242 		abort();
    243 		break;
    244 	    }
    245 	}
    246 	break;
    247 
    248     case EL_ADDFN:
    249 	{
    250 	    char 	*name = va_arg(va, char *);
    251 	    char 	*help = va_arg(va, char *);
    252 	    el_func_t    func = va_arg(va, el_func_t);
    253 	    rv = map_addfunc(el, name, help, func);
    254 	}
    255 	break;
    256 
    257     case EL_HIST:
    258 	{
    259 	    hist_fun_t func = va_arg(va, hist_fun_t);
    260 	    ptr_t      ptr = va_arg(va, char *);
    261 	    rv = hist_set(el, func, ptr);
    262 	}
    263 	break;
    264 
    265     default:
    266 	rv = -1;
    267     }
    268 
    269     va_end(va);
    270     return rv;
    271 } /* end el_set */
    272 
    273 
    274 /* el_line():
    275  *	Return editing info
    276  */
    277 public const LineInfo *
    278 el_line(el)
    279     EditLine *el;
    280 {
    281     return (const LineInfo *) &el->el_line;
    282 }
    283 
    284 static const char elpath[] = "/.editrc";
    285 
    286 /* el_source():
    287  *	Source a file
    288  */
    289 public int
    290 el_source(el, fname)
    291     EditLine *el;
    292     const char *fname;
    293 {
    294     FILE *fp;
    295     size_t len;
    296     char *ptr, path[MAXPATHLEN];
    297 
    298     if (fname == NULL) {
    299 	fname = &elpath[1];
    300 	if ((fp = fopen(fname, "r")) == NULL) {
    301 	    if ((ptr = getenv("HOME")) == NULL)
    302 		return -1;
    303 	    (void)snprintf(path, sizeof(path), "%s%s", ptr, elpath);
    304 	    fname = path;
    305 	}
    306     }
    307 
    308     if ((fp = fopen(fname, "r")) == NULL)
    309 	return -1;
    310 
    311     while ((ptr = fgetln(fp, &len)) != NULL) {
    312 	if (ptr[len - 1] == '\n')
    313 	    --len;
    314 	ptr[len] = '\0';
    315 	if (parse_line(el, ptr) == -1) {
    316 	    (void) fclose(fp);
    317 	    return -1;
    318 	}
    319     }
    320 
    321     (void) fclose(fp);
    322     return 0;
    323 }
    324 
    325 
    326 /* el_resize():
    327  *	Called from program when terminal is resized
    328  */
    329 public void
    330 el_resize(el)
    331     EditLine *el;
    332 {
    333     int lins, cols;
    334     sigset_t oset, nset;
    335     (void) sigemptyset(&nset);
    336     (void) sigaddset(&nset, SIGWINCH);
    337     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
    338 
    339     /* get the correct window size */
    340     if (term_get_size(el, &lins, &cols))
    341 	term_change_size(el, lins, cols);
    342 
    343     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
    344 }
    345