Commit | Line | Data |
---|---|---|
738a3e54 KB |
1 | /*- |
2 | * Copyright (c) 1992 The Regents of the University of California. | |
3 | * 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 | ||
b6dd18ed CZ |
11 | #if !defined(lint) && !defined(SCCSID) |
12 | static char sccsid[] = "@(#)el.c 5.2 (Berkeley) %G%"; | |
13 | #endif /* not lint && not SCCSID */ | |
738a3e54 KB |
14 | |
15 | /* | |
16 | * el.c: EditLine interface functions | |
17 | */ | |
18 | #include "sys.h" | |
19 | ||
b6dd18ed CZ |
20 | #include <sys/types.h> |
21 | #include <sys/param.h> | |
22 | #include <string.h> | |
738a3e54 KB |
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 | ||
b6dd18ed CZ |
153 | case EL_TERMINAL: |
154 | rv = term_set(el, va_arg(va, char *)); | |
155 | break; | |
156 | ||
738a3e54 KB |
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"; | |
b6dd18ed | 189 | rv = term_telltc(el, i, argv); |
738a3e54 KB |
190 | break; |
191 | ||
192 | case EL_SETTC: | |
193 | argv[0] = "settc"; | |
b6dd18ed | 194 | rv = term_settc(el, i, argv); |
738a3e54 KB |
195 | break; |
196 | ||
197 | case EL_ECHOTC: | |
198 | argv[0] = "echotc"; | |
b6dd18ed | 199 | rv = term_echotc(el, i, argv); |
738a3e54 KB |
200 | break; |
201 | ||
202 | case EL_SETTY: | |
203 | argv[0] = "setty"; | |
b6dd18ed | 204 | rv = tty_stty(el, i, argv); |
738a3e54 KB |
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 | ||
b6dd18ed CZ |
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 | char path[MAXPATHLEN]; | |
262 | FILE *fp; | |
263 | char *ptr; | |
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, NULL)) != NULL) | |
280 | if (parse_line(el, ptr) == -1) { | |
281 | (void) fclose(fp); | |
282 | return -1; | |
283 | } | |
284 | ||
285 | (void) fclose(fp); | |
286 | return 0; | |
287 | } | |
288 | ||
738a3e54 KB |
289 | |
290 | /* el_resize(): | |
291 | * Called from program when terminal is resized | |
292 | */ | |
293 | public void | |
294 | el_resize(el) | |
295 | EditLine *el; | |
296 | { | |
297 | int lins, cols; | |
298 | sigset_t oset, nset; | |
299 | (void) sigemptyset(&nset); | |
300 | (void) sigaddset(&nset, SIGWINCH); | |
301 | (void) sigprocmask(SIG_BLOCK, &nset, &oset); | |
302 | ||
303 | /* get the correct window size */ | |
304 | if (term_get_size(el, &lins, &cols)) | |
305 | term_change_size(el, lins, cols); | |
306 | ||
307 | (void) sigprocmask(SIG_SETMASK, &oset, NULL); | |
308 | } |