154214Sbostic /*-
261275Sbostic * Copyright (c) 1992, 1993
361275Sbostic * The Regents of the University of California. All rights reserved.
454214Sbostic *
554214Sbostic * This code is derived from software contributed to Berkeley by
654214Sbostic * Christos Zoulas of Cornell University.
754214Sbostic *
854214Sbostic * %sccs.include.redist.c%
954214Sbostic */
1054214Sbostic
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*65356Sbostic static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 01/03/94";
1354624Schristos #endif /* not lint && not SCCSID */
1454214Sbostic
1554214Sbostic /*
1654214Sbostic * el.c: EditLine interface functions
1754214Sbostic */
1854214Sbostic #include "sys.h"
1954214Sbostic
2054624Schristos #include <sys/types.h>
2154624Schristos #include <sys/param.h>
2254624Schristos #include <string.h>
2354214Sbostic #include <stdlib.h>
2454214Sbostic #if __STDC__
2554214Sbostic # include <stdarg.h>
2654214Sbostic #else
2754214Sbostic # include <varargs.h>
2854214Sbostic #endif
2954214Sbostic #include "el.h"
3054214Sbostic
3154214Sbostic /* el_init():
3254214Sbostic * Initialize editline and set default parameters.
3354214Sbostic */
3454214Sbostic public EditLine *
el_init(prog,fin,fout)3554214Sbostic el_init(prog, fin, fout)
3654214Sbostic const char *prog;
3754214Sbostic FILE *fin, *fout;
3854214Sbostic {
3954214Sbostic EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
4054214Sbostic #ifdef DEBUG
4154214Sbostic char *tty;
4254214Sbostic #endif
4354214Sbostic
4454214Sbostic if (el == NULL)
4554214Sbostic return NULL;
4654214Sbostic
4754214Sbostic memset(el, 0, sizeof(EditLine));
4854214Sbostic
4954214Sbostic el->el_infd = fileno(fin);
5054214Sbostic el->el_outfile = fout;
5154214Sbostic el->el_prog = strdup(prog);
5254214Sbostic
5354214Sbostic #ifdef DEBUG
5454214Sbostic if ((tty = getenv("DEBUGTTY")) != NULL) {
5554214Sbostic el->el_errfile = fopen(tty, "w");
5654214Sbostic if (el->el_errfile == NULL) {
5754214Sbostic extern errno;
5854214Sbostic (void) fprintf(stderr, "Cannot open %s (%s).\n",
5954214Sbostic tty, strerror(errno));
6054214Sbostic return NULL;
6154214Sbostic }
6254214Sbostic }
6354214Sbostic else
6454214Sbostic #endif
6554214Sbostic el->el_errfile = stderr;
6654214Sbostic
6754214Sbostic /*
6854214Sbostic * Initialize all the modules. Order is important!!!
6954214Sbostic */
7054214Sbostic (void) term_init(el);
7154214Sbostic (void) tty_init(el);
7254214Sbostic (void) key_init(el);
7354214Sbostic (void) map_init(el);
7454214Sbostic (void) ch_init(el);
7554214Sbostic (void) search_init(el);
7654214Sbostic (void) hist_init(el);
7754214Sbostic (void) prompt_init(el);
7854214Sbostic (void) sig_init(el);
7954214Sbostic el->el_flags = 0;
8054214Sbostic
8154214Sbostic return el;
8254214Sbostic } /* end el_init */
8354214Sbostic
8454214Sbostic
8554214Sbostic /* el_end():
8654214Sbostic * Clean up.
8754214Sbostic */
8854214Sbostic public void
el_end(el)8954214Sbostic el_end(el)
9054214Sbostic EditLine *el;
9154214Sbostic {
9254214Sbostic if (el == NULL)
9354214Sbostic return;
9454214Sbostic
9554214Sbostic el_reset(el);
9654214Sbostic
9754214Sbostic term_end(el);
9854214Sbostic tty_end(el);
9954214Sbostic key_end(el);
10054214Sbostic map_end(el);
10154214Sbostic ch_end(el);
10254214Sbostic search_end(el);
10354214Sbostic hist_end(el);
10454214Sbostic prompt_end(el);
10554214Sbostic sig_end(el);
10654214Sbostic
10754214Sbostic el_free((ptr_t) el->el_prog);
10854214Sbostic el_free((ptr_t) el);
10954214Sbostic } /* end el_end */
11054214Sbostic
11154214Sbostic
11254214Sbostic /* el_reset():
11354214Sbostic * Reset the tty and the parser
11454214Sbostic */
11554214Sbostic public void
el_reset(el)11654214Sbostic el_reset(el)
11754214Sbostic EditLine *el;
11854214Sbostic {
11954214Sbostic tty_cookedmode(el);
12054214Sbostic ch_reset(el); /* XXX: Do we want that? */
12154214Sbostic }
12254214Sbostic
12354214Sbostic
12454214Sbostic /* el_set():
12554214Sbostic * set the editline parameters
12654214Sbostic */
12754214Sbostic public int
12854214Sbostic #if __STDC__
el_set(EditLine * el,int op,...)12954214Sbostic el_set(EditLine *el, int op, ...)
13054214Sbostic #else
13154214Sbostic el_set(va_alist)
13254214Sbostic va_dcl
13354214Sbostic #endif
13454214Sbostic {
13554214Sbostic va_list va;
13654214Sbostic int rv;
13754214Sbostic #if __STDC__
13854214Sbostic va_start(va, op);
13954214Sbostic #else
14054214Sbostic EditLine *el;
14154214Sbostic int op;
14254214Sbostic
14354214Sbostic va_start(va);
14454214Sbostic el = va_arg(va, EditLine *);
14554214Sbostic op = va_arg(va, int);
14654214Sbostic #endif
14754214Sbostic
14854214Sbostic switch (op) {
14954214Sbostic case EL_PROMPT:
15054214Sbostic rv = prompt_set(el, va_arg(va, el_pfunc_t));
15154214Sbostic break;
15254214Sbostic
15354624Schristos case EL_TERMINAL:
15454624Schristos rv = term_set(el, va_arg(va, char *));
15554624Schristos break;
15654624Schristos
15754214Sbostic case EL_EDITOR:
15854214Sbostic rv = map_set_editor(el, va_arg(va, char *));
15954214Sbostic break;
16054214Sbostic
16154214Sbostic case EL_SIGNAL:
16254214Sbostic if (va_arg(va, int))
16354214Sbostic el->el_flags |= HANDLE_SIGNALS;
16454214Sbostic else
16554214Sbostic el->el_flags &= ~HANDLE_SIGNALS;
16654214Sbostic rv = 0;
16754214Sbostic break;
16854214Sbostic
16954214Sbostic case EL_BIND:
17054214Sbostic case EL_TELLTC:
17154214Sbostic case EL_SETTC:
17254214Sbostic case EL_ECHOTC:
17354214Sbostic case EL_SETTY:
17454214Sbostic {
17554214Sbostic char *argv[20];
17654214Sbostic int i;
17754214Sbostic for (i = 1; i < 20; i++)
17854214Sbostic if ((argv[i] = va_arg(va, char *)) == NULL)
17954214Sbostic break;
18054214Sbostic
18154214Sbostic switch (op) {
18254214Sbostic case EL_BIND:
18354214Sbostic argv[0] = "bind";
18454214Sbostic rv = map_bind(el, i, argv);
18554214Sbostic break;
18654214Sbostic
18754214Sbostic case EL_TELLTC:
18854214Sbostic argv[0] = "telltc";
18954624Schristos rv = term_telltc(el, i, argv);
19054214Sbostic break;
19154214Sbostic
19254214Sbostic case EL_SETTC:
19354214Sbostic argv[0] = "settc";
19454624Schristos rv = term_settc(el, i, argv);
19554214Sbostic break;
19654214Sbostic
19754214Sbostic case EL_ECHOTC:
19854214Sbostic argv[0] = "echotc";
19954624Schristos rv = term_echotc(el, i, argv);
20054214Sbostic break;
20154214Sbostic
20254214Sbostic case EL_SETTY:
20354214Sbostic argv[0] = "setty";
20454624Schristos rv = tty_stty(el, i, argv);
20554214Sbostic break;
20654214Sbostic
20754214Sbostic default:
20854214Sbostic rv = -1;
20954214Sbostic abort();
21054214Sbostic break;
21154214Sbostic }
21254214Sbostic }
21354214Sbostic break;
21454214Sbostic
21554214Sbostic case EL_ADDFN:
21654214Sbostic {
21754214Sbostic char *name = va_arg(va, char *);
21854214Sbostic char *help = va_arg(va, char *);
21954214Sbostic el_func_t func = va_arg(va, el_func_t);
22054214Sbostic rv = map_addfunc(el, name, help, func);
22154214Sbostic }
22254214Sbostic break;
22354214Sbostic
22454214Sbostic case EL_HIST:
22554214Sbostic {
22654214Sbostic hist_fun_t func = va_arg(va, hist_fun_t);
22754214Sbostic ptr_t ptr = va_arg(va, char *);
22854214Sbostic rv = hist_set(el, func, ptr);
22954214Sbostic }
23054214Sbostic break;
23154214Sbostic
23254214Sbostic default:
23354214Sbostic rv = -1;
23454214Sbostic }
23554214Sbostic
23654214Sbostic va_end(va);
23754214Sbostic return rv;
23854214Sbostic } /* end el_set */
23954214Sbostic
24054214Sbostic
24154214Sbostic /* el_line():
24254214Sbostic * Return editing info
24354214Sbostic */
24454214Sbostic public const LineInfo *
el_line(el)24554214Sbostic el_line(el)
24654214Sbostic EditLine *el;
24754214Sbostic {
24854214Sbostic return (const LineInfo *) &el->el_line;
24954214Sbostic }
25054214Sbostic
25154624Schristos static const char elpath[] = "/.editrc";
25254214Sbostic
25354624Schristos /* el_source():
25454624Schristos * Source a file
25554624Schristos */
25654624Schristos public int
el_source(el,fname)25754624Schristos el_source(el, fname)
25854624Schristos EditLine *el;
25954624Schristos const char *fname;
26054624Schristos {
26154624Schristos FILE *fp;
26258444Sbostic size_t len;
26358444Sbostic char *ptr, path[MAXPATHLEN];
26454624Schristos
26554624Schristos if (fname == NULL) {
26654624Schristos fname = &elpath[1];
26754624Schristos if ((fp = fopen(fname, "r")) == NULL) {
26854624Schristos if ((ptr = getenv("HOME")) == NULL)
26954624Schristos return -1;
27054624Schristos fname = strncpy(path, ptr, MAXPATHLEN);
27154624Schristos (void) strncat(path, elpath, MAXPATHLEN);
27254624Schristos path[MAXPATHLEN-1] = '\0';
27354624Schristos }
27454624Schristos }
27554624Schristos
27654624Schristos if ((fp = fopen(fname, "r")) == NULL)
27754624Schristos return -1;
27854624Schristos
279*65356Sbostic while ((ptr = fgetln(fp, &len)) != NULL)
28058444Sbostic ptr[len - 1] = '\0';
28154624Schristos if (parse_line(el, ptr) == -1) {
28254624Schristos (void) fclose(fp);
28354624Schristos return -1;
28454624Schristos }
28554624Schristos
28654624Schristos (void) fclose(fp);
28754624Schristos return 0;
28854624Schristos }
28954624Schristos
29054624Schristos
29154214Sbostic /* el_resize():
29254214Sbostic * Called from program when terminal is resized
29354214Sbostic */
29454214Sbostic public void
el_resize(el)29554214Sbostic el_resize(el)
29654214Sbostic EditLine *el;
29754214Sbostic {
29854214Sbostic int lins, cols;
29954214Sbostic sigset_t oset, nset;
30054214Sbostic (void) sigemptyset(&nset);
30154214Sbostic (void) sigaddset(&nset, SIGWINCH);
30254214Sbostic (void) sigprocmask(SIG_BLOCK, &nset, &oset);
30354214Sbostic
30454214Sbostic /* get the correct window size */
30554214Sbostic if (term_get_size(el, &lins, &cols))
30654214Sbostic term_change_size(el, lins, cols);
30754214Sbostic
30854214Sbostic (void) sigprocmask(SIG_SETMASK, &oset, NULL);
30954214Sbostic }
310