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