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