Update libedit to snapshot 2019-09-10
This commit is contained in:
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
@ -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
553
TEST/test_filecompletion.c
Normal 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;
|
||||
|
||||
}
|
22
chared.c
22
chared.c
@ -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)
|
||||
|
26
chartype.c
26
chartype.c
@ -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
|
||||
|
12
common.c
12
common.c
@ -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);
|
||||
}
|
||||
|
@ -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
30
el.c
@ -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
4
el.h
@ -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
14
eln.c
@ -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;
|
||||
}
|
||||
|
||||
|
324
filecomplete.c
324
filecomplete.c
@ -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
8
hist.c
@ -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;
|
||||
}
|
||||
|
16
history.c
16
history.c
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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
12
map.c
@ -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)
|
||||
|
8
parse.c
8
parse.c
@ -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
15
read.c
@ -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;
|
||||
|
98
readline.c
98
readline.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
18
refresh.c
18
refresh.c
@ -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, ' ');
|
||||
|
10
search.c
10
search.c
@ -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 */
|
||||
|
69
terminal.c
69
terminal.c
@ -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
39
tty.c
@ -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
5
tty.h
@ -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
8
vi.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user