Home | History | Annotate | Line # | Download | only in libedit
read.c revision 1.8
      1  1.8     lukem /*	$NetBSD: read.c,v 1.8 1998/01/21 10:12:22 lukem Exp $	*/
      2  1.2     lukem 
      3  1.1       cgd /*-
      4  1.1       cgd  * Copyright (c) 1992, 1993
      5  1.1       cgd  *	The Regents of the University of California.  All rights reserved.
      6  1.1       cgd  *
      7  1.1       cgd  * This code is derived from software contributed to Berkeley by
      8  1.1       cgd  * Christos Zoulas of Cornell University.
      9  1.1       cgd  *
     10  1.1       cgd  * Redistribution and use in source and binary forms, with or without
     11  1.1       cgd  * modification, are permitted provided that the following conditions
     12  1.1       cgd  * are met:
     13  1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     14  1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     15  1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     17  1.1       cgd  *    documentation and/or other materials provided with the distribution.
     18  1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     19  1.1       cgd  *    must display the following acknowledgement:
     20  1.1       cgd  *	This product includes software developed by the University of
     21  1.1       cgd  *	California, Berkeley and its contributors.
     22  1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     23  1.1       cgd  *    may be used to endorse or promote products derived from this software
     24  1.1       cgd  *    without specific prior written permission.
     25  1.1       cgd  *
     26  1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27  1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28  1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30  1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31  1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32  1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33  1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34  1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35  1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36  1.1       cgd  * SUCH DAMAGE.
     37  1.1       cgd  */
     38  1.1       cgd 
     39  1.5  christos #include <sys/cdefs.h>
     40  1.1       cgd #if !defined(lint) && !defined(SCCSID)
     41  1.2     lukem #if 0
     42  1.1       cgd static char sccsid[] = "@(#)read.c	8.1 (Berkeley) 6/4/93";
     43  1.2     lukem #else
     44  1.8     lukem __RCSID("$NetBSD: read.c,v 1.8 1998/01/21 10:12:22 lukem Exp $");
     45  1.2     lukem #endif
     46  1.2     lukem #endif /* not lint && not SCCSID */
     47  1.1       cgd 
     48  1.1       cgd /*
     49  1.1       cgd  * read.c: Clean this junk up! This is horrible code.
     50  1.1       cgd  *	   Terminal read functions
     51  1.1       cgd  */
     52  1.1       cgd #include "sys.h"
     53  1.1       cgd #include <sys/errno.h>
     54  1.1       cgd #include <unistd.h>
     55  1.1       cgd #include <stdlib.h>
     56  1.1       cgd extern int errno;
     57  1.1       cgd #include "el.h"
     58  1.1       cgd 
     59  1.1       cgd #define OKCMD -1
     60  1.1       cgd 
     61  1.1       cgd private int read__fixio		__P((int, int));
     62  1.1       cgd private int read_preread	__P((EditLine *));
     63  1.1       cgd private int read_getcmd		__P((EditLine *, el_action_t *, char *));
     64  1.6  christos private int read_char		__P((EditLine *, char *));
     65  1.1       cgd 
     66  1.1       cgd #ifdef DEBUG_EDIT
     67  1.1       cgd private void
     68  1.1       cgd read_debug(el)
     69  1.1       cgd     EditLine *el;
     70  1.1       cgd {
     71  1.1       cgd 
     72  1.1       cgd     if (el->el_line.cursor > el->el_line.lastchar)
     73  1.1       cgd 	(void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
     74  1.1       cgd     if (el->el_line.cursor < el->el_line.buffer)
     75  1.1       cgd 	(void) fprintf(el->el_errfile, "cursor < buffer\r\n");
     76  1.1       cgd     if (el->el_line.cursor > el->el_line.limit)
     77  1.1       cgd 	(void) fprintf(el->el_errfile, "cursor > limit\r\n");
     78  1.1       cgd     if (el->el_line.lastchar > el->el_line.limit)
     79  1.1       cgd 	(void) fprintf(el->el_errfile, "lastchar > limit\r\n");
     80  1.1       cgd     if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
     81  1.1       cgd 	(void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
     82  1.1       cgd }
     83  1.1       cgd #endif /* DEBUG_EDIT */
     84  1.1       cgd 
     85  1.1       cgd /* read__fixio():
     86  1.1       cgd  *	Try to recover from a read error
     87  1.1       cgd  */
     88  1.1       cgd private int
     89  1.1       cgd read__fixio(fd, e)
     90  1.1       cgd     int fd, e;
     91  1.1       cgd {
     92  1.1       cgd     switch (e) {
     93  1.1       cgd     case -1:	/* Make sure that the code is reachable */
     94  1.1       cgd 
     95  1.1       cgd #ifdef EWOULDBLOCK
     96  1.1       cgd     case EWOULDBLOCK:
     97  1.4  christos # ifndef TRY_AGAIN
     98  1.4  christos #  define TRY_AGAIN
     99  1.4  christos # endif
    100  1.1       cgd #endif /* EWOULDBLOCK */
    101  1.1       cgd 
    102  1.1       cgd #if defined(POSIX) && defined(EAGAIN)
    103  1.1       cgd # if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
    104  1.1       cgd     case EAGAIN:
    105  1.4  christos #  ifndef TRY_AGAIN
    106  1.4  christos #   define TRY_AGAIN
    107  1.4  christos #  endif
    108  1.1       cgd # endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
    109  1.1       cgd #endif /* POSIX && EAGAIN */
    110  1.1       cgd 
    111  1.1       cgd 	e = 0;
    112  1.1       cgd #ifdef TRY_AGAIN
    113  1.1       cgd # if defined(F_SETFL) && defined(O_NDELAY)
    114  1.1       cgd 	if ((e = fcntl(fd, F_GETFL, 0)) == -1)
    115  1.1       cgd 	    return -1;
    116  1.1       cgd 
    117  1.1       cgd 	if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
    118  1.1       cgd 	    return -1;
    119  1.1       cgd 	else
    120  1.1       cgd 	    e = 1;
    121  1.1       cgd # endif /* F_SETFL && O_NDELAY */
    122  1.1       cgd 
    123  1.1       cgd # ifdef FIONBIO
    124  1.5  christos 	{
    125  1.5  christos 		int zero = 0;
    126  1.5  christos 
    127  1.5  christos 		if (ioctl(fd, FIONBIO, (ioctl_t) &zero) == -1)
    128  1.5  christos 		    return -1;
    129  1.5  christos 		else
    130  1.5  christos 		    e = 1;
    131  1.5  christos 	}
    132  1.1       cgd # endif	/* FIONBIO */
    133  1.1       cgd 
    134  1.1       cgd #endif /* TRY_AGAIN */
    135  1.1       cgd 	return e ? 0 : -1;
    136  1.1       cgd 
    137  1.1       cgd     case EINTR:
    138  1.1       cgd 	return 0;
    139  1.1       cgd 
    140  1.1       cgd     default:
    141  1.1       cgd 	return -1;
    142  1.1       cgd     }
    143  1.1       cgd }
    144  1.1       cgd 
    145  1.1       cgd 
    146  1.1       cgd /* read_preread():
    147  1.1       cgd  *	Try to read the stuff in the input queue;
    148  1.1       cgd  */
    149  1.1       cgd private int
    150  1.1       cgd read_preread(el)
    151  1.1       cgd     EditLine *el;
    152  1.1       cgd {
    153  1.1       cgd     int    chrs = 0;
    154  1.1       cgd 
    155  1.1       cgd     if (el->el_chared.c_macro.nline) {
    156  1.1       cgd 	el_free((ptr_t) el->el_chared.c_macro.nline);
    157  1.1       cgd 	el->el_chared.c_macro.nline = NULL;
    158  1.1       cgd     }
    159  1.1       cgd 
    160  1.1       cgd     if (el->el_tty.t_mode == ED_IO)
    161  1.1       cgd 	return 0;
    162  1.1       cgd 
    163  1.1       cgd #ifdef FIONREAD
    164  1.1       cgd     (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs);
    165  1.1       cgd     if (chrs > 0) {
    166  1.1       cgd 	char    buf[EL_BUFSIZ];
    167  1.1       cgd 
    168  1.1       cgd 	chrs = read(el->el_infd, buf, (size_t) MIN(chrs, EL_BUFSIZ - 1));
    169  1.1       cgd 	if (chrs > 0) {
    170  1.1       cgd 	    buf[chrs] = '\0';
    171  1.1       cgd 	    el->el_chared.c_macro.nline = strdup(buf);
    172  1.8     lukem 	    el_push(el, el->el_chared.c_macro.nline);
    173  1.1       cgd 	}
    174  1.1       cgd     }
    175  1.1       cgd #endif  /* FIONREAD */
    176  1.1       cgd 
    177  1.1       cgd     return chrs > 0;
    178  1.1       cgd }
    179  1.1       cgd 
    180  1.1       cgd 
    181  1.1       cgd /* el_push():
    182  1.1       cgd  *	Push a macro
    183  1.1       cgd  */
    184  1.1       cgd public void
    185  1.1       cgd el_push(el, str)
    186  1.1       cgd     EditLine *el;
    187  1.1       cgd     const char   *str;
    188  1.1       cgd {
    189  1.1       cgd     c_macro_t *ma = &el->el_chared.c_macro;
    190  1.1       cgd 
    191  1.1       cgd     if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
    192  1.1       cgd 	ma->level++;
    193  1.1       cgd 	ma->macro[ma->level] = (char *) str;
    194  1.1       cgd     }
    195  1.1       cgd     else {
    196  1.1       cgd 	term_beep(el);
    197  1.1       cgd 	term__flush();
    198  1.1       cgd     }
    199  1.1       cgd }
    200  1.1       cgd 
    201  1.1       cgd 
    202  1.1       cgd /* read_getcmd():
    203  1.1       cgd  *	Return next command from the input stream.
    204  1.1       cgd  */
    205  1.1       cgd private int
    206  1.1       cgd read_getcmd(el, cmdnum, ch)
    207  1.1       cgd     EditLine *el;
    208  1.1       cgd     el_action_t *cmdnum;
    209  1.1       cgd     char *ch;
    210  1.1       cgd {
    211  1.1       cgd     el_action_t  cmd = 0;
    212  1.1       cgd     int     num;
    213  1.1       cgd 
    214  1.1       cgd     while (cmd == 0 || cmd == ED_SEQUENCE_LEAD_IN) {
    215  1.1       cgd 	if ((num = el_getc(el, ch)) != 1)	/* if EOF or error */
    216  1.1       cgd 	    return num;
    217  1.1       cgd 
    218  1.1       cgd #ifdef	KANJI
    219  1.1       cgd 	if ((*ch & 0200)) {
    220  1.1       cgd 	    el->el_state.metanext = 0;
    221  1.1       cgd 	    cmd = CcViMap[' '];
    222  1.1       cgd 	    break;
    223  1.1       cgd 	}
    224  1.1       cgd 	else
    225  1.1       cgd #endif /* KANJI */
    226  1.1       cgd 
    227  1.1       cgd 	if (el->el_state.metanext) {
    228  1.1       cgd 	    el->el_state.metanext = 0;
    229  1.1       cgd 	    *ch |= 0200;
    230  1.1       cgd 	}
    231  1.1       cgd 	cmd = el->el_map.current[(unsigned char) *ch];
    232  1.1       cgd 	if (cmd == ED_SEQUENCE_LEAD_IN) {
    233  1.1       cgd 	    key_value_t val;
    234  1.1       cgd 	    switch (key_get(el, ch, &val)) {
    235  1.1       cgd 	    case XK_CMD:
    236  1.1       cgd 		cmd = val.cmd;
    237  1.1       cgd 		break;
    238  1.1       cgd 	    case XK_STR:
    239  1.1       cgd 		el_push(el, val.str);
    240  1.1       cgd 		break;
    241  1.1       cgd #ifdef notyet
    242  1.1       cgd 	    case XK_EXE:
    243  1.1       cgd 		/* XXX: In the future to run a user function */
    244  1.1       cgd 		RunCommand(val.str);
    245  1.1       cgd 		break;
    246  1.1       cgd #endif
    247  1.1       cgd 	    default:
    248  1.1       cgd 		abort();
    249  1.1       cgd 		break;
    250  1.1       cgd 	    }
    251  1.1       cgd 	}
    252  1.1       cgd 	if (el->el_map.alt == NULL)
    253  1.1       cgd 	    el->el_map.current = el->el_map.key;
    254  1.1       cgd     }
    255  1.1       cgd     *cmdnum = cmd;
    256  1.1       cgd     return OKCMD;
    257  1.1       cgd }
    258  1.1       cgd 
    259  1.6  christos /* read_char():
    260  1.6  christos  *	Read a character from the tty.
    261  1.6  christos  */
    262  1.6  christos private int
    263  1.6  christos read_char(el, cp)
    264  1.6  christos 	EditLine *el;
    265  1.6  christos 	char *cp;
    266  1.6  christos {
    267  1.6  christos     int num_read;
    268  1.6  christos     int tried = 0;
    269  1.6  christos 
    270  1.6  christos     while ((num_read = read(el->el_infd, cp, 1)) == -1)
    271  1.6  christos 	if (!tried && read__fixio(el->el_infd, errno) == 0)
    272  1.6  christos 	    tried = 1;
    273  1.6  christos 	else {
    274  1.6  christos 	    *cp = '\0';
    275  1.6  christos 	    return -1;
    276  1.6  christos 	}
    277  1.6  christos 
    278  1.6  christos     return num_read;
    279  1.6  christos }
    280  1.6  christos 
    281  1.1       cgd 
    282  1.1       cgd /* el_getc():
    283  1.1       cgd  *	Read a character
    284  1.1       cgd  */
    285  1.1       cgd public int
    286  1.1       cgd el_getc(el, cp)
    287  1.1       cgd     EditLine *el;
    288  1.1       cgd     char *cp;
    289  1.1       cgd {
    290  1.1       cgd     int num_read;
    291  1.1       cgd     c_macro_t *ma = &el->el_chared.c_macro;
    292  1.1       cgd 
    293  1.1       cgd     term__flush();
    294  1.1       cgd     for (;;) {
    295  1.1       cgd 	if (ma->level < 0) {
    296  1.1       cgd 	    if (!read_preread(el))
    297  1.1       cgd 		break;
    298  1.1       cgd 	}
    299  1.1       cgd 	if (ma->level < 0)
    300  1.1       cgd 	    break;
    301  1.1       cgd 
    302  1.1       cgd 	if (*ma->macro[ma->level] == 0) {
    303  1.1       cgd 	    ma->level--;
    304  1.1       cgd 	    continue;
    305  1.1       cgd 	}
    306  1.1       cgd 	*cp = *ma->macro[ma->level]++ & 0377;
    307  1.1       cgd 	if (*ma->macro[ma->level] == 0) {	/* Needed for QuoteMode On */
    308  1.1       cgd 	    ma->level--;
    309  1.1       cgd 	}
    310  1.1       cgd 	return 1;
    311  1.1       cgd     }
    312  1.1       cgd 
    313  1.1       cgd #ifdef DEBUG_READ
    314  1.1       cgd     (void) fprintf(el->el_errfile, "Turning raw mode on\n");
    315  1.1       cgd #endif /* DEBUG_READ */
    316  1.1       cgd     if (tty_rawmode(el) < 0)	/* make sure the tty is set up correctly */
    317  1.1       cgd 	return 0;
    318  1.1       cgd 
    319  1.1       cgd #ifdef DEBUG_READ
    320  1.1       cgd     (void) fprintf(el->el_errfile, "Reading a character\n");
    321  1.1       cgd #endif /* DEBUG_READ */
    322  1.6  christos     num_read = read_char(el, cp);
    323  1.1       cgd #ifdef DEBUG_READ
    324  1.6  christos     (void) fprintf(el->el_errfile, "Got it %c\n", cp);
    325  1.1       cgd #endif /* DEBUG_READ */
    326  1.1       cgd     return num_read;
    327  1.1       cgd }
    328  1.1       cgd 
    329  1.1       cgd 
    330  1.1       cgd 
    331  1.1       cgd public const char *
    332  1.1       cgd el_gets(el, nread)
    333  1.1       cgd     EditLine *el;
    334  1.1       cgd     int *nread;
    335  1.1       cgd {
    336  1.1       cgd     int retval;
    337  1.1       cgd     el_action_t  cmdnum = 0;
    338  1.1       cgd     int     num;		/* how many chars we have read at NL */
    339  1.1       cgd     char    ch;
    340  1.8     lukem #ifdef FIONREAD
    341  1.8     lukem     c_macro_t *ma = &el->el_chared.c_macro;
    342  1.8     lukem #endif /* FIONREAD */
    343  1.1       cgd 
    344  1.1       cgd     if (el->el_flags & HANDLE_SIGNALS)
    345  1.1       cgd 	sig_set(el);
    346  1.6  christos 
    347  1.7  christos     if (el->el_flags & NO_TTY) {
    348  1.6  christos 	char *cp = el->el_line.buffer;
    349  1.6  christos 
    350  1.7  christos 	while (read_char(el, cp) == 1) {
    351  1.7  christos 		cp++;
    352  1.7  christos 		if (cp == el->el_line.limit || *cp == '\r' || *cp == '\n') {
    353  1.6  christos 			--cp;
    354  1.6  christos 			break;
    355  1.6  christos 		}
    356  1.7  christos 	}
    357  1.6  christos 	el->el_line.cursor = el->el_line.lastchar = cp;
    358  1.6  christos 	*cp = '\0';
    359  1.6  christos 	if (nread)
    360  1.6  christos 		*nread = el->el_line.cursor - el->el_line.buffer;
    361  1.6  christos 	return el->el_line.buffer;
    362  1.6  christos     }
    363  1.1       cgd 
    364  1.1       cgd     re_clear_display(el);		/* reset the display stuff */
    365  1.1       cgd     ch_reset(el);
    366  1.1       cgd 
    367  1.1       cgd #ifdef FIONREAD
    368  1.1       cgd     if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
    369  1.1       cgd 	long    chrs = 0;
    370  1.1       cgd 
    371  1.1       cgd 	(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs);
    372  1.1       cgd 	if (chrs == 0) {
    373  1.1       cgd 	    if (tty_rawmode(el) < 0) {
    374  1.1       cgd 		if (nread)
    375  1.1       cgd 			*nread = 0;
    376  1.1       cgd 		return NULL;
    377  1.1       cgd 	    }
    378  1.1       cgd 	}
    379  1.1       cgd     }
    380  1.1       cgd #endif /* FIONREAD */
    381  1.1       cgd 
    382  1.1       cgd     re_refresh(el);			/* print the prompt */
    383  1.1       cgd 
    384  1.1       cgd     for (num = OKCMD; num == OKCMD;) {	/* while still editing this line */
    385  1.1       cgd #ifdef DEBUG_EDIT
    386  1.1       cgd 	read_debug(el);
    387  1.1       cgd #endif /* DEBUG_EDIT */
    388  1.1       cgd 	/* if EOF or error */
    389  1.1       cgd 	if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
    390  1.1       cgd #ifdef DEBUG_READ
    391  1.1       cgd 	    (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num);
    392  1.1       cgd #endif /* DEBUG_READ */
    393  1.1       cgd 	    break;
    394  1.1       cgd 	}
    395  1.1       cgd 
    396  1.1       cgd 	if (cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
    397  1.1       cgd #ifdef DEBUG_EDIT
    398  1.1       cgd 	    (void) fprintf(el->el_errfile,
    399  1.1       cgd 			   "ERROR: illegal command from key 0%o\r\n", ch);
    400  1.1       cgd #endif /* DEBUG_EDIT */
    401  1.1       cgd 	    continue;		/* try again */
    402  1.1       cgd 	}
    403  1.1       cgd 
    404  1.1       cgd 	/* now do the real command */
    405  1.1       cgd #ifdef DEBUG_READ
    406  1.1       cgd 	{
    407  1.1       cgd 	    el_bindings_t *b;
    408  1.1       cgd 	    for (b = el->el_map.help; b->name; b++)
    409  1.1       cgd 		if (b->func == cmdnum)
    410  1.1       cgd 		    break;
    411  1.1       cgd 	    if (b->name)
    412  1.1       cgd 		(void) fprintf(el->el_errfile, "Executing %s\n", b->name);
    413  1.1       cgd 	    else
    414  1.1       cgd 		(void) fprintf(el->el_errfile, "Error command = %d\n", cmdnum);
    415  1.1       cgd 	}
    416  1.1       cgd #endif /* DEBUG_READ */
    417  1.1       cgd 	retval = (*el->el_map.func[cmdnum])(el, ch);
    418  1.1       cgd 
    419  1.1       cgd 	/* save the last command here */
    420  1.1       cgd 	el->el_state.lastcmd = cmdnum;
    421  1.1       cgd 
    422  1.1       cgd 	/* use any return value */
    423  1.1       cgd 	switch (retval) {
    424  1.1       cgd 	case CC_CURSOR:
    425  1.1       cgd 	    el->el_state.argument = 1;
    426  1.1       cgd 	    el->el_state.doingarg = 0;
    427  1.1       cgd 	    re_refresh_cursor(el);
    428  1.1       cgd 	    break;
    429  1.3     lukem 
    430  1.3     lukem 	case CC_REDISPLAY:
    431  1.3     lukem 	    re_clear_lines(el);
    432  1.3     lukem 	    re_clear_display(el);
    433  1.3     lukem 		/* FALLTHROUGH */
    434  1.1       cgd 
    435  1.1       cgd 	case CC_REFRESH:
    436  1.1       cgd 	    el->el_state.argument = 1;
    437  1.1       cgd 	    el->el_state.doingarg = 0;
    438  1.1       cgd 	    re_refresh(el);
    439  1.1       cgd 	    break;
    440  1.1       cgd 
    441  1.1       cgd 	case CC_NORM:		/* normal char */
    442  1.1       cgd 	    el->el_state.argument = 1;
    443  1.1       cgd 	    el->el_state.doingarg = 0;
    444  1.1       cgd 	    break;
    445  1.1       cgd 
    446  1.1       cgd 	case CC_ARGHACK:	/* Suggested by Rich Salz */
    447  1.1       cgd 	    /* <rsalz (at) pineapple.bbn.com> */
    448  1.1       cgd 	    break;		/* keep going... */
    449  1.1       cgd 
    450  1.1       cgd 	case CC_EOF:		/* end of file typed */
    451  1.1       cgd 	    num = 0;
    452  1.1       cgd 	    break;
    453  1.1       cgd 
    454  1.1       cgd 	case CC_NEWLINE:	/* normal end of line */
    455  1.1       cgd 	    num = el->el_line.lastchar - el->el_line.buffer;
    456  1.1       cgd 	    break;
    457  1.1       cgd 
    458  1.1       cgd 	case CC_FATAL:		/* fatal error, reset to known state */
    459  1.1       cgd #ifdef DEBUG_READ
    460  1.1       cgd 	    (void) fprintf(el->el_errfile, "*** editor fatal ERROR ***\r\n\n");
    461  1.1       cgd #endif /* DEBUG_READ */
    462  1.1       cgd 	    /* put (real) cursor in a known place */
    463  1.1       cgd 	    re_clear_display(el);	/* reset the display stuff */
    464  1.1       cgd 	    ch_reset(el);		/* reset the input pointers */
    465  1.1       cgd 	    re_refresh(el);		/* print the prompt again */
    466  1.1       cgd 	    el->el_state.argument = 1;
    467  1.1       cgd 	    el->el_state.doingarg = 0;
    468  1.1       cgd 	    break;
    469  1.1       cgd 
    470  1.1       cgd 	case CC_ERROR:
    471  1.1       cgd 	default:		/* functions we don't know about */
    472  1.1       cgd #ifdef DEBUG_READ
    473  1.1       cgd 	    (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n");
    474  1.1       cgd #endif /* DEBUG_READ */
    475  1.1       cgd 	    el->el_state.argument = 1;
    476  1.1       cgd 	    el->el_state.doingarg = 0;
    477  1.1       cgd 	    term_beep(el);
    478  1.1       cgd 	    term__flush();
    479  1.1       cgd 	    break;
    480  1.1       cgd 	}
    481  1.1       cgd     }
    482  1.1       cgd 
    483  1.1       cgd     (void) tty_cookedmode(el);	/* make sure the tty is set up correctly */
    484  1.1       cgd     term__flush();		/* flush any buffered output */
    485  1.1       cgd     if (el->el_flags & HANDLE_SIGNALS)
    486  1.1       cgd 	sig_clr(el);
    487  1.1       cgd     if (nread)
    488  1.1       cgd 	    *nread = num;
    489  1.1       cgd     return num ? el->el_line.buffer : NULL;
    490  1.1       cgd }
    491