libedit: import version snapshot 2021-09-10

This commit is contained in:
Baptiste Daroussin 2021-09-22 10:11:18 +02:00
parent 31595a7c3a
commit 30f4a9aee1
17 changed files with 396 additions and 190 deletions

6
ChangeLog Normal file
View File

@ -0,0 +1,6 @@
2021-08-29 Christos Zoulas <christos@netbsd.org>
Change default mappings:
map ^W to ed-delete-prev-word and not kill-region
map ^R to em-inc-search-next and not redisplay

63
TEST/fuzz1.c Normal file
View File

@ -0,0 +1,63 @@
/*
* build:
* CC=clang CXX=clang++ CFLAGS="-fsanitize=address,fuzzer-no-link -g" \
* CXXFLAGS="-fsanitize=address,fuzzer-no-link -g" ./configure && make
* run:
* LD_LIBRARY_PATH=../src/.libs/ .libs/fuzz1 -max_len=32 \
* -use_value_profile=1 -only_ascii=1
*/
#include <readline/readline.h>
#include <locale.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int init = 0;
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (!Size)
return 0;
if (!init) {
setlocale(LC_CTYPE, "");
stifle_history(7);
init = 1;
}
clear_history();
size_t lasti = 0;
for (size_t i = 0;; ++i) {
if (i == Size || Data[i] == '\n') {
if (i - lasti) {
char *s = (char *)malloc(i - lasti + 1);
memcpy(s, &Data[lasti], i - lasti);
s[i - lasti] = '\0';
char *expansion;
int result;
#ifdef DEBUG
fprintf(stderr, "Calling history_expand: >%s<\n", s);
#endif
result = history_expand(s, &expansion);
if (result < 0 || result == 2) {
/* Errors ignored */
} else {
add_history(expansion);
}
free(expansion);
free(s);
}
lasti = i + 1;
}
if (i == Size)
break;
}
return 0;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.99 2018/11/18 17:09:39 christos Exp $
.\" $NetBSD: editline.3,v 1.101 2021/08/15 10:12:54 wiz Exp $
.\"
.\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -26,7 +26,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 9, 2018
.Dd August 15, 2021
.Dt EDITLINE 3
.Os
.Sh NAME
@ -507,6 +507,16 @@ unbuffered mode is disabled (the default).
In unbuffered mode,
.Fn el_gets
will return immediately after processing a single character.
.It Dv EL_SAFEREAD , Fa "int flag"
If the
.Fa flag
argument is non-zero, then
.Nm editline
attempts to recover from read errors, ignoring the first interrrupted
error, and trying to reset the input file descriptor to reset non-blocking I/O.
This is disabled by default, and desirable only when
.Nm editline
is used in shell-like applications.
.It Dv EL_GETCFN , Fa "el_rfunc_t f"
Whenever reading a character, use the function
.Bd -ragged -offset indent -compact
@ -634,6 +644,10 @@ call.
Set
.Fa c
to non-zero if unbuffered mode is enabled.
.It Dv EL_SAFEREAD , Fa "int *c"
Set
.Fa c
to non-zero if safe read is set.
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
Set
.Fa fp

