summary refs log tree commit diff
path: root/bin/1sh/libedit/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/1sh/libedit/read.c')
-rw-r--r--bin/1sh/libedit/read.c628
1 files changed, 0 insertions, 628 deletions
diff --git a/bin/1sh/libedit/read.c b/bin/1sh/libedit/read.c
deleted file mode 100644
index f9b6684d..00000000
--- a/bin/1sh/libedit/read.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*	$NetBSD: read.c,v 1.102.6.1 2017/07/23 14:41:26 snj Exp $	*/
-
-/*-
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas of Cornell University.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)read.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: read.c,v 1.102.6.1 2017/07/23 14:41:26 snj Exp $");
-#endif
-#endif /* not lint && not SCCSID */
-
-/*
- * read.c: Terminal read functions
- */
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "el.h"
-#include "fcns.h"
-#include "read.h"
-
-#define	EL_MAXMACRO	10
-
-struct macros {
-	wchar_t	**macro;
-	int	  level;
-	int	  offset;
-};
-
-struct el_read_t {
-	struct macros	 macros;
-	el_rfunc_t	 read_char;	/* Function to read a character. */
-	int		 read_errno;
-};
-
-static int	read__fixio(int, int);
-static int	read_char(EditLine *, wchar_t *);
-static int	read_getcmd(EditLine *, el_action_t *, wchar_t *);
-static void	read_clearmacros(struct macros *);
-static void	read_pop(struct macros *);
-static const wchar_t *noedit_wgets(EditLine *, int *);
-
-/* read_init():
- *	Initialize the read stuff
- */
-libedit_private int
-read_init(EditLine *el)
-{
-	struct macros *ma;
-
-	if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
-		return -1;
-
-	ma = &el->el_read->macros;
-	if ((ma->macro = el_malloc(EL_MAXMACRO *
-	    sizeof(*ma->macro))) == NULL) {
-		free(el->el_read);
-		return -1;
-	}
-	ma->level = -1;
-	ma->offset = 0;
-
-	/* builtin read_char */
-	el->el_read->read_char = read_char;
-	return 0;
-}
-
-/* el_read_end():
- *	Free the data structures used by the read stuff.
- */
-libedit_private void
-read_end(struct el_read_t *el_read)
-{
-	read_clearmacros(&el_read->macros);
-	el_free(el_read->macros.macro);
-	el_read->macros.macro = NULL;
-	el_free(el_read);
-}
-
-/* el_read_setfn():
- *	Set the read char function to the one provided.
- *	If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
- */
-libedit_private int
-el_read_setfn(struct el_read_t *el_read, el_rfunc_t rc)
-{
-	el_read->read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
-	return 0;
-}
-
-
-/* el_read_getfn():
- *	return the current read char function, or EL_BUILTIN_GETCFN
- *	if it is the default one
- */
-libedit_private el_rfunc_t
-el_read_getfn(struct el_read_t *el_read)
-{
-       return el_read->read_char == read_char ?
-	    EL_BUILTIN_GETCFN : el_read->read_char;
-}
-
-
-/* read__fixio():
- *	Try to recover from a read error
- */
-/* ARGSUSED */
-static int
-read__fixio(int fd __attribute__((__unused__)), int e)
-{
-
-	switch (e) {
-	case -1:		/* Make sure that the code is reachable */
-
-#ifdef EWOULDBLOCK
-	case EWOULDBLOCK:
-#ifndef TRY_AGAIN
-#define TRY_AGAIN
-#endif
-#endif /* EWOULDBLOCK */
-
-#if defined(POSIX) && defined(EAGAIN)
-#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
-	case EAGAIN:
-#ifndef TRY_AGAIN
-#define TRY_AGAIN
-#endif
-#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
-#endif /* POSIX && EAGAIN */
-
-		e = 0;
-#ifdef TRY_AGAIN
-#if defined(F_SETFL) && defined(O_NDELAY)
-		if ((e = fcntl(fd, F_GETFL, 0)) == -1)
-			return -1;
-
-		if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
-			return -1;
-		else
-			e = 1;
-#endif /* F_SETFL && O_NDELAY */
-
-#ifdef FIONBIO
-		{
-			int zero = 0;
-
-			if (ioctl(fd, FIONBIO, &zero) == -1)
-				return -1;
-			else
-				e = 1;
-		}
-#endif /* FIONBIO */
-
-#endif /* TRY_AGAIN */
-		return e ? 0 : -1;
-
-	case EINTR:
-		return 0;
-
-	default:
-		return -1;
-	}
-}
-
-
-/* el_push():
- *	Push a macro
- */
-void
-el_wpush(EditLine *el, const wchar_t *str)
-{
-	struct macros *ma = &el->el_read->macros;
-
-	if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
-		ma->level++;
-		if ((ma->macro[ma->level] = wcsdup(str)) != NULL)
-			return;
-		ma->level--;
-	}
-	terminal_beep(el);
-	terminal__flush(el);
-}
-
-
-/* read_getcmd():
- *	Get next command from the input stream,
- *	return 0 on success or -1 on EOF or error.
- *	Character values > 255 are not looked up in the map, but inserted.
- */
-static int
-read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
-{
-	static const wchar_t meta = (wchar_t)0x80;
-	el_action_t cmd;
-
-	do {
-		if (el_wgetc(el, ch) != 1)
-			return -1;
-
-#ifdef	KANJI
-		if ((*ch & meta)) {
-			el->el_state.metanext = 0;
-			cmd = CcViMap[' '];
-			break;
-		} else
-#endif /* KANJI */
-
-		if (el->el_state.metanext) {
-			el->el_state.metanext = 0;
-			*ch |= meta;
-		}
-		if (*ch >= N_KEYS)
-			cmd = ED_INSERT;
-		else
-			cmd = el->el_map.current[(unsigned char) *ch];
-		if (cmd == ED_SEQUENCE_LEAD_IN) {
-			keymacro_value_t val;
-			switch (keymacro_get(el, ch, &val)) {
-			case XK_CMD:
-				cmd = val.cmd;
-				break;
-			case XK_STR:
-				el_wpush(el, val.str);
-				break;
-			case XK_NOD:
-				return -1;
-			default:
-				EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
-				break;
-			}
-		}
-	} while (cmd == ED_SEQUENCE_LEAD_IN);
-	*cmdnum = cmd;
-	return 0;
-}
-
-/* read_char():
- *	Read a character from the tty.
- */
-static int
-read_char(EditLine *el, wchar_t *cp)
-{
-	ssize_t num_read;
-	int tried = 0;
-	char cbuf[MB_LEN_MAX];
-	size_t cbp = 0;
-	int save_errno = errno;
-
- again:
-	el->el_signal->sig_no = 0;
-	while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
-		int e = errno;
-		switch (el->el_signal->sig_no) {
-		case SIGCONT:
-			el_wset(el, EL_REFRESH);
-			/*FALLTHROUGH*/
-		case SIGWINCH:
-			sig_set(el);
-			goto again;
-		default:
-			break;
-		}
-		if (!tried && read__fixio(el->el_infd, e) == 0) {
-			errno = save_errno;
-			tried = 1;
-		} else {
-			errno = e;
-			*cp = L'\0';
-			return -1;
-		}
-	}
-
-	/* Test for EOF */
-	if (num_read == 0) {
-		*cp = L'\0';
-		return 0;
-	}
-
-	for (;;) {
-		mbstate_t mbs;
-
-		++cbp;
-		/* This only works because UTF8 is stateless. */
-		memset(&mbs, 0, sizeof(mbs));
-		switch (mbrtowc(cp, cbuf, cbp, &mbs)) {
-		case (size_t)-1:
-			if (cbp > 1) {
-				/*
-				 * Invalid sequence, discard all bytes
-				 * except the last one.
-				 */
-				cbuf[0] = cbuf[cbp - 1];
-				cbp = 0;
-				break;
-			} else {
-				/* Invalid byte, discard it. */
-				cbp = 0;
-				goto again;
-			}
-		case (size_t)-2:
-			/*
-			 * We don't support other multibyte charsets.
-			 * The second condition shouldn't happen
-			 * and is here merely for additional safety.
-			 */
-			if ((el->el_flags & CHARSET_IS_UTF8) == 0 ||
-			    cbp >= MB_LEN_MAX) {
-				errno = EILSEQ;
-				*cp = L'\0';
-				return -1;
-			}
-			/* Incomplete sequence, read another byte. */
-			goto again;
-		default:
-			/* Valid character, process it. */
-			return 1;
-		}
-	}
-}
-
-/* read_pop():
- *	Pop a macro from the stack
- */
-static void
-read_pop(struct macros *ma)
-{
-	int i;
-
-	el_free(ma->macro[0]);
-	for (i = 0; i < ma->level; i++)
-		ma->macro[i] = ma->macro[i + 1];
-	ma->level--;
-	ma->offset = 0;
-}
-
-static void
-read_clearmacros(struct macros *ma)
-{
-	while (ma->level >= 0)
-		el_free(ma->macro[ma->level--]);
-	ma->offset = 0;
-}
-
-/* el_wgetc():
- *	Read a wide character
- */
-int
-el_wgetc(EditLine *el, wchar_t *cp)
-{
-	struct macros *ma = &el->el_read->macros;
-	int num_read;
-
-	terminal__flush(el);
-	for (;;) {
-		if (ma->level < 0)
-			break;
-
-		if (ma->macro[0][ma->offset] == '\0') {
-			read_pop(ma);
-			continue;
-		}
-
-		*cp = ma->macro[0][ma->offset++];
-
-		if (ma->macro[0][ma->offset] == '\0') {
-			/* Needed for QuoteMode On */
-			read_pop(ma);
-		}
-
-		return 1;
-	}
-
-	if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
-		return 0;
-
-	num_read = (*el->el_read->read_char)(el, cp);
-
-	/*
-	 * Remember the original reason of a read failure
-	 * such that el_wgets() can restore it after doing
-	 * various cleanup operation that might change errno.
-	 */
-	if (num_read < 0)
-		el->el_read->read_errno = errno;
-
-	return num_read;
-}
-
-libedit_private void
-read_prepare(EditLine *el)
-{
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_set(el);
-	if (el->el_flags & NO_TTY)
-		return;
-	if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
-		tty_rawmode(el);
-
-	/* This is relatively cheap, and things go terribly wrong if
-	   we have the wrong size. */
-	el_resize(el);
-	re_clear_display(el);	/* reset the display stuff */
-	ch_reset(el);
-	re_refresh(el);		/* print the prompt */
-
-	if (el->el_flags & UNBUFFERED)
-		terminal__flush(el);
-}
-
-libedit_private void
-read_finish(EditLine *el)
-{
-	if ((el->el_flags & UNBUFFERED) == 0)
-		(void) tty_cookedmode(el);
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_clr(el);
-}
-
-static const wchar_t *
-noedit_wgets(EditLine *el, int *nread)
-{
-	el_line_t	*lp = &el->el_line;
-	int		 num;
-
-	while ((num = (*el->el_read->read_char)(el, lp->lastchar)) == 1) {
-		if (lp->lastchar + 1 >= lp->limit &&
-		    !ch_enlargebufs(el, (size_t)2))
-			break;
-		lp->lastchar++;
-		if (el->el_flags & UNBUFFERED ||
-		    lp->lastchar[-1] == '\r' ||
-		    lp->lastchar[-1] == '\n')
-			break;
-	}
-	if (num == -1 && errno == EINTR)
-		lp->lastchar = lp->buffer;
-	lp->cursor = lp->lastchar;
-	*lp->lastchar = '\0';
-	*nread = (int)(lp->lastchar - lp->buffer);
-	return *nread ? lp->buffer : NULL;
-}
-
-const wchar_t *
-el_wgets(EditLine *el, int *nread)
-{
-	int retval;
-	el_action_t cmdnum = 0;
-	int num;		/* how many chars we have read at NL */
-	wchar_t ch;
-	int nrb;
-
-	if (nread == NULL)
-		nread = &nrb;
-	*nread = 0;
-	el->el_read->read_errno = 0;
-
-	if (el->el_flags & NO_TTY) {
-		el->el_line.lastchar = el->el_line.buffer;
-		return noedit_wgets(el, nread);
-	}
-
-#ifdef FIONREAD
-	if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) {
-		int chrs = 0;
-
-		(void) ioctl(el->el_infd, FIONREAD, &chrs);
-		if (chrs == 0) {
-			if (tty_rawmode(el) < 0) {
-				errno = 0;
-				*nread = 0;
-				return NULL;
-			}
-		}
-	}
-#endif /* FIONREAD */
-
-	if ((el->el_flags & UNBUFFERED) == 0)
-		read_prepare(el);
-
-	if (el->el_flags & EDIT_DISABLED) {
-		if ((el->el_flags & UNBUFFERED) == 0)
-			el->el_line.lastchar = el->el_line.buffer;
-		terminal__flush(el);
-		return noedit_wgets(el, nread);
-	}
-
-	for (num = -1; num == -1;) {  /* while still editing this line */
-		/* if EOF or error */
-		if (read_getcmd(el, &cmdnum, &ch) == -1)
-			break;
-		if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
-			continue;	/* try again */
-		/* now do the real command */
-		/* vi redo needs these way down the levels... */
-		el->el_state.thiscmd = cmdnum;
-		el->el_state.thisch = ch;
-		if (el->el_map.type == MAP_VI &&
-		    el->el_map.current == el->el_map.key &&
-		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
-			if (cmdnum == VI_DELETE_PREV_CHAR &&
-			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
-			    && iswprint(el->el_chared.c_redo.pos[-1]))
-				el->el_chared.c_redo.pos--;
-			else
-				*el->el_chared.c_redo.pos++ = ch;
-		}
-		retval = (*el->el_map.func[cmdnum]) (el, ch);
-
-		/* save the last command here */
-		el->el_state.lastcmd = cmdnum;
-
-		/* use any return value */
-		switch (retval) {
-		case CC_CURSOR:
-			re_refresh_cursor(el);
-			break;
-
-		case CC_REDISPLAY:
-			re_clear_lines(el);
-			re_clear_display(el);
-			/* FALLTHROUGH */
-
-		case CC_REFRESH:
-			re_refresh(el);
-			break;
-
-		case CC_REFRESH_BEEP:
-			re_refresh(el);
-			terminal_beep(el);
-			break;
-
-		case CC_NORM:	/* normal char */
-			break;
-
-		case CC_ARGHACK:	/* Suggested by Rich Salz */
-			/* <rsalz@pineapple.bbn.com> */
-			continue;	/* keep going... */
-
-		case CC_EOF:	/* end of file typed */
-			if ((el->el_flags & UNBUFFERED) == 0)
-				num = 0;
-			else if (num == -1) {
-				*el->el_line.lastchar++ = CONTROL('d');
-				el->el_line.cursor = el->el_line.lastchar;
-				num = 1;
-			}
-			break;
-
-		case CC_NEWLINE:	/* normal end of line */
-			num = (int)(el->el_line.lastchar - el->el_line.buffer);
-			break;
-
-		case CC_FATAL:	/* fatal error, reset to known state */
-			/* put (real) cursor in a known place */
-			re_clear_display(el);	/* reset the display stuff */
-			ch_reset(el);	/* reset the input pointers */
-			read_clearmacros(&el->el_read->macros);
-			re_refresh(el); /* print the prompt again */
-			break;
-
-		case CC_ERROR:
-		default:	/* functions we don't know about */
-			terminal_beep(el);
-			terminal__flush(el);
-			break;
-		}
-		el->el_state.argument = 1;
-		el->el_state.doingarg = 0;
-		el->el_chared.c_vcmd.action = NOP;
-		if (el->el_flags & UNBUFFERED)
-			break;
-	}
-
-	terminal__flush(el);		/* flush any buffered output */
-	/* make sure the tty is set up correctly */
-	if ((el->el_flags & UNBUFFERED) == 0) {
-		read_finish(el);
-		*nread = num != -1 ? num : 0;
-	} else
-		*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
-
-	if (*nread == 0) {
-		if (num == -1) {
-			*nread = -1;
-			if (el->el_read->read_errno)
-				errno = el->el_read->read_errno;
-		}
-		return NULL;
-	} else
-		return el->el_line.buffer;
-}