"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libedit/read.c" between
tnftp-20151004.tar.gz and tnftp-20200705.tar.gz

About: tnftp is an enhanced ftp client (prior name "lukemftp").

read.c  (tnftp-20151004):read.c  (tnftp-20200705)
/* $NetBSD: read.c,v 1.7 2005/06/09 16:48:58 lukem Exp $ */ /* $NetBSD: read.c,v 1.10 2020/07/04 13:43:21 lukem Exp $ */
/* from NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp */ /* from NetBSD: read.c,v 1.106 2019/07/23 10:18:52 christos Exp */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
* This code is derived from software contributed to Berkeley by * This code is derived from software contributed to Berkeley by
* Christos Zoulas of Cornell University. * Christos Zoulas of Cornell University.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
skipping to change at line 36 skipping to change at line 36
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include "tnftp.h" #include "config.h"
#include "sys.h"
#if 0 /* tnftp */
#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.106 2019/07/23 10:18:52 christos Exp ");
#endif
#endif /* not lint && not SCCSID */
#endif /* tnftp */
/* /*
* read.c: Clean this junk up! This is horrible code. * read.c: Terminal read functions
* Terminal read functions
*/ */
#if 0 /* tnftp */
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h>
#endif /* tnftp */
#include "el.h" #include "el.h"
#include "fcns.h"
#include "read.h"
#define OKCMD -1 #define EL_MAXMACRO 10
private int read__fixio(int, int); struct macros {
private int read_preread(EditLine *); wchar_t **macro;
private int read_char(EditLine *, char *); int level;
private int read_getcmd(EditLine *, el_action_t *, char *); 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(): /* read_init():
* Initialize the read stuff * Initialize the read stuff
*/ */
protected int libedit_private int
read_init(EditLine *el) 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_calloc(EL_MAXMACRO, sizeof(*ma->macro))) == NULL) {
free(el->el_read);
return -1;
}
ma->level = -1;
ma->offset = 0;
/* builtin read_char */ /* builtin read_char */
el->el_read.read_char = read_char; el->el_read->read_char = read_char;
return 0; 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(): /* el_read_setfn():
* Set the read char function to the one provided. * Set the read char function to the one provided.
* If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
*/ */
protected int libedit_private int
el_read_setfn(EditLine *el, el_rfunc_t rc) el_read_setfn(struct el_read_t *el_read, el_rfunc_t rc)
{ {
el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; el_read->read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
return 0; return 0;
} }
/* el_read_getfn(): /* el_read_getfn():
* return the current read char function, or EL_BUILTIN_GETCFN * return the current read char function, or EL_BUILTIN_GETCFN
* if it is the default one * if it is the default one
*/ */
protected el_rfunc_t libedit_private el_rfunc_t
el_read_getfn(EditLine *el) el_read_getfn(struct el_read_t *el_read)
{ {
return (el->el_read.read_char == read_char) ? return el_read->read_char == read_char ?
EL_BUILTIN_GETCFN : el->el_read.read_char; EL_BUILTIN_GETCFN : el_read->read_char;
}
#ifndef MIN
#define MIN(A,B) ((A) < (B) ? (A) : (B))
#endif
#ifdef DEBUG_EDIT
private void
read_debug(EditLine *el)
{
if (el->el_line.cursor > el->el_line.lastchar)
(void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
if (el->el_line.cursor < el->el_line.buffer)
(void) fprintf(el->el_errfile, "cursor < buffer\r\n");
if (el->el_line.cursor > el->el_line.limit)
(void) fprintf(el->el_errfile, "cursor > limit\r\n");
if (el->el_line.lastchar > el->el_line.limit)
(void) fprintf(el->el_errfile, "lastchar > limit\r\n");
if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
(void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n
");
} }
#endif /* DEBUG_EDIT */
/* read__fixio(): /* read__fixio():
* Try to recover from a read error * Try to recover from a read error
*/ */
/* ARGSUSED */ /* ARGSUSED */
private int static int
read__fixio(int fd __attribute__((__unused__)), int e) read__fixio(int fd __attribute__((__unused__)), int e)
{ {
switch (e) { switch (e) {
case -1: /* Make sure that the code is reachable */ case -1: /* Make sure that the code is reachable */
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
case EWOULDBLOCK: case EWOULDBLOCK:
#ifndef TRY_AGAIN #ifndef TRY_AGAIN
#define TRY_AGAIN #define TRY_AGAIN
#endif #endif
#endif /* EWOULDBLOCK */ #endif /* EWOULDBLOCK */
#if defined(POSIX) && defined(EAGAIN) #if defined(POSIX) && defined(EAGAIN)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN: case EAGAIN:
#ifndef TRY_AGAIN #ifndef TRY_AGAIN
#define TRY_AGAIN #define TRY_AGAIN
#endif #endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */ #endif /* POSIX && EAGAIN */
e = 0; e = 0;
#ifdef TRY_AGAIN #ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY) #if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1) if ((e = fcntl(fd, F_GETFL, 0)) == -1)
return (-1); return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
return (-1); return -1;
else else
e = 1; e = 1;
#endif /* F_SETFL && O_NDELAY */ #endif /* F_SETFL && O_NDELAY */
#ifdef FIONBIO #ifdef FIONBIO
{ {
int zero = 0; int zero = 0;
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) if (ioctl(fd, FIONBIO, &zero) == -1)
return (-1); return -1;
else else
e = 1; e = 1;
} }
#endif /* FIONBIO */ #endif /* FIONBIO */
#endif /* TRY_AGAIN */ #endif /* TRY_AGAIN */
return (e ? 0 : -1); return e ? 0 : -1;
case EINTR: case EINTR:
return (0); return 0;
default: default:
return (-1); return -1;
}
}
/* read_preread():
* Try to read the stuff in the input queue;
*/
private int
read_preread(EditLine *el)
{
int chrs = 0;
if (el->el_tty.t_mode == ED_IO)
return (0);
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
chrs = read(el->el_infd, buf,
(size_t) MIN(chrs, EL_BUFSIZ - 1));
if (chrs > 0) {
buf[chrs] = '\0';
el_push(el, buf);
}
} }
#endif /* FIONREAD */
return (chrs > 0);
} }
/* el_push(): /* el_push():
* Push a macro * Push a macro
*/ */
public void void
el_push(EditLine *el, char *str) el_wpush(EditLine *el, const wchar_t *str)
{ {
c_macro_t *ma = &el->el_chared.c_macro; struct macros *ma = &el->el_read->macros;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) { if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++; ma->level++;
if ((ma->macro[ma->level] = el_strdup(str)) != NULL) if ((ma->macro[ma->level] = wcsdup(str)) != NULL)
return; return;
ma->level--; ma->level--;
} }
term_beep(el); terminal_beep(el);
term__flush(); terminal__flush(el);
} }
/* read_getcmd(): /* read_getcmd():
* Return next command from the input stream. * 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.
*/ */
private int static int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
{ {
static const wchar_t meta = (wchar_t)0x80;
el_action_t cmd; el_action_t cmd;
int num;
do { do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ if (el_wgetc(el, ch) != 1)
return (num); return -1;
#ifdef KANJI #ifdef KANJI
if ((*ch & 0200)) { if ((*ch & meta)) {
el->el_state.metanext = 0; el->el_state.metanext = 0;
cmd = CcViMap[' ']; cmd = CcViMap[' '];
break; break;
} else } else
#endif /* KANJI */ #endif /* KANJI */
if (el->el_state.metanext) { if (el->el_state.metanext) {
el->el_state.metanext = 0; el->el_state.metanext = 0;
*ch |= 0200; *ch |= meta;
} }
cmd = el->el_map.current[(unsigned char) *ch]; if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) { if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val; keymacro_value_t val;
switch (key_get(el, ch, &val)) { switch (keymacro_get(el, ch, &val)) {
case XK_CMD: case XK_CMD:
cmd = val.cmd; cmd = val.cmd;
break; break;
case XK_STR: case XK_STR:
el_push(el, val.str); el_wpush(el, val.str);
break; break;
#ifdef notyet case XK_NOD:
case XK_EXE: return -1;
/* XXX: In the future to run a user function */
RunCommand(val.str);
break;
#endif
default: default:
EL_ABORT((el->el_errfile, "Bad XK_ type \n")); EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
break; break;
} }
} }
if (el->el_map.alt == NULL)
el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN); } while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd; *cmdnum = cmd;
return (OKCMD); return 0;
} }
/* read_char(): /* read_char():
* Read a character from the tty. * Read a character from the tty.
*/ */
private int static int
read_char(EditLine *el, char *cp) read_char(EditLine *el, wchar_t *cp)
{ {
int num_read; ssize_t num_read;
int tried = 0; int tried = 0;
char cbuf[MB_LEN_MAX];
while ((num_read = read(el->el_infd, cp, 1)) == -1) size_t cbp = 0;
if (!tried && read__fixio(el->el_infd, errno) == 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; tried = 1;
else { } else {
*cp = '\0'; errno = e;
return (-1); *cp = L'\0';
return -1;
} }
}
/* Test for EOF */
if (num_read == 0) {
*cp = L'\0';
return 0;
}
for (;;) {
mbstate_t mbs;
return (num_read); ++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:
if (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;
}
}
} }
/* el_getc(): /* read_pop():
* Read a character * Pop a macro from the stack
*/ */
public int static void
el_getc(EditLine *el, char *cp) 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; int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
term__flush(); terminal__flush(el);
for (;;) { for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
break;
}
if (ma->level < 0) if (ma->level < 0)
break; break;
if (ma->macro[ma->level][ma->offset] == '\0') { if (ma->macro[0][ma->offset] == '\0') {
el_free(ma->macro[ma->level--]); read_pop(ma);
ma->offset = 0;
continue; continue;
} }
*cp = ma->macro[ma->level][ma->offset++] & 0377;
if (ma->macro[ma->level][ma->offset] == '\0') { *cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */ /* Needed for QuoteMode On */
el_free(ma->macro[ma->level--]); read_pop(ma);
ma->offset = 0;
} }
return (1);
return 1;
} }
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Turning raw mode on\n");
#endif /* DEBUG_READ */
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
return (0); 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;
#ifdef DEBUG_READ return num_read;
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
return (num_read);
} }
protected void libedit_private void
read_prepare(EditLine *el) read_prepare(EditLine *el)
{ {
if (el->el_flags & HANDLE_SIGNALS) if (el->el_flags & HANDLE_SIGNALS)
sig_set(el); sig_set(el);
if (el->el_flags & NO_TTY) if (el->el_flags & NO_TTY)
return; return;
if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
tty_rawmode(el); tty_rawmode(el);
/* This is relatively cheap, and things go terribly wrong if /* This is relatively cheap, and things go terribly wrong if
we have the wrong size. */ we have the wrong size. */
el_resize(el); el_resize(el);
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el); ch_reset(el);
re_refresh(el); /* print the prompt */ re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
term__flush(); terminal__flush(el);
} }
protected void libedit_private void
read_finish(EditLine *el) read_finish(EditLine *el)
{ {
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
(void) tty_cookedmode(el); (void) tty_cookedmode(el);
if (el->el_flags & HANDLE_SIGNALS) if (el->el_flags & HANDLE_SIGNALS)
sig_clr(el); sig_clr(el);
} }
public const char * static const wchar_t *
el_gets(EditLine *el, int *nread) 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; int retval;
el_action_t cmdnum = 0; el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */ int num; /* how many chars we have read at NL */
char ch; wchar_t ch;
int crlf = 0; int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (el->el_flags & NO_TTY) { if (nread == NULL)
char *cp = el->el_line.buffer; nread = &nrb;
size_t idx; *nread = 0;
el->el_read->read_errno = 0;
while ((*el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
if (el->el_flags & UNBUFFERED)
break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
el->el_line.cursor = el->el_line.lastchar = cp; if (el->el_flags & NO_TTY) {
*cp = '\0'; el->el_line.lastchar = el->el_line.buffer;
if (nread) return noedit_wgets(el, nread);
*nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer);
} }
#ifdef FIONREAD #ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) { if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) {
long chrs = 0; int chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); (void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) { if (chrs == 0) {
if (tty_rawmode(el) < 0) { if (tty_rawmode(el) < 0) {
if (nread) errno = 0;
*nread = 0; *nread = 0;
return (NULL); return NULL;
} }
} }
} }
#endif /* FIONREAD */ #endif /* FIONREAD */
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
read_prepare(el); read_prepare(el);
if (el->el_flags & EDIT_DISABLED) { if (el->el_flags & EDIT_DISABLED) {
char *cp;
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
else terminal__flush(el);
cp = el->el_line.lastchar; return noedit_wgets(el, nread);
term__flush();
while ((*el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2))
break;
cp = &el->el_line.buffer[idx];
}
if (*cp == 4) /* ought to be stty eof */
break;
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
break;
if (crlf)
break;
}
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
if (nread)
*nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer);
} }
for (num = OKCMD; num == OKCMD;) { /* while still editing this for (num = -1; num == -1;) { /* while still editing this line */
* line */
#ifdef DEBUG_EDIT
read_debug(el);
#endif /* DEBUG_EDIT */
/* if EOF or error */ /* if EOF or error */
if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { if (read_getcmd(el, &cmdnum, &ch) == -1)
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile,
"Returning from el_gets %d\n", num);
#endif /* DEBUG_READ */
break; break;
} if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK comm
and */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
#endif /* DEBUG_EDIT */
continue; /* try again */ continue; /* try again */
}
/* now do the real command */ /* now do the real command */
#ifdef DEBUG_READ
{
el_bindings_t *b;
for (b = el->el_map.help; b->name; b++)
if (b->func == cmdnum)
break;
if (b->name)
(void) fprintf(el->el_errfile,
"Executing %s\n", b->name);
else
(void) fprintf(el->el_errfile,
"Error command = %d\n", cmdnum);
}
#endif /* DEBUG_READ */
/* vi redo needs these way down the levels... */ /* vi redo needs these way down the levels... */
el->el_state.thiscmd = cmdnum; el->el_state.thiscmd = cmdnum;
el->el_state.thisch = ch; el->el_state.thisch = ch;
if (el->el_map.type == MAP_VI && if (el->el_map.type == MAP_VI &&
el->el_map.current == el->el_map.key && el->el_map.current == el->el_map.key &&
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR && if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
&& isprint((unsigned char)el->el_chared.c_redo.pos[-1 ])) && iswprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--; el->el_chared.c_redo.pos--;
else else
*el->el_chared.c_redo.pos++ = ch; *el->el_chared.c_redo.pos++ = ch;
} }
retval = (*el->el_map.func[cmdnum]) (el, ch); retval = (*el->el_map.func[cmdnum]) (el, ch);
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile,
"Returned state %d\n", retval );
#endif /* DEBUG_READ */
/* save the last command here */ /* save the last command here */
el->el_state.lastcmd = cmdnum; el->el_state.lastcmd = cmdnum;
/* use any return value */ /* use any return value */
switch (retval) { switch (retval) {
case CC_CURSOR: case CC_CURSOR:
re_refresh_cursor(el); re_refresh_cursor(el);
break; break;
skipping to change at line 534 skipping to change at line 561
re_clear_lines(el); re_clear_lines(el);
re_clear_display(el); re_clear_display(el);
/* FALLTHROUGH */ /* FALLTHROUGH */
case CC_REFRESH: case CC_REFRESH:
re_refresh(el); re_refresh(el);
break; break;
case CC_REFRESH_BEEP: case CC_REFRESH_BEEP:
re_refresh(el); re_refresh(el);
term_beep(el); terminal_beep(el);
break; break;
case CC_NORM: /* normal char */ case CC_NORM: /* normal char */
break; break;
case CC_ARGHACK: /* Suggested by Rich Salz */ case CC_ARGHACK: /* Suggested by Rich Salz */
/* <rsalz@pineapple.bbn.com> */ /* <rsalz@pineapple.bbn.com> */
continue; /* keep going... */ continue; /* keep going... */
case CC_EOF: /* end of file typed */ case CC_EOF: /* end of file typed */
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
num = 0; num = 0;
else if (num == -1) { else if (num == -1) {
*el->el_line.lastchar++ = CONTROL('d'); *el->el_line.lastchar++ = CONTROL('d');
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
num = 1; num = 1;
} }
break; break;
case CC_NEWLINE: /* normal end of line */ case CC_NEWLINE: /* normal end of line */
num = el->el_line.lastchar - el->el_line.buffer; num = (int)(el->el_line.lastchar - el->el_line.buffer);
break; break;
case CC_FATAL: /* fatal error, reset to known state */ case CC_FATAL: /* fatal error, reset to known state */
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile,
"*** editor fatal ERROR ***\r\n\n");
#endif /* DEBUG_READ */
/* put (real) cursor in a known place */ /* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el); /* reset the input pointers */ ch_reset(el); /* reset the input pointers */
re_refresh(el); /* print the prompt again */ read_clearmacros(&el->el_read->macros);
re_refresh(el); /* print the prompt again */
break; break;
case CC_ERROR: case CC_ERROR:
default: /* functions we don't know about */ default: /* functions we don't know about */
#ifdef DEBUG_READ terminal_beep(el);
(void) fprintf(el->el_errfile, terminal__flush(el);
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
term__flush();
break; break;
} }
el->el_state.argument = 1; el->el_state.argument = 1;
el->el_state.doingarg = 0; el->el_state.doingarg = 0;
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
break; break;
} }
term__flush(); /* flush any buffered output */ terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */ /* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) { if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el); read_finish(el);
if (nread) *nread = num != -1 ? num : 0;
*nread = num; } else
} else { *nread = (int)(el->el_line.lastchar - el->el_line.buffer);
if (nread)
*nread = el->el_line.lastchar - el->el_line.buffer; if (*nread == 0) {
} if (num == -1) {
return (num ? el->el_line.buffer : NULL); *nread = -1;
if (el->el_read->read_errno)
errno = el->el_read->read_errno;
}
return NULL;
} else
return el->el_line.buffer;
} }
 End of changes. 90 change blocks. 
277 lines changed or deleted 301 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)