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