17
el.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.99 2019/07/23 10:18:52 christos Exp $ */
/* $NetBSD: el.c,v 1.100 2021/08/15 10:08:41 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
__RCSID("$NetBSD: el.c,v 1.99 2019/07/23 10:18:52 christos Exp $");
__RCSID("$NetBSD: el.c,v 1.100 2021/08/15 10:08:41 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -300,6 +300,14 @@ el_wset(EditLine *el, int op, ...)
break;
}
case EL_SAFEREAD:
if (va_arg(ap, int))
el->el_flags |= FIXIO;
else
el->el_flags &= ~FIXIO;
rv = 0;
break;
case EL_EDITMODE:
if (va_arg(ap, int))
el->el_flags &= ~EDIT_DISABLED;
@ -429,6 +437,11 @@ el_wget(EditLine *el, int op, ...)
rv = 0;
break;
case EL_SAFEREAD:
*va_arg(ap, int *) = (el->el_flags & FIXIO);
rv = 0;
break;
case EL_TERMINAL:
terminal_get(el, va_arg(ap, const char **));
rv = 0;

15
el.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.45 2019/07/23 10:18:52 christos Exp $ */
/* $NetBSD: el.h,v 1.46 2021/08/15 10:08:41 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -51,12 +51,13 @@
#define EL_BUFSIZ ((size_t)1024) /* Maximum line size */
#define HANDLE_SIGNALS 0x01
#define NO_TTY 0x02
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define NARROW_HISTORY 0x40
#define NO_RESET 0x80
#define HANDLE_SIGNALS 0x001
#define NO_TTY 0x002
#define EDIT_DISABLED 0x004
#define UNBUFFERED 0x008
#define NARROW_HISTORY 0x040
#define NO_RESET 0x080
#define FIXIO 0x100
typedef unsigned char el_action_t; /* Index to command array */

