xref: /minix3/lib/libedit/read.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $	*/
23e1db26aSLionel Sambuc 
33e1db26aSLionel Sambuc /*-
43e1db26aSLionel Sambuc  * Copyright (c) 1992, 1993
53e1db26aSLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
63e1db26aSLionel Sambuc  *
73e1db26aSLionel Sambuc  * This code is derived from software contributed to Berkeley by
83e1db26aSLionel Sambuc  * Christos Zoulas of Cornell University.
93e1db26aSLionel Sambuc  *
103e1db26aSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
113e1db26aSLionel Sambuc  * modification, are permitted provided that the following conditions
123e1db26aSLionel Sambuc  * are met:
133e1db26aSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
143e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
153e1db26aSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
163e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
173e1db26aSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
183e1db26aSLionel Sambuc  * 3. Neither the name of the University nor the names of its contributors
193e1db26aSLionel Sambuc  *    may be used to endorse or promote products derived from this software
203e1db26aSLionel Sambuc  *    without specific prior written permission.
213e1db26aSLionel Sambuc  *
223e1db26aSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233e1db26aSLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243e1db26aSLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253e1db26aSLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263e1db26aSLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273e1db26aSLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283e1db26aSLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293e1db26aSLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303e1db26aSLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313e1db26aSLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323e1db26aSLionel Sambuc  * SUCH DAMAGE.
333e1db26aSLionel Sambuc  */
343e1db26aSLionel Sambuc 
353e1db26aSLionel Sambuc #include "config.h"
363e1db26aSLionel Sambuc #if !defined(lint) && !defined(SCCSID)
373e1db26aSLionel Sambuc #if 0
383e1db26aSLionel Sambuc static char sccsid[] = "@(#)read.c	8.1 (Berkeley) 6/4/93";
393e1db26aSLionel Sambuc #else
40*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: read.c,v 1.71 2014/07/06 18:15:34 christos Exp $");
413e1db26aSLionel Sambuc #endif
423e1db26aSLionel Sambuc #endif /* not lint && not SCCSID */
433e1db26aSLionel Sambuc 
443e1db26aSLionel Sambuc /*
453e1db26aSLionel Sambuc  * read.c: Clean this junk up! This is horrible code.
463e1db26aSLionel Sambuc  *	   Terminal read functions
473e1db26aSLionel Sambuc  */
483e1db26aSLionel Sambuc #include <errno.h>
493e1db26aSLionel Sambuc #include <fcntl.h>
503e1db26aSLionel Sambuc #include <unistd.h>
513e1db26aSLionel Sambuc #include <stdlib.h>
523e1db26aSLionel Sambuc #include <limits.h>
533e1db26aSLionel Sambuc #include "el.h"
543e1db26aSLionel Sambuc 
553e1db26aSLionel Sambuc #define OKCMD	-1	/* must be -1! */
563e1db26aSLionel Sambuc 
573e1db26aSLionel Sambuc private int	read__fixio(int, int);
583e1db26aSLionel Sambuc private int	read_preread(EditLine *);
593e1db26aSLionel Sambuc private int	read_char(EditLine *, Char *);
603e1db26aSLionel Sambuc private int	read_getcmd(EditLine *, el_action_t *, Char *);
613e1db26aSLionel Sambuc private void	read_pop(c_macro_t *);
623e1db26aSLionel Sambuc 
633e1db26aSLionel Sambuc /* read_init():
643e1db26aSLionel Sambuc  *	Initialize the read stuff
653e1db26aSLionel Sambuc  */
663e1db26aSLionel Sambuc protected int
read_init(EditLine * el)673e1db26aSLionel Sambuc read_init(EditLine *el)
683e1db26aSLionel Sambuc {
693e1db26aSLionel Sambuc 	/* builtin read_char */
703e1db26aSLionel Sambuc 	el->el_read.read_char = read_char;
713e1db26aSLionel Sambuc 	return 0;
723e1db26aSLionel Sambuc }
733e1db26aSLionel Sambuc 
743e1db26aSLionel Sambuc 
753e1db26aSLionel Sambuc /* el_read_setfn():
763e1db26aSLionel Sambuc  *	Set the read char function to the one provided.
773e1db26aSLionel Sambuc  *	If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
783e1db26aSLionel Sambuc  */
793e1db26aSLionel Sambuc protected int
el_read_setfn(EditLine * el,el_rfunc_t rc)803e1db26aSLionel Sambuc el_read_setfn(EditLine *el, el_rfunc_t rc)
813e1db26aSLionel Sambuc {
823e1db26aSLionel Sambuc 	el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
833e1db26aSLionel Sambuc 	return 0;
843e1db26aSLionel Sambuc }
853e1db26aSLionel Sambuc 
863e1db26aSLionel Sambuc 
873e1db26aSLionel Sambuc /* el_read_getfn():
883e1db26aSLionel Sambuc  *	return the current read char function, or EL_BUILTIN_GETCFN
893e1db26aSLionel Sambuc  *	if it is the default one
903e1db26aSLionel Sambuc  */
913e1db26aSLionel Sambuc protected el_rfunc_t
el_read_getfn(EditLine * el)923e1db26aSLionel Sambuc el_read_getfn(EditLine *el)
933e1db26aSLionel Sambuc {
943e1db26aSLionel Sambuc        return el->el_read.read_char == read_char ?
953e1db26aSLionel Sambuc 	    EL_BUILTIN_GETCFN : el->el_read.read_char;
963e1db26aSLionel Sambuc }
973e1db26aSLionel Sambuc 
983e1db26aSLionel Sambuc 
993e1db26aSLionel Sambuc #ifndef MIN
1003e1db26aSLionel Sambuc #define MIN(A,B) ((A) < (B) ? (A) : (B))
1013e1db26aSLionel Sambuc #endif
1023e1db26aSLionel Sambuc 
1033e1db26aSLionel Sambuc #ifdef DEBUG_EDIT
1043e1db26aSLionel Sambuc private void
read_debug(EditLine * el)1053e1db26aSLionel Sambuc read_debug(EditLine *el)
1063e1db26aSLionel Sambuc {
1073e1db26aSLionel Sambuc 
1083e1db26aSLionel Sambuc 	if (el->el_line.cursor > el->el_line.lastchar)
1093e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
1103e1db26aSLionel Sambuc 	if (el->el_line.cursor < el->el_line.buffer)
1113e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile, "cursor < buffer\r\n");
1123e1db26aSLionel Sambuc 	if (el->el_line.cursor > el->el_line.limit)
1133e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile, "cursor > limit\r\n");
1143e1db26aSLionel Sambuc 	if (el->el_line.lastchar > el->el_line.limit)
1153e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile, "lastchar > limit\r\n");
1163e1db26aSLionel Sambuc 	if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
1173e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
1183e1db26aSLionel Sambuc }
1193e1db26aSLionel Sambuc #endif /* DEBUG_EDIT */
1203e1db26aSLionel Sambuc 
1213e1db26aSLionel Sambuc 
1223e1db26aSLionel Sambuc /* read__fixio():
1233e1db26aSLionel Sambuc  *	Try to recover from a read error
1243e1db26aSLionel Sambuc  */
1253e1db26aSLionel Sambuc /* ARGSUSED */
1263e1db26aSLionel Sambuc private int
read__fixio(int fd,int e)1273e1db26aSLionel Sambuc read__fixio(int fd __attribute__((__unused__)), int e)
1283e1db26aSLionel Sambuc {
1293e1db26aSLionel Sambuc 
1303e1db26aSLionel Sambuc 	switch (e) {
1313e1db26aSLionel Sambuc 	case -1:		/* Make sure that the code is reachable */
1323e1db26aSLionel Sambuc 
1333e1db26aSLionel Sambuc #ifdef EWOULDBLOCK
1343e1db26aSLionel Sambuc 	case EWOULDBLOCK:
1353e1db26aSLionel Sambuc #ifndef TRY_AGAIN
1363e1db26aSLionel Sambuc #define TRY_AGAIN
1373e1db26aSLionel Sambuc #endif
1383e1db26aSLionel Sambuc #endif /* EWOULDBLOCK */
1393e1db26aSLionel Sambuc 
1403e1db26aSLionel Sambuc #if defined(POSIX) && defined(EAGAIN)
1413e1db26aSLionel Sambuc #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
1423e1db26aSLionel Sambuc 	case EAGAIN:
1433e1db26aSLionel Sambuc #ifndef TRY_AGAIN
1443e1db26aSLionel Sambuc #define TRY_AGAIN
1453e1db26aSLionel Sambuc #endif
1463e1db26aSLionel Sambuc #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
1473e1db26aSLionel Sambuc #endif /* POSIX && EAGAIN */
1483e1db26aSLionel Sambuc 
1493e1db26aSLionel Sambuc 		e = 0;
1503e1db26aSLionel Sambuc #ifdef TRY_AGAIN
1513e1db26aSLionel Sambuc #if defined(F_SETFL) && defined(O_NDELAY)
1523e1db26aSLionel Sambuc 		if ((e = fcntl(fd, F_GETFL, 0)) == -1)
1533e1db26aSLionel Sambuc 			return -1;
1543e1db26aSLionel Sambuc 
1553e1db26aSLionel Sambuc 		if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
1563e1db26aSLionel Sambuc 			return -1;
1573e1db26aSLionel Sambuc 		else
1583e1db26aSLionel Sambuc 			e = 1;
1593e1db26aSLionel Sambuc #endif /* F_SETFL && O_NDELAY */
1603e1db26aSLionel Sambuc 
1613e1db26aSLionel Sambuc #ifdef FIONBIO
1623e1db26aSLionel Sambuc 		{
1633e1db26aSLionel Sambuc 			int zero = 0;
1643e1db26aSLionel Sambuc 
1653e1db26aSLionel Sambuc 			if (ioctl(fd, FIONBIO, &zero) == -1)
1663e1db26aSLionel Sambuc 				return -1;
1673e1db26aSLionel Sambuc 			else
1683e1db26aSLionel Sambuc 				e = 1;
1693e1db26aSLionel Sambuc 		}
1703e1db26aSLionel Sambuc #endif /* FIONBIO */
1713e1db26aSLionel Sambuc 
1723e1db26aSLionel Sambuc #endif /* TRY_AGAIN */
1733e1db26aSLionel Sambuc 		return e ? 0 : -1;
1743e1db26aSLionel Sambuc 
1753e1db26aSLionel Sambuc 	case EINTR:
1763e1db26aSLionel Sambuc 		return 0;
1773e1db26aSLionel Sambuc 
1783e1db26aSLionel Sambuc 	default:
1793e1db26aSLionel Sambuc 		return -1;
1803e1db26aSLionel Sambuc 	}
1813e1db26aSLionel Sambuc }
1823e1db26aSLionel Sambuc 
1833e1db26aSLionel Sambuc 
1843e1db26aSLionel Sambuc /* read_preread():
1853e1db26aSLionel Sambuc  *	Try to read the stuff in the input queue;
1863e1db26aSLionel Sambuc  */
1873e1db26aSLionel Sambuc private int
read_preread(EditLine * el)1883e1db26aSLionel Sambuc read_preread(EditLine *el)
1893e1db26aSLionel Sambuc {
1903e1db26aSLionel Sambuc 	int chrs = 0;
1913e1db26aSLionel Sambuc 
1923e1db26aSLionel Sambuc 	if (el->el_tty.t_mode == ED_IO)
1933e1db26aSLionel Sambuc 		return 0;
1943e1db26aSLionel Sambuc 
1953e1db26aSLionel Sambuc #ifndef WIDECHAR
1963e1db26aSLionel Sambuc /* FIONREAD attempts to buffer up multiple bytes, and to make that work
1973e1db26aSLionel Sambuc  * properly with partial wide/UTF-8 characters would need some careful work. */
1983e1db26aSLionel Sambuc #ifdef FIONREAD
1993e1db26aSLionel Sambuc 	(void) ioctl(el->el_infd, FIONREAD, &chrs);
2003e1db26aSLionel Sambuc 	if (chrs > 0) {
2013e1db26aSLionel Sambuc 		char buf[EL_BUFSIZ];
2023e1db26aSLionel Sambuc 
2033e1db26aSLionel Sambuc 		chrs = read(el->el_infd, buf,
2043e1db26aSLionel Sambuc 		    (size_t) MIN(chrs, EL_BUFSIZ - 1));
2053e1db26aSLionel Sambuc 		if (chrs > 0) {
2063e1db26aSLionel Sambuc 			buf[chrs] = '\0';
2073e1db26aSLionel Sambuc 			el_push(el, buf);
2083e1db26aSLionel Sambuc 		}
2093e1db26aSLionel Sambuc 	}
2103e1db26aSLionel Sambuc #endif /* FIONREAD */
2113e1db26aSLionel Sambuc #endif
2123e1db26aSLionel Sambuc 	return chrs > 0;
2133e1db26aSLionel Sambuc }
2143e1db26aSLionel Sambuc 
2153e1db26aSLionel Sambuc 
2163e1db26aSLionel Sambuc /* el_push():
2173e1db26aSLionel Sambuc  *	Push a macro
2183e1db26aSLionel Sambuc  */
2193e1db26aSLionel Sambuc public void
FUN(el,push)2203e1db26aSLionel Sambuc FUN(el,push)(EditLine *el, const Char *str)
2213e1db26aSLionel Sambuc {
2223e1db26aSLionel Sambuc 	c_macro_t *ma = &el->el_chared.c_macro;
2233e1db26aSLionel Sambuc 
2243e1db26aSLionel Sambuc 	if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
2253e1db26aSLionel Sambuc 		ma->level++;
2263e1db26aSLionel Sambuc 		if ((ma->macro[ma->level] = Strdup(str)) != NULL)
2273e1db26aSLionel Sambuc 			return;
2283e1db26aSLionel Sambuc 		ma->level--;
2293e1db26aSLionel Sambuc 	}
2303e1db26aSLionel Sambuc 	terminal_beep(el);
2313e1db26aSLionel Sambuc 	terminal__flush(el);
2323e1db26aSLionel Sambuc }
2333e1db26aSLionel Sambuc 
2343e1db26aSLionel Sambuc 
2353e1db26aSLionel Sambuc /* read_getcmd():
2363e1db26aSLionel Sambuc  *	Get next command from the input stream, return OKCMD on success.
2373e1db26aSLionel Sambuc  *	Character values > 255 are not looked up in the map, but inserted.
2383e1db26aSLionel Sambuc  */
2393e1db26aSLionel Sambuc private int
read_getcmd(EditLine * el,el_action_t * cmdnum,Char * ch)2403e1db26aSLionel Sambuc read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
2413e1db26aSLionel Sambuc {
2423e1db26aSLionel Sambuc 	el_action_t cmd;
2433e1db26aSLionel Sambuc 	int num;
2443e1db26aSLionel Sambuc 
2453e1db26aSLionel Sambuc 	el->el_errno = 0;
2463e1db26aSLionel Sambuc 	do {
2473e1db26aSLionel Sambuc 		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
2483e1db26aSLionel Sambuc 			el->el_errno = num == 0 ? 0 : errno;
2493e1db26aSLionel Sambuc 			return 0;	/* not OKCMD */
2503e1db26aSLionel Sambuc 		}
2513e1db26aSLionel Sambuc 
2523e1db26aSLionel Sambuc #ifdef	KANJI
2533e1db26aSLionel Sambuc 		if ((*ch & 0200)) {
2543e1db26aSLionel Sambuc 			el->el_state.metanext = 0;
2553e1db26aSLionel Sambuc 			cmd = CcViMap[' '];
2563e1db26aSLionel Sambuc 			break;
2573e1db26aSLionel Sambuc 		} else
2583e1db26aSLionel Sambuc #endif /* KANJI */
2593e1db26aSLionel Sambuc 
2603e1db26aSLionel Sambuc 		if (el->el_state.metanext) {
2613e1db26aSLionel Sambuc 			el->el_state.metanext = 0;
2623e1db26aSLionel Sambuc 			*ch |= 0200;
2633e1db26aSLionel Sambuc 		}
2643e1db26aSLionel Sambuc #ifdef WIDECHAR
2653e1db26aSLionel Sambuc 		if (*ch >= N_KEYS)
2663e1db26aSLionel Sambuc 			cmd = ED_INSERT;
2673e1db26aSLionel Sambuc 		else
2683e1db26aSLionel Sambuc #endif
2693e1db26aSLionel Sambuc 			cmd = el->el_map.current[(unsigned char) *ch];
2703e1db26aSLionel Sambuc 		if (cmd == ED_SEQUENCE_LEAD_IN) {
2713e1db26aSLionel Sambuc 			keymacro_value_t val;
2723e1db26aSLionel Sambuc 			switch (keymacro_get(el, ch, &val)) {
2733e1db26aSLionel Sambuc 			case XK_CMD:
2743e1db26aSLionel Sambuc 				cmd = val.cmd;
2753e1db26aSLionel Sambuc 				break;
2763e1db26aSLionel Sambuc 			case XK_STR:
2773e1db26aSLionel Sambuc 				FUN(el,push)(el, val.str);
2783e1db26aSLionel Sambuc 				break;
2793e1db26aSLionel Sambuc #ifdef notyet
2803e1db26aSLionel Sambuc 			case XK_EXE:
2813e1db26aSLionel Sambuc 				/* XXX: In the future to run a user function */
2823e1db26aSLionel Sambuc 				RunCommand(val.str);
2833e1db26aSLionel Sambuc 				break;
2843e1db26aSLionel Sambuc #endif
2853e1db26aSLionel Sambuc 			default:
2863e1db26aSLionel Sambuc 				EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
2873e1db26aSLionel Sambuc 				break;
2883e1db26aSLionel Sambuc 			}
2893e1db26aSLionel Sambuc 		}
2903e1db26aSLionel Sambuc 		if (el->el_map.alt == NULL)
2913e1db26aSLionel Sambuc 			el->el_map.current = el->el_map.key;
2923e1db26aSLionel Sambuc 	} while (cmd == ED_SEQUENCE_LEAD_IN);
2933e1db26aSLionel Sambuc 	*cmdnum = cmd;
2943e1db26aSLionel Sambuc 	return OKCMD;
2953e1db26aSLionel Sambuc }
2963e1db26aSLionel Sambuc 
2973e1db26aSLionel Sambuc #ifdef WIDECHAR
2983e1db26aSLionel Sambuc /* utf8_islead():
2993e1db26aSLionel Sambuc  *	Test whether a byte is a leading byte of a UTF-8 sequence.
3003e1db26aSLionel Sambuc  */
3013e1db26aSLionel Sambuc private int
utf8_islead(int c)3023e1db26aSLionel Sambuc utf8_islead(int c)
3033e1db26aSLionel Sambuc {
3043e1db26aSLionel Sambuc 	return c < 0x80 ||	       /* single byte char */
3053e1db26aSLionel Sambuc 	       (c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */
3063e1db26aSLionel Sambuc }
3073e1db26aSLionel Sambuc #endif
3083e1db26aSLionel Sambuc 
3093e1db26aSLionel Sambuc /* read_char():
3103e1db26aSLionel Sambuc  *	Read a character from the tty.
3113e1db26aSLionel Sambuc  */
3123e1db26aSLionel Sambuc private int
read_char(EditLine * el,Char * cp)3133e1db26aSLionel Sambuc read_char(EditLine *el, Char *cp)
3143e1db26aSLionel Sambuc {
3153e1db26aSLionel Sambuc 	ssize_t num_read;
3163e1db26aSLionel Sambuc 	int tried = 0;
3173e1db26aSLionel Sambuc 	char cbuf[MB_LEN_MAX];
3183e1db26aSLionel Sambuc 	size_t cbp = 0;
3193e1db26aSLionel Sambuc 	int bytes = 0;
3203e1db26aSLionel Sambuc 
3213e1db26aSLionel Sambuc  again:
3223e1db26aSLionel Sambuc 	el->el_signal->sig_no = 0;
3233e1db26aSLionel Sambuc 	while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
3243e1db26aSLionel Sambuc 		int e = errno;
3253e1db26aSLionel Sambuc 		switch (el->el_signal->sig_no) {
3263e1db26aSLionel Sambuc 		case SIGCONT:
3273e1db26aSLionel Sambuc 			FUN(el,set)(el, EL_REFRESH);
3283e1db26aSLionel Sambuc 			/*FALLTHROUGH*/
3293e1db26aSLionel Sambuc 		case SIGWINCH:
3303e1db26aSLionel Sambuc 			sig_set(el);
3313e1db26aSLionel Sambuc 			goto again;
3323e1db26aSLionel Sambuc 		default:
3333e1db26aSLionel Sambuc 			break;
3343e1db26aSLionel Sambuc 		}
3353e1db26aSLionel Sambuc 		if (!tried && read__fixio(el->el_infd, e) == 0)
3363e1db26aSLionel Sambuc 			tried = 1;
3373e1db26aSLionel Sambuc 		else {
3383e1db26aSLionel Sambuc 			errno = e;
3393e1db26aSLionel Sambuc 			*cp = '\0';
3403e1db26aSLionel Sambuc 			return -1;
3413e1db26aSLionel Sambuc 		}
3423e1db26aSLionel Sambuc 	}
3433e1db26aSLionel Sambuc 
34484d9c625SLionel Sambuc 	/* Test for EOF */
34584d9c625SLionel Sambuc 	if (num_read == 0) {
34684d9c625SLionel Sambuc 		errno = 0;
34784d9c625SLionel Sambuc 		*cp = '\0';
34884d9c625SLionel Sambuc 		return 0;
34984d9c625SLionel Sambuc 	}
35084d9c625SLionel Sambuc 
3513e1db26aSLionel Sambuc #ifdef WIDECHAR
3523e1db26aSLionel Sambuc 	if (el->el_flags & CHARSET_IS_UTF8) {
3533e1db26aSLionel Sambuc 		if (!utf8_islead((unsigned char)cbuf[0]))
3543e1db26aSLionel Sambuc 			goto again; /* discard the byte we read and try again */
3553e1db26aSLionel Sambuc 		++cbp;
3563e1db26aSLionel Sambuc 		if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
3573e1db26aSLionel Sambuc 			ct_mbtowc_reset;
3583e1db26aSLionel Sambuc 			if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
3593e1db26aSLionel Sambuc 				errno = EILSEQ;
3603e1db26aSLionel Sambuc 				*cp = '\0';
3613e1db26aSLionel Sambuc 				return -1;
3623e1db26aSLionel Sambuc 			}
3633e1db26aSLionel Sambuc 			goto again;
3643e1db26aSLionel Sambuc 		}
3653e1db26aSLionel Sambuc 	} else if (isascii((unsigned char)cbuf[0]) ||
3663e1db26aSLionel Sambuc 		/* we don't support other multibyte charsets */
3673e1db26aSLionel Sambuc 		++cbp != 1 ||
3683e1db26aSLionel Sambuc 		/* Try non-ASCII characters in a 8-bit character set */
3693e1db26aSLionel Sambuc 		(bytes = ct_mbtowc(cp, cbuf, cbp)) != 1)
3703e1db26aSLionel Sambuc #endif
3713e1db26aSLionel Sambuc 		*cp = (unsigned char)cbuf[0];
3723e1db26aSLionel Sambuc 
3733e1db26aSLionel Sambuc 	if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
3743e1db26aSLionel Sambuc 		cbp = 0; /* skip this character */
3753e1db26aSLionel Sambuc 		goto again;
3763e1db26aSLionel Sambuc 	}
3773e1db26aSLionel Sambuc 
3783e1db26aSLionel Sambuc 	return (int)num_read;
3793e1db26aSLionel Sambuc }
3803e1db26aSLionel Sambuc 
3813e1db26aSLionel Sambuc /* read_pop():
3823e1db26aSLionel Sambuc  *	Pop a macro from the stack
3833e1db26aSLionel Sambuc  */
3843e1db26aSLionel Sambuc private void
read_pop(c_macro_t * ma)3853e1db26aSLionel Sambuc read_pop(c_macro_t *ma)
3863e1db26aSLionel Sambuc {
3873e1db26aSLionel Sambuc 	int i;
3883e1db26aSLionel Sambuc 
3893e1db26aSLionel Sambuc 	el_free(ma->macro[0]);
3903e1db26aSLionel Sambuc 	for (i = 0; i < ma->level; i++)
3913e1db26aSLionel Sambuc 		ma->macro[i] = ma->macro[i + 1];
3923e1db26aSLionel Sambuc 	ma->level--;
3933e1db26aSLionel Sambuc 	ma->offset = 0;
3943e1db26aSLionel Sambuc }
3953e1db26aSLionel Sambuc 
3963e1db26aSLionel Sambuc /* el_getc():
3973e1db26aSLionel Sambuc  *	Read a character
3983e1db26aSLionel Sambuc  */
3993e1db26aSLionel Sambuc public int
FUN(el,getc)4003e1db26aSLionel Sambuc FUN(el,getc)(EditLine *el, Char *cp)
4013e1db26aSLionel Sambuc {
4023e1db26aSLionel Sambuc 	int num_read;
4033e1db26aSLionel Sambuc 	c_macro_t *ma = &el->el_chared.c_macro;
4043e1db26aSLionel Sambuc 
4053e1db26aSLionel Sambuc 	terminal__flush(el);
4063e1db26aSLionel Sambuc 	for (;;) {
4073e1db26aSLionel Sambuc 		if (ma->level < 0) {
4083e1db26aSLionel Sambuc 			if (!read_preread(el))
4093e1db26aSLionel Sambuc 				break;
4103e1db26aSLionel Sambuc 		}
4113e1db26aSLionel Sambuc 
4123e1db26aSLionel Sambuc 		if (ma->level < 0)
4133e1db26aSLionel Sambuc 			break;
4143e1db26aSLionel Sambuc 
4153e1db26aSLionel Sambuc 		if (ma->macro[0][ma->offset] == '\0') {
4163e1db26aSLionel Sambuc 			read_pop(ma);
4173e1db26aSLionel Sambuc 			continue;
4183e1db26aSLionel Sambuc 		}
4193e1db26aSLionel Sambuc 
4203e1db26aSLionel Sambuc 		*cp = ma->macro[0][ma->offset++];
4213e1db26aSLionel Sambuc 
4223e1db26aSLionel Sambuc 		if (ma->macro[0][ma->offset] == '\0') {
4233e1db26aSLionel Sambuc 			/* Needed for QuoteMode On */
4243e1db26aSLionel Sambuc 			read_pop(ma);
4253e1db26aSLionel Sambuc 		}
4263e1db26aSLionel Sambuc 
4273e1db26aSLionel Sambuc 		return 1;
4283e1db26aSLionel Sambuc 	}
4293e1db26aSLionel Sambuc 
4303e1db26aSLionel Sambuc #ifdef DEBUG_READ
4313e1db26aSLionel Sambuc 	(void) fprintf(el->el_errfile, "Turning raw mode on\n");
4323e1db26aSLionel Sambuc #endif /* DEBUG_READ */
4333e1db26aSLionel Sambuc 	if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
4343e1db26aSLionel Sambuc 		return 0;
4353e1db26aSLionel Sambuc 
4363e1db26aSLionel Sambuc #ifdef DEBUG_READ
4373e1db26aSLionel Sambuc 	(void) fprintf(el->el_errfile, "Reading a character\n");
4383e1db26aSLionel Sambuc #endif /* DEBUG_READ */
4393e1db26aSLionel Sambuc 	num_read = (*el->el_read.read_char)(el, cp);
4403e1db26aSLionel Sambuc 	if (num_read < 0)
4413e1db26aSLionel Sambuc 		el->el_errno = errno;
4423e1db26aSLionel Sambuc #ifdef WIDECHAR
4433e1db26aSLionel Sambuc 	if (el->el_flags & NARROW_READ)
4443e1db26aSLionel Sambuc 		*cp = *(char *)(void *)cp;
4453e1db26aSLionel Sambuc #endif
4463e1db26aSLionel Sambuc #ifdef DEBUG_READ
4473e1db26aSLionel Sambuc 	(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
4483e1db26aSLionel Sambuc #endif /* DEBUG_READ */
4493e1db26aSLionel Sambuc 	return num_read;
4503e1db26aSLionel Sambuc }
4513e1db26aSLionel Sambuc 
4523e1db26aSLionel Sambuc protected void
read_prepare(EditLine * el)4533e1db26aSLionel Sambuc read_prepare(EditLine *el)
4543e1db26aSLionel Sambuc {
4553e1db26aSLionel Sambuc 	if (el->el_flags & HANDLE_SIGNALS)
4563e1db26aSLionel Sambuc 		sig_set(el);
4573e1db26aSLionel Sambuc 	if (el->el_flags & NO_TTY)
4583e1db26aSLionel Sambuc 		return;
4593e1db26aSLionel Sambuc 	if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
4603e1db26aSLionel Sambuc 		tty_rawmode(el);
4613e1db26aSLionel Sambuc 
4623e1db26aSLionel Sambuc 	/* This is relatively cheap, and things go terribly wrong if
4633e1db26aSLionel Sambuc 	   we have the wrong size. */
4643e1db26aSLionel Sambuc 	el_resize(el);
4653e1db26aSLionel Sambuc 	re_clear_display(el);	/* reset the display stuff */
4663e1db26aSLionel Sambuc 	ch_reset(el, 0);
4673e1db26aSLionel Sambuc 	re_refresh(el);		/* print the prompt */
4683e1db26aSLionel Sambuc 
4693e1db26aSLionel Sambuc 	if (el->el_flags & UNBUFFERED)
4703e1db26aSLionel Sambuc 		terminal__flush(el);
4713e1db26aSLionel Sambuc }
4723e1db26aSLionel Sambuc 
4733e1db26aSLionel Sambuc protected void
read_finish(EditLine * el)4743e1db26aSLionel Sambuc read_finish(EditLine *el)
4753e1db26aSLionel Sambuc {
4763e1db26aSLionel Sambuc 	if ((el->el_flags & UNBUFFERED) == 0)
4773e1db26aSLionel Sambuc 		(void) tty_cookedmode(el);
4783e1db26aSLionel Sambuc 	if (el->el_flags & HANDLE_SIGNALS)
4793e1db26aSLionel Sambuc 		sig_clr(el);
4803e1db26aSLionel Sambuc }
4813e1db26aSLionel Sambuc 
4823e1db26aSLionel Sambuc public const Char *
FUN(el,gets)4833e1db26aSLionel Sambuc FUN(el,gets)(EditLine *el, int *nread)
4843e1db26aSLionel Sambuc {
4853e1db26aSLionel Sambuc 	int retval;
4863e1db26aSLionel Sambuc 	el_action_t cmdnum = 0;
4873e1db26aSLionel Sambuc 	int num;		/* how many chars we have read at NL */
4883e1db26aSLionel Sambuc 	Char ch, *cp;
4893e1db26aSLionel Sambuc 	int crlf = 0;
4903e1db26aSLionel Sambuc 	int nrb;
4913e1db26aSLionel Sambuc #ifdef FIONREAD
4923e1db26aSLionel Sambuc 	c_macro_t *ma = &el->el_chared.c_macro;
4933e1db26aSLionel Sambuc #endif /* FIONREAD */
4943e1db26aSLionel Sambuc 
4953e1db26aSLionel Sambuc 	if (nread == NULL)
4963e1db26aSLionel Sambuc 		nread = &nrb;
4973e1db26aSLionel Sambuc 	*nread = 0;
4983e1db26aSLionel Sambuc 
4993e1db26aSLionel Sambuc 	if (el->el_flags & NO_TTY) {
5003e1db26aSLionel Sambuc 		size_t idx;
5013e1db26aSLionel Sambuc 
5023e1db26aSLionel Sambuc 		cp = el->el_line.buffer;
5033e1db26aSLionel Sambuc 		while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
5043e1db26aSLionel Sambuc 			/* make sure there is space for next character */
5053e1db26aSLionel Sambuc 			if (cp + 1 >= el->el_line.limit) {
5063e1db26aSLionel Sambuc 				idx = (size_t)(cp - el->el_line.buffer);
5073e1db26aSLionel Sambuc 				if (!ch_enlargebufs(el, (size_t)2))
5083e1db26aSLionel Sambuc 					break;
5093e1db26aSLionel Sambuc 				cp = &el->el_line.buffer[idx];
5103e1db26aSLionel Sambuc 			}
5113e1db26aSLionel Sambuc 			cp++;
5123e1db26aSLionel Sambuc 			if (el->el_flags & UNBUFFERED)
5133e1db26aSLionel Sambuc 				break;
5143e1db26aSLionel Sambuc 			if (cp[-1] == '\r' || cp[-1] == '\n')
5153e1db26aSLionel Sambuc 				break;
5163e1db26aSLionel Sambuc 		}
5173e1db26aSLionel Sambuc 		if (num == -1) {
5183e1db26aSLionel Sambuc 			if (errno == EINTR)
5193e1db26aSLionel Sambuc 				cp = el->el_line.buffer;
5203e1db26aSLionel Sambuc 			el->el_errno = errno;
5213e1db26aSLionel Sambuc 		}
5223e1db26aSLionel Sambuc 
5233e1db26aSLionel Sambuc 		goto noedit;
5243e1db26aSLionel Sambuc 	}
5253e1db26aSLionel Sambuc 
5263e1db26aSLionel Sambuc 
5273e1db26aSLionel Sambuc #ifdef FIONREAD
5283e1db26aSLionel Sambuc 	if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
5293e1db26aSLionel Sambuc 		long chrs = 0;
5303e1db26aSLionel Sambuc 
5313e1db26aSLionel Sambuc 		(void) ioctl(el->el_infd, FIONREAD, &chrs);
5323e1db26aSLionel Sambuc 		if (chrs == 0) {
5333e1db26aSLionel Sambuc 			if (tty_rawmode(el) < 0) {
5343e1db26aSLionel Sambuc 				errno = 0;
5353e1db26aSLionel Sambuc 				*nread = 0;
5363e1db26aSLionel Sambuc 				return NULL;
5373e1db26aSLionel Sambuc 			}
5383e1db26aSLionel Sambuc 		}
5393e1db26aSLionel Sambuc 	}
5403e1db26aSLionel Sambuc #endif /* FIONREAD */
5413e1db26aSLionel Sambuc 
5423e1db26aSLionel Sambuc 	if ((el->el_flags & UNBUFFERED) == 0)
5433e1db26aSLionel Sambuc 		read_prepare(el);
5443e1db26aSLionel Sambuc 
5453e1db26aSLionel Sambuc 	if (el->el_flags & EDIT_DISABLED) {
5463e1db26aSLionel Sambuc 		size_t idx;
5473e1db26aSLionel Sambuc 
5483e1db26aSLionel Sambuc 		if ((el->el_flags & UNBUFFERED) == 0)
5493e1db26aSLionel Sambuc 			cp = el->el_line.buffer;
5503e1db26aSLionel Sambuc 		else
5513e1db26aSLionel Sambuc 			cp = el->el_line.lastchar;
5523e1db26aSLionel Sambuc 
5533e1db26aSLionel Sambuc 		terminal__flush(el);
5543e1db26aSLionel Sambuc 
5553e1db26aSLionel Sambuc 		while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
5563e1db26aSLionel Sambuc 			/* make sure there is space next character */
5573e1db26aSLionel Sambuc 			if (cp + 1 >= el->el_line.limit) {
5583e1db26aSLionel Sambuc 				idx = (size_t)(cp - el->el_line.buffer);
5593e1db26aSLionel Sambuc 				if (!ch_enlargebufs(el, (size_t)2))
5603e1db26aSLionel Sambuc 					break;
5613e1db26aSLionel Sambuc 				cp = &el->el_line.buffer[idx];
5623e1db26aSLionel Sambuc 			}
5633e1db26aSLionel Sambuc 			cp++;
5643e1db26aSLionel Sambuc 			crlf = cp[-1] == '\r' || cp[-1] == '\n';
5653e1db26aSLionel Sambuc 			if (el->el_flags & UNBUFFERED)
5663e1db26aSLionel Sambuc 				break;
5673e1db26aSLionel Sambuc 			if (crlf)
5683e1db26aSLionel Sambuc 				break;
5693e1db26aSLionel Sambuc 		}
5703e1db26aSLionel Sambuc 
5713e1db26aSLionel Sambuc 		if (num == -1) {
5723e1db26aSLionel Sambuc 			if (errno == EINTR)
5733e1db26aSLionel Sambuc 				cp = el->el_line.buffer;
5743e1db26aSLionel Sambuc 			el->el_errno = errno;
5753e1db26aSLionel Sambuc 		}
5763e1db26aSLionel Sambuc 
5773e1db26aSLionel Sambuc 		goto noedit;
5783e1db26aSLionel Sambuc 	}
5793e1db26aSLionel Sambuc 
5803e1db26aSLionel Sambuc 	for (num = OKCMD; num == OKCMD;) {	/* while still editing this
5813e1db26aSLionel Sambuc 						 * line */
5823e1db26aSLionel Sambuc #ifdef DEBUG_EDIT
5833e1db26aSLionel Sambuc 		read_debug(el);
5843e1db26aSLionel Sambuc #endif /* DEBUG_EDIT */
5853e1db26aSLionel Sambuc 		/* if EOF or error */
5863e1db26aSLionel Sambuc 		if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
5873e1db26aSLionel Sambuc 			num = -1;
5883e1db26aSLionel Sambuc #ifdef DEBUG_READ
5893e1db26aSLionel Sambuc 			(void) fprintf(el->el_errfile,
5903e1db26aSLionel Sambuc 			    "Returning from el_gets %d\n", num);
5913e1db26aSLionel Sambuc #endif /* DEBUG_READ */
5923e1db26aSLionel Sambuc 			break;
5933e1db26aSLionel Sambuc 		}
5943e1db26aSLionel Sambuc 		if (el->el_errno == EINTR) {
5953e1db26aSLionel Sambuc 			el->el_line.buffer[0] = '\0';
5963e1db26aSLionel Sambuc 			el->el_line.lastchar =
5973e1db26aSLionel Sambuc 			    el->el_line.cursor = el->el_line.buffer;
5983e1db26aSLionel Sambuc 			break;
5993e1db26aSLionel Sambuc 		}
600*0a6a1f1dSLionel Sambuc 		if ((size_t)cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
6013e1db26aSLionel Sambuc #ifdef DEBUG_EDIT
6023e1db26aSLionel Sambuc 			(void) fprintf(el->el_errfile,
6033e1db26aSLionel Sambuc 			    "ERROR: illegal command from key 0%o\r\n", ch);
6043e1db26aSLionel Sambuc #endif /* DEBUG_EDIT */
6053e1db26aSLionel Sambuc 			continue;	/* try again */
6063e1db26aSLionel Sambuc 		}
6073e1db26aSLionel Sambuc 		/* now do the real command */
6083e1db26aSLionel Sambuc #ifdef DEBUG_READ
6093e1db26aSLionel Sambuc 		{
6103e1db26aSLionel Sambuc 			el_bindings_t *b;
6113e1db26aSLionel Sambuc 			for (b = el->el_map.help; b->name; b++)
6123e1db26aSLionel Sambuc 				if (b->func == cmdnum)
6133e1db26aSLionel Sambuc 					break;
6143e1db26aSLionel Sambuc 			if (b->name)
6153e1db26aSLionel Sambuc 				(void) fprintf(el->el_errfile,
6163e1db26aSLionel Sambuc 				    "Executing %s\n", b->name);
6173e1db26aSLionel Sambuc 			else
6183e1db26aSLionel Sambuc 				(void) fprintf(el->el_errfile,
6193e1db26aSLionel Sambuc 				    "Error command = %d\n", cmdnum);
6203e1db26aSLionel Sambuc 		}
6213e1db26aSLionel Sambuc #endif /* DEBUG_READ */
6223e1db26aSLionel Sambuc 		/* vi redo needs these way down the levels... */
6233e1db26aSLionel Sambuc 		el->el_state.thiscmd = cmdnum;
6243e1db26aSLionel Sambuc 		el->el_state.thisch = ch;
6253e1db26aSLionel Sambuc 		if (el->el_map.type == MAP_VI &&
6263e1db26aSLionel Sambuc 		    el->el_map.current == el->el_map.key &&
6273e1db26aSLionel Sambuc 		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
6283e1db26aSLionel Sambuc 			if (cmdnum == VI_DELETE_PREV_CHAR &&
6293e1db26aSLionel Sambuc 			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
6303e1db26aSLionel Sambuc 			    && Isprint(el->el_chared.c_redo.pos[-1]))
6313e1db26aSLionel Sambuc 				el->el_chared.c_redo.pos--;
6323e1db26aSLionel Sambuc 			else
6333e1db26aSLionel Sambuc 				*el->el_chared.c_redo.pos++ = ch;
6343e1db26aSLionel Sambuc 		}
6353e1db26aSLionel Sambuc 		retval = (*el->el_map.func[cmdnum]) (el, ch);
6363e1db26aSLionel Sambuc #ifdef DEBUG_READ
6373e1db26aSLionel Sambuc 		(void) fprintf(el->el_errfile,
6383e1db26aSLionel Sambuc 			"Returned state %d\n", retval );
6393e1db26aSLionel Sambuc #endif /* DEBUG_READ */
6403e1db26aSLionel Sambuc 
6413e1db26aSLionel Sambuc 		/* save the last command here */
6423e1db26aSLionel Sambuc 		el->el_state.lastcmd = cmdnum;
6433e1db26aSLionel Sambuc 
6443e1db26aSLionel Sambuc 		/* use any return value */
6453e1db26aSLionel Sambuc 		switch (retval) {
6463e1db26aSLionel Sambuc 		case CC_CURSOR:
6473e1db26aSLionel Sambuc 			re_refresh_cursor(el);
6483e1db26aSLionel Sambuc 			break;
6493e1db26aSLionel Sambuc 
6503e1db26aSLionel Sambuc 		case CC_REDISPLAY:
6513e1db26aSLionel Sambuc 			re_clear_lines(el);
6523e1db26aSLionel Sambuc 			re_clear_display(el);
6533e1db26aSLionel Sambuc 			/* FALLTHROUGH */
6543e1db26aSLionel Sambuc 
6553e1db26aSLionel Sambuc 		case CC_REFRESH:
6563e1db26aSLionel Sambuc 			re_refresh(el);
6573e1db26aSLionel Sambuc 			break;
6583e1db26aSLionel Sambuc 
6593e1db26aSLionel Sambuc 		case CC_REFRESH_BEEP:
6603e1db26aSLionel Sambuc 			re_refresh(el);
6613e1db26aSLionel Sambuc 			terminal_beep(el);
6623e1db26aSLionel Sambuc 			break;
6633e1db26aSLionel Sambuc 
6643e1db26aSLionel Sambuc 		case CC_NORM:	/* normal char */
6653e1db26aSLionel Sambuc 			break;
6663e1db26aSLionel Sambuc 
6673e1db26aSLionel Sambuc 		case CC_ARGHACK:	/* Suggested by Rich Salz */
6683e1db26aSLionel Sambuc 			/* <rsalz@pineapple.bbn.com> */
6693e1db26aSLionel Sambuc 			continue;	/* keep going... */
6703e1db26aSLionel Sambuc 
6713e1db26aSLionel Sambuc 		case CC_EOF:	/* end of file typed */
6723e1db26aSLionel Sambuc 			if ((el->el_flags & UNBUFFERED) == 0)
6733e1db26aSLionel Sambuc 				num = 0;
6743e1db26aSLionel Sambuc 			else if (num == -1) {
6753e1db26aSLionel Sambuc 				*el->el_line.lastchar++ = CONTROL('d');
6763e1db26aSLionel Sambuc 				el->el_line.cursor = el->el_line.lastchar;
6773e1db26aSLionel Sambuc 				num = 1;
6783e1db26aSLionel Sambuc 			}
6793e1db26aSLionel Sambuc 			break;
6803e1db26aSLionel Sambuc 
6813e1db26aSLionel Sambuc 		case CC_NEWLINE:	/* normal end of line */
6823e1db26aSLionel Sambuc 			num = (int)(el->el_line.lastchar - el->el_line.buffer);
6833e1db26aSLionel Sambuc 			break;
6843e1db26aSLionel Sambuc 
6853e1db26aSLionel Sambuc 		case CC_FATAL:	/* fatal error, reset to known state */
6863e1db26aSLionel Sambuc #ifdef DEBUG_READ
6873e1db26aSLionel Sambuc 			(void) fprintf(el->el_errfile,
6883e1db26aSLionel Sambuc 			    "*** editor fatal ERROR ***\r\n\n");
6893e1db26aSLionel Sambuc #endif /* DEBUG_READ */
6903e1db26aSLionel Sambuc 			/* put (real) cursor in a known place */
6913e1db26aSLionel Sambuc 			re_clear_display(el);	/* reset the display stuff */
6923e1db26aSLionel Sambuc 			ch_reset(el, 1);	/* reset the input pointers */
6933e1db26aSLionel Sambuc 			re_refresh(el); /* print the prompt again */
6943e1db26aSLionel Sambuc 			break;
6953e1db26aSLionel Sambuc 
6963e1db26aSLionel Sambuc 		case CC_ERROR:
6973e1db26aSLionel Sambuc 		default:	/* functions we don't know about */
6983e1db26aSLionel Sambuc #ifdef DEBUG_READ
6993e1db26aSLionel Sambuc 			(void) fprintf(el->el_errfile,
7003e1db26aSLionel Sambuc 			    "*** editor ERROR ***\r\n\n");
7013e1db26aSLionel Sambuc #endif /* DEBUG_READ */
7023e1db26aSLionel Sambuc 			terminal_beep(el);
7033e1db26aSLionel Sambuc 			terminal__flush(el);
7043e1db26aSLionel Sambuc 			break;
7053e1db26aSLionel Sambuc 		}
7063e1db26aSLionel Sambuc 		el->el_state.argument = 1;
7073e1db26aSLionel Sambuc 		el->el_state.doingarg = 0;
7083e1db26aSLionel Sambuc 		el->el_chared.c_vcmd.action = NOP;
7093e1db26aSLionel Sambuc 		if (el->el_flags & UNBUFFERED)
7103e1db26aSLionel Sambuc 			break;
7113e1db26aSLionel Sambuc 	}
7123e1db26aSLionel Sambuc 
7133e1db26aSLionel Sambuc 	terminal__flush(el);		/* flush any buffered output */
7143e1db26aSLionel Sambuc 	/* make sure the tty is set up correctly */
7153e1db26aSLionel Sambuc 	if ((el->el_flags & UNBUFFERED) == 0) {
7163e1db26aSLionel Sambuc 		read_finish(el);
7173e1db26aSLionel Sambuc 		*nread = num != -1 ? num : 0;
7183e1db26aSLionel Sambuc 	} else {
7193e1db26aSLionel Sambuc 		*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
7203e1db26aSLionel Sambuc 	}
7213e1db26aSLionel Sambuc 	goto done;
7223e1db26aSLionel Sambuc noedit:
7233e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.lastchar = cp;
7243e1db26aSLionel Sambuc 	*cp = '\0';
7253e1db26aSLionel Sambuc 	*nread = (int)(el->el_line.cursor - el->el_line.buffer);
7263e1db26aSLionel Sambuc done:
7273e1db26aSLionel Sambuc 	if (*nread == 0) {
7283e1db26aSLionel Sambuc 		if (num == -1) {
7293e1db26aSLionel Sambuc 			*nread = -1;
7303e1db26aSLionel Sambuc 			errno = el->el_errno;
7313e1db26aSLionel Sambuc 		}
7323e1db26aSLionel Sambuc 		return NULL;
7333e1db26aSLionel Sambuc 	} else
7343e1db26aSLionel Sambuc 		return el->el_line.buffer;
7353e1db26aSLionel Sambuc }
736