Update libedit from NetBSD.
[dragonfly.git] / lib / libedit / read.c
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  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * @(#)read.c   8.1 (Berkeley) 6/4/93
33  * $NetBSD: read.c,v 1.36 2005/06/01 11:37:52 lukem Exp $
34  * $DragonFly: src/lib/libedit/read.c,v 1.4 2005/11/13 11:58:30 corecode Exp $
35  */
36
37 #include "config.h"
38
39 /*
40  * read.c: Clean this junk up! This is horrible code.
41  *         Terminal read functions
42  */
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <stdlib.h>
47 #include "el.h"
48
49 #define OKCMD   -1
50
51 private int     read__fixio(int, int);
52 private int     read_preread(EditLine *);
53 private int     read_char(EditLine *, char *);
54 private int     read_getcmd(EditLine *, el_action_t *, char *);
55
56 /* read_init():
57  *      Initialize the read stuff
58  */
59 protected int
60 read_init(EditLine *el)
61 {
62         /* builtin read_char */
63         el->el_read.read_char = read_char;
64         return 0;
65 }
66
67
68 /* el_read_setfn():
69  *      Set the read char function to the one provided.
70  *      If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
71  */
72 protected int
73 el_read_setfn(EditLine *el, el_rfunc_t rc)
74 {
75         el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
76         return 0;
77 }
78
79
80 /* el_read_getfn():
81  *      return the current read char function, or EL_BUILTIN_GETCFN
82  *      if it is the default one
83  */
84 protected el_rfunc_t
85 el_read_getfn(EditLine *el)
86 {
87        return (el->el_read.read_char == read_char) ?
88             EL_BUILTIN_GETCFN : el->el_read.read_char;
89 }
90
91
92 #ifndef MIN
93 #define MIN(A,B) ((A) < (B) ? (A) : (B))
94 #endif
95
96 #ifdef DEBUG_EDIT
97 private void
98 read_debug(EditLine *el)
99 {
100
101         if (el->el_line.cursor > el->el_line.lastchar)
102                 (void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
103         if (el->el_line.cursor < el->el_line.buffer)
104                 (void) fprintf(el->el_errfile, "cursor < buffer\r\n");
105         if (el->el_line.cursor > el->el_line.limit)
106                 (void) fprintf(el->el_errfile, "cursor > limit\r\n");
107         if (el->el_line.lastchar > el->el_line.limit)
108                 (void) fprintf(el->el_errfile, "lastchar > limit\r\n");
109         if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
110                 (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
111 }
112 #endif /* DEBUG_EDIT */
113
114
115 /* read__fixio():
116  *      Try to recover from a read error
117  */
118 /* ARGSUSED */
119 private int
120 read__fixio(int fd __attribute__((__unused__)), int e)
121 {
122
123         switch (e) {
124         case -1:                /* Make sure that the code is reachable */
125
126 #ifdef EWOULDBLOCK
127         case EWOULDBLOCK:
128 #ifndef TRY_AGAIN
129 #define TRY_AGAIN
130 #endif
131 #endif /* EWOULDBLOCK */
132
133 #if defined(POSIX) && defined(EAGAIN)
134 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
135         case EAGAIN:
136 #ifndef TRY_AGAIN
137 #define TRY_AGAIN
138 #endif
139 #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
140 #endif /* POSIX && EAGAIN */
141
142                 e = 0;
143 #ifdef TRY_AGAIN
144 #if defined(F_SETFL) && defined(O_NDELAY)
145                 if ((e = fcntl(fd, F_GETFL, 0)) == -1)
146                         return (-1);
147
148                 if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
149                         return (-1);
150                 else
151                         e = 1;
152 #endif /* F_SETFL && O_NDELAY */
153
154 #ifdef FIONBIO
155                 {
156                         int zero = 0;
157
158                         if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
159                                 return (-1);
160                         else
161                                 e = 1;
162                 }
163 #endif /* FIONBIO */
164
165 #endif /* TRY_AGAIN */
166                 return (e ? 0 : -1);
167
168         case EINTR:
169                 return (0);
170
171         default:
172                 return (-1);
173         }
174 }
175
176
177 /* read_preread():
178  *      Try to read the stuff in the input queue;
179  */
180 private int
181 read_preread(EditLine *el)
182 {
183         int chrs = 0;
184
185         if (el->el_tty.t_mode == ED_IO)
186                 return (0);
187
188 #ifdef FIONREAD
189         (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
190         if (chrs > 0) {
191                 char buf[EL_BUFSIZ];
192
193                 chrs = read(el->el_infd, buf,
194                     (size_t) MIN(chrs, EL_BUFSIZ - 1));
195                 if (chrs > 0) {
196                         buf[chrs] = '\0';
197                         el_push(el, buf);
198                 }
199         }
200 #endif /* FIONREAD */
201
202         return (chrs > 0);
203 }
204
205
206 /* el_push():
207  *      Push a macro
208  */
209 public void
210 el_push(EditLine *el, char *str)
211 {
212         c_macro_t *ma = &el->el_chared.c_macro;
213
214         if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
215                 ma->level++;
216                 if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
217                         return;
218                 ma->level--;
219         }
220         term_beep(el);
221         term__flush();
222 }
223
224
225 /* read_getcmd():
226  *      Return next command from the input stream.
227  */
228 private int
229 read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
230 {
231         el_action_t cmd;
232         int num;
233
234         do {
235                 if ((num = el_getc(el, ch)) != 1)       /* if EOF or error */
236                         return (num);
237
238 #ifdef  KANJI
239                 if ((*ch & 0200)) {
240                         el->el_state.metanext = 0;
241                         cmd = CcViMap[' '];
242                         break;
243                 } else
244 #endif /* KANJI */
245
246                 if (el->el_state.metanext) {
247                         el->el_state.metanext = 0;
248                         *ch |= 0200;
249                 }
250                 cmd = el->el_map.current[(unsigned char) *ch];
251                 if (cmd == ED_SEQUENCE_LEAD_IN) {
252                         key_value_t val;
253                         switch (key_get(el, ch, &val)) {
254                         case XK_CMD:
255                                 cmd = val.cmd;
256                                 break;
257                         case XK_STR:
258                                 el_push(el, val.str);
259                                 break;
260 #ifdef notyet
261                         case XK_EXE:
262                                 /* XXX: In the future to run a user function */
263                                 RunCommand(val.str);
264                                 break;
265 #endif
266                         default:
267                                 EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
268                                 break;
269                         }
270                 }
271                 if (el->el_map.alt == NULL)
272                         el->el_map.current = el->el_map.key;
273         } while (cmd == ED_SEQUENCE_LEAD_IN);
274         *cmdnum = cmd;
275         return (OKCMD);
276 }
277
278
279 /* read_char():
280  *      Read a character from the tty.
281  */
282 private int
283 read_char(EditLine *el, char *cp)
284 {
285         int num_read;
286         int tried = 0;
287
288         while ((num_read = read(el->el_infd, cp, 1)) == -1)
289                 if (!tried && read__fixio(el->el_infd, errno) == 0)
290                         tried = 1;
291                 else {
292                         *cp = '\0';
293                         return (-1);
294                 }
295
296         return (num_read);
297 }
298
299
300 /* el_getc():
301  *      Read a character
302  */
303 public int
304 el_getc(EditLine *el, char *cp)
305 {
306         int num_read;
307         c_macro_t *ma = &el->el_chared.c_macro;
308
309         term__flush();
310         for (;;) {
311                 if (ma->level < 0) {
312                         if (!read_preread(el))
313                                 break;
314                 }
315                 if (ma->level < 0)
316                         break;
317
318                 if (ma->macro[ma->level][ma->offset] == '\0') {
319                         el_free(ma->macro[ma->level--]);
320                         ma->offset = 0;
321                         continue;
322                 }
323                 *cp = ma->macro[ma->level][ma->offset++] & 0377;
324                 if (ma->macro[ma->level][ma->offset] == '\0') {
325                         /* Needed for QuoteMode On */
326                         el_free(ma->macro[ma->level--]);
327                         ma->offset = 0;
328                 }
329                 return (1);
330         }
331
332 #ifdef DEBUG_READ
333         (void) fprintf(el->el_errfile, "Turning raw mode on\n");
334 #endif /* DEBUG_READ */
335         if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
336                 return (0);
337
338 #ifdef DEBUG_READ
339         (void) fprintf(el->el_errfile, "Reading a character\n");
340 #endif /* DEBUG_READ */
341         num_read = (*el->el_read.read_char)(el, cp);
342 #ifdef DEBUG_READ
343         (void) fprintf(el->el_errfile, "Got it %c\n", *cp);
344 #endif /* DEBUG_READ */
345         return (num_read);
346 }
347
348 protected void
349 read_prepare(EditLine *el)
350 {
351         if (el->el_flags & HANDLE_SIGNALS)
352                 sig_set(el);
353         if (el->el_flags & NO_TTY)
354                 return;
355         if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
356                 tty_rawmode(el);
357
358         /* This is relatively cheap, and things go terribly wrong if
359            we have the wrong size. */
360         el_resize(el);
361         re_clear_display(el);   /* reset the display stuff */
362         ch_reset(el);
363         re_refresh(el);         /* print the prompt */
364
365         if (el->el_flags & UNBUFFERED)
366                 term__flush();
367 }
368
369 protected void
370 read_finish(EditLine *el)
371 {
372         if ((el->el_flags & UNBUFFERED) == 0)
373                 (void) tty_cookedmode(el);
374         if (el->el_flags & HANDLE_SIGNALS)
375                 sig_clr(el);
376 }
377
378 public const char *
379 el_gets(EditLine *el, int *nread)
380 {
381         int retval;
382         el_action_t cmdnum = 0;
383         int num;                /* how many chars we have read at NL */
384         char ch;
385         int crlf = 0;
386 #ifdef FIONREAD
387         c_macro_t *ma = &el->el_chared.c_macro;
388 #endif /* FIONREAD */
389
390         if (el->el_flags & NO_TTY) {
391                 char *cp = el->el_line.buffer;
392                 size_t idx;
393
394                 while ((*el->el_read.read_char)(el, cp) == 1) {
395                         /* make sure there is space for next character */
396                         if (cp + 1 >= el->el_line.limit) {
397                                 idx = (cp - el->el_line.buffer);
398                                 if (!ch_enlargebufs(el, 2))
399                                         break;
400                                 cp = &el->el_line.buffer[idx];
401                         }
402                         cp++;
403                         if (el->el_flags & UNBUFFERED)
404                                 break;
405                         if (cp[-1] == '\r' || cp[-1] == '\n')
406                                 break;
407                 }
408
409                 el->el_line.cursor = el->el_line.lastchar = cp;
410                 *cp = '\0';
411                 if (nread)
412                         *nread = el->el_line.cursor - el->el_line.buffer;
413                 return (el->el_line.buffer);
414         }
415
416
417 #ifdef FIONREAD
418         if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
419                 long chrs = 0;
420
421                 (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
422                 if (chrs == 0) {
423                         if (tty_rawmode(el) < 0) {
424                                 if (nread)
425                                         *nread = 0;
426                                 return (NULL);
427                         }
428                 }
429         }
430 #endif /* FIONREAD */
431
432         if ((el->el_flags & UNBUFFERED) == 0)
433                 read_prepare(el);
434
435         if (el->el_flags & EDIT_DISABLED) {
436                 char *cp;
437                 size_t idx;
438                 if ((el->el_flags & UNBUFFERED) == 0)
439                         cp = el->el_line.buffer;
440                 else
441                         cp = el->el_line.lastchar;
442
443                 term__flush();
444
445                 while ((*el->el_read.read_char)(el, cp) == 1) {
446                         /* make sure there is space next character */
447                         if (cp + 1 >= el->el_line.limit) {
448                                 idx = (cp - el->el_line.buffer);
449                                 if (!ch_enlargebufs(el, 2))
450                                         break;
451                                 cp = &el->el_line.buffer[idx];
452                         }
453                         if (*cp == 4)   /* ought to be stty eof */
454                                 break;
455                         cp++;
456                         crlf = cp[-1] == '\r' || cp[-1] == '\n';
457                         if (el->el_flags & UNBUFFERED)
458                                 break;
459                         if (crlf)
460                                 break;
461                 }
462
463                 el->el_line.cursor = el->el_line.lastchar = cp;
464                 *cp = '\0';
465                 if (nread)
466                         *nread = el->el_line.cursor - el->el_line.buffer;
467                 return (el->el_line.buffer);
468         }
469
470         for (num = OKCMD; num == OKCMD;) {      /* while still editing this
471                                                  * line */
472 #ifdef DEBUG_EDIT
473                 read_debug(el);
474 #endif /* DEBUG_EDIT */
475                 /* if EOF or error */
476                 if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
477 #ifdef DEBUG_READ
478                         (void) fprintf(el->el_errfile,
479                             "Returning from el_gets %d\n", num);
480 #endif /* DEBUG_READ */
481                         break;
482                 }
483                 if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
484 #ifdef DEBUG_EDIT
485                         (void) fprintf(el->el_errfile,
486                             "ERROR: illegal command from key 0%o\r\n", ch);
487 #endif /* DEBUG_EDIT */
488                         continue;       /* try again */
489                 }
490                 /* now do the real command */
491 #ifdef DEBUG_READ
492                 {
493                         el_bindings_t *b;
494                         for (b = el->el_map.help; b->name; b++)
495                                 if (b->func == cmdnum)
496                                         break;
497                         if (b->name)
498                                 (void) fprintf(el->el_errfile,
499                                     "Executing %s\n", b->name);
500                         else
501                                 (void) fprintf(el->el_errfile,
502                                     "Error command = %d\n", cmdnum);
503                 }
504 #endif /* DEBUG_READ */
505                 /* vi redo needs these way down the levels... */
506                 el->el_state.thiscmd = cmdnum;
507                 el->el_state.thisch = ch;
508                 if (el->el_map.type == MAP_VI &&
509                     el->el_map.current == el->el_map.key &&
510                     el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
511                         if (cmdnum == VI_DELETE_PREV_CHAR &&
512                             el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
513                             && isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
514                                 el->el_chared.c_redo.pos--;
515                         else
516                                 *el->el_chared.c_redo.pos++ = ch;
517                 }
518                 retval = (*el->el_map.func[cmdnum]) (el, ch);
519 #ifdef DEBUG_READ
520                 (void) fprintf(el->el_errfile,
521                         "Returned state %d\n", retval );
522 #endif /* DEBUG_READ */
523
524                 /* save the last command here */
525                 el->el_state.lastcmd = cmdnum;
526
527                 /* use any return value */
528                 switch (retval) {
529                 case CC_CURSOR:
530                         re_refresh_cursor(el);
531                         break;
532
533                 case CC_REDISPLAY:
534                         re_clear_lines(el);
535                         re_clear_display(el);
536                         /* FALLTHROUGH */
537
538                 case CC_REFRESH:
539                         re_refresh(el);
540                         break;
541
542                 case CC_REFRESH_BEEP:
543                         re_refresh(el);
544                         term_beep(el);
545                         break;
546
547                 case CC_NORM:   /* normal char */
548                         break;
549
550                 case CC_ARGHACK:        /* Suggested by Rich Salz */
551                         /* <rsalz@pineapple.bbn.com> */
552                         continue;       /* keep going... */
553
554                 case CC_EOF:    /* end of file typed */
555                         if ((el->el_flags & UNBUFFERED) == 0)
556                                 num = 0;
557                         else if (num == -1) {
558                                 *el->el_line.lastchar++ = CONTROL('d');
559                                 el->el_line.cursor = el->el_line.lastchar;
560                                 num = 1;
561                         }
562                         break;
563
564                 case CC_NEWLINE:        /* normal end of line */
565                         num = el->el_line.lastchar - el->el_line.buffer;
566                         break;
567
568                 case CC_FATAL:  /* fatal error, reset to known state */
569 #ifdef DEBUG_READ
570                         (void) fprintf(el->el_errfile,
571                             "*** editor fatal ERROR ***\r\n\n");
572 #endif /* DEBUG_READ */
573                         /* put (real) cursor in a known place */
574                         re_clear_display(el);   /* reset the display stuff */
575                         ch_reset(el);   /* reset the input pointers */
576                         re_refresh(el); /* print the prompt again */
577                         break;
578
579                 case CC_ERROR:
580                 default:        /* functions we don't know about */
581 #ifdef DEBUG_READ
582                         (void) fprintf(el->el_errfile,
583                             "*** editor ERROR ***\r\n\n");
584 #endif /* DEBUG_READ */
585                         term_beep(el);
586                         term__flush();
587                         break;
588                 }
589                 el->el_state.argument = 1;
590                 el->el_state.doingarg = 0;
591                 el->el_chared.c_vcmd.action = NOP;
592                 if (el->el_flags & UNBUFFERED)
593                         break;
594         }
595
596         term__flush();          /* flush any buffered output */
597         /* make sure the tty is set up correctly */
598         if ((el->el_flags & UNBUFFERED) == 0) {
599                 read_finish(el);
600                 if (nread)
601                         *nread = num;
602         } else {
603                 if (nread)
604                         *nread = el->el_line.lastchar - el->el_line.buffer;
605         }
606         return (num ? el->el_line.buffer : NULL);
607 }