1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

WL#5945 : Improve libedit library

Updated libedit library.
This commit is contained in:
Nirbhay Choubey
2011-10-14 01:03:25 +05:30
parent 41b97529d0
commit 05a38e7bf3
52 changed files with 5379 additions and 3000 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */
/* $NetBSD: read.c,v 1.67 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -48,14 +48,15 @@ static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include "el.h"
#define OKCMD -1
#define OKCMD -1 /* must be -1! */
private int read__fixio(int, int);
private int read_preread(EditLine *);
private int read_char(EditLine *, char *);
private int read_getcmd(EditLine *, el_action_t *, char *);
private int read_char(EditLine *, Char *);
private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *);
/* read_init():
@ -89,7 +90,7 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
protected el_rfunc_t
el_read_getfn(EditLine *el)
{
return (el->el_read.read_char == read_char) ?
return el->el_read.read_char == read_char ?
EL_BUILTIN_GETCFN : el->el_read.read_char;
}
@ -131,7 +132,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK */
@ -139,7 +140,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */
@ -148,10 +149,10 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1)
return (-1);
return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
return (-1);
return -1;
else
e = 1;
#endif /* F_SETFL && O_NDELAY */
@ -160,21 +161,21 @@ read__fixio(int fd __attribute__((__unused__)), int e)
{
int zero = 0;
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
return (-1);
if (ioctl(fd, FIONBIO, &zero) == -1)
return -1;
else
e = 1;
}
#endif /* FIONBIO */
#endif /* TRY_AGAIN */
return (e ? 0 : -1);
return e ? 0 : -1;
case EINTR:
return (0);
return 0;
default:
return (-1);
return -1;
}
}
@ -188,10 +189,13 @@ read_preread(EditLine *el)
int chrs = 0;
if (el->el_tty.t_mode == ED_IO)
return (0);
return 0;
#ifndef WIDECHAR
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
* properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
@ -203,8 +207,8 @@ read_preread(EditLine *el)
}
}
#endif /* FIONREAD */
return (chrs > 0);
#endif
return chrs > 0;
}
@ -212,33 +216,37 @@ read_preread(EditLine *el)
* Push a macro
*/
public void
el_push(EditLine *el, const char *str)
FUN(el,push)(EditLine *el, const Char *str)
{
c_macro_t *ma = &el->el_chared.c_macro;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++;
if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
if ((ma->macro[ma->level] = Strdup(str)) != NULL)
return;
ma->level--;
}
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
}
/* read_getcmd():
* Return next command from the input stream.
* Character values > 255 are not looked up in the map, but inserted.
*/
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{
el_action_t cmd;
int num;
el->el_errno = 0;
do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
return (num);
if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return num;
}
#ifdef KANJI
if ((*ch & 0200)) {
@ -252,15 +260,20 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_state.metanext = 0;
*ch |= 0200;
}
cmd = el->el_map.current[(unsigned char) *ch];
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val;
switch (key_get(el, ch, &val)) {
keymacro_value_t val;
switch (keymacro_get(el, ch, &val)) {
case XK_CMD:
cmd = val.cmd;
break;
case XK_STR:
el_push(el, val.str);
FUN(el,push)(el, val.str);
break;
#ifdef notyet
case XK_EXE:
@ -277,28 +290,82 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd;
return (OKCMD);
return OKCMD;
}
/* read_char():
* Read a character from the tty.
*/
private int
read_char(EditLine *el, char *cp)
read_char(EditLine *el, Char *cp)
{
int num_read;
ssize_t num_read;
int tried = 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int bytes = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1)
#ifdef WIDECHAR
static mbstate_t state, temp_state;
memset(&state, 0, sizeof(mbstate_t));
#endif
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
switch (el->el_signal->sig_no) {
case SIGCONT:
FUN(el,set)(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
goto again;
default:
break;
}
if (!tried && read__fixio(el->el_infd, errno) == 0)
tried = 1;
else {
*cp = '\0';
return (-1);
return -1;
}
}
return (num_read);
#ifdef WIDECHAR
++cbp;
if (cbp > MB_CUR_MAX) { /* "shouldn't happen" */
*cp = '\0';
return (-1);
}
temp_state= state;
if ((bytes = mbrtowc(cp, cbuf, cbp, &state)) == -2)
{
/* Incomplete sequence, restore the state and scan more bytes. */
state= temp_state;
goto again;
}
else if (bytes == -1)
{
/* Invalid sequence, reset the state and continue. */
cbp= 0;
memset(&state, 0, sizeof(mbstate_t));
goto again;
}
/* We successfully read one single or multi-byte character */
#else
*cp = (unsigned char)cbuf[0];
#endif
#if 0
if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
cbp = 0; /* skip this character */
goto again;
}
#endif
return (int)num_read;
}
/* read_pop():
@ -310,8 +377,9 @@ read_pop(c_macro_t *ma)
int i;
el_free(ma->macro[0]);
for (i = ma->level--; i > 0; i--)
ma->macro[i - 1] = ma->macro[i];
for (i = 0; i < ma->level; i++)
ma->macro[i] = ma->macro[i + 1];
ma->level--;
ma->offset = 0;
}
@ -319,12 +387,12 @@ read_pop(c_macro_t *ma)
* Read a character
*/
public int
el_getc(EditLine *el, char *cp)
FUN(el,getc)(EditLine *el, Char *cp)
{
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
term__flush(el);
terminal__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
@ -339,30 +407,34 @@ el_getc(EditLine *el, char *cp)
continue;
}
*cp = ma->macro[0][ma->offset++] & 0377;
*cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */
read_pop(ma);
}
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 */
return (0);
return 0;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
#ifdef WIDECHAR
if (el->el_flags & NARROW_READ)
*cp = *(char *)(void *)cp;
#endif
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
return (num_read);
return num_read;
}
protected void
@ -383,7 +455,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
term__flush(el);
terminal__flush(el);
}
protected void
@ -395,27 +467,32 @@ read_finish(EditLine *el)
sig_clr(el);
}
public const char *
el_gets(EditLine *el, int *nread)
public const Char *
FUN(el,gets)(EditLine *el, int *nread)
{
int retval;
el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */
char ch;
Char ch, *cp;
int crlf = 0;
int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
size_t idx;
while ((*el->el_read.read_char)(el, cp) == 1) {
cp = el->el_line.buffer;
while ((num = (*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))
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
@ -425,12 +502,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
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);
goto noedit;
}
@ -438,12 +516,12 @@ el_gets(EditLine *el, int *nread)
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
if (nread)
*nread = 0;
return (NULL);
errno = 0;
*nread = 0;
return NULL;
}
}
}
@ -453,25 +531,23 @@ el_gets(EditLine *el, int *nread)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
char *cp;
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
cp = el->el_line.lastchar;
term__flush(el);
terminal__flush(el);
while ((*el->el_read.read_char)(el, cp) == 1) {
while ((num = (*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))
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)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)
@ -480,11 +556,13 @@ el_gets(EditLine *el, int *nread)
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);
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
goto noedit;
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -500,6 +578,12 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
@ -530,7 +614,7 @@ el_gets(EditLine *el, int *nread)
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
&& el_isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
&& Isprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
@ -561,7 +645,7 @@ el_gets(EditLine *el, int *nread)
case CC_REFRESH_BEEP:
re_refresh(el);
term_beep(el);
terminal_beep(el);
break;
case CC_NORM: /* normal char */
@ -582,7 +666,7 @@ el_gets(EditLine *el, int *nread)
break;
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;
case CC_FATAL: /* fatal error, reset to known state */
@ -593,7 +677,7 @@ el_gets(EditLine *el, int *nread)
/* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */
ch_reset(el, 1); /* reset the input pointers */
re_refresh(el); /* print the prompt again */
re_refresh(el); /* print the prompt again */
break;
case CC_ERROR:
@ -602,8 +686,8 @@ el_gets(EditLine *el, int *nread)
(void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
break;
}
el->el_state.argument = 1;
@ -613,15 +697,26 @@ el_gets(EditLine *el, int *nread)
break;
}
term__flush(el); /* flush any buffered output */
terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
if (nread)
*nread = num;
*nread = num != -1 ? num : 0;
} else {
if (nread)
*nread = el->el_line.lastchar - el->el_line.buffer;
*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
}
return (num ? el->el_line.buffer : NULL);
goto done;
noedit:
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else
return el->el_line.buffer;
}