root/src/noitedit/el.c

Revision bafab25395cb398ddf5eae42145f0d0bfc00ec22, 9.3 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

import of libedit... prepare to hack

  • Property mode set to 100644
Line 
1 /*      $NetBSD: el.c,v 1.21 2001/01/05 22:45:30 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 "compat.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.21 2001/01/05 22:45:30 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 #if !_MSC_VER
55 #include <sys/param.h>
56 #endif
57 #include <string.h>
58 #include <stdlib.h>
59 #include <stdarg.h>
60 #include "el.h"
61
62 /* el_init():
63  *      Initialize editline and set default parameters.
64  */
65 public EditLine *
66 el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
67 {
68
69         EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
70 #ifdef DEBUG
71         char *tty;
72 #endif
73
74         if (el == NULL)
75                 return (NULL);
76
77         memset(el, 0, sizeof(EditLine));
78
79         el->el_infd = fileno(fin);
80         el->el_outfile = fout;
81         el->el_errfile = ferr;
82         el->el_prog = strdup(prog);
83
84         /*
85          * Initialize all the modules. Order is important!!!
86          */
87         el->el_flags = 0;
88
89         (void) term_init(el);
90         (void) key_init(el);
91         (void) map_init(el);
92         if (tty_init(el) == -1)
93                 el->el_flags |= NO_TTY;
94         (void) ch_init(el);
95         (void) search_init(el);
96         (void) hist_init(el);
97         (void) prompt_init(el);
98         (void) sig_init(el);
99
100         return (el);
101 }
102
103
104 /* el_end():
105  *      Clean up.
106  */
107 public void
108 el_end(EditLine *el)
109 {
110
111         if (el == NULL)
112                 return;
113
114         el_reset(el);
115
116         term_end(el);
117         key_end(el);
118         map_end(el);
119         tty_end(el);
120         ch_end(el);
121         search_end(el);
122         hist_end(el);
123         prompt_end(el);
124         sig_end(el);
125
126         el_free((ptr_t) el->el_prog);
127         el_free((ptr_t) el);
128 }
129
130
131 /* el_reset():
132  *      Reset the tty and the parser
133  */
134 public void
135 el_reset(EditLine *el)
136 {
137
138         tty_cookedmode(el);
139         ch_reset(el);           /* XXX: Do we want that? */
140 }
141
142
143 /* el_set():
144  *      set the editline parameters
145  */
146 public int
147 el_set(EditLine *el, int op, ...)
148 {
149         va_list va;
150         int rv;
151         va_start(va, op);
152
153         if (el == NULL)
154                 return (-1);
155         switch (op) {
156         case EL_PROMPT:
157         case EL_RPROMPT:
158                 rv = prompt_set(el, va_arg(va, el_pfunc_t), op);
159                 break;
160
161         case EL_TERMINAL:
162                 rv = term_set(el, va_arg(va, char *));
163                 break;
164
165         case EL_EDITOR:
166                 rv = map_set_editor(el, va_arg(va, char *));
167                 break;
168
169         case EL_SIGNAL:
170                 if (va_arg(va, int))
171                         el->el_flags |= HANDLE_SIGNALS;
172                 else
173                         el->el_flags &= ~HANDLE_SIGNALS;
174                 rv = 0;
175                 break;
176
177         case EL_BIND:
178         case EL_TELLTC:
179         case EL_SETTC:
180         case EL_ECHOTC:
181         case EL_SETTY:
182         {
183                 char *argv[20];
184                 int i;
185
186                 for (i = 1; i < 20; i++)
187                         if ((argv[i] = va_arg(va, char *)) == NULL)
188                                 break;
189
190                 switch (op) {
191                 case EL_BIND:
192                         argv[0] = "bind";
193                         rv = map_bind(el, i, argv);
194                         break;
195
196                 case EL_TELLTC:
197                         argv[0] = "telltc";
198                         rv = term_telltc(el, i, argv);
199                         break;
200
201                 case EL_SETTC:
202                         argv[0] = "settc";
203                         rv = term_settc(el, i, argv);
204                         break;
205
206                 case EL_ECHOTC:
207                         argv[0] = "echotc";
208                         rv = term_echotc(el, i, argv);
209                         break;
210
211                 case EL_SETTY:
212                         argv[0] = "setty";
213                         rv = tty_stty(el, i, argv);
214                         break;
215
216                 default:
217                         rv = -1;
218                         EL_ABORT((el->el_errfile, "Bad op %d\n", op));
219                         break;
220                 }
221                 break;
222         }
223
224         case EL_ADDFN:
225         {
226                 char *name = va_arg(va, char *);
227                 char *help = va_arg(va, char *);
228                 el_func_t func = va_arg(va, el_func_t);
229
230                 rv = map_addfunc(el, name, help, func);
231                 break;
232         }
233
234         case EL_HIST:
235         {
236                 hist_fun_t func = va_arg(va, hist_fun_t);
237                 ptr_t ptr = va_arg(va, char *);
238
239                 rv = hist_set(el, func, ptr);
240                 break;
241         }
242
243         case EL_EDITMODE:
244                 if (va_arg(va, int))
245                         el->el_flags &= ~EDIT_DISABLED;
246                 else
247                         el->el_flags |= EDIT_DISABLED;
248                 rv = 0;
249                 break;
250
251         default:
252                 rv = -1;
253         }
254
255         va_end(va);
256         return (rv);
257 }
258
259
260 /* el_get():
261  *      retrieve the editline parameters
262  */
263 public int
264 el_get(EditLine *el, int op, void *ret)
265 {
266         int rv;
267         union {
268                 void *vptr;
269                 const char *cptr;
270                 el_pfunc_t elpf;
271         } vret;
272
273         vret.vptr = ret;
274         if (el == NULL || ret == NULL)
275                 return (-1);
276         switch (op) {
277         case EL_PROMPT:
278         case EL_RPROMPT:
279                 rv = prompt_get(el, &vret.elpf, op);
280                 break;
281
282         case EL_EDITOR:
283                 rv = map_get_editor(el, &vret.cptr);
284                 break;
285
286         case EL_SIGNAL:
287                 *((int *) ret) = (el->el_flags & HANDLE_SIGNALS);
288                 rv = 0;
289                 break;
290
291         case EL_EDITMODE:
292                 *((int *) ret) = (!(el->el_flags & EDIT_DISABLED));
293                 rv = 0;
294                 break;
295
296 #if 0                           /* XXX */
297         case EL_TERMINAL:
298                 rv = term_get(el, (const char *) &ret);
299                 break;
300
301         case EL_BIND:
302         case EL_TELLTC:
303         case EL_SETTC:
304         case EL_ECHOTC:
305         case EL_SETTY:
306         {
307                 char *argv[20];
308                 int i;
309
310                 for (i = 1; i < 20; i++)
311                         if ((argv[i] = va_arg(va, char *)) == NULL)
312                                 break;
313
314                 switch (op) {
315                 case EL_BIND:
316                         argv[0] = "bind";
317                         rv = map_bind(el, i, argv);
318                         break;
319
320                 case EL_TELLTC:
321                         argv[0] = "telltc";
322                         rv = term_telltc(el, i, argv);
323                         break;
324
325                 case EL_SETTC:
326                         argv[0] = "settc";
327                         rv = term_settc(el, i, argv);
328                         break;
329
330                 case EL_ECHOTC:
331                         argv[0] = "echotc";
332                         rv = term_echotc(el, i, argv);
333                         break;
334
335                 case EL_SETTY:
336                         argv[0] = "setty";
337                         rv = tty_stty(el, i, argv);
338                         break;
339
340                 default:
341                         rv = -1;
342                         EL_ABORT((el->errfile, "Bad op %d\n", op));
343                         break;
344                 }
345                 break;
346         }
347
348         case EL_ADDFN:
349         {
350                 char *name = va_arg(va, char *);
351                 char *help = va_arg(va, char *);
352                 el_func_t func = va_arg(va, el_func_t);
353
354                 rv = map_addfunc(el, name, help, func);
355                 break;
356         }
357
358         case EL_HIST:
359                 {
360                         hist_fun_t func = va_arg(va, hist_fun_t);
361                         ptr_t ptr = va_arg(va, char *);
362                         rv = hist_set(el, func, ptr);
363                 }
364                 break;
365 #endif /* XXX */
366
367         default:
368                 rv = -1;
369         }
370
371         return (rv);
372 }
373
374
375 /* el_line():
376  *      Return editing info
377  */
378 public const LineInfo *
379 el_line(EditLine *el)
380 {
381
382         return (const LineInfo *) (void *) &el->el_line;
383 }
384
385 static const char elpath[] = "/.editrc";
386
387 /* el_source():
388  *      Source a file
389  */
390 public int
391 el_source(EditLine *el, const char *fname)
392 {
393         FILE *fp;
394         size_t len;
395         char *ptr, path[MAXPATHLEN];
396
397         fp = NULL;
398         if (fname == NULL) {
399                 if (issetugid())
400                         return (-1);
401 #if _WIN32
402                 if (getenv("HOMEDRIVE") && getenv("HOMEPATH")) {
403                         snprintf(path, sizeof(path), "%s%s%s", getenv("HOMEDRIVE"), getenv("HOMEPATH"), elpath);
404                         fname = path;
405                 }
406 #else
407                 if ((ptr = getenv("HOME")) == NULL)
408                         return (-1);
409                 if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
410                         return (-1);
411                 if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
412                         return (-1);
413                 fname = path;
414 #endif
415         }
416         if (fname == NULL)
417                 return -1;
418         if (fp == NULL)
419                 fp = fopen(fname, "r");
420         if (fp == NULL) {
421                 return (-1);
422         }
423
424         while ((ptr = fgetln(fp, &len)) != NULL) {
425                 if (len > 0 && ptr[len - 1] == '\n')
426                         --len;
427                 ptr[len] = '\0';
428                 if (parse_line(el, ptr) == -1) {
429                         (void) fclose(fp);
430                         return (-1);
431                 }
432         }
433
434         (void) fclose(fp);
435         return (0);
436 }
437
438
439 /* el_resize():
440  *      Called from program when terminal is resized
441  */
442 public void
443 el_resize(EditLine *el)
444 {
445         int lins, cols;
446 #if !_MSC_VER
447         sigset_t oset, nset;
448
449         (void) sigemptyset(&nset);
450         (void) sigaddset(&nset, SIGWINCH);
451         (void) sigprocmask(SIG_BLOCK, &nset, &oset);
452 #endif
453
454         /* get the correct window size */
455         if (term_get_size(el, &lins, &cols))
456                 term_change_size(el, lins, cols);
457
458 #if !_MSC_VER
459         (void) sigprocmask(SIG_SETMASK, &oset, NULL);
460 #endif
461 }
462
463
464 /* el_beep():
465  *      Called from the program to beep
466  */
467 public void
468 el_beep(EditLine *el)
469 {
470
471         term_beep(el);
472 }
473
474
475 /* el_editmode()
476  *      Set the state of EDIT_DISABLED from the `edit' command.
477  */
478 protected int
479 /*ARGSUSED*/
480 el_editmode(EditLine *el, int argc, char **argv)
481 {
482         const char *how;
483
484         if (argv == NULL || argc != 2 || argv[1] == NULL)
485                 return (-1);
486
487         how = argv[1];
488         if (strcmp(how, "on") == 0)
489                 el->el_flags &= ~EDIT_DISABLED;
490         else if (strcmp(how, "off") == 0)
491                 el->el_flags |= EDIT_DISABLED;
492         else {
493                 (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
494                 return (-1);
495         }
496         return (0);
497 }
Note: See TracBrowser for help on using the browser.