6
eln.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 christos Exp $ */
/* $NetBSD: eln.c,v 1.36 2021/08/15 10:08:41 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -27,7 +27,7 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 christos Exp $");
__RCSID("$NetBSD: eln.c,v 1.36 2021/08/15 10:08:41 christos Exp $");
#endif /* not lint && not SCCSID */
#include <errno.h>
@ -153,6 +153,7 @@ el_set(EditLine *el, int op, ...)
case EL_SIGNAL: /* int */
case EL_EDITMODE:
case EL_SAFEREAD:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wset(el, op, va_arg(ap, int));
@ -315,6 +316,7 @@ el_get(EditLine *el, int op, ...)
case EL_SIGNAL: /* int * */
case EL_EDITMODE:
case EL_SAFEREAD:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wget(el, op, va_arg(ap, int *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.67 2021/03/28 13:39:39 christos Exp $ */
/* $NetBSD: filecomplete.c,v 1.68 2021/05/05 14:49:59 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.67 2021/03/28 13:39:39 christos Exp $");
__RCSID("$NetBSD: filecomplete.c,v 1.68 2021/05/05 14:49:59 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -727,7 +727,7 @@ fn_complete2(EditLine *el,
else
completion = strdup(matches[0]);
if (completion == NULL)
goto out;
goto out2;
/*
* Replace the completed string with the common part of
@ -810,6 +810,7 @@ fn_complete2(EditLine *el,
}
/* free elements of array and the array itself */
out2:
for (i = 0; matches[i]; i++)
el_free(matches[i]);
el_free(matches);

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.57 2017/09/01 10:19:10 christos Exp $ */
/* $NetBSD: histedit.h,v 1.58 2021/08/15 10:08:41 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -157,6 +157,7 @@ unsigned char _el_fn_complete(EditLine *, int);
#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */
#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */
#define EL_ALIAS_TEXT 24 /* , el_afunc_t, void *); set */
#define EL_SAFEREAD 25 /* , int); set/get */
#define EL_BUILTIN_GETCFN (NULL)

8
map.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.53 2020/03/30 06:54:37 ryo Exp $ */
/* $NetBSD: map.c,v 1.54 2021/08/29 09:41:59 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.53 2020/03/30 06:54:37 ryo Exp $");
__RCSID("$NetBSD: map.c,v 1.54 2021/08/29 09:41:59 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -85,12 +85,12 @@ static const el_action_t el_map_emacs[] = {
/* 15 */ ED_IGNORE, /* ^O */
/* 16 */ ED_PREV_HISTORY, /* ^P */
/* 17 */ ED_IGNORE, /* ^Q */
/* 18 */ ED_REDISPLAY, /* ^R */
/* 18 */ EM_INC_SEARCH_PREV, /* ^R */
/* 19 */ ED_IGNORE, /* ^S */
/* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
/* 21 */ EM_KILL_LINE, /* ^U */
/* 22 */ ED_QUOTED_INSERT, /* ^V */
/* 23 */ EM_KILL_REGION, /* ^W */
/* 23 */ ED_DELETE_PREV_WORD, /* ^W */
/* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */
/* 25 */ EM_YANK, /* ^Y */
/* 26 */ ED_IGNORE, /* ^Z */

6
read.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.106 2019/07/23 10:18:52 christos Exp $ */
/* $NetBSD: read.c,v 1.107 2021/08/15 10:08:41 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#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 $");
__RCSID("$NetBSD: read.c,v 1.107 2021/08/15 10:08:41 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -277,7 +277,7 @@ static int
read_char(EditLine *el, wchar_t *cp)
{
ssize_t num_read;
int tried = 0;
int tried = (el->el_flags & FIXIO) == 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int save_errno = errno;

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.c,v 1.159 2019/10/09 14:31:07 christos Exp $ */
/* $NetBSD: readline.c,v 1.168 2021/09/10 18:51:36 rillig Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: readline.c,v 1.159 2019/10/09 14:31:07 christos Exp $");
__RCSID("$NetBSD: readline.c,v 1.168 2021/09/10 18:51:36 rillig Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -108,6 +108,7 @@ int rl_attempted_completion_over = 0;
const char *rl_basic_word_break_characters = break_chars;
char *rl_completer_word_break_characters = NULL;
const char *rl_completer_quote_characters = NULL;
const char *rl_basic_quote_characters = "\"'";
rl_compentry_func_t *rl_completion_entry_function = NULL;
char *(*rl_completion_word_break_hook)(void) = NULL;
rl_completion_func_t *rl_attempted_completion_function = NULL;
@ -122,11 +123,19 @@ int readline_echoing_p = 1;
int _rl_print_completions_horizontally = 0;
VFunction *rl_redisplay_function = NULL;
Function *rl_startup_hook = NULL;
int rl_did_startup_hook = 0;
VFunction *rl_completion_display_matches_hook = NULL;
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
unsigned long rl_readline_state;
int _rl_complete_mark_directories;
rl_icppfunc_t *rl_directory_completion_hook;
int rl_completion_suppress_append;
int rl_sort_completion_matches;
int _rl_completion_prefix_display_length;
int _rl_echoing_p;
int history_max_entries;
char *rl_display_prompt;
/*
* The current prompt string.
@ -208,11 +217,10 @@ static void
_resize_fun(EditLine *el, void *a)
{
const LineInfo *li;
char **ap = a;
const char **ap = a;
li = el_line(el);
/* a cheesy way to get rid of const cast. */
*ap = memchr(li->buffer, *li->buffer, (size_t)1);
*ap = li->buffer;
}
static const char *
@ -416,8 +424,7 @@ readline(const char *p)
if (e == NULL || h == NULL)
rl_initialize();
if (rl_did_startup_hook == 0 && rl_startup_hook) {
rl_did_startup_hook = 1;
if (rl_startup_hook) {
(*rl_startup_hook)(NULL, 0);
}
tty_init(e);
@ -451,14 +458,10 @@ readline(const char *p)
ret = el_gets(e, &count);
if (ret && count > 0) {
int lastidx;
buf = strdup(ret);
if (buf == NULL)
goto out;
lastidx = count - 1;
if (buf[lastidx] == '\n')
buf[lastidx] = '\0';
buf[strcspn(buf, "\n")] = '\0';
} else
buf = NULL;
@ -593,7 +596,7 @@ get_history_event(const char *cmd, int *cindex, int qchar)
if (sub && cmd[idx] == '?')
break;
if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
|| cmd[idx] == '\t' || cmd[idx] == qchar))
|| cmd[idx] == '\t' || cmd[idx] == qchar))
break;
idx++;
}
@ -619,8 +622,7 @@ get_history_event(const char *cmd, int *cindex, int qchar)
if (sub) {
if (pat != last_search_pat) {
if (last_search_pat)
el_free(last_search_pat);
el_free(last_search_pat);
last_search_pat = pat;
}
ret = history_search(pat, -1);
@ -637,9 +639,8 @@ get_history_event(const char *cmd, int *cindex, int qchar)
}
if (sub && len) {
if (last_search_match && last_search_match != pat)
el_free(last_search_match);
last_search_match = pat;
el_free(last_search_match);
last_search_match = strdup(pat);
}
if (pat != last_search_pat)
@ -656,6 +657,123 @@ get_history_event(const char *cmd, int *cindex, int qchar)
return rptr;
}
static int
getfrom(const char **cmdp, char **fromp, const char *search, int delim)
{
size_t size = 16;
size_t len = 0;
const char *cmd = *cmdp;
char *what = el_realloc(*fromp, size * sizeof(*what));
if (what == NULL){
el_free(*fromp);
*fromp = NULL;
return 0;
}
for (; *cmd && *cmd != delim; cmd++) {
if (*cmd == '\\' && cmd[1] == delim)
cmd++;
if (len - 1 >= size) {
char *nwhat;
nwhat = el_realloc(what, (size <<= 1) * sizeof(*nwhat));
if (nwhat == NULL) {
el_free(what);
el_free(*fromp);
*cmdp = cmd;
*fromp = NULL;
return 0;
}
what = nwhat;
}
what[len++] = *cmd;
}
what[len] = '\0';
*fromp = what;
*cmdp = cmd;
if (*what == '\0') {
el_free(what);
if (search) {
*fromp = strdup(search);
if (*fromp == NULL) {
return 0;
}
} else {
*fromp = NULL;
return -1;
}
}
if (!*cmd) {
el_free(what);
*fromp = NULL;
return -1;
}
cmd++; /* shift after delim */
*cmdp = cmd;
if (!*cmd) {
el_free(what);
*fromp = NULL;
return -1;
}
return 1;
}
static int
getto(const char **cmdp, char **top, const char *from, int delim)
{
size_t size = 16;
size_t len = 0;
size_t from_len = strlen(from);
const char *cmd = *cmdp;
char *with = el_realloc(*top, size * sizeof(*with));
*top = NULL;
if (with == NULL)
goto out;
for (; *cmd && *cmd != delim; cmd++) {
if (len + from_len + 1 >= size) {
char *nwith;
size += from_len + 1;
nwith = el_realloc(with, size * sizeof(*nwith));
if (nwith == NULL)
goto out;
with = nwith;
}
if (*cmd == '&') {
/* safe */
strcpy(&with[len], from);
len += from_len;
continue;
}
if (*cmd == '\\' && (*(cmd + 1) == delim || *(cmd + 1) == '&'))
cmd++;
with[len++] = *cmd;
}
if (!*cmd)
goto out;
with[len] = '\0';
*top = with;
*cmdp = cmd;
return 1;
out:
el_free(with);
el_free(*top);
*top = NULL;
*cmdp = cmd;
return -1;
}
static void
replace(char **tmp, int c)
{
char *aptr;
if ((aptr = strrchr(*tmp, c)) == NULL)
return;
aptr = strdup(aptr + 1); // XXX: check
el_free(*tmp);
*tmp = aptr;
}
/*
* the real function doing history expansion - takes as argument command
* to do and data upon which the command should be executed
@ -670,11 +788,11 @@ static int
_history_expand_command(const char *command, size_t offs, size_t cmdlen,
char **result)
{
char *tmp, *search = NULL, *aptr;
char *tmp, *search = NULL, *aptr, delim;
const char *ptr, *cmd;
static char *from = NULL, *to = NULL;
int start, end, idx, has_mods = 0;
int p_on = 0, g_on = 0;
int p_on = 0, g_on = 0, ev;
*result = NULL;
aptr = NULL;
@ -706,7 +824,8 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
} else {
int qchar;
qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
qchar = (offs > 0 && command[offs - 1] == '"')
? '"' : '\0';
ptr = get_history_event(command + offs, &idx, qchar);
}
has_mods = command[offs + (size_t)idx] == ':';
@ -729,7 +848,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
/* Now parse any word designators */
if (*cmd == '%') /* last word matched by ?pat? */
tmp = strdup(last_search_match? last_search_match:"");
tmp = strdup(last_search_match ? last_search_match : "");
else if (strchr("^*$-0123456789", *cmd)) {
start = end = -1;
if (*cmd == '^')
@ -738,7 +857,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
start = -1, cmd++;
else if (*cmd == '*')
start = 1, cmd++;
else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
start = 0;
while (*cmd && '0' <= *cmd && *cmd <= '9')
start = start * 10 + *cmd++ - '0';
@ -781,132 +900,58 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
}
for (; *cmd; cmd++) {
if (*cmd == ':')
switch (*cmd) {
case ':':
continue;
else if (*cmd == 'h') { /* remove trailing path */
case 'h': /* remove trailing path */
if ((aptr = strrchr(tmp, '/')) != NULL)
*aptr = '\0';
} else if (*cmd == 't') { /* remove leading path */
if ((aptr = strrchr(tmp, '/')) != NULL) {
aptr = strdup(aptr + 1);
el_free(tmp);
tmp = aptr;
}
} else if (*cmd == 'r') { /* remove trailing suffix */
continue;
case 't': /* remove leading path */
replace(&tmp, '/');
continue;
case 'r': /* remove trailing suffix */
if ((aptr = strrchr(tmp, '.')) != NULL)
*aptr = '\0';
} else if (*cmd == 'e') { /* remove all but suffix */
if ((aptr = strrchr(tmp, '.')) != NULL) {
aptr = strdup(aptr);
el_free(tmp);
tmp = aptr;
}
} else if (*cmd == 'p') /* print only */
continue;
case 'e': /* remove all but suffix */
replace(&tmp, '.');
continue;
case 'p': /* print only */
p_on = 1;
else if (*cmd == 'g')
continue;
case 'g':
g_on = 2;
else if (*cmd == 's' || *cmd == '&') {
char *what, *with, delim;
size_t len, from_len;
size_t size;
if (*cmd == '&' && (from == NULL || to == NULL))
continue;
case '&':
if (from == NULL || to == NULL)
continue;
else if (*cmd == 's') {
delim = *(++cmd), cmd++;
size = 16;
what = el_realloc(from, size * sizeof(*what));
if (what == NULL) {
el_free(from);
el_free(tmp);
return 0;
}
len = 0;
for (; *cmd && *cmd != delim; cmd++) {
if (*cmd == '\\' && cmd[1] == delim)
cmd++;
if (len >= size) {
char *nwhat;
nwhat = el_realloc(what,
(size <<= 1) *
sizeof(*nwhat));
if (nwhat == NULL) {
el_free(what);
el_free(tmp);
return 0;
}
what = nwhat;
}
what[len++] = *cmd;
}
what[len] = '\0';
from = what;
if (*what == '\0') {
el_free(what);
if (search) {
from = strdup(search);
if (from == NULL) {
el_free(tmp);
return 0;
}
} else {
from = NULL;
el_free(tmp);
return -1;
}
}
cmd++; /* shift after delim */
if (!*cmd)
continue;
size = 16;
with = el_realloc(to, size * sizeof(*with));
if (with == NULL) {
el_free(to);
el_free(tmp);
return -1;
}
len = 0;
from_len = strlen(from);
for (; *cmd && *cmd != delim; cmd++) {
if (len + from_len + 1 >= size) {
char *nwith;
size += from_len + 1;
nwith = el_realloc(with,
size * sizeof(*nwith));
if (nwith == NULL) {
el_free(with);
el_free(tmp);
return -1;
}
with = nwith;
}
if (*cmd == '&') {
/* safe */
(void)strcpy(&with[len], from);
len += from_len;
continue;
}
if (*cmd == '\\'
&& (*(cmd + 1) == delim
|| *(cmd + 1) == '&'))
cmd++;
with[len++] = *cmd;
}
with[len] = '\0';
to = with;
}
/*FALLTHROUGH*/
case 's':
ev = -1;
delim = *++cmd;
if (delim == '\0' || *++cmd == '\0')
goto out;
if ((ev = getfrom(&cmd, &from, search, delim)) != 1)
goto out;
if ((ev = getto(&cmd, &to, from, delim)) != 1)
goto out;
aptr = _rl_compat_sub(tmp, from, to, g_on);
if (aptr) {
el_free(tmp);
tmp = aptr;
}
g_on = 0;
cmd--;
continue;
}
}
*result = tmp;
return p_on? 2:1;
return p_on ? 2 : 1;
out:
el_free(tmp);
return ev;
}
@ -952,8 +997,7 @@ history_expand(char *str, char **output)
(size += len + 1) * sizeof(*nresult)); \
if (nresult == NULL) { \
el_free(*output); \
if (/*CONSTCOND*/fr) \
el_free(tmp); \
el_free(fr); \
return 0; \
} \
result = nresult; \
@ -1003,11 +1047,11 @@ history_expand(char *str, char **output)
goto loop;
}
len = i - start;
ADD_STRING(&str[start], len, 0);
ADD_STRING(&str[start], len, NULL);
if (str[i] == '\0' || str[i] != history_expansion_char) {
len = j - i;
ADD_STRING(&str[i], len, 0);
ADD_STRING(&str[i], len, NULL);
if (start == 0)
ret = 0;
else
@ -1017,7 +1061,7 @@ history_expand(char *str, char **output)
ret = _history_expand_command (str, i, (j - i), &tmp);
if (ret > 0 && tmp) {
len = strlen(tmp);
ADD_STRING(tmp, len, 1);
ADD_STRING(tmp, len, tmp);
}
if (tmp) {
el_free(tmp);
@ -1359,7 +1403,7 @@ read_history(const char *filename)
return errno;
errno = 0;
if (history(h, &ev, H_LOAD, filename) == -1)
return errno ? errno : EINVAL;
return errno ? errno : EINVAL;
if (history(h, &ev, H_GETSIZE) == 0)
history_length = ev.num;
if (history_length < 0)
@ -2037,7 +2081,7 @@ static unsigned char
rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c)
{
if (map[c] == NULL)
return CC_ERROR;
return CC_ERROR;
_rl_update_pos();
@ -2070,6 +2114,7 @@ rl_callback_read_char(void)
const char *buf = el_gets(e, &count);
char *wbuf;
el_set(e, EL_UNBUFFERED, 1);
if (buf == NULL || count-- <= 0)
return;
if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
@ -2085,7 +2130,6 @@ rl_callback_read_char(void)
} else
wbuf = NULL;
(*(void (*)(const char *))rl_linefunc)(wbuf);
el_set(e, EL_UNBUFFERED, 1);
}
}
@ -2103,9 +2147,8 @@ rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
void
rl_callback_handler_remove(void)
{
el_set(e, EL_UNBUFFERED, 0);
rl_linefunc = NULL;
el_end(e);
e = NULL;
}
void
@ -2439,3 +2482,40 @@ rl_echo_signal_char(int sig)
return;
re_putc(e, c, 0);
}
int
rl_crlf(void)
{
re_putc(e, '\n', 0);
return 0;
}
int
rl_ding(void)
{
re_putc(e, '\a', 0);
return 0;
}
int
rl_abort(int count, int key)
{
return count && key ? 0 : 0;
}
int
rl_set_keymap_name(const char *name, Keymap k)
{
return name && k ? 0 : 0;
}
histdata_t
free_history_entry(HIST_ENTRY *he)
{
return he ? NULL : NULL;
}
void
_rl_erase_entire_line(void)
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.46 2019/06/07 15:19:29 christos Exp $ */
/* $NetBSD: readline.h,v 1.47 2021/08/21 12:34:59 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -45,6 +45,7 @@ typedef char **rl_completion_func_t(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, int);
typedef int rl_command_func_t(int, int);
typedef int rl_hook_func_t(void);
typedef int rl_icppfunc_t(char **);
/* only supports length */
typedef struct {
@ -106,6 +107,7 @@ extern char *rl_line_buffer;
extern int rl_point, rl_end;
extern int history_base, history_length;
extern int max_input_history;
extern const char *rl_basic_quote_characters;
extern const char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters;
extern const char *rl_completer_quote_characters;
@ -127,6 +129,7 @@ extern int rl_done;
/*
* The following is not implemented
*/
extern unsigned long rl_readline_state;
extern int rl_catch_signals;
extern int rl_catch_sigwinch;
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
@ -142,6 +145,14 @@ extern VFunction *rl_deprep_term_function;
extern rl_hook_func_t *rl_event_hook;
extern int readline_echoing_p;
extern int _rl_print_completions_horizontally;
extern int _rl_complete_mark_directories;
extern rl_icppfunc_t *rl_directory_completion_hook;
extern int rl_completion_suppress_append;
extern int rl_sort_completion_matches;
extern int _rl_completion_prefix_display_length;
extern int _rl_echoing_p;
extern int history_max_entries;
extern char *rl_display_prompt;
/* supported functions */
char *readline(const char *);
@ -213,6 +224,8 @@ int rl_set_prompt(const char *);
int rl_on_new_line(void);
void rl_reset_after_signal(void);
void rl_echo_signal_char(int);
int rl_crlf(void);
int rl_ding(void);
/*
* The following are not implemented
@ -226,6 +239,10 @@ int rl_bind_key_in_map(int, rl_command_func_t *, Keymap);
void rl_cleanup_after_signal(void);
void rl_free_line_state(void);
int rl_set_keyboard_input_timeout(int);
int rl_abort(int, int);
int rl_set_keymap_name(const char *, Keymap);
histdata_t free_history_entry(HIST_ENTRY *);
void _rl_erase_entire_line(void);
#ifdef __cplusplus
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.57 2020/03/30 06:54:37 ryo Exp $ */
/* $NetBSD: refresh.c,v 1.58 2021/09/09 20:24:07 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: refresh.c,v 1.57 2020/03/30 06:54:37 ryo Exp $");
__RCSID("$NetBSD: refresh.c,v 1.58 2021/09/09 20:24:07 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -105,7 +105,7 @@ re_nextline(EditLine *el)
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
wchar_t *firstline = el->el_vdisplay[0];
wint_t *firstline = el->el_vdisplay[0];
for(i = 1; i < lins; i++)
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
@ -334,7 +334,8 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
for (i = 0; i <= el->el_refresh.r_newcv; i++) {
/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
re_update_line(el, (wchar_t *)el->el_display[i],
(wchar_t *)el->el_vdisplay[i], i);
/*
* Copy the new line to be the current one, and pad out with
@ -343,7 +344,8 @@ re_refresh(EditLine *el)
* end of the screen line, it won't be a NUL or some old
* leftover stuff.
*/
re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
re__copy_and_pad((wchar_t *)el->el_display[i],
(wchar_t *)el->el_vdisplay[i],
(size_t) el->el_terminal.t_size.h);
}
ELRE_DEBUG(1, (__F,
@ -355,7 +357,8 @@ re_refresh(EditLine *el)
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
/* This wcslen should be safe even with MB_FILL_CHARs */
terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
terminal_clear_EOL(el,
(int) wcslen((const wchar_t *)el->el_display[i]));
#ifdef DEBUG_REFRESH
terminal_overwrite(el, L"C\b", 2);
#endif /* DEBUG_REFRESH */
@ -1091,7 +1094,7 @@ re_refresh_cursor(EditLine *el)
static void
re_fastputc(EditLine *el, wint_t c)
{
wchar_t *lastline;
wint_t *lastline;
int w;
w = wcwidth(c);
@ -1126,7 +1129,8 @@ re_fastputc(EditLine *el, wint_t c)
el->el_cursor.v++;
lastline = el->el_display[++el->el_refresh.r_oldcv];
}
re__copy_and_pad(lastline, L"", (size_t)el->el_terminal.t_size.h);
re__copy_and_pad((wchar_t *)lastline, L"",
(size_t)el->el_terminal.t_size.h);
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: terminal.c,v 1.43 2020/07/10 20:34:24 christos Exp $ */
/* $NetBSD: terminal.c,v 1.44 2021/09/09 20:24:07 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#else
__RCSID("$NetBSD: terminal.c,v 1.43 2020/07/10 20:34:24 christos Exp $");
__RCSID("$NetBSD: terminal.c,v 1.44 2021/09/09 20:24:07 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -588,7 +588,8 @@ terminal_move_to_char(EditLine *el, int where)
* NOTE THAT terminal_overwrite() WILL CHANGE
* el->el_cursor.h!!!
*/
terminal_overwrite(el, &el->el_display[
terminal_overwrite(el,
(wchar_t *)&el->el_display[
el->el_cursor.v][el->el_cursor.h],
(size_t)(where - el->el_cursor.h));

12
tty.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.69 2020/05/31 23:24:23 christos Exp $ */
/* $NetBSD: tty.c,v 1.70 2021/07/14 07:47:23 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tty.c,v 1.69 2020/05/31 23:24:23 christos Exp $");
__RCSID("$NetBSD: tty.c,v 1.70 2021/07/14 07:47:23 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -1350,19 +1350,19 @@ tty_get_signal_character(EditLine *el, int sig)
return -1;
#endif
switch (sig) {
#ifdef SIGINT
#if defined(SIGINT) && defined(VINTR)
case SIGINT:
return el->el_tty.t_c[ED_IO][VINTR];
#endif
#ifdef SIGQUIT
#if defined(SIGQUIT) && defined(VQUIT)
case SIGQUIT:
return el->el_tty.t_c[ED_IO][VQUIT];
#endif
#ifdef SIGINFO
#if defined(SIGINFO) && defined(VSTATUS)
case SIGINFO:
return el->el_tty.t_c[ED_IO][VSTATUS];
#endif
#ifdef SIGTSTP
#if defined(SIGTSTP) && defined(VSUSP)
case SIGTSTP:
return el->el_tty.t_c[ED_IO][VSUSP];
#endif

4
tty.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.23 2018/12/02 16:58:13 christos Exp $ */
/* $NetBSD: tty.h,v 1.24 2021/07/31 20:51:32 andvar Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -432,7 +432,7 @@
#define C_SH(A) ((unsigned int)(1 << (A)))
/*
* Terminal dependend data structures
* Terminal dependent data structures
*/
#define EX_IO 0 /* while we are executing */
#define ED_IO 1 /* while we are editing */

9
vi.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 christos Exp $ */
/* $NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 christos Exp $");
__RCSID("$NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -1008,12 +1008,15 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
char *cp = NULL;
size_t len;
wchar_t *line = NULL;
const char *editor;
if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR)
return CC_ERROR;
}
if ((editor = getenv("EDITOR")) == NULL)
editor = "vi";
fd = mkstemp(tempfile);
if (fd < 0)
return CC_ERROR;
@ -1038,7 +1041,7 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
goto error;
case 0:
close(fd);
execlp("vi", "vi", tempfile, (char *)NULL);
execlp(editor, editor, tempfile, (char *)NULL);
exit(0);
/*NOTREACHED*/
default: