Update libedit to snapshot 2019-09-10

This commit is contained in:
Baptiste Daroussin 2019-09-10 13:55:44 +00:00
parent 8c36b0434c
commit 3150625201
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/NetBSD/libedit/dist/; revision=352134
svn path=/vendor/NetBSD/libedit/2019-09-10/; revision=352135; tag=vendor/NetBSD/libedit/2019-09-10
25 changed files with 1083 additions and 253 deletions

View File

@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.7 2016/03/23 22:27:48 christos Exp $
# $NetBSD: Makefile,v 1.8 2017/10/15 18:59:00 abhinav Exp $
NOMAN=1
PROG=wtc1
PROG=wtc1 test_filecompletion
CPPFLAGS=-I${.CURDIR}/..
LDADD+=-ledit -ltermlib
DPADD+=${LIBEDIT} ${LIBTERMLIB}

553
TEST/test_filecompletion.c Normal file
View File

@ -0,0 +1,553 @@
/* $NetBSD: test_filecompletion.c,v 1.5 2019/09/08 05:50:58 abhinav Exp $ */
/*-
* Copyright (c) 2017 Abhinav Upadhyay <abhinav@NetBSD.org>
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT HOLDERS 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"
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <histedit.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "filecomplete.h"
#include "el.h"
typedef struct {
const wchar_t *user_typed_text; /* The actual text typed by the user on the terminal */
const char *completion_function_input ; /*the text received by fn_filename_completion_function */
const char *expanded_text[2]; /* the value to which completion_function_input should be expanded */
const wchar_t *escaped_output; /* expected escaped value of expanded_text */
} test_input;
static test_input inputs[] = {
{
/* simple test for escaping angular brackets */
L"ls ang",
"ang",
{"ang<ular>test", NULL},
L"ls ang\\<ular\\>test "
},
{
/* test angular bracket inside double quotes: ls "dq_ang */
L"ls \"dq_ang",
"dq_ang",
{"dq_ang<ular>test", NULL},
L"ls \"dq_ang<ular>test\""
},
{
/* test angular bracket inside singlq quotes: ls "sq_ang */
L"ls 'sq_ang",
"sq_ang",
{"sq_ang<ular>test", NULL},
L"ls 'sq_ang<ular>test'"
},
{
/* simple test for backslash */
L"ls back",
"back",
{"backslash\\test", NULL},
L"ls backslash\\\\test "
},
{
/* backslash inside single quotes */
L"ls 'sback",
"sback",
{"sbackslash\\test", NULL},
L"ls 'sbackslash\\test'"
},
{
/* backslash inside double quotes */
L"ls \"dback",
"dback",
{"dbackslash\\test", NULL},
L"ls \"dbackslash\\\\test\""
},
{
/* test braces */
L"ls br",
"br",
{"braces{test}", NULL},
L"ls braces\\{test\\} "
},
{
/* test braces inside single quotes */
L"ls 'sbr",
"sbr",
{"sbraces{test}", NULL},
L"ls 'sbraces{test}'"
},
{
/* test braces inside double quotes */
L"ls \"dbr",
"dbr",
{"dbraces{test}", NULL},
L"ls \"dbraces{test}\""
},
{
/* test dollar */
L"ls doll",
"doll",
{"doll$artest", NULL},
L"ls doll\\$artest "
},
{
/* test dollar inside single quotes */
L"ls 'sdoll",
"sdoll",
{"sdoll$artest", NULL},
L"ls 'sdoll$artest'"
},
{
/* test dollar inside double quotes */
L"ls \"ddoll",
"ddoll",
{"ddoll$artest", NULL},
L"ls \"ddoll\\$artest\""
},
{
/* test equals */
L"ls eq",
"eq",
{"equals==test", NULL},
L"ls equals\\=\\=test "
},
{
/* test equals inside sinqle quotes */
L"ls 'seq",
"seq",
{"sequals==test", NULL},
L"ls 'sequals==test'"
},
{
/* test equals inside double quotes */
L"ls \"deq",
"deq",
{"dequals==test", NULL},
L"ls \"dequals==test\""
},
{
/* test \n */
L"ls new",
"new",
{"new\\nline", NULL},
L"ls new\\\\nline "
},
{
/* test \n inside single quotes */
L"ls 'snew",
"snew",
{"snew\nline", NULL},
L"ls 'snew\nline'"
},
{
/* test \n inside double quotes */
L"ls \"dnew",
"dnew",
{"dnew\nline", NULL},
L"ls \"dnew\nline\""
},
{
/* test single space */
L"ls spac",
"spac",
{"space test", NULL},
L"ls space\\ test "
},
{
/* test single space inside singlq quotes */
L"ls 's_spac",
"s_spac",
{"s_space test", NULL},
L"ls 's_space test'"
},
{
/* test single space inside double quotes */
L"ls \"d_spac",
"d_spac",
{"d_space test", NULL},
L"ls \"d_space test\""
},
{
/* test multiple spaces */
L"ls multi",
"multi",
{"multi space test", NULL},
L"ls multi\\ space\\ \\ test "
},
{
/* test multiple spaces inside single quotes */
L"ls 's_multi",
"s_multi",
{"s_multi space test", NULL},
L"ls 's_multi space test'"
},
{
/* test multiple spaces inside double quotes */
L"ls \"d_multi",
"d_multi",
{"d_multi space test", NULL},
L"ls \"d_multi space test\""
},
{
/* test double quotes */
L"ls doub",
"doub",
{"doub\"quotes", NULL},
L"ls doub\\\"quotes "
},
{
/* test double quotes inside single quotes */
L"ls 's_doub",
"s_doub",
{"s_doub\"quotes", NULL},
L"ls 's_doub\"quotes'"
},
{
/* test double quotes inside double quotes */
L"ls \"d_doub",
"d_doub",
{"d_doub\"quotes", NULL},
L"ls \"d_doub\\\"quotes\""
},
{
/* test multiple double quotes */
L"ls mud",
"mud",
{"mud\"qu\"otes\"", NULL},
L"ls mud\\\"qu\\\"otes\\\" "
},
{
/* test multiple double quotes inside single quotes */
L"ls 'smud",
"smud",
{"smud\"qu\"otes\"", NULL},
L"ls 'smud\"qu\"otes\"'"
},
{
/* test multiple double quotes inside double quotes */
L"ls \"dmud",
"dmud",
{"dmud\"qu\"otes\"", NULL},
L"ls \"dmud\\\"qu\\\"otes\\\"\""
},
{
/* test one single quote */
L"ls sing",
"sing",
{"single'quote", NULL},
L"ls single\\'quote "
},
{
/* test one single quote inside single quote */
L"ls 'ssing",
"ssing",
{"ssingle'quote", NULL},
L"ls 'ssingle'\\''quote'"
},
{
/* test one single quote inside double quote */
L"ls \"dsing",
"dsing",
{"dsingle'quote", NULL},
L"ls \"dsingle'quote\""
},
{
/* test multiple single quotes */
L"ls mu_sing",
"mu_sing",
{"mu_single''quotes''", NULL},
L"ls mu_single\\'\\'quotes\\'\\' "
},
{
/* test multiple single quotes inside single quote */
L"ls 'smu_sing",
"smu_sing",
{"smu_single''quotes''", NULL},
L"ls 'smu_single'\\'''\\''quotes'\\\'''\\'''"
},
{
/* test multiple single quotes inside double quote */
L"ls \"dmu_sing",
"dmu_sing",
{"dmu_single''quotes''", NULL},
L"ls \"dmu_single''quotes''\""
},
{
/* test parenthesis */
L"ls paren",
"paren",
{"paren(test)", NULL},
L"ls paren\\(test\\) "
},
{
/* test parenthesis inside single quote */
L"ls 'sparen",
"sparen",
{"sparen(test)", NULL},
L"ls 'sparen(test)'"
},
{
/* test parenthesis inside double quote */
L"ls \"dparen",
"dparen",
{"dparen(test)", NULL},
L"ls \"dparen(test)\""
},
{
/* test pipe */
L"ls pip",
"pip",
{"pipe|test", NULL},
L"ls pipe\\|test "
},
{
/* test pipe inside single quote */
L"ls 'spip",
"spip",
{"spipe|test", NULL},
L"ls 'spipe|test'",
},
{
/* test pipe inside double quote */
L"ls \"dpip",
"dpip",
{"dpipe|test", NULL},
L"ls \"dpipe|test\""
},
{
/* test tab */
L"ls ta",
"ta",
{"tab\ttest", NULL},
L"ls tab\\\ttest "
},
{
/* test tab inside single quote */
L"ls 'sta",
"sta",
{"stab\ttest", NULL},
L"ls 'stab\ttest'"
},
{
/* test tab inside double quote */
L"ls \"dta",
"dta",
{"dtab\ttest", NULL},
L"ls \"dtab\ttest\""
},
{
/* test back tick */
L"ls tic",
"tic",
{"tick`test`", NULL},
L"ls tick\\`test\\` "
},
{
/* test back tick inside single quote */
L"ls 'stic",
"stic",
{"stick`test`", NULL},
L"ls 'stick`test`'"
},
{
/* test back tick inside double quote */
L"ls \"dtic",
"dtic",
{"dtick`test`", NULL},
L"ls \"dtick\\`test\\`\""
},
{
/* test for @ */
L"ls at",
"at",
{"atthe@rate", NULL},
L"ls atthe\\@rate "
},
{
/* test for @ inside single quote */
L"ls 'sat",
"sat",
{"satthe@rate", NULL},
L"ls 'satthe@rate'"
},
{
/* test for @ inside double quote */
L"ls \"dat",
"dat",
{"datthe@rate", NULL},
L"ls \"datthe@rate\""
},
{
/* test ; */
L"ls semi",
"semi",
{"semi;colon;test", NULL},
L"ls semi\\;colon\\;test "
},
{
/* test ; inside single quote */
L"ls 'ssemi",
"ssemi",
{"ssemi;colon;test", NULL},
L"ls 'ssemi;colon;test'"
},
{
/* test ; inside double quote */
L"ls \"dsemi",
"dsemi",
{"dsemi;colon;test", NULL},
L"ls \"dsemi;colon;test\""
},
{
/* test & */
L"ls amp",
"amp",
{"ampers&and", NULL},
L"ls ampers\\&and "
},
{
/* test & inside single quote */
L"ls 'samp",
"samp",
{"sampers&and", NULL},
L"ls 'sampers&and'"
},
{
/* test & inside double quote */
L"ls \"damp",
"damp",
{"dampers&and", NULL},
L"ls \"dampers&and\""
},
{
/* test completion when cursor at \ */
L"ls foo\\",
"foo",
{"foo bar", NULL},
L"ls foo\\ bar "
},
{
/* test completion when cursor at single quote */
L"ls foo'",
"foo'",
{"foo bar", NULL},
L"ls foo\\ bar "
},
{
/* test completion when cursor at double quote */
L"ls foo\"",
"foo\"",
{"foo bar", NULL},
L"ls foo\\ bar "
},
{
/* test multiple completion matches */
L"ls fo",
"fo",
{"foo bar", "foo baz"},
L"ls foo\\ ba"
},
{
L"ls ba",
"ba",
{"bar <bar>", "bar <baz>"},
L"ls bar\\ \\<ba"
}
};
static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
/*
* Custom completion function passed to fn_complet, NULLe.
* The function returns hardcoded completion matches
* based on the test cases present in inputs[] (above)
*/
static char *
mycomplet_func(const char *text, int index)
{
static int last_index = 0;
size_t i = 0;
if (last_index == 2) {
last_index = 0;
return NULL;
}
for (i = 0; i < sizeof(inputs)/sizeof(inputs[0]); i++) {
if (strcmp(text, inputs[i].completion_function_input) == 0) {
if (inputs[i].expanded_text[last_index] != NULL)
return strdup(inputs[i].expanded_text[last_index++]);
else {
last_index = 0;
return NULL;
}
}
}
return NULL;
}
int
main(int argc, char **argv)
{
EditLine *el = el_init(argv[0], stdin, stdout, stderr);
size_t i;
size_t input_len;
el_line_t line;
wchar_t *buffer = malloc(64 * sizeof(*buffer));
if (buffer == NULL)
err(EXIT_FAILURE, "malloc failed");
for (i = 0; i < sizeof(inputs)/sizeof(inputs[0]); i++) {
memset(buffer, 0, 64 * sizeof(*buffer));
input_len = wcslen(inputs[i].user_typed_text);
wmemcpy(buffer, inputs[i].user_typed_text, input_len);
buffer[input_len] = 0;
line.buffer = buffer;
line.cursor = line.buffer + input_len ;
line.lastchar = line.cursor - 1;
line.limit = line.buffer + 64 * sizeof(*buffer);
el->el_line = line;
fn_complete(el, mycomplet_func, NULL, break_chars, NULL, NULL, 10, NULL, NULL, NULL, NULL);
/*
* fn_complete would have expanded and escaped the input in el->el_line.buffer.
* We need to assert that it matches with the expected value in our test data
*/
printf("User input: %ls\t Expected output: %ls\t Generated output: %ls\n",
inputs[i].user_typed_text, inputs[i].escaped_output, el->el_line.buffer);
assert(wcscmp(el->el_line.buffer, inputs[i].escaped_output) == 0);
}
el_end(el);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $ */
/* $NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $");
__RCSID("$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -174,7 +174,7 @@ c_delbefore(EditLine *el, int num)
wchar_t *cp;
for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar;
&cp[num] <= el->el_line.lastchar;
cp++)
*cp = cp[num];
@ -396,26 +396,22 @@ cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
libedit_private int
ch_init(EditLine *el)
{
el->el_line.buffer = el_malloc(EL_BUFSIZ *
el->el_line.buffer = el_calloc(EL_BUFSIZ,
sizeof(*el->el_line.buffer));
if (el->el_line.buffer == NULL)
return -1;
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
sizeof(*el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer;
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ *
el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ,
sizeof(*el->el_chared.c_undo.buf));
if (el->el_chared.c_undo.buf == NULL)
return -1;
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0;
el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ *
el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ,
sizeof(*el->el_chared.c_redo.buf));
if (el->el_chared.c_redo.buf == NULL)
return -1;
@ -426,12 +422,10 @@ ch_init(EditLine *el)
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ *
el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ,
sizeof(*el->el_chared.c_kill.buf));
if (el->el_chared.c_kill.buf == NULL)
return -1;
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
el->el_chared.c_kill.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
el->el_chared.c_resizefun = NULL;
@ -591,7 +585,7 @@ ch_end(EditLine *el)
/* el_insertstr():
* Insert string at cursorI
* Insert string at cursor
*/
int
el_winsertstr(EditLine *el, const wchar_t *s)

View File

@ -1,4 +1,4 @@
/* $NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $ */
/* $NetBSD: chartype.c,v 1.35 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -31,10 +31,11 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $");
__RCSID("$NetBSD: chartype.c,v 1.35 2019/07/23 10:18:52 christos Exp $");
#endif /* not lint && not SCCSID */
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@ -156,7 +157,7 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1)
return NULL;
wargv = el_malloc((size_t)(argc + 1) * sizeof(*wargv));
wargv = el_calloc((size_t)(argc + 1), sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
@ -183,17 +184,14 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
libedit_private size_t
ct_enc_width(wchar_t c)
{
/* UTF-8 encoding specific values */
if (c < 0x80)
return 1;
else if (c < 0x0800)
return 2;
else if (c < 0x10000)
return 3;
else if (c < 0x110000)
return 4;
else
return 0; /* not a valid codepoint */
mbstate_t mbs;
char buf[MB_LEN_MAX];
size_t size;
memset(&mbs, 0, sizeof(mbs));
if ((size = wcrtomb(buf, c, &mbs)) == (size_t)-1)
return 0;
return size;
}
libedit_private ssize_t

View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $ */
/* $NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $");
__RCSID("$NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -363,15 +363,17 @@ ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
* [^V] [^V]
*/
libedit_private el_action_t
ed_quoted_insert(EditLine *el, wint_t c)
/*ARGSUSED*/
ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__)))
{
int num;
wchar_t ch;
tty_quotemode(el);
num = el_wgetc(el, &c);
num = el_wgetc(el, &ch);
tty_noquotemode(el);
if (num == 1)
return ed_insert(el, c);
return ed_insert(el, ch);
else
return ed_end_of_file(el, 0);
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.98 2017/09/02 06:48:10 wiz Exp $
.\" $NetBSD: editline.3,v 1.99 2018/11/18 17:09:39 christos 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 September 1, 2017
.Dd November 9, 2018
.Dt EDITLINE 3
.Os
.Sh NAME
@ -181,8 +181,6 @@ library respects the
locale set by the application program and never uses
.Xr setlocale 3
to change the locale.
The only locales supported are UTF-8 and the default C or POSIX locale.
If any other locale is set, behaviour is undefined.
.Sh LINE EDITING FUNCTIONS
The line editing functions use a common data structure,
.Fa EditLine ,

30
el.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.95 2017/09/05 18:07:59 christos Exp $ */
/* $NetBSD: el.c,v 1.99 2019/07/23 10:18:52 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.95 2017/09/05 18:07:59 christos Exp $");
__RCSID("$NetBSD: el.c,v 1.99 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -71,13 +71,11 @@ libedit_private EditLine *
el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr, int flags)
{
EditLine *el = el_malloc(sizeof(*el));
EditLine *el = el_calloc(1, sizeof(*el));
if (el == NULL)
return NULL;
memset(el, 0, sizeof(EditLine));
el->el_infile = fin;
el->el_outfile = fout;
el->el_errfile = ferr;
@ -96,10 +94,6 @@ el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
* Initialize all the modules. Order is important!!!
*/
el->el_flags = flags;
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
if (terminal_init(el) == -1) {
el_free(el->el_prog);
@ -146,7 +140,7 @@ el_end(EditLine *el)
keymacro_end(el);
map_end(el);
if (!(el->el_flags & NO_TTY))
tty_end(el);
tty_end(el, TCSAFLUSH);
ch_end(el);
read_end(el->el_read);
search_end(el);
@ -301,7 +295,7 @@ el_wset(EditLine *el, int op, ...)
void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
if (!(el->el_flags & CHARSET_IS_UTF8))
if (MB_CUR_MAX == 1)
el->el_flags &= ~NARROW_HISTORY;
break;
}
@ -443,15 +437,11 @@ el_wget(EditLine *el, int op, ...)
case EL_GETTC:
{
static char name[] = "gettc";
char *argv[20];
int i;
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
char *argv[3];
argv[0] = name;
rv = terminal_gettc(el, i, argv);
argv[1] = va_arg(ap, char *);
argv[2] = va_arg(ap, void *);
rv = terminal_gettc(el, 3, argv);
break;
}
@ -542,7 +532,7 @@ el_source(EditLine *el, const char *fname)
if ((ptr = getenv("HOME")) == NULL)
return -1;
plen += strlen(ptr);
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
if ((path = el_calloc(plen, sizeof(*path))) == NULL)
return -1;
(void)snprintf(path, plen, "%s%s", ptr,
elpath + (*ptr == '\0'));

4
el.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.43 2017/09/05 18:07:59 christos Exp $ */
/* $NetBSD: el.h,v 1.45 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -55,7 +55,6 @@
#define NO_TTY 0x02
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
#define NARROW_HISTORY 0x40
#define NO_RESET 0x80
@ -90,6 +89,7 @@ typedef struct el_state_t {
* Until we come up with something better...
*/
#define el_malloc(a) malloc(a)
#define el_calloc(a,b) calloc(a, b)
#define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a)

14
eln.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $ */
/* $NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 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.34 2016/05/09 21:37:34 christos Exp $");
__RCSID("$NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 christos Exp $");
#endif /* not lint && not SCCSID */
#include <errno.h>
@ -321,14 +321,12 @@ el_get(EditLine *el, int op, ...)
break;
case EL_GETTC: {
char *argv[20];
char *argv[3];
static char gettc[] = "gettc";
int i;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = gettc;
ret = terminal_gettc(el, i, argv);
argv[1] = va_arg(ap, char *);
argv[2] = va_arg(ap, void *);
ret = terminal_gettc(el, 3, argv);
break;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.45 2017/04/21 05:38:03 abhinav Exp $ */
/* $NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav 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.45 2017/04/21 05:38:03 abhinav Exp $");
__RCSID("$NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -83,7 +83,7 @@ fn_tilde_expand(const char *txt)
} else {
/* text until string after slash */
len = (size_t)(temp - txt + 1);
temp = el_malloc(len * sizeof(*temp));
temp = el_calloc(len, sizeof(*temp));
if (temp == NULL)
return NULL;
(void)strncpy(temp, txt + 1, len - 2);
@ -118,7 +118,7 @@ fn_tilde_expand(const char *txt)
txt += len;
len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
temp = el_malloc(len * sizeof(*temp));
temp = el_calloc(len, sizeof(*temp));
if (temp == NULL)
return NULL;
(void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
@ -126,6 +126,192 @@ fn_tilde_expand(const char *txt)
return temp;
}
static int
needs_escaping(char c)
{
switch (c) {
case '\'':
case '"':
case '(':
case ')':
case '\\':
case '<':
case '>':
case '$':
case '#':
case ' ':
case '\n':
case '\t':
case '?':
case ';':
case '`':
case '@':
case '=':
case '|':
case '{':
case '}':
case '&':
case '*':
case '[':
return 1;
default:
return 0;
}
}
static int
needs_dquote_escaping(char c)
{
switch (c) {
case '"':
case '\\':
case '`':
case '$':
return 1;
default:
return 0;
}
}
static wchar_t *
unescape_string(const wchar_t *string, size_t length)
{
size_t i;
size_t j = 0;
wchar_t *unescaped = el_calloc(length + 1, sizeof(*string));
if (unescaped == NULL)
return NULL;
for (i = 0; i < length ; i++) {
if (string[i] == '\\')
continue;
unescaped[j++] = string[i];
}
unescaped[j] = 0;
return unescaped;
}
static char *
escape_filename(EditLine * el, const char *filename, int single_match,
const char *(*app_func)(const char *))
{
size_t original_len = 0;
size_t escaped_character_count = 0;
size_t offset = 0;
size_t newlen;
const char *s;
char c;
size_t s_quoted = 0; /* does the input contain a single quote */
size_t d_quoted = 0; /* does the input contain a double quote */
char *escaped_str;
wchar_t *temp = el->el_line.buffer;
const char *append_char = NULL;
if (filename == NULL)
return NULL;
while (temp != el->el_line.cursor) {
/*
* If we see a single quote but have not seen a double quote
* so far set/unset s_quote
*/
if (temp[0] == '\'' && !d_quoted)
s_quoted = !s_quoted;
/*
* vice versa to the above condition
*/
else if (temp[0] == '"' && !s_quoted)
d_quoted = !d_quoted;
temp++;
}
/* Count number of special characters so that we can calculate
* number of extra bytes needed in the new string
*/
for (s = filename; *s; s++, original_len++) {
c = *s;
/* Inside a single quote only single quotes need escaping */
if (s_quoted && c == '\'') {
escaped_character_count += 3;
continue;
}
/* Inside double quotes only ", \, ` and $ need escaping */
if (d_quoted && needs_dquote_escaping(c)) {
escaped_character_count++;
continue;
}
if (!s_quoted && !d_quoted && needs_escaping(c))
escaped_character_count++;
}
newlen = original_len + escaped_character_count + 1;
if (s_quoted || d_quoted)
newlen++;
if (single_match && app_func)
newlen++;
if ((escaped_str = el_malloc(newlen)) == NULL)
return NULL;
for (s = filename; *s; s++) {
c = *s;
if (!needs_escaping(c)) {
/* no escaping is required continue as usual */
escaped_str[offset++] = c;
continue;
}
/* single quotes inside single quotes require special handling */
if (c == '\'' && s_quoted) {
escaped_str[offset++] = '\'';
escaped_str[offset++] = '\\';
escaped_str[offset++] = '\'';
escaped_str[offset++] = '\'';
continue;
}
/* Otherwise no escaping needed inside single quotes */
if (s_quoted) {
escaped_str[offset++] = c;
continue;
}
/* No escaping needed inside a double quoted string either
* unless we see a '$', '\', '`', or '"' (itself)
*/
if (d_quoted && !needs_dquote_escaping(c)) {
escaped_str[offset++] = c;
continue;
}
/* If we reach here that means escaping is actually needed */
escaped_str[offset++] = '\\';
escaped_str[offset++] = c;
}
if (single_match && app_func) {
escaped_str[offset] = 0;
append_char = app_func(escaped_str);
/* we want to append space only if we are not inside quotes */
if (append_char[0] == ' ') {
if (!s_quoted && !d_quoted)
escaped_str[offset++] = append_char[0];
} else
escaped_str[offset++] = append_char[0];
}
/* close the quotes if single match and the match is not a directory */
if (single_match && (append_char && append_char[0] == ' ')) {
if (s_quoted)
escaped_str[offset++] = '\'';
else if (d_quoted)
escaped_str[offset++] = '"';
}
escaped_str[offset] = 0;
return escaped_str;
}
/*
* return first found file name starting by the ``text'' or NULL if no
@ -242,7 +428,7 @@ fn_filename_completion_function(const char *text, int state)
#endif
len = strlen(dirname) + len + 1;
temp = el_malloc(len * sizeof(*temp));
temp = el_calloc(len, sizeof(*temp));
if (temp == NULL)
return NULL;
(void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
@ -318,7 +504,7 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
max_equal = i;
}
retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
retstr = el_calloc(max_equal + 1, sizeof(*retstr));
if (retstr == NULL) {
el_free(match_list);
return NULL;
@ -370,7 +556,7 @@ fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
* Find out how many entries can be put on one line; count
* with one space between strings the same way it's printed.
*/
cols = (size_t)screenwidth / (width + 1);
cols = (size_t)screenwidth / (width + 2);
if (cols == 0)
cols = 1;
@ -390,7 +576,7 @@ fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
break;
(void)fprintf(el->el_outfile, "%s%s%s",
col == 0 ? "" : " ", matches[thisguy],
append_char_function(matches[thisguy]));
(*app_func)(matches[thisguy]));
(void)fprintf(el->el_outfile, "%-*s",
(int) (width - strlen(matches[thisguy])), "");
}
@ -398,6 +584,60 @@ fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
}
}
static wchar_t *
find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length)
{
/* We now look backwards for the start of a filename/variable word */
const wchar_t *ctemp = cursor;
size_t len;
/* if the cursor is placed at a slash or a quote, we need to find the
* word before it
*/
if (ctemp > buffer) {
switch (ctemp[-1]) {
case '\\':
case '\'':
case '"':
ctemp--;
break;
default:
break;
}
}
for (;;) {
if (ctemp <= buffer)
break;
if (wcschr(word_break, ctemp[-1])) {
if (ctemp - buffer >= 2 && ctemp[-2] == '\\') {
ctemp -= 2;
continue;
} else if (ctemp - buffer >= 2 &&
(ctemp[-2] == '\'' || ctemp[-2] == '"')) {
ctemp--;
continue;
} else
break;
}
if (special_prefixes && wcschr(special_prefixes, ctemp[-1]))
break;
ctemp--;
}
len = (size_t) (cursor - ctemp);
if (len == 1 && (ctemp[0] == '\'' || ctemp[0] == '"')) {
len = 0;
ctemp++;
}
*length = len;
wchar_t *unescaped_word = unescape_string(ctemp, len);
if (unescaped_word == NULL)
return NULL;
return unescaped_word;
}
/*
* Complete the word at or before point,
* 'what_to_do' says what to do with the completion.
@ -420,8 +660,8 @@ fn_complete(EditLine *el,
{
const LineInfoW *li;
wchar_t *temp;
char **matches;
const wchar_t *ctemp;
char **matches;
char *completion;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
@ -438,18 +678,11 @@ fn_complete(EditLine *el,
if (!app_func)
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = el_wline(el);
ctemp = li->cursor;
while (ctemp > li->buffer
&& !wcschr(word_break, ctemp[-1])
&& (!special_prefixes || !wcschr(special_prefixes, ctemp[-1]) ) )
ctemp--;
len = (size_t)(li->cursor - ctemp);
temp = el_malloc((len + 1) * sizeof(*temp));
(void)wcsncpy(temp, ctemp, len);
temp[len] = '\0';
temp = find_word_to_complete(li->cursor,
li->buffer, word_break, special_prefixes, &len);
if (temp == NULL)
goto out;
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
@ -476,30 +709,41 @@ fn_complete(EditLine *el,
if (matches) {
int i;
size_t matches_num, maxlen, match_len, match_display=1;
int single_match = matches[2] == NULL &&
(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);
retval = CC_REFRESH;
/*
* Only replace the completed string with common part of
* possible matches if there is possible completion.
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
el_winsertstr(el,
ct_decode_string(matches[0], &el->el_scratch));
el_deletestr(el, (int)len);
if (!attempted_completion_function)
completion = escape_filename(el, matches[0],
single_match, app_func);
else
completion = strdup(matches[0]);
if (completion == NULL)
goto out;
if (single_match) {
/* We found exact match. Add a space after it,
* unless we do filename completion and the
* object is a directory. Also do necessary
* escape quoting
*/
el_winsertstr(el,
ct_decode_string(completion, &el->el_scratch));
} else {
/* Only replace the completed string with
* common part of possible matches if there is
* possible completion.
*/
el_winsertstr(el,
ct_decode_string(completion, &el->el_scratch));
}
free(completion);
}
if (matches[2] == NULL &&
(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) {
/*
* We found exact match. Add a space after
* it, unless we do filename completion and the
* object is a directory.
*/
el_winsertstr(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} else if (what_to_do == '!' || what_to_do == '?') {
if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
/*
* More than one match and requested to list possible
* matches.
@ -562,6 +806,8 @@ fn_complete(EditLine *el,
el_free(matches);
matches = NULL;
}
out:
el_free(temp);
return retval;
}

8
hist.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 christos Exp $ */
/* $NetBSD: hist.c,v 1.34 2019/07/23 10:19:35 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.34 2019/07/23 10:19:35 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -59,10 +59,10 @@ hist_init(EditLine *el)
el->el_history.fun = NULL;
el->el_history.ref = NULL;
el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
el->el_history.sz = EL_BUFSIZ;
el->el_history.buf = el_calloc(EL_BUFSIZ, sizeof(*el->el_history.buf));
if (el->el_history.buf == NULL)
return -1;
el->el_history.sz = EL_BUFSIZ;
el->el_history.last = el->el_history.buf;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $ */
/* $NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -775,6 +775,7 @@ history_load(TYPE(History) *h, const char *fname)
char *ptr;
int i = -1;
TYPE(HistEvent) ev;
Char *decode_result;
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
@ -807,7 +808,10 @@ history_load(TYPE(History) *h, const char *fname)
ptr = nptr;
}
(void) strunvis(ptr, line);
if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) {
decode_result = ct_decode_string(ptr, &conv);
if (decode_result == NULL)
continue;
if (HENTER(h, &ev, decode_result) == -1) {
i = -1;
goto oomem;
}
@ -1082,11 +1086,13 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
break;
case H_NSAVE_FP:
retval = history_save_fp(h, va_arg(va, size_t),
va_arg(va, FILE *));
{
size_t sz = va_arg(va, size_t);
retval = history_save_fp(h, sz, va_arg(va, FILE *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;
}
case H_PREV_EVENT:
retval = history_prev_event(h, ev, va_arg(va, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $ */
/* $NetBSD: keymacro.c,v 1.24 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $");
__RCSID("$NetBSD: keymacro.c,v 1.24 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -105,7 +105,7 @@ libedit_private int
keymacro_init(EditLine *el)
{
el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
el->el_keymacro.buf = el_calloc(KEY_BUFSIZ,
sizeof(*el->el_keymacro.buf));
if (el->el_keymacro.buf == NULL)
return -1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $ */
/* $NetBSD: literal.c,v 1.5 2019/07/23 13:10:11 christos Exp $ */
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $");
__RCSID("$NetBSD: literal.c,v 1.5 2019/07/23 13:10:11 christos Exp $");
#endif /* not lint && not SCCSID */
/*
@ -98,8 +98,8 @@ literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)
return 0;
for (n = 0, i = 0; i < len; i++)
n += ct_encode_char(b + n, w - n, buf[i]);
n += ct_encode_char(b + n, w - n, end[1]);
n += ct_encode_char(b + n, (size_t)(w - n), buf[i]);
n += ct_encode_char(b + n, (size_t)(w - n), end[1]);
b[n] = '\0';
/*

12
map.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $ */
/* $NetBSD: map.c,v 1.52 2019/07/23 10:18:52 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.51 2016/05/09 21:46:56 christos Exp $");
__RCSID("$NetBSD: map.c,v 1.52 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -913,21 +913,21 @@ map_init(EditLine *el)
EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif
el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS);
el->el_map.alt = el_calloc(N_KEYS, sizeof(*el->el_map.alt));
if (el->el_map.alt == NULL)
return -1;
el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS);
el->el_map.key = el_calloc(N_KEYS, sizeof(*el->el_map.key));
if (el->el_map.key == NULL)
return -1;
el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert;
el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS);
el->el_map.help = el_calloc(EL_NUM_FCNS, sizeof(*el->el_map.help));
if (el->el_map.help == NULL)
return -1;
(void) memcpy(el->el_map.help, el_func_help,
sizeof(*el->el_map.help) * EL_NUM_FCNS);
el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS);
el->el_map.func = el_calloc(EL_NUM_FCNS, sizeof(*el->el_map.func));
if (el->el_map.func == NULL)
return -1;
memcpy(el->el_map.func, el_func, sizeof(*el->el_map.func)

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $ */
/* $NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $");
__RCSID("$NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -111,8 +111,8 @@ el_wparse(EditLine *el, int argc, const wchar_t *argv[])
if (ptr == argv[0])
return 0;
l = (size_t)(ptr - argv[0] - 1);
tprog = el_malloc((l + 1) * sizeof(*tprog));
l = (size_t)(ptr - argv[0]);
tprog = el_calloc(l + 1, sizeof(*tprog));
if (tprog == NULL)
return 0;
(void) wcsncpy(tprog, argv[0], l);

15
read.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.103 2017/06/27 23:24:19 christos Exp $ */
/* $NetBSD: read.c,v 1.106 2019/07/23 10:18:52 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.103 2017/06/27 23:24:19 christos Exp $");
__RCSID("$NetBSD: read.c,v 1.106 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -89,8 +89,7 @@ read_init(EditLine *el)
return -1;
ma = &el->el_read->macros;
if ((ma->macro = el_malloc(EL_MAXMACRO *
sizeof(*ma->macro))) == NULL) {
if ((ma->macro = el_calloc(EL_MAXMACRO, sizeof(*ma->macro))) == NULL) {
free(el->el_read);
return -1;
}
@ -335,13 +334,7 @@ read_char(EditLine *el, wchar_t *cp)
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) {
if (cbp >= MB_LEN_MAX) {
errno = EILSEQ;
*cp = L'\0';
return -1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.c,v 1.143 2017/09/05 18:07:59 christos Exp $ */
/* $NetBSD: readline.c,v 1.157 2019/08/21 11:11:48 christos 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.143 2017/09/05 18:07:59 christos Exp $");
__RCSID("$NetBSD: readline.c,v 1.157 2019/08/21 11:11:48 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -72,7 +72,7 @@ static char empty[] = { '\0' };
static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
char *rl_readline_name = empty;
const char *rl_readline_name = empty;
FILE *rl_instream = NULL;
FILE *rl_outstream = NULL;
int rl_point = 0;
@ -80,7 +80,7 @@ int rl_end = 0;
char *rl_line_buffer = NULL;
rl_vcpfunc_t *rl_linefunc = NULL;
int rl_done = 0;
VFunction *rl_event_hook = NULL;
rl_hook_func_t *rl_event_hook = NULL;
KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_meta_keymap,
emacs_ctlx_keymap;
@ -105,9 +105,9 @@ char *history_arg_extract(int start, int end, const char *str);
int rl_inhibit_completion = 0;
int rl_attempted_completion_over = 0;
char *rl_basic_word_break_characters = break_chars;
const char *rl_basic_word_break_characters = break_chars;
char *rl_completer_word_break_characters = NULL;
char *rl_completer_quote_characters = NULL;
const char *rl_completer_quote_characters = NULL;
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;
@ -150,7 +150,7 @@ int rl_completion_query_items = 100;
* in the parsed text when it is passed to the completion function.
* Shell uses this to help determine what kind of completing to do.
*/
char *rl_special_prefixes = NULL;
const char *rl_special_prefixes = NULL;
/*
* This is the character appended to the completed words if at the end of
@ -258,8 +258,14 @@ rl_set_prompt(const char *prompt)
if (rl_prompt == NULL)
return -1;
while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
*p = RL_PROMPT_START_IGNORE;
while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) {
/* Remove adjacent end/start markers to avoid double-escapes. */
if (p[1] == RL_PROMPT_START_IGNORE) {
memmove(p, p + 2, 1 + strlen(p + 2));
} else {
*p = RL_PROMPT_START_IGNORE;
}
}
return 0;
}
@ -319,7 +325,7 @@ rl_initialize(void)
el_end(e);
return -1;
}
el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
el_set(e, EL_PROMPT_ESC, _get_prompt, RL_PROMPT_START_IGNORE);
el_set(e, EL_SIGNAL, rl_catch_signals);
/* set default mode to "emacs"-style and read setting afterwards */
@ -388,7 +394,7 @@ rl_initialize(void)
_resize_fun(e, &rl_line_buffer);
_rl_update_pos();
tty_end(e);
tty_end(e, TCSADRAIN);
return 0;
}
@ -429,7 +435,7 @@ readline(const char *p)
if (rl_pre_input_hook)
(*rl_pre_input_hook)(NULL, 0);
if (rl_event_hook && !(e->el_flags&NO_TTY)) {
if (rl_event_hook && !(e->el_flags & NO_TTY)) {
el_set(e, EL_GETCFN, _rl_event_read_char);
used_event_hook = 1;
}
@ -460,7 +466,7 @@ readline(const char *p)
history_length = ev.num;
out:
tty_end(e);
tty_end(e, TCSADRAIN);
return buf;
}
@ -509,7 +515,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with,
} else
s++;
}
r = result = el_malloc((len + 1) * sizeof(*r));
r = result = el_calloc(len + 1, sizeof(*r));
if (result == NULL)
return NULL;
s = str;
@ -599,7 +605,7 @@ get_history_event(const char *cmd, int *cindex, int qchar)
else if (len == 0)
return NULL;
else {
if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
if ((pat = el_calloc(len + 1, sizeof(*pat))) == NULL)
return NULL;
(void)strncpy(pat, cmd + begin, len);
pat[len] = '\0';
@ -693,7 +699,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
} else {
if (command[offs + 1] == '#') {
/* use command so far */
if ((aptr = el_malloc((offs + 1) * sizeof(*aptr)))
if ((aptr = el_calloc(offs + 1, sizeof(*aptr)))
== NULL)
return -1;
(void)strncpy(aptr, command, offs);
@ -927,7 +933,7 @@ history_expand(char *str, char **output)
*output = NULL;
if (str[0] == history_subst_char) {
/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
*output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output));
*output = el_calloc(strlen(str) + 4 + 1, sizeof(**output));
if (*output == NULL)
return 0;
(*output)[0] = (*output)[1] = history_expansion_char;
@ -1075,7 +1081,7 @@ history_arg_extract(int start, int end, const char *str)
for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
len += strlen(arr[i]) + 1;
len++;
result = el_malloc(len * sizeof(*result));
result = el_calloc(len, sizeof(*result));
if (result == NULL)
goto out;
@ -1137,7 +1143,7 @@ history_tokenize(const char *str)
result = nresult;
}
len = (size_t)i - (size_t)start;
temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
temp = el_calloc(len + 1, sizeof(*temp));
if (temp == NULL) {
for (i = 0; i < idx; i++)
el_free(result[i]);
@ -1355,8 +1361,14 @@ read_history(const char *filename)
rl_initialize();
if (filename == NULL && (filename = _default_history_file()) == NULL)
return errno;
return history(h, &ev, H_LOAD, filename) == -1 ?
(errno ? errno : EINVAL) : 0;
errno = 0;
if (history(h, &ev, H_LOAD, filename) == -1)
return errno ? errno : EINVAL;
if (history(h, &ev, H_GETSIZE) == 0)
history_length = ev.num;
if (history_length < 0)
return EINVAL;
return 0;
}
@ -1465,8 +1477,10 @@ add_history(const char *line)
(void)history(h, &ev, H_GETSIZE);
if (ev.num == history_length)
history_base++;
else
else {
history_offset++;
history_length = ev.num;
}
return 0;
}
@ -1584,7 +1598,7 @@ history_list(void)
return NULL;
if ((nlp = el_realloc(_history_listp,
(size_t)history_length * sizeof(*nlp))) == NULL)
((size_t)history_length + 1) * sizeof(*nlp))) == NULL)
return NULL;
_history_listp = nlp;
@ -1601,6 +1615,7 @@ history_list(void)
if (i++ == history_length)
abort();
} while (history(h, &ev, H_PREV) == 0);
_history_listp[i] = NULL;
return _history_listp;
}
@ -1878,7 +1893,7 @@ int
rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
{
static ct_buffer_t wbreak_conv, sprefix_conv;
char *breakchars;
const char *breakchars;
if (h == NULL || e == NULL)
rl_initialize();
@ -1964,13 +1979,14 @@ rl_read_key(void)
* reset the terminal
*/
/* ARGSUSED */
void
int
rl_reset_terminal(const char *p __attribute__((__unused__)))
{
if (h == NULL || e == NULL)
rl_initialize();
el_reset(e);
return 0;
}
@ -2068,8 +2084,8 @@ rl_callback_read_char(void)
if (done && rl_linefunc != NULL) {
el_set(e, EL_UNBUFFERED, 0);
if (done == 2) {
if ((wbuf = strdup(buf)) != NULL)
wbuf[count] = '\0';
if ((wbuf = strdup(buf)) != NULL)
wbuf[count] = '\0';
} else
wbuf = NULL;
(*(void (*)(const char *))rl_linefunc)(wbuf);
@ -2159,7 +2175,7 @@ rl_variable_bind(const char *var, const char *value)
return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0;
}
void
int
rl_stuff_char(int c)
{
char buf[2];
@ -2167,6 +2183,7 @@ rl_stuff_char(int c)
buf[0] = (char)c;
buf[1] = '\0';
el_insertstr(e, buf);
return 1;
}
static int
@ -2222,15 +2239,16 @@ _rl_update_pos(void)
rl_point = (int)(li->cursor - li->buffer);
rl_end = (int)(li->lastchar - li->buffer);
rl_line_buffer[rl_end] = '\0';
}
void
rl_get_screen_size(int *rows, int *cols)
{
if (rows)
el_get(e, EL_GETTC, "li", rows, (void *)0);
el_get(e, EL_GETTC, "li", rows);
if (cols)
el_get(e, EL_GETTC, "co", cols, (void *)0);
el_get(e, EL_GETTC, "co", cols);
}
void
@ -2251,7 +2269,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun)
len = 1;
max = 10;
if ((list = el_malloc(max * sizeof(*list))) == NULL)
if ((list = el_calloc(max, sizeof(*list))) == NULL)
return NULL;
while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
@ -2286,7 +2304,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun)
if ((list[0] = strdup(str)) == NULL)
goto out;
} else {
if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL)
if ((list[0] = el_calloc(min + 1, sizeof(*list[0]))) == NULL)
goto out;
(void)memcpy(list[0], list[1], min);
list[0][min] = '\0';
@ -2409,3 +2427,19 @@ rl_resize_terminal(void)
{
el_resize(e);
}
void
rl_reset_after_signal(void)
{
if (rl_prep_term_function)
(*rl_prep_term_function)();
}
void
rl_echo_signal_char(int sig)
{
int c = tty_get_signal_character(e, sig);
if (c == -1)
return;
re_putc(e, c, 0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.42 2017/09/01 10:19:10 christos Exp $ */
/* $NetBSD: readline.h,v 1.46 2019/06/07 15:19:29 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -38,11 +38,13 @@
/* typedefs */
typedef int Function(const char *, int);
typedef char *CPFunction(const char *, int);
typedef void VFunction(void);
typedef void rl_vcpfunc_t(char *);
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);
/* only supports length */
typedef struct {
@ -97,23 +99,23 @@ extern "C" {
#endif
extern const char *rl_library_version;
extern int rl_readline_version;
extern char *rl_readline_name;
extern const char *rl_readline_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
extern char *rl_line_buffer;
extern int rl_point, rl_end;
extern int history_base, history_length;
extern int max_input_history;
extern char *rl_basic_word_break_characters;
extern const char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
extern const char *rl_completer_quote_characters;
extern rl_compentry_func_t *rl_completion_entry_function;
extern char *(*rl_completion_word_break_hook)(void);
extern rl_completion_func_t *rl_attempted_completion_function;
extern int rl_attempted_completion_over;
extern int rl_completion_type;
extern int rl_completion_query_items;
extern char *rl_special_prefixes;
extern const char *rl_special_prefixes;
extern int rl_completion_append_character;
extern int rl_inhibit_completion;
extern Function *rl_pre_input_hook;
@ -137,6 +139,7 @@ extern VFunction *rl_redisplay_function;
extern VFunction *rl_completion_display_matches_hook;
extern VFunction *rl_prep_term_function;
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;
@ -177,12 +180,12 @@ char *filename_completion_function(const char *, int);
char *username_completion_function(const char *, int);
int rl_complete(int, int);
int rl_read_key(void);
char **completion_matches(const char *, rl_compentry_func_t *);
char **completion_matches(/* const */ char *, rl_compentry_func_t *);
void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
int rl_insert_text(const char *);
void rl_reset_terminal(const char *);
int rl_reset_terminal(const char *);
void rl_resize_terminal(void);
int rl_bind_key(int, rl_command_func_t *);
int rl_newline(int, int);
@ -196,7 +199,7 @@ void rl_deprep_terminal(void);
int rl_read_init_file(const char *);
int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int);
int rl_stuff_char(int);
int rl_add_defun(const char *, rl_command_func_t *, int);
HISTORY_STATE *history_get_history_state(void);
void rl_get_screen_size(int *, int *);
@ -208,6 +211,8 @@ char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);
int rl_on_new_line(void);
void rl_reset_after_signal(void);
void rl_echo_signal_char(int);
/*
* The following are not implemented

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $ */
/* $NetBSD: refresh.c,v 1.56 2019/01/04 03:03:44 uwe 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.54 2017/06/30 20:26:52 kre Exp $");
__RCSID("$NetBSD: refresh.c,v 1.56 2019/01/04 03:03:44 uwe Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -1090,7 +1090,10 @@ re_refresh_cursor(EditLine *el)
static void
re_fastputc(EditLine *el, wint_t c)
{
int w = wcwidth(c);
wchar_t *lastline;
int w;
w = wcwidth(c);
while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
re_fastputc(el, ' ');
@ -1112,17 +1115,18 @@ re_fastputc(EditLine *el, wint_t c)
*/
if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
wchar_t *firstline = el->el_display[0];
lastline = el->el_display[0];
for(i = 1; i < lins; i++)
el->el_display[i - 1] = el->el_display[i];
re__copy_and_pad(firstline, L"", (size_t)0);
el->el_display[i - 1] = firstline;
el->el_display[i - 1] = lastline;
} else {
el->el_cursor.v++;
el->el_refresh.r_oldcv++;
lastline = el->el_display[++el->el_refresh.r_oldcv];
}
re__copy_and_pad(lastline, L"", (size_t)el->el_terminal.t_size.h);
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {
terminal__putc(el, ' ');

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $ */
/* $NetBSD: search.c,v 1.49 2019/07/23 10:18:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $");
__RCSID("$NetBSD: search.c,v 1.49 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -70,7 +70,7 @@ libedit_private int
search_init(EditLine *el)
{
el->el_search.patbuf = el_malloc(EL_BUFSIZ *
el->el_search.patbuf = el_calloc(EL_BUFSIZ,
sizeof(*el->el_search.patbuf));
if (el->el_search.patbuf == NULL)
return -1;
@ -603,8 +603,10 @@ cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag)
return CC_ERROR;
if (ch == (wint_t)-1) {
if (el_wgetc(el, &ch) != 1)
wchar_t c;
if (el_wgetc(el, &c) != 1)
return ed_end_of_file(el, 0);
ch = c;
}
/* Save for ';' and ',' commands */

View File

@ -1,4 +1,4 @@
/* $NetBSD: terminal.c,v 1.33 2017/06/27 23:23:09 christos Exp $ */
/* $NetBSD: terminal.c,v 1.39 2019/07/23 10:18:52 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.33 2017/06/27 23:23:09 christos Exp $");
__RCSID("$NetBSD: terminal.c,v 1.39 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -269,31 +269,27 @@ libedit_private int
terminal_init(EditLine *el)
{
el->el_terminal.t_buf = el_malloc(TC_BUFSIZE *
el->el_terminal.t_buf = el_calloc(TC_BUFSIZE,
sizeof(*el->el_terminal.t_buf));
if (el->el_terminal.t_buf == NULL)
goto fail1;
el->el_terminal.t_cap = el_malloc(TC_BUFSIZE *
el->el_terminal.t_cap = el_calloc(TC_BUFSIZE,
sizeof(*el->el_terminal.t_cap));
if (el->el_terminal.t_cap == NULL)
goto fail2;
el->el_terminal.t_fkey = el_malloc(A_K_NKEYS *
el->el_terminal.t_fkey = el_calloc(A_K_NKEYS,
sizeof(*el->el_terminal.t_fkey));
if (el->el_terminal.t_fkey == NULL)
goto fail3;
el->el_terminal.t_loc = 0;
el->el_terminal.t_str = el_malloc(T_str *
el->el_terminal.t_str = el_calloc(T_str,
sizeof(*el->el_terminal.t_str));
if (el->el_terminal.t_str == NULL)
goto fail4;
(void) memset(el->el_terminal.t_str, 0, T_str *
sizeof(*el->el_terminal.t_str));
el->el_terminal.t_val = el_malloc(T_val *
el->el_terminal.t_val = el_calloc(T_val,
sizeof(*el->el_terminal.t_val));
if (el->el_terminal.t_val == NULL)
goto fail5;
(void) memset(el->el_terminal.t_val, 0, T_val *
sizeof(*el->el_terminal.t_val));
(void) terminal_set(el, NULL);
terminal_init_arrow(el);
return 0;
@ -419,18 +415,18 @@ terminal_rebuffer_display(EditLine *el)
return 0;
}
static wchar_t **
static wint_t **
terminal_alloc_buffer(EditLine *el)
{
wint_t **b;
coord_t *c = &el->el_terminal.t_size;
int i;
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
b = el_calloc((size_t)(c->v + 1), sizeof(*b));
if (b == NULL)
return NULL;
for (i = 0; i < c->v; i++) {
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
b[i] = el_calloc((size_t)(c->h + 1), sizeof(**b));
if (b[i] == NULL) {
while (--i >= 0)
el_free(b[i]);
@ -509,37 +505,14 @@ terminal_move_to_line(EditLine *el, int where)
return;
}
if ((del = where - el->el_cursor.v) > 0) {
while (del > 0) {
if (EL_HAS_AUTO_MARGINS &&
el->el_display[el->el_cursor.v][0] != '\0') {
size_t h = (size_t)
(el->el_terminal.t_size.h - 1);
for (; h > 0 &&
el->el_display[el->el_cursor.v][h] ==
MB_FILL_CHAR;
h--)
continue;
/* move without newline */
terminal_move_to_char(el, (int)h);
terminal_overwrite(el, &el->el_display
[el->el_cursor.v][el->el_cursor.h],
(size_t)(el->el_terminal.t_size.h -
el->el_cursor.h));
/* updates Cursor */
del--;
} else {
if ((del > 1) && GoodStr(T_DO)) {
terminal_tputs(el, tgoto(Str(T_DO), del,
del), del);
del = 0;
} else {
for (; del > 0; del--)
terminal__putc(el, '\n');
/* because the \n will become \r\n */
el->el_cursor.h = 0;
}
}
}
/*
* We don't use DO here because some terminals are buggy
* if the destination is beyond bottom of the screen.
*/
for (; del > 0; del--)
terminal__putc(el, '\n');
/* because the \n will become \r\n */
el->el_cursor.h = 0;
} else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
@ -988,9 +961,10 @@ terminal_get_size(EditLine *el, int *lins, int *cols)
libedit_private int
terminal_change_size(EditLine *el, int lins, int cols)
{
coord_t cur = el->el_cursor;
/*
* Just in case
*/
* Just in case
*/
Val(T_co) = (cols < 2) ? 80 : cols;
Val(T_li) = (lins < 1) ? 24 : lins;
@ -998,6 +972,7 @@ terminal_change_size(EditLine *el, int lins, int cols)
if (terminal_rebuffer_display(el) == -1)
return -1;
re_clear_display(el);
el->el_cursor = cur;
return 0;
}

39
tty.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.66 2017/09/05 18:07:59 christos Exp $ */
/* $NetBSD: tty.c,v 1.68 2018/12/02 16:58:13 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.66 2017/09/05 18:07:59 christos Exp $");
__RCSID("$NetBSD: tty.c,v 1.68 2018/12/02 16:58:13 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -586,7 +586,7 @@ tty_init(EditLine *el)
*/
libedit_private void
/*ARGSUSED*/
tty_end(EditLine *el)
tty_end(EditLine *el, int how)
{
if (el->el_flags & EDIT_DISABLED)
return;
@ -594,7 +594,8 @@ tty_end(EditLine *el)
if (!el->el_tty.t_initialized)
return;
if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
if (tty_setty(el, how, &el->el_tty.t_or) == -1)
{
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"%s: tty_setty: %s\n", __func__, strerror(errno));
@ -1340,3 +1341,33 @@ tty_setup_flags(EditLine *el, struct termios *tios, int mode)
*f = tty_update_flag(el, *f, mode, kind);
}
}
libedit_private int
tty_get_signal_character(EditLine *el, int sig)
{
#ifdef ECHOCTL
tcflag_t *ed = tty__get_flag(&el->el_tty.t_ed, MD_INP);
if ((*ed & ECHOCTL) == 0)
return -1;
#endif
switch (sig) {
#ifdef SIGINT
case SIGINT:
return el->el_tty.t_c[ED_IO][VINTR];
#endif
#ifdef SIGQUIT
case SIGQUIT:
return el->el_tty.t_c[ED_IO][VQUIT];
#endif
#ifdef SIGINFO
case SIGINFO:
return el->el_tty.t_c[ED_IO][VSTATUS];
#endif
#ifdef SIGTSTP
case SIGTSTP:
return el->el_tty.t_c[ED_IO][VSUSP];
#endif
default:
return -1;
}
}

5
tty.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.21 2016/05/09 21:46:56 christos Exp $ */
/* $NetBSD: tty.h,v 1.23 2018/12/02 16:58:13 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -457,13 +457,14 @@ typedef struct {
typedef unsigned char ttychar_t[NN_IO][C_NCC];
libedit_private int tty_init(EditLine *);
libedit_private void tty_end(EditLine *);
libedit_private void tty_end(EditLine *, int);
libedit_private int tty_stty(EditLine *, int, const wchar_t **);
libedit_private int tty_rawmode(EditLine *);
libedit_private int tty_cookedmode(EditLine *);
libedit_private int tty_quotemode(EditLine *);
libedit_private int tty_noquotemode(EditLine *);
libedit_private void tty_bind_char(EditLine *, int);
libedit_private int tty_get_signal_character(EditLine *, int);
typedef struct {
ttyperm_t t_t;

8
vi.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $ */
/* $NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 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.62 2016/05/09 21:46:56 christos Exp $");
__RCSID("$NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -1019,10 +1019,10 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
return CC_ERROR;
len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
cp = el_calloc(TMP_BUFSIZ, sizeof(*cp));
if (cp == NULL)
goto error;
line = el_malloc(len * sizeof(*line) + 1);
line = el_calloc(len + 1, sizeof(*line));
if (line == NULL)
goto error;
wcsncpy(line, el->el_line.buffer, len);