Merge ^/head r352105 through r352307.
This commit is contained in:
commit
61c1328eb0
@ -198,6 +198,11 @@ OLD_FILES+=usr/include/c++/v1/experimental/string_view
|
||||
OLD_FILES+=usr/include/c++/v1/experimental/system_error
|
||||
OLD_FILES+=usr/include/c++/v1/experimental/tuple
|
||||
OLD_FILES+=usr/lib/libc++fs.a
|
||||
# 20190910: mklocale(1) and colldef(1) removed
|
||||
OLD_FILES+=usr/bin/mklocale
|
||||
OLD_FILES+=usr/share/man/man1/mklocale.1.gz
|
||||
OLD_FILES+=usr/bin/colldef
|
||||
OLD_FILES+=usr/share/man/man1/colldef.1.gz
|
||||
# 20190904: Remove boot1.efifat
|
||||
OLD_FILES+=boot/boot1.efifat
|
||||
# 20190903: pc-sysinstall(8) removed
|
||||
|
4
RELNOTES
4
RELNOTES
@ -10,6 +10,10 @@ newline. Entries should be separated by a newline.
|
||||
|
||||
Changes to this file should not be MFCed.
|
||||
|
||||
r352304:
|
||||
ntpd is no longer by default locked in memory. rlimit memlock 32
|
||||
or rlimit memlock 0 can be used to restore this behaviour.
|
||||
|
||||
r351522:
|
||||
Add kernel-side support for in-kernel Transport Layer Security
|
||||
(KTLS). KTLS permits using sendfile(2) over sockets using
|
||||
|
6
UPDATING
6
UPDATING
@ -26,6 +26,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20190913:
|
||||
ntpd no longer by default locks its pages in memory, allowing them
|
||||
to be paged out by the kernel. Use rlimit memlock to restore
|
||||
historic BSD behaviour. For example, add "rlimit memlock 32"
|
||||
to ntp.conf to lock up to 32 MB of ntpd address space in memory.
|
||||
|
||||
20190823:
|
||||
Several of ping6's options have been renamed for better consistency
|
||||
with ping. If you use any of -ARWXaghmrtwx, you must update your
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "readline/readline.h"
|
||||
#include "readline/tilde.h"
|
||||
#include "completer.h"
|
||||
#include "target.h" /* For baud_rate, remote_debug and remote_timeout */
|
||||
#include "gdb_wait.h" /* For shell escape implementation */
|
||||
|
@ -18,7 +18,6 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "readline/tilde.h"
|
||||
#include "value.h"
|
||||
#include <ctype.h>
|
||||
#include "gdb_string.h"
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
/* readline include files */
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
@ -48,7 +48,6 @@
|
||||
|
||||
/* readline include files */
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
@ -45,7 +45,6 @@
|
||||
|
||||
/* readline include files */
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
@ -20,6 +20,9 @@
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* For uint32_t and uint64_t */
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* ARM-specific unwind definitions. These are taken from the ARM EHABI
|
||||
* specification.
|
||||
|
139
contrib/libedit/Makefile
Normal file
139
contrib/libedit/Makefile
Normal file
@ -0,0 +1,139 @@
|
||||
# $NetBSD: Makefile,v 1.65 2017/06/30 20:26:52 kre Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
|
||||
USE_SHLIBDIR= yes
|
||||
|
||||
WARNS?= 5
|
||||
LIB= edit
|
||||
|
||||
LIBDPLIBS+= terminfo ${.CURDIR}/../libterminfo
|
||||
|
||||
.include "bsd.own.mk"
|
||||
|
||||
COPTS+= -Wunused-parameter
|
||||
CWARNFLAGS.gcc+= -Wconversion
|
||||
CWARNFLAGS.clang+= -Wno-cast-qual
|
||||
|
||||
SRCS = chared.c chartype.c common.c el.c eln.c emacs.c filecomplete.c \
|
||||
hist.c history.c historyn.c keymacro.c literal.c map.c \
|
||||
parse.c prompt.c read.c readline.c refresh.c search.c sig.c \
|
||||
terminal.c tokenizer.c tokenizern.c tty.c vi.c
|
||||
|
||||
MAN= editline.3 editrc.5 editline.7
|
||||
|
||||
MLINKS= \
|
||||
editline.3 el_deletestr.3 \
|
||||
editline.3 el_end.3 \
|
||||
editline.3 el_get.3 \
|
||||
editline.3 el_getc.3 \
|
||||
editline.3 el_gets.3 \
|
||||
editline.3 el_init.3 \
|
||||
editline.3 el_init_fd.3 \
|
||||
editline.3 el_insertstr.3 \
|
||||
editline.3 el_line.3 \
|
||||
editline.3 el_parse.3 \
|
||||
editline.3 el_push.3 \
|
||||
editline.3 el_reset.3 \
|
||||
editline.3 el_resize.3 \
|
||||
editline.3 el_set.3 \
|
||||
editline.3 el_source.3 \
|
||||
editline.3 history.3 \
|
||||
editline.3 history_end.3 \
|
||||
editline.3 history_init.3 \
|
||||
editline.3 tok_end.3 \
|
||||
editline.3 tok_init.3 \
|
||||
editline.3 tok_line.3 \
|
||||
editline.3 tok_reset.3 \
|
||||
editline.3 tok_str.3
|
||||
|
||||
MLINKS+= \
|
||||
editline.3 el_wdeletestr.3 \
|
||||
editline.3 el_wget.3 \
|
||||
editline.3 el_wgetc.3 \
|
||||
editline.3 el_wgets.3 \
|
||||
editline.3 el_winsertstr.3 \
|
||||
editline.3 el_wline.3 \
|
||||
editline.3 el_wparse.3 \
|
||||
editline.3 el_wpush.3 \
|
||||
editline.3 el_wset.3 \
|
||||
editline.3 history_w.3 \
|
||||
editline.3 history_wend.3 \
|
||||
editline.3 history_winit.3 \
|
||||
editline.3 tok_wend.3 \
|
||||
editline.3 tok_winit.3 \
|
||||
editline.3 tok_wline.3 \
|
||||
editline.3 tok_wreset.3 \
|
||||
editline.3 tok_wstr.3
|
||||
|
||||
LIBEDITDIR?=${.CURDIR}
|
||||
|
||||
INCS= histedit.h
|
||||
INCSDIR=/usr/include
|
||||
|
||||
CLEANFILES+=common.h.tmp emacs.h.tmp fcns.h.tmp func.h.tmp
|
||||
CLEANFILES+=help.h.tmp vi.h.tmp tc1.o tc1 .depend
|
||||
|
||||
CPPFLAGS+=-I. -I${LIBEDITDIR}
|
||||
CPPFLAGS+=-I. -I${.CURDIR}
|
||||
#CPPFLAGS+=-DDEBUG_TTY -DDEBUG_KEY -DDEBUG -DDEBUG_REFRESH
|
||||
#CPPFLAGS+=-DDEBUG_PASTE -DDEBUG_EDIT
|
||||
|
||||
AHDR=vi.h emacs.h common.h
|
||||
ASRC=${LIBEDITDIR}/vi.c ${LIBEDITDIR}/emacs.c ${LIBEDITDIR}/common.c
|
||||
|
||||
DPSRCS+= ${AHDR} fcns.h func.h help.h
|
||||
CLEANFILES+= ${AHDR} fcns.h func.h help.h
|
||||
|
||||
SUBDIR= readline
|
||||
|
||||
.depend: ${AHDR} fcns.h func.h help.h
|
||||
|
||||
vi.h: vi.c makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c \
|
||||
> ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
emacs.h: emacs.c makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/emacs.c \
|
||||
> ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
common.h: common.c makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/common.c \
|
||||
> ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
fcns.h: ${AHDR} makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
func.h: ${AHDR} makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
help.h: ${ASRC} makelist Makefile
|
||||
${_MKTARGET_CREATE}
|
||||
${HOST_SH} ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
|
||||
tc1.o: ${LIBEDITDIR}/TEST/tc1.c
|
||||
|
||||
tc1: libedit.a tc1.o
|
||||
${_MKTARGET_LINK}
|
||||
${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermlib
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
# XXX
|
||||
.if defined(HAVE_GCC)
|
||||
COPTS.editline.c+= -Wno-cast-qual
|
||||
COPTS.literal.c+= -Wno-sign-conversion
|
||||
COPTS.tokenizer.c+= -Wno-cast-qual
|
||||
COPTS.tokenizern.c+= -Wno-cast-qual
|
||||
.endif
|
13
contrib/libedit/TEST/Makefile
Normal file
13
contrib/libedit/TEST/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# $NetBSD: Makefile,v 1.8 2017/10/15 18:59:00 abhinav Exp $
|
||||
|
||||
NOMAN=1
|
||||
PROG=wtc1 test_filecompletion
|
||||
CPPFLAGS=-I${.CURDIR}/..
|
||||
LDADD+=-ledit -ltermlib
|
||||
DPADD+=${LIBEDIT} ${LIBTERMLIB}
|
||||
|
||||
.ifdef DEBUG
|
||||
CPPFLAGS+=-DDEBUG
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -33,7 +33,6 @@
|
||||
#if !defined(lint)
|
||||
__RCSID("$NetBSD: rl1.c,v 1.2 2016/02/29 00:54:19 christos Exp $");
|
||||
#endif /* not lint */
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* test.c: A little test program
|
@ -45,7 +45,6 @@ static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
|
||||
__RCSID("$NetBSD: tc1.c,v 1.7 2016/02/17 19:47:49 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* test.c: A little test program
|
||||
@ -276,7 +275,7 @@ main(int argc, char *argv[])
|
||||
} else if (el_parse(el, ac, av) == -1) {
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
execvp(av[0], __DECONST(char **, av));
|
||||
execvp(av[0], (char *const *)__UNCONST(av));
|
||||
perror(av[0]);
|
||||
_exit(1);
|
||||
/*NOTREACHED*/
|
553
contrib/libedit/TEST/test_filecompletion.c
Normal file
553
contrib/libedit/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;
|
||||
|
||||
}
|
@ -1,9 +1,3 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: chared.c,v 1.49 2016/02/24 14:29:21 christos Exp $ */
|
||||
/* $NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: chared.c,v 1.49 2016/02/24 14:29:21 christos Exp $");
|
||||
__RCSID("$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* chared.c: Character editor utilities
|
||||
@ -52,8 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
|
||||
private void ch__clearmacro (EditLine *);
|
||||
#include "fcns.h"
|
||||
|
||||
/* value to leave unused in line buffer */
|
||||
#define EL_LEAVE 2
|
||||
@ -61,7 +58,7 @@ private void ch__clearmacro (EditLine *);
|
||||
/* cv_undo():
|
||||
* Handle state for the vi undo command
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
cv_undo(EditLine *el)
|
||||
{
|
||||
c_undo_t *vu = &el->el_chared.c_undo;
|
||||
@ -85,8 +82,8 @@ cv_undo(EditLine *el)
|
||||
/* cv_yank():
|
||||
* Save yank/delete data for paste
|
||||
*/
|
||||
protected void
|
||||
cv_yank(EditLine *el, const Char *ptr, int size)
|
||||
libedit_private void
|
||||
cv_yank(EditLine *el, const wchar_t *ptr, int size)
|
||||
{
|
||||
c_kill_t *k = &el->el_chared.c_kill;
|
||||
|
||||
@ -98,10 +95,10 @@ cv_yank(EditLine *el, const Char *ptr, int size)
|
||||
/* c_insert():
|
||||
* Insert num characters
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_insert(EditLine *el, int num)
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
if (el->el_line.lastchar + num >= el->el_line.limit) {
|
||||
if (!ch_enlargebufs(el, (size_t)num))
|
||||
@ -120,7 +117,7 @@ c_insert(EditLine *el, int num)
|
||||
/* c_delafter():
|
||||
* Delete num characters after the cursor
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_delafter(EditLine *el, int num)
|
||||
{
|
||||
|
||||
@ -133,7 +130,7 @@ c_delafter(EditLine *el, int num)
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
|
||||
*cp = cp[num];
|
||||
@ -146,10 +143,10 @@ c_delafter(EditLine *el, int num)
|
||||
/* c_delafter1():
|
||||
* Delete the character after the cursor, do not yank
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_delafter1(EditLine *el)
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
|
||||
*cp = cp[1];
|
||||
@ -161,7 +158,7 @@ c_delafter1(EditLine *el)
|
||||
/* c_delbefore():
|
||||
* Delete num characters before the cursor
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_delbefore(EditLine *el, int num)
|
||||
{
|
||||
|
||||
@ -174,10 +171,10 @@ c_delbefore(EditLine *el, int num)
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
Char *cp;
|
||||
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];
|
||||
|
||||
@ -189,10 +186,10 @@ c_delbefore(EditLine *el, int num)
|
||||
/* c_delbefore1():
|
||||
* Delete the character before the cursor, do not yank
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_delbefore1(EditLine *el)
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
|
||||
*cp = cp[1];
|
||||
@ -204,22 +201,22 @@ c_delbefore1(EditLine *el)
|
||||
/* ce__isword():
|
||||
* Return if p is part of a word according to emacs
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
ce__isword(wint_t p)
|
||||
{
|
||||
return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL;
|
||||
return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
|
||||
}
|
||||
|
||||
|
||||
/* cv__isword():
|
||||
* Return if p is part of a word according to vi
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
cv__isword(wint_t p)
|
||||
{
|
||||
if (Isalnum(p) || p == '_')
|
||||
if (iswalnum(p) || p == L'_')
|
||||
return 1;
|
||||
if (Isgraph(p))
|
||||
if (iswgraph(p))
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
@ -228,18 +225,18 @@ cv__isword(wint_t p)
|
||||
/* cv__isWord():
|
||||
* Return if p is part of a big word according to vi
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
cv__isWord(wint_t p)
|
||||
{
|
||||
return !Isspace(p);
|
||||
return !iswspace(p);
|
||||
}
|
||||
|
||||
|
||||
/* c__prev_word():
|
||||
* Find the previous word
|
||||
*/
|
||||
protected Char *
|
||||
c__prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
|
||||
libedit_private wchar_t *
|
||||
c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
|
||||
{
|
||||
p--;
|
||||
|
||||
@ -262,8 +259,8 @@ c__prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
|
||||
/* c__next_word():
|
||||
* Find the next word
|
||||
*/
|
||||
protected Char *
|
||||
c__next_word(Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
libedit_private wchar_t *
|
||||
c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
|
||||
{
|
||||
while (n--) {
|
||||
while ((p < high) && !(*wtest)(*p))
|
||||
@ -280,8 +277,9 @@ c__next_word(Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
/* cv_next_word():
|
||||
* Find the next word vi style
|
||||
*/
|
||||
protected Char *
|
||||
cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
libedit_private wchar_t *
|
||||
cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
|
||||
int (*wtest)(wint_t))
|
||||
{
|
||||
int test;
|
||||
|
||||
@ -294,7 +292,7 @@ cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
* trailing whitespace! This is not what 'w' does..
|
||||
*/
|
||||
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
|
||||
while ((p < high) && Isspace(*p))
|
||||
while ((p < high) && iswspace(*p))
|
||||
p++;
|
||||
}
|
||||
|
||||
@ -309,14 +307,14 @@ cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
/* cv_prev_word():
|
||||
* Find the previous word vi style
|
||||
*/
|
||||
protected Char *
|
||||
cv_prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
|
||||
libedit_private wchar_t *
|
||||
cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
|
||||
{
|
||||
int test;
|
||||
|
||||
p--;
|
||||
while (n--) {
|
||||
while ((p > low) && Isspace(*p))
|
||||
while ((p > low) && iswspace(*p))
|
||||
p--;
|
||||
test = (*wtest)(*p);
|
||||
while ((p >= low) && (*wtest)(*p) == test)
|
||||
@ -335,7 +333,7 @@ cv_prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
|
||||
/* cv_delfini():
|
||||
* Finish vi delete action
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
cv_delfini(EditLine *el)
|
||||
{
|
||||
int size;
|
||||
@ -373,15 +371,15 @@ cv_delfini(EditLine *el)
|
||||
/* cv__endword():
|
||||
* Go to the end of this word according to vi
|
||||
*/
|
||||
protected Char *
|
||||
cv__endword(Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
libedit_private wchar_t *
|
||||
cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
|
||||
{
|
||||
int test;
|
||||
|
||||
p++;
|
||||
|
||||
while (n--) {
|
||||
while ((p < high) && Isspace(*p))
|
||||
while ((p < high) && iswspace(*p))
|
||||
p++;
|
||||
|
||||
test = (*wtest)(*p);
|
||||
@ -395,31 +393,25 @@ cv__endword(Char *p, Char *high, int n, int (*wtest)(wint_t))
|
||||
/* ch_init():
|
||||
* Initialize the character editor
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
ch_init(EditLine *el)
|
||||
{
|
||||
c_macro_t *ma = &el->el_chared.c_macro;
|
||||
|
||||
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;
|
||||
@ -430,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;
|
||||
@ -451,19 +441,14 @@ ch_init(EditLine *el)
|
||||
el->el_state.argument = 1;
|
||||
el->el_state.lastcmd = ED_UNASSIGNED;
|
||||
|
||||
ma->level = -1;
|
||||
ma->offset = 0;
|
||||
ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
|
||||
if (ma->macro == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ch_reset():
|
||||
* Reset the character editor
|
||||
*/
|
||||
protected void
|
||||
ch_reset(EditLine *el, int mclear)
|
||||
libedit_private void
|
||||
ch_reset(EditLine *el)
|
||||
{
|
||||
el->el_line.cursor = el->el_line.buffer;
|
||||
el->el_line.lastchar = el->el_line.buffer;
|
||||
@ -485,28 +470,17 @@ ch_reset(EditLine *el, int mclear)
|
||||
el->el_state.lastcmd = ED_UNASSIGNED;
|
||||
|
||||
el->el_history.eventno = 0;
|
||||
|
||||
if (mclear)
|
||||
ch__clearmacro(el);
|
||||
}
|
||||
|
||||
private void
|
||||
ch__clearmacro(EditLine *el)
|
||||
{
|
||||
c_macro_t *ma = &el->el_chared.c_macro;
|
||||
while (ma->level >= 0)
|
||||
el_free(ma->macro[ma->level--]);
|
||||
}
|
||||
|
||||
/* ch_enlargebufs():
|
||||
* Enlarge line buffer to be able to hold twice as much characters.
|
||||
* Returns 1 if successful, 0 if not.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
ch_enlargebufs(EditLine *el, size_t addlen)
|
||||
{
|
||||
size_t sz, newsz;
|
||||
Char *newbuffer, *oldbuf, *oldkbuf;
|
||||
wchar_t *newbuffer, *oldbuf, *oldkbuf;
|
||||
|
||||
sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
|
||||
newsz = sz * 2;
|
||||
@ -591,7 +565,7 @@ ch_enlargebufs(EditLine *el, size_t addlen)
|
||||
/* ch_end():
|
||||
* Free the data structures used by the editor
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
ch_end(EditLine *el)
|
||||
{
|
||||
el_free(el->el_line.buffer);
|
||||
@ -606,21 +580,19 @@ ch_end(EditLine *el)
|
||||
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
|
||||
el_free(el->el_chared.c_kill.buf);
|
||||
el->el_chared.c_kill.buf = NULL;
|
||||
ch_reset(el, 1);
|
||||
el_free(el->el_chared.c_macro.macro);
|
||||
el->el_chared.c_macro.macro = NULL;
|
||||
ch_reset(el);
|
||||
}
|
||||
|
||||
|
||||
/* el_insertstr():
|
||||
* Insert string at cursorI
|
||||
* Insert string at cursor
|
||||
*/
|
||||
public int
|
||||
FUN(el,insertstr)(EditLine *el, const Char *s)
|
||||
int
|
||||
el_winsertstr(EditLine *el, const wchar_t *s)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (s == NULL || (len = Strlen(s)) == 0)
|
||||
if (s == NULL || (len = wcslen(s)) == 0)
|
||||
return -1;
|
||||
if (el->el_line.lastchar + len >= el->el_line.limit) {
|
||||
if (!ch_enlargebufs(el, len))
|
||||
@ -637,7 +609,7 @@ FUN(el,insertstr)(EditLine *el, const Char *s)
|
||||
/* el_deletestr():
|
||||
* Delete num characters before the cursor
|
||||
*/
|
||||
public void
|
||||
void
|
||||
el_deletestr(EditLine *el, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
@ -655,7 +627,7 @@ el_deletestr(EditLine *el, int n)
|
||||
/* el_cursor():
|
||||
* Move the cursor to the left or the right of the current position
|
||||
*/
|
||||
public int
|
||||
int
|
||||
el_cursor(EditLine *el, int n)
|
||||
{
|
||||
if (n == 0)
|
||||
@ -674,15 +646,14 @@ out:
|
||||
/* c_gets():
|
||||
* Get a string
|
||||
*/
|
||||
protected int
|
||||
c_gets(EditLine *el, Char *buf, const Char *prompt)
|
||||
libedit_private int
|
||||
c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
|
||||
{
|
||||
wchar_t wch;
|
||||
ssize_t len;
|
||||
Char *cp = el->el_line.buffer, ch;
|
||||
wchar_t *cp = el->el_line.buffer, ch;
|
||||
|
||||
if (prompt) {
|
||||
len = (ssize_t)Strlen(prompt);
|
||||
len = (ssize_t)wcslen(prompt);
|
||||
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
|
||||
cp += len;
|
||||
}
|
||||
@ -694,12 +665,11 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
|
||||
el->el_line.lastchar = cp + 1;
|
||||
re_refresh(el);
|
||||
|
||||
if (el_wgetc(el, &wch) != 1) {
|
||||
if (el_wgetc(el, &ch) != 1) {
|
||||
ed_end_of_file(el, 0);
|
||||
len = -1;
|
||||
break;
|
||||
}
|
||||
ch = (Char)wch;
|
||||
|
||||
switch (ch) {
|
||||
|
||||
@ -741,10 +711,10 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
|
||||
/* c_hpos():
|
||||
* Return the current horizontal position of the cursor
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
c_hpos(EditLine *el)
|
||||
{
|
||||
Char *ptr;
|
||||
wchar_t *ptr;
|
||||
|
||||
/*
|
||||
* Find how many characters till the beginning of this line.
|
||||
@ -760,7 +730,7 @@ c_hpos(EditLine *el)
|
||||
}
|
||||
}
|
||||
|
||||
protected int
|
||||
libedit_private int
|
||||
ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
|
||||
{
|
||||
el->el_chared.c_resizefun = f;
|
||||
@ -768,7 +738,7 @@ ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int
|
||||
libedit_private int
|
||||
ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
|
||||
{
|
||||
el->el_chared.c_aliasfun = f;
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: chared.h,v 1.27 2016/02/16 22:53:14 christos Exp $ */
|
||||
/* $NetBSD: chared.h,v 1.30 2016/05/22 19:44:26 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)chared.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,8 +40,6 @@
|
||||
#ifndef _h_el_chared
|
||||
#define _h_el_chared
|
||||
|
||||
#define EL_MAXMACRO 10
|
||||
|
||||
/*
|
||||
* This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works
|
||||
* like real vi: i.e. the transition from command<->insert modes moves
|
||||
@ -55,29 +52,22 @@
|
||||
*/
|
||||
#define VI_MOVE
|
||||
|
||||
|
||||
typedef struct c_macro_t {
|
||||
int level;
|
||||
int offset;
|
||||
Char **macro;
|
||||
} c_macro_t;
|
||||
|
||||
/*
|
||||
* Undo information for vi - no undo in emacs (yet)
|
||||
*/
|
||||
typedef struct c_undo_t {
|
||||
ssize_t len; /* length of saved line */
|
||||
int cursor; /* position of saved cursor */
|
||||
Char *buf; /* full saved text */
|
||||
wchar_t *buf; /* full saved text */
|
||||
} c_undo_t;
|
||||
|
||||
/* redo for vi */
|
||||
typedef struct c_redo_t {
|
||||
Char *buf; /* redo insert key sequence */
|
||||
Char *pos;
|
||||
Char *lim;
|
||||
wchar_t *buf; /* redo insert key sequence */
|
||||
wchar_t *pos;
|
||||
wchar_t *lim;
|
||||
el_action_t cmd; /* command to redo */
|
||||
Char ch; /* char that invoked it */
|
||||
wchar_t ch; /* char that invoked it */
|
||||
int count;
|
||||
int action; /* from cv_action() */
|
||||
} c_redo_t;
|
||||
@ -87,16 +77,16 @@ typedef struct c_redo_t {
|
||||
*/
|
||||
typedef struct c_vcmd_t {
|
||||
int action;
|
||||
Char *pos;
|
||||
wchar_t *pos;
|
||||
} c_vcmd_t;
|
||||
|
||||
/*
|
||||
* Kill buffer for emacs
|
||||
*/
|
||||
typedef struct c_kill_t {
|
||||
Char *buf;
|
||||
Char *last;
|
||||
Char *mark;
|
||||
wchar_t *buf;
|
||||
wchar_t *last;
|
||||
wchar_t *mark;
|
||||
} c_kill_t;
|
||||
|
||||
typedef void (*el_zfunc_t)(EditLine *, void *);
|
||||
@ -111,7 +101,6 @@ typedef struct el_chared_t {
|
||||
c_kill_t c_kill;
|
||||
c_redo_t c_redo;
|
||||
c_vcmd_t c_vcmd;
|
||||
c_macro_t c_macro;
|
||||
el_zfunc_t c_resizefun;
|
||||
el_afunc_t c_aliasfun;
|
||||
void * c_resizearg;
|
||||
@ -136,30 +125,31 @@ typedef struct el_chared_t {
|
||||
#define MODE_REPLACE_1 2
|
||||
|
||||
|
||||
protected int cv__isword(wint_t);
|
||||
protected int cv__isWord(wint_t);
|
||||
protected void cv_delfini(EditLine *);
|
||||
protected Char *cv__endword(Char *, Char *, int, int (*)(wint_t));
|
||||
protected int ce__isword(wint_t);
|
||||
protected void cv_undo(EditLine *);
|
||||
protected void cv_yank(EditLine *, const Char *, int);
|
||||
protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(wint_t));
|
||||
protected Char *cv_prev_word(Char *, Char *, int, int (*)(wint_t));
|
||||
protected Char *c__next_word(Char *, Char *, int, int (*)(wint_t));
|
||||
protected Char *c__prev_word(Char *, Char *, int, int (*)(wint_t));
|
||||
protected void c_insert(EditLine *, int);
|
||||
protected void c_delbefore(EditLine *, int);
|
||||
protected void c_delbefore1(EditLine *);
|
||||
protected void c_delafter(EditLine *, int);
|
||||
protected void c_delafter1(EditLine *);
|
||||
protected int c_gets(EditLine *, Char *, const Char *);
|
||||
protected int c_hpos(EditLine *);
|
||||
libedit_private int cv__isword(wint_t);
|
||||
libedit_private int cv__isWord(wint_t);
|
||||
libedit_private void cv_delfini(EditLine *);
|
||||
libedit_private wchar_t *cv__endword(wchar_t *, wchar_t *, int, int (*)(wint_t));
|
||||
libedit_private int ce__isword(wint_t);
|
||||
libedit_private void cv_undo(EditLine *);
|
||||
libedit_private void cv_yank(EditLine *, const wchar_t *, int);
|
||||
libedit_private wchar_t *cv_next_word(EditLine*, wchar_t *, wchar_t *, int,
|
||||
int (*)(wint_t));
|
||||
libedit_private wchar_t *cv_prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
|
||||
libedit_private wchar_t *c__next_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
|
||||
libedit_private wchar_t *c__prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
|
||||
libedit_private void c_insert(EditLine *, int);
|
||||
libedit_private void c_delbefore(EditLine *, int);
|
||||
libedit_private void c_delbefore1(EditLine *);
|
||||
libedit_private void c_delafter(EditLine *, int);
|
||||
libedit_private void c_delafter1(EditLine *);
|
||||
libedit_private int c_gets(EditLine *, wchar_t *, const wchar_t *);
|
||||
libedit_private int c_hpos(EditLine *);
|
||||
|
||||
protected int ch_init(EditLine *);
|
||||
protected void ch_reset(EditLine *, int);
|
||||
protected int ch_resizefun(EditLine *, el_zfunc_t, void *);
|
||||
protected int ch_aliasfun(EditLine *, el_afunc_t, void *);
|
||||
protected int ch_enlargebufs(EditLine *, size_t);
|
||||
protected void ch_end(EditLine *);
|
||||
libedit_private int ch_init(EditLine *);
|
||||
libedit_private void ch_reset(EditLine *);
|
||||
libedit_private int ch_resizefun(EditLine *, el_zfunc_t, void *);
|
||||
libedit_private int ch_aliasfun(EditLine *, el_afunc_t, void *);
|
||||
libedit_private int ch_enlargebufs(EditLine *, size_t);
|
||||
libedit_private void ch_end(EditLine *);
|
||||
|
||||
#endif /* _h_el_chared */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: chartype.c,v 1.23 2016/02/28 23:02:24 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,8 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: chartype.c,v 1.23 2016/02/28 23:02:24 christos Exp $");
|
||||
__RCSID("$NetBSD: chartype.c,v 1.35 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
@ -45,8 +43,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define CT_BUFSIZ ((size_t)1024)
|
||||
|
||||
#ifdef WIDECHAR
|
||||
protected int
|
||||
static int ct_conv_cbuff_resize(ct_buffer_t *, size_t);
|
||||
static int ct_conv_wbuff_resize(ct_buffer_t *, size_t);
|
||||
|
||||
static int
|
||||
ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
|
||||
{
|
||||
void *p;
|
||||
@ -67,7 +67,7 @@ ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int
|
||||
static int
|
||||
ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
|
||||
{
|
||||
void *p;
|
||||
@ -89,8 +89,8 @@ ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
|
||||
}
|
||||
|
||||
|
||||
public char *
|
||||
ct_encode_string(const Char *s, ct_buffer_t *conv)
|
||||
char *
|
||||
ct_encode_string(const wchar_t *s, ct_buffer_t *conv)
|
||||
{
|
||||
char *dst;
|
||||
ssize_t used;
|
||||
@ -119,7 +119,7 @@ ct_encode_string(const Char *s, ct_buffer_t *conv)
|
||||
return conv->cbuff;
|
||||
}
|
||||
|
||||
public Char *
|
||||
wchar_t *
|
||||
ct_decode_string(const char *s, ct_buffer_t *conv)
|
||||
{
|
||||
size_t len;
|
||||
@ -127,7 +127,7 @@ ct_decode_string(const char *s, ct_buffer_t *conv)
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
len = ct_mbstowcs(NULL, s, (size_t)0);
|
||||
len = mbstowcs(NULL, s, (size_t)0);
|
||||
if (len == (size_t)-1)
|
||||
return NULL;
|
||||
|
||||
@ -135,18 +135,18 @@ ct_decode_string(const char *s, ct_buffer_t *conv)
|
||||
if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1)
|
||||
return NULL;
|
||||
|
||||
ct_mbstowcs(conv->wbuff, s, conv->wsize);
|
||||
mbstowcs(conv->wbuff, s, conv->wsize);
|
||||
return conv->wbuff;
|
||||
}
|
||||
|
||||
|
||||
protected Char **
|
||||
libedit_private wchar_t **
|
||||
ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
|
||||
{
|
||||
size_t bufspace;
|
||||
int i;
|
||||
Char *p;
|
||||
Char **wargv;
|
||||
wchar_t *p;
|
||||
wchar_t **wargv;
|
||||
ssize_t bytes;
|
||||
|
||||
/* Make sure we have enough space in the conversion buffer to store all
|
||||
@ -157,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 */
|
||||
@ -181,109 +181,79 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
|
||||
}
|
||||
|
||||
|
||||
protected size_t
|
||||
ct_enc_width(Char c)
|
||||
libedit_private size_t
|
||||
ct_enc_width(wchar_t c)
|
||||
{
|
||||
mbstate_t ps = (mbstate_t){{0}};
|
||||
size_t len;
|
||||
char cbuf[MB_LEN_MAX];
|
||||
len = ct_wcrtomb(cbuf, c, &ps);
|
||||
if (len == (size_t)-1)
|
||||
return (0);
|
||||
return (len);
|
||||
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;
|
||||
}
|
||||
|
||||
protected ssize_t
|
||||
ct_encode_char(char *dst, size_t len, Char c)
|
||||
libedit_private ssize_t
|
||||
ct_encode_char(char *dst, size_t len, wchar_t c)
|
||||
{
|
||||
ssize_t l = 0;
|
||||
if (len < ct_enc_width(c))
|
||||
return -1;
|
||||
l = ct_wctomb(dst, c);
|
||||
l = wctomb(dst, c);
|
||||
|
||||
if (l < 0) {
|
||||
ct_wctomb_reset;
|
||||
wctomb(NULL, L'\0');
|
||||
l = 0;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
size_t
|
||||
ct_mbrtowc(wchar_t *wc, const char *s, size_t n)
|
||||
libedit_private const wchar_t *
|
||||
ct_visual_string(const wchar_t *s, ct_buffer_t *conv)
|
||||
{
|
||||
mbstate_t mbs;
|
||||
/* This only works because UTF-8 is stateless */
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
return mbrtowc(wc, s, n, &mbs);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
size_t
|
||||
ct_mbrtowc(wchar_t *wc, const char *s, size_t n)
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
if (n == 0)
|
||||
return (size_t)-2;
|
||||
if (wc != NULL)
|
||||
*wc = *s;
|
||||
return *s != '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
protected const Char *
|
||||
ct_visual_string(const Char *s)
|
||||
{
|
||||
static Char *buff = NULL;
|
||||
static size_t buffsize = 0;
|
||||
void *p;
|
||||
Char *dst;
|
||||
ssize_t used = 0;
|
||||
wchar_t *dst;
|
||||
ssize_t used;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (!buff) {
|
||||
buffsize = CT_BUFSIZ;
|
||||
buff = el_malloc(buffsize * sizeof(*buff));
|
||||
}
|
||||
dst = buff;
|
||||
|
||||
if (ct_conv_wbuff_resize(conv, CT_BUFSIZ) == -1)
|
||||
return NULL;
|
||||
|
||||
used = 0;
|
||||
dst = conv->wbuff;
|
||||
while (*s) {
|
||||
used = ct_visual_char(dst, buffsize - (size_t)(dst - buff), *s);
|
||||
if (used == -1) { /* failed to encode, need more buffer space */
|
||||
used = dst - buff;
|
||||
buffsize += CT_BUFSIZ;
|
||||
p = el_realloc(buff, buffsize * sizeof(*buff));
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
buff = p;
|
||||
dst = buff + used;
|
||||
/* don't increment s here - we want to retry it! */
|
||||
used = ct_visual_char(dst,
|
||||
conv->wsize - (size_t)(dst - conv->wbuff), *s);
|
||||
if (used != -1) {
|
||||
++s;
|
||||
dst += used;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
++s;
|
||||
dst += used;
|
||||
|
||||
/* failed to encode, need more buffer space */
|
||||
used = dst - conv->wbuff;
|
||||
if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1)
|
||||
return NULL;
|
||||
dst = conv->wbuff + used;
|
||||
}
|
||||
if (dst >= (buff + buffsize)) { /* sigh */
|
||||
buffsize += 1;
|
||||
p = el_realloc(buff, buffsize * sizeof(*buff));
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
buff = p;
|
||||
dst = buff + buffsize - 1;
|
||||
|
||||
if (dst >= (conv->wbuff + conv->wsize)) { /* sigh */
|
||||
used = dst - conv->wbuff;
|
||||
if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1)
|
||||
return NULL;
|
||||
dst = conv->wbuff + used;
|
||||
}
|
||||
*dst = 0;
|
||||
return buff;
|
||||
out:
|
||||
el_free(buff);
|
||||
buffsize = 0;
|
||||
return NULL;
|
||||
|
||||
*dst = L'\0';
|
||||
return conv->wbuff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected int
|
||||
ct_visual_width(Char c)
|
||||
libedit_private int
|
||||
ct_visual_width(wchar_t c)
|
||||
{
|
||||
int t = ct_chr_class(c);
|
||||
switch (t) {
|
||||
@ -293,7 +263,6 @@ ct_visual_width(Char c)
|
||||
return 1; /* Hmm, this really need to be handled outside! */
|
||||
case CHTYPE_NL:
|
||||
return 0; /* Should this be 1 instead? */
|
||||
#ifdef WIDECHAR
|
||||
case CHTYPE_PRINT:
|
||||
return wcwidth(c);
|
||||
case CHTYPE_NONPRINT:
|
||||
@ -301,20 +270,14 @@ ct_visual_width(Char c)
|
||||
return 8; /* \U+12345 */
|
||||
else
|
||||
return 7; /* \U+1234 */
|
||||
#else
|
||||
case CHTYPE_PRINT:
|
||||
return 1;
|
||||
case CHTYPE_NONPRINT:
|
||||
return 4; /* \123 */
|
||||
#endif
|
||||
default:
|
||||
return 0; /* should not happen */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ssize_t
|
||||
ct_visual_char(Char *dst, size_t len, Char c)
|
||||
libedit_private ssize_t
|
||||
ct_visual_char(wchar_t *dst, size_t len, wchar_t c)
|
||||
{
|
||||
int t = ct_chr_class(c);
|
||||
switch (t) {
|
||||
@ -339,7 +302,6 @@ ct_visual_char(Char *dst, size_t len, Char c)
|
||||
* so this is right */
|
||||
if ((ssize_t)len < ct_visual_width(c))
|
||||
return -1; /* insufficient space */
|
||||
#ifdef WIDECHAR
|
||||
*dst++ = '\\';
|
||||
*dst++ = 'U';
|
||||
*dst++ = '+';
|
||||
@ -351,13 +313,6 @@ ct_visual_char(Char *dst, size_t len, Char c)
|
||||
*dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
|
||||
*dst = tohexdigit(((unsigned int) c ) & 0xf);
|
||||
return c > 0xffff ? 8 : 7;
|
||||
#else
|
||||
*dst++ = '\\';
|
||||
#define tooctaldigit(v) (Char)((v) + '0')
|
||||
*dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
|
||||
*dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
|
||||
*dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
|
||||
#endif
|
||||
/*FALLTHROUGH*/
|
||||
/* these two should be handled outside this function */
|
||||
default: /* we should never hit the default */
|
||||
@ -368,16 +323,16 @@ ct_visual_char(Char *dst, size_t len, Char c)
|
||||
|
||||
|
||||
|
||||
protected int
|
||||
ct_chr_class(Char c)
|
||||
libedit_private int
|
||||
ct_chr_class(wchar_t c)
|
||||
{
|
||||
if (c == '\t')
|
||||
return CHTYPE_TAB;
|
||||
else if (c == '\n')
|
||||
return CHTYPE_NL;
|
||||
else if (IsASCII(c) && Iscntrl(c))
|
||||
else if (c < 0x100 && iswcntrl(c))
|
||||
return CHTYPE_ASCIICTL;
|
||||
else if (Isprint(c))
|
||||
else if (iswprint(c))
|
||||
return CHTYPE_PRINT;
|
||||
else
|
||||
return CHTYPE_NONPRINT;
|
119
contrib/libedit/chartype.h
Normal file
119
contrib/libedit/chartype.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* $NetBSD: chartype.h,v 1.35 2017/05/22 19:16:25 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef _h_chartype_f
|
||||
#define _h_chartype_f
|
||||
|
||||
/* Ideally we should also test the value of the define to see if it
|
||||
* supports non-BMP code points without requiring UTF-16, but nothing
|
||||
* seems to actually advertise this properly, despite Unicode 3.1 having
|
||||
* been around since 2001... */
|
||||
#if !defined(__NetBSD__) && \
|
||||
!defined(__sun) && \
|
||||
!(defined(__APPLE__) && defined(__MACH__)) && \
|
||||
!defined(__OpenBSD__) && \
|
||||
!defined(__FreeBSD__) && \
|
||||
!defined(__DragonFly__)
|
||||
#ifndef __STDC_ISO_10646__
|
||||
/* In many places it is assumed that the first 127 code points are ASCII
|
||||
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
|
||||
* funky encoding that could break us in weird and wonderful ways. */
|
||||
#error wchar_t must store ISO 10646 characters
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Oh for a <uchar.h> with char32_t and __STDC_UTF_32__ in it...
|
||||
* ref: ISO/IEC DTR 19769
|
||||
*/
|
||||
#if WCHAR_MAX < INT32_MAX
|
||||
#warning Build environment does not support non-BMP characters
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Conversion buffer
|
||||
*/
|
||||
typedef struct ct_buffer_t {
|
||||
char *cbuff;
|
||||
size_t csize;
|
||||
wchar_t *wbuff;
|
||||
size_t wsize;
|
||||
} ct_buffer_t;
|
||||
|
||||
/* Encode a wide-character string and return the UTF-8 encoded result. */
|
||||
char *ct_encode_string(const wchar_t *, ct_buffer_t *);
|
||||
|
||||
/* Decode a (multi)?byte string and return the wide-character string result. */
|
||||
wchar_t *ct_decode_string(const char *, ct_buffer_t *);
|
||||
|
||||
/* Decode a (multi)?byte argv string array.
|
||||
* The pointer returned must be free()d when done. */
|
||||
libedit_private wchar_t **ct_decode_argv(int, const char *[], ct_buffer_t *);
|
||||
|
||||
/* Encode a character into the destination buffer, provided there is sufficient
|
||||
* buffer space available. Returns the number of bytes used up (zero if the
|
||||
* character cannot be encoded, -1 if there was not enough space available). */
|
||||
libedit_private ssize_t ct_encode_char(char *, size_t, wchar_t);
|
||||
libedit_private size_t ct_enc_width(wchar_t);
|
||||
|
||||
/* The maximum buffer size to hold the most unwieldy visual representation,
|
||||
* in this case \U+nnnnn. */
|
||||
#define VISUAL_WIDTH_MAX ((size_t)8)
|
||||
|
||||
/* The terminal is thought of in terms of X columns by Y lines. In the cases
|
||||
* where a wide character takes up more than one column, the adjacent
|
||||
* occupied column entries will contain this faux character. */
|
||||
#define MB_FILL_CHAR ((wchar_t)-1)
|
||||
|
||||
/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn
|
||||
* style visual expansions. */
|
||||
libedit_private int ct_visual_width(wchar_t);
|
||||
|
||||
/* Turn the given character into the appropriate visual format, matching
|
||||
* the width given by ct_visual_width(). Returns the number of characters used
|
||||
* up, or -1 if insufficient space. Buffer length is in count of wchar_t's. */
|
||||
libedit_private ssize_t ct_visual_char(wchar_t *, size_t, wchar_t);
|
||||
|
||||
/* Convert the given string into visual format, using the ct_visual_char()
|
||||
* function. Uses a static buffer, so not threadsafe. */
|
||||
libedit_private const wchar_t *ct_visual_string(const wchar_t *, ct_buffer_t *);
|
||||
|
||||
|
||||
/* printable character, use ct_visual_width() to find out display width */
|
||||
#define CHTYPE_PRINT ( 0)
|
||||
/* control character found inside the ASCII portion of the charset */
|
||||
#define CHTYPE_ASCIICTL (-1)
|
||||
/* a \t */
|
||||
#define CHTYPE_TAB (-2)
|
||||
/* a \n */
|
||||
#define CHTYPE_NL (-3)
|
||||
/* non-printable character */
|
||||
#define CHTYPE_NONPRINT (-4)
|
||||
/* classification of character c, as one of the above defines */
|
||||
libedit_private int ct_chr_class(wchar_t c);
|
||||
|
||||
#endif /* _chartype_f */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $ */
|
||||
/* $NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
|
||||
__RCSID("$NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* common.c: Common Editor functions
|
||||
@ -51,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
#include "fcns.h"
|
||||
#include "parse.h"
|
||||
#include "vi.h"
|
||||
|
||||
@ -58,7 +57,7 @@ __FBSDID("$FreeBSD$");
|
||||
* Indicate end of file
|
||||
* [^D]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -73,7 +72,7 @@ ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Add character to the line
|
||||
* Insert a character [bound to all insert keys]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ed_insert(EditLine *el, wint_t c)
|
||||
{
|
||||
int count = el->el_state.argument;
|
||||
@ -93,14 +92,14 @@ ed_insert(EditLine *el, wint_t c)
|
||||
|| el->el_line.cursor >= el->el_line.lastchar)
|
||||
c_insert(el, 1);
|
||||
|
||||
*el->el_line.cursor++ = (Char)c;
|
||||
*el->el_line.cursor++ = c;
|
||||
re_fastaddc(el); /* fast refresh for one char. */
|
||||
} else {
|
||||
if (el->el_state.inputmode != MODE_REPLACE_1)
|
||||
c_insert(el, el->el_state.argument);
|
||||
|
||||
while (count-- && el->el_line.cursor < el->el_line.lastchar)
|
||||
*el->el_line.cursor++ = (Char)c;
|
||||
*el->el_line.cursor++ = c;
|
||||
re_refresh(el);
|
||||
}
|
||||
|
||||
@ -115,11 +114,11 @@ ed_insert(EditLine *el, wint_t c)
|
||||
* Delete from beginning of current word to cursor
|
||||
* [M-^?] [^W]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *p, *kp;
|
||||
wchar_t *cp, *p, *kp;
|
||||
|
||||
if (el->el_line.cursor == el->el_line.buffer)
|
||||
return CC_ERROR;
|
||||
@ -143,15 +142,14 @@ ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Delete character under cursor
|
||||
* [^D] [x]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
#ifdef DEBUG_EDIT
|
||||
#define EL el->el_line
|
||||
(void) fprintf(el->el_errfile,
|
||||
"\nD(b: %p(" FSTR ") c: %p(" FSTR ") last: %p(" FSTR
|
||||
") limit: %p(" FSTR ")\n",
|
||||
"\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
|
||||
EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
|
||||
EL.lastchar, EL.limit, EL.limit);
|
||||
#endif
|
||||
@ -191,11 +189,11 @@ ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Cut to the end of line
|
||||
* [^K] [^K]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
cp = el->el_line.cursor;
|
||||
kp = el->el_chared.c_kill.buf;
|
||||
@ -212,7 +210,7 @@ ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move cursor to the end of line
|
||||
* [^E] [^E]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -235,7 +233,7 @@ ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move cursor to the beginning of line
|
||||
* [^A] [^A]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -244,7 +242,7 @@ ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
|
||||
if (el->el_map.type == MAP_VI) {
|
||||
/* We want FIRST non space character */
|
||||
while (Isspace(*el->el_line.cursor))
|
||||
while (iswspace(*el->el_line.cursor))
|
||||
el->el_line.cursor++;
|
||||
if (el->el_chared.c_vcmd.action != NOP) {
|
||||
cv_delfini(el);
|
||||
@ -259,7 +257,7 @@ ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Exchange the character to the left of the cursor with the one under it
|
||||
* [^T] [^T]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ed_transpose_chars(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
@ -273,7 +271,7 @@ ed_transpose_chars(EditLine *el, wint_t c)
|
||||
/* must have at least two chars entered */
|
||||
c = el->el_line.cursor[-2];
|
||||
el->el_line.cursor[-2] = el->el_line.cursor[-1];
|
||||
el->el_line.cursor[-1] = (Char)c;
|
||||
el->el_line.cursor[-1] = c;
|
||||
return CC_REFRESH;
|
||||
} else
|
||||
return CC_ERROR;
|
||||
@ -284,11 +282,11 @@ ed_transpose_chars(EditLine *el, wint_t c)
|
||||
* Move to the right one character
|
||||
* [^F] [^F]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *lim = el->el_line.lastchar;
|
||||
wchar_t *lim = el->el_line.lastchar;
|
||||
|
||||
if (el->el_line.cursor >= lim ||
|
||||
(el->el_line.cursor == lim - 1 &&
|
||||
@ -313,7 +311,7 @@ ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move to the beginning of the current word
|
||||
* [M-b] [b]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -339,7 +337,7 @@ ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move to the left one character
|
||||
* [^B] [^B]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -364,16 +362,18 @@ ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Add the next character typed verbatim
|
||||
* [^V] [^V]
|
||||
*/
|
||||
protected el_action_t
|
||||
ed_quoted_insert(EditLine *el, wint_t c)
|
||||
libedit_private el_action_t
|
||||
/*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);
|
||||
}
|
||||
@ -382,11 +382,11 @@ ed_quoted_insert(EditLine *el, wint_t c)
|
||||
/* ed_digit():
|
||||
* Adds to argument or enters a digit
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ed_digit(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
if (!Isdigit(c))
|
||||
if (!iswdigit(c))
|
||||
return CC_ERROR;
|
||||
|
||||
if (el->el_state.doingarg) {
|
||||
@ -410,11 +410,11 @@ ed_digit(EditLine *el, wint_t c)
|
||||
* Digit that starts argument
|
||||
* For ESC-n
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ed_argument_digit(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
if (!Isdigit(c))
|
||||
if (!iswdigit(c))
|
||||
return CC_ERROR;
|
||||
|
||||
if (el->el_state.doingarg) {
|
||||
@ -434,7 +434,7 @@ ed_argument_digit(EditLine *el, wint_t c)
|
||||
* Indicates unbound character
|
||||
* Bound to keys that are not assigned
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_unassigned(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
@ -444,17 +444,13 @@ ed_unassigned(EditLine *el __attribute__((__unused__)),
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** TTY key handling.
|
||||
**/
|
||||
|
||||
/* ed_tty_sigint():
|
||||
* Tty interrupt character
|
||||
* [^C]
|
||||
/* ed_ignore():
|
||||
* Input characters that have no effect
|
||||
* [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
|
||||
ed_ignore(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
@ -462,95 +458,11 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)),
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_dsusp():
|
||||
* Tty delayed suspend character
|
||||
* [^Y]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_flush_output():
|
||||
* Tty flush output characters
|
||||
* [^O]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_sigquit():
|
||||
* Tty quit character
|
||||
* [^\]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_sigtstp():
|
||||
* Tty suspend character
|
||||
* [^Z]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_stop_output():
|
||||
* Tty disallow output characters
|
||||
* [^S]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_tty_start_output():
|
||||
* Tty allow output characters
|
||||
* [^Q]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_tty_start_output(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
|
||||
/* ed_newline():
|
||||
* Execute command
|
||||
* [^J]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -566,7 +478,7 @@ ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Delete the character to the left of the cursor
|
||||
* [^?]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -586,7 +498,7 @@ ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Clear screen leaving current line at the top
|
||||
* [^L]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -601,7 +513,7 @@ ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Redisplay everything
|
||||
* ^R
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_redisplay(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
@ -615,12 +527,12 @@ ed_redisplay(EditLine *el __attribute__((__unused__)),
|
||||
* Erase current line and start from scratch
|
||||
* [^G]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
ch_reset(el, 0);
|
||||
ch_reset(el);
|
||||
return CC_REFRESH;
|
||||
}
|
||||
|
||||
@ -629,7 +541,7 @@ ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* First character in a bound sequence
|
||||
* Placeholder for external keys
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
|
||||
wint_t c __attribute__((__unused__)))
|
||||
@ -643,7 +555,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
|
||||
* Move to the previous history line
|
||||
* [^P] [k]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -655,7 +567,7 @@ ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
|
||||
if (el->el_history.eventno == 0) { /* save the current buffer
|
||||
* away */
|
||||
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
|
||||
(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
|
||||
EL_BUFSIZ);
|
||||
el->el_history.last = el->el_history.buf +
|
||||
(el->el_line.lastchar - el->el_line.buffer);
|
||||
@ -680,7 +592,7 @@ ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move to the next history line
|
||||
* [^N] [j]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -707,11 +619,11 @@ ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Search previous in history for a line matching the current
|
||||
* next search history [M-P] [K]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
const Char *hp;
|
||||
const wchar_t *hp;
|
||||
int h;
|
||||
int found = 0;
|
||||
|
||||
@ -727,7 +639,7 @@ ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
return CC_ERROR;
|
||||
}
|
||||
if (el->el_history.eventno == 0) {
|
||||
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
|
||||
(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
|
||||
EL_BUFSIZ);
|
||||
el->el_history.last = el->el_history.buf +
|
||||
(el->el_line.lastchar - el->el_line.buffer);
|
||||
@ -748,7 +660,7 @@ ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
#ifdef SDEBUG
|
||||
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
|
||||
#endif
|
||||
if ((Strncmp(hp, el->el_line.buffer, (size_t)
|
||||
if ((wcsncmp(hp, el->el_line.buffer, (size_t)
|
||||
(el->el_line.lastchar - el->el_line.buffer)) ||
|
||||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
|
||||
c_hmatch(el, hp)) {
|
||||
@ -775,11 +687,11 @@ ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Search next in history for a line matching the current
|
||||
* [M-N] [J]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
const Char *hp;
|
||||
const wchar_t *hp;
|
||||
int h;
|
||||
int found = 0;
|
||||
|
||||
@ -803,7 +715,7 @@ ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
#ifdef SDEBUG
|
||||
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
|
||||
#endif
|
||||
if ((Strncmp(hp, el->el_line.buffer, (size_t)
|
||||
if ((wcsncmp(hp, el->el_line.buffer, (size_t)
|
||||
(el->el_line.lastchar - el->el_line.buffer)) ||
|
||||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
|
||||
c_hmatch(el, hp))
|
||||
@ -829,11 +741,11 @@ ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move up one line
|
||||
* Could be [k] [^p]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *ptr;
|
||||
wchar_t *ptr;
|
||||
int nchars = c_hpos(el);
|
||||
|
||||
/*
|
||||
@ -872,11 +784,11 @@ ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Move down one line
|
||||
* Could be [j] [^n]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *ptr;
|
||||
wchar_t *ptr;
|
||||
int nchars = c_hpos(el);
|
||||
|
||||
/*
|
||||
@ -906,14 +818,14 @@ ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Editline extended command
|
||||
* [M-X] [:]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char tmpbuf[EL_BUFSIZ];
|
||||
wchar_t tmpbuf[EL_BUFSIZ];
|
||||
int tmplen;
|
||||
|
||||
tmplen = c_gets(el, tmpbuf, STR("\n: "));
|
||||
tmplen = c_gets(el, tmpbuf, L"\n: ");
|
||||
terminal__putc(el, '\n');
|
||||
|
||||
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
|
@ -1,4 +1,3 @@
|
||||
/* $FreeBSD$ */
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
@ -48,13 +47,13 @@
|
||||
/* #undef HAVE_LIBCURSES */
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
#define HAVE_LIBNCURSES 1
|
||||
/* #undef HAVE_LIBNCURSES */
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
/* #undef HAVE_LIBTERMCAP */
|
||||
|
||||
/* Define to 1 if you have the `terminfo' library (-lterminfo). */
|
||||
/* #undef HAVE_LIBTERMINFO */
|
||||
#define HAVE_LIBTERMINFO 1
|
||||
|
||||
/* Define to 1 if you have the `termlib' library (-ltermlib). */
|
||||
/* #undef HAVE_LIBTERMLIB */
|
||||
@ -75,7 +74,7 @@
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||
#define HAVE_NCURSES_H 1
|
||||
/* #undef HAVE_NCURSES_H */
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
@ -257,9 +256,6 @@
|
||||
/* Define to 1 if the system provides the SIZE_MAX constant */
|
||||
#define HAVE_SIZE_MAX 1
|
||||
|
||||
/* Define to 1 if you want wide-character code */
|
||||
/* #undef WIDECHAR */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
@ -284,7 +280,7 @@
|
||||
|
||||
|
||||
#include "sys.h"
|
||||
#undef SCCSID
|
||||
#undef LIBC_SCCS
|
||||
#undef lint
|
||||
#undef SIZE_T_MAX
|
||||
/* #undef SCCSID */
|
||||
/* #undef LIBC_SCCS */
|
||||
/* #undef lint */
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: editline.3,v 1.88 2016/02/25 14:59:22 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,9 +26,7 @@
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 28, 2017
|
||||
.Dd November 9, 2018
|
||||
.Dt EDITLINE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -94,11 +92,11 @@
|
||||
.Ft int
|
||||
.Fn el_getc "EditLine *e" "char *ch"
|
||||
.Ft int
|
||||
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
|
||||
.Fn el_wgetc "EditLine *e" "wchar_t *wc"
|
||||
.Ft void
|
||||
.Fn el_push "EditLine *e" "const char *str"
|
||||
.Fn el_push "EditLine *e" "const char *mbs"
|
||||
.Ft void
|
||||
.Fn el_wpush "EditLine *e" "const wchar_t *str"
|
||||
.Fn el_wpush "EditLine *e" "const wchar_t *wcs"
|
||||
.Ft int
|
||||
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
|
||||
.Ft int
|
||||
@ -115,7 +113,7 @@
|
||||
.Fn el_source "EditLine *e" "const char *file"
|
||||
.Ft void
|
||||
.Fn el_resize "EditLine *e"
|
||||
.Fn int
|
||||
.Ft int
|
||||
.Fn el_cursor "EditLine *e" "int count"
|
||||
.Ft const LineInfo *
|
||||
.Fn el_line "EditLine *e"
|
||||
@ -183,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 ,
|
||||
@ -252,18 +248,16 @@ The return value may not remain valid across calls to
|
||||
and must be copied if the data is to be retained.
|
||||
.It Fn el_wgetc
|
||||
Read a wide character from the tty, respecting the current locale,
|
||||
or from the input stream written by
|
||||
.Fn el_wpush
|
||||
and
|
||||
.Fn el_push
|
||||
or from the input queue described in
|
||||
.Xr editline 7
|
||||
if that is not empty, and store it in
|
||||
.Fa ch .
|
||||
.Fa wc .
|
||||
If an invalid or incomplete character is found, it is discarded,
|
||||
.Va errno
|
||||
is set to
|
||||
.Er EILSEQ ,
|
||||
and the next character is read and stored in
|
||||
.Fa ch .
|
||||
.Fa wc .
|
||||
Returns 1 if a valid character was read, 0 on end of file, or \-1 on
|
||||
.Xr read 2
|
||||
failure.
|
||||
@ -286,17 +280,23 @@ to
|
||||
and return \-1.
|
||||
In the C or POSIX locale, this simply reads a byte, but for any other
|
||||
locale, including UTF-8, this is rarely useful.
|
||||
.It Fn el_wpush
|
||||
Push the wide character string
|
||||
.Fa wcs
|
||||
back onto the input queue described in
|
||||
.Xr editline 7 .
|
||||
If the queue overflows, for example due to a recursive macro,
|
||||
or if an error occurs, for example because
|
||||
.Fa wcs
|
||||
is
|
||||
.Dv NULL
|
||||
or memory allocation fails, the function beeps at the user,
|
||||
but does not report the problem to the caller.
|
||||
.It Fn el_push
|
||||
Pushes
|
||||
.Fa str
|
||||
back onto the input stream.
|
||||
This is used by the macro expansion mechanism.
|
||||
Refer to the description of
|
||||
.Ic bind
|
||||
.Fl s
|
||||
in
|
||||
.Xr editrc 5
|
||||
for more information.
|
||||
Use the current locale to convert the multibyte string
|
||||
.Fa mbs
|
||||
to a wide character string, and pass the result to
|
||||
.Fn el_wpush .
|
||||
.It Fn el_parse
|
||||
Parses the
|
||||
.Fa argv
|
||||
@ -356,6 +356,8 @@ terminal without affecting the state of the current line.
|
||||
A subsequent second start/stop literal character ends this behavior.
|
||||
This is typically used to embed literal escape sequences that change the
|
||||
color/style of the terminal in the prompt.
|
||||
Note that the literal escape character cannot be the last character in the
|
||||
prompt, as the escape sequence is attached to the next character in the prompt.
|
||||
.Dv 0
|
||||
unsets it.
|
||||
.It Dv EL_REFRESH
|
||||
@ -505,18 +507,31 @@ unbuffered mode is disabled (the default).
|
||||
In unbuffered mode,
|
||||
.Fn el_gets
|
||||
will return immediately after processing a single character.
|
||||
.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
|
||||
Define the character reading function as
|
||||
.Fa f ,
|
||||
which is to return the number of characters read and store them in
|
||||
.Fa c .
|
||||
This function is called internally by
|
||||
.Fn el_gets
|
||||
.It Dv EL_GETCFN , Fa "el_rfunc_t f"
|
||||
Whenever reading a character, use the function
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Ft int
|
||||
.Fo f
|
||||
.Fa "EditLine *e"
|
||||
.Fa "wchar_t *wc"
|
||||
.Fc
|
||||
.Ed
|
||||
which stores the character in
|
||||
.Fa wc
|
||||
and returns 1 on success, 0 on end of file, or \-1 on I/O or encoding
|
||||
errors.
|
||||
Functions internally using it include
|
||||
.Fn el_wgets ,
|
||||
.Fn el_wgetc ,
|
||||
.Fn el_gets ,
|
||||
and
|
||||
.Fn el_getc .
|
||||
The builtin function can be set or restored with the special function
|
||||
name
|
||||
.Dq Dv EL_BUILTIN_GETCFN .
|
||||
Initially, a builtin function is installed, and replacing it
|
||||
is discouraged because writing such a function is very error prone.
|
||||
The builtin function can be restored at any time by passing the
|
||||
special value
|
||||
.Dv EL_BUILTIN_GETCFN
|
||||
instead of a function pointer.
|
||||
.It Dv EL_CLIENTDATA , Fa "void *data"
|
||||
Register
|
||||
.Fa data
|
||||
@ -560,7 +575,7 @@ are supported, along with actual type of
|
||||
.Bl -tag -width 4n
|
||||
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
|
||||
Set
|
||||
.Fa f .
|
||||
.Fa f
|
||||
to a pointer to the function that displays the prompt.
|
||||
If
|
||||
.Fa c
|
||||
@ -569,7 +584,7 @@ is not
|
||||
set it to the start/stop literal prompt character.
|
||||
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
|
||||
Set
|
||||
.Fa f .
|
||||
.Fa f
|
||||
to a pointer to the function that displays the prompt.
|
||||
If
|
||||
.Fa c
|
||||
@ -594,7 +609,7 @@ to the current value of that capability.
|
||||
.It Dv EL_SIGNAL , Fa "int *s"
|
||||
Set
|
||||
.Fa s
|
||||
to non zero if
|
||||
to non-zero if
|
||||
.Nm
|
||||
has installed private signal handlers (see
|
||||
.Fn el_get
|
||||
@ -603,10 +618,12 @@ above).
|
||||
Set
|
||||
.Fa c
|
||||
to non-zero if editing is enabled.
|
||||
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
|
||||
Return a pointer to the function that read characters, which is equal to
|
||||
.Dq Dv EL_BUILTIN_GETCFN
|
||||
in the case of the default builtin function.
|
||||
.It Dv EL_GETCFN , Fa "el_rfunc_t *f"
|
||||
Set
|
||||
.Fa f
|
||||
to a pointer to the function that reads characters, or to
|
||||
.Dv EL_BUILTIN_GETCFN
|
||||
if the builtin function is in use.
|
||||
.It Dv EL_CLIENTDATA , Fa "void **data"
|
||||
Set
|
||||
.Fa data
|
||||
@ -650,6 +667,8 @@ If
|
||||
is
|
||||
.Dv NULL ,
|
||||
try
|
||||
.Pa $EDITRC
|
||||
and if that is not set
|
||||
.Pa $HOME/.editrc .
|
||||
Refer to
|
||||
.Xr editrc 5
|
||||
@ -763,8 +782,10 @@ Return the first element in the history.
|
||||
Return the last element in the history.
|
||||
.It Dv H_PREV
|
||||
Return the previous element in the history.
|
||||
It is newer than the current one.
|
||||
.It Dv H_NEXT
|
||||
Return the next element in the history.
|
||||
It is older than the current one.
|
||||
.It Dv H_CURR
|
||||
Return the current element in the history.
|
||||
.It Dv H_SET , Fa "int position"
|
||||
@ -820,6 +841,13 @@ Save the history list to the opened
|
||||
.Ft FILE
|
||||
pointer
|
||||
.Fa fp .
|
||||
.It Dv H_NSAVE_FP , Fa "size_t n" , Fa "FILE *fp"
|
||||
Save the last
|
||||
.Ft n
|
||||
history entries to the opened
|
||||
.Ft FILE
|
||||
pointer
|
||||
.Fa fp .
|
||||
.It Dv H_SETUNIQUE , Fa "int unique"
|
||||
Set flag that adjacent identical event strings should not be entered
|
||||
into the history.
|
||||
@ -830,14 +858,14 @@ be entered into the history.
|
||||
Delete the event numbered
|
||||
.Fa e .
|
||||
This function is only provided for
|
||||
.Xr readline 3
|
||||
.Nm readline
|
||||
compatibility.
|
||||
The caller is responsible for free'ing the string in the returned
|
||||
.Fa HistEvent .
|
||||
.El
|
||||
.Pp
|
||||
.Fn history
|
||||
returns \*[Gt]= 0 if the operation
|
||||
returns >= 0 if the operation
|
||||
.Fa op
|
||||
succeeds.
|
||||
Otherwise, \-1 is returned and
|
||||
@ -923,7 +951,8 @@ is a NUL terminated string to tokenize.
|
||||
.Xr signal 3 ,
|
||||
.Xr termcap 3 ,
|
||||
.Xr editrc 5 ,
|
||||
.Xr termcap 5
|
||||
.Xr termcap 5 ,
|
||||
.Xr editline 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
935
contrib/libedit/editline.7
Normal file
935
contrib/libedit/editline.7
Normal file
@ -0,0 +1,935 @@
|
||||
.\" $NetBSD: editline.7,v 1.5 2016/05/09 21:27:55 christos Exp $
|
||||
.\" $OpenBSD: editline.7,v 1.1 2016/04/20 01:11:45 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd May 7, 2016
|
||||
.Dt EDITLINE 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm editline
|
||||
.Nd line editing user interface
|
||||
.Sh DESCRIPTION
|
||||
When a program using the
|
||||
.Xr editline 3
|
||||
library prompts for an input string using the function
|
||||
.Xr el_wgets 3 ,
|
||||
it reads characters from the terminal.
|
||||
Invalid input bytes that do not form characters are silently
|
||||
discarded.
|
||||
For each character read, one editor command is executed.
|
||||
The mapping of input characters to editor commands depends on the
|
||||
editing mode.
|
||||
There are three editing modes: vi insert mode, vi command mode,
|
||||
and emacs mode.
|
||||
The default is vi insert mode.
|
||||
The program can switch the default to emacs mode by using the
|
||||
.Xr el_set 3
|
||||
or
|
||||
.Xr el_parse 3
|
||||
functions, and the user can switch to emacs mode either in the
|
||||
.Xr editrc 5
|
||||
configuration file or interactively with the
|
||||
.Ic ed-command
|
||||
editor command, in all three cases executing the
|
||||
.Ic bind Fl e
|
||||
builtin command.
|
||||
.Pp
|
||||
If trying to read from the terminal results in end of file or an
|
||||
error, the library signals end of file to the program and does not
|
||||
return a string.
|
||||
.Ss Input character bindings
|
||||
All default bindings described below can be overridden by individual
|
||||
programs and can be changed with the
|
||||
.Xr editrc 5
|
||||
.Ic bind
|
||||
builtin command.
|
||||
.Pp
|
||||
In the following tables,
|
||||
.Sq Ctrl-
|
||||
indicates a character with the bit 0x40 flipped, and
|
||||
.Sq Meta-
|
||||
indicates a character with the bit 0x80 set.
|
||||
In vi insert mode and in emacs mode, all Meta-characters considered
|
||||
printable by the current
|
||||
.Xr locale 1
|
||||
are bound to
|
||||
.Ic ed-insert
|
||||
instead of to the editor command listed below.
|
||||
Consequently, in UTF-8 mode, most of the Meta-characters are not
|
||||
directly accessible because their code points are occupied by
|
||||
printable Unicode characters, and Meta-characters are usually input
|
||||
using the
|
||||
.Ic em-meta-next
|
||||
editor command.
|
||||
For example, to enter
|
||||
.Sq Meta-B
|
||||
in order to call the
|
||||
.Ic ed-prev-word
|
||||
editor command in emacs mode, call
|
||||
.Ic em-meta-next
|
||||
by pressing and releasing the escape key (or equivalently, Ctrl-[),
|
||||
then press and release the
|
||||
.Sq B
|
||||
key.
|
||||
If you have configured a Meta-key on your keyboard, for example
|
||||
with
|
||||
.Ql setxkbmap -option altwin:left_meta_win ,
|
||||
the Ctrl-Meta-characters are directly accessible.
|
||||
For example, to enter
|
||||
.Sq Ctrl-Meta-H
|
||||
in order to call the
|
||||
.Ic ed-delete-prev-word
|
||||
editor command in emacs mode, hold down the keys
|
||||
.Sq Ctrl ,
|
||||
.Sq Meta ,
|
||||
and
|
||||
.Sq H
|
||||
at the same time.
|
||||
Alternatively, press and release the escape key, then press and
|
||||
release
|
||||
.Sq Ctrl-H .
|
||||
.Pp
|
||||
In vi input mode, input characters are bound to the following editor
|
||||
commands by default:
|
||||
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
|
||||
.It Ctrl-D, EOF Ta Ic vi-list-or-eof
|
||||
.It Ctrl-H, BS Ta Ic vi-delete-prev-char
|
||||
.It Ctrl-J, LF Ta Ic ed-newline
|
||||
.It Ctrl-M, CR Ta Ic ed-newline
|
||||
.It Ctrl-Q Ta Ic ed-tty-start-output
|
||||
.It Ctrl-S Ta Ic ed-tty-stop-output
|
||||
.It Ctrl-U Ta Ic vi-kill-line-prev
|
||||
.It Ctrl-V Ta Ic ed-quoted-insert
|
||||
.It Ctrl-W Ta Ic ed-delete-prev-word
|
||||
.It Ctrl-[, ESC Ta Ic vi-command-mode
|
||||
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
|
||||
.It Ctrl-?, DEL Ta Ic vi-delete-prev-char
|
||||
.El
|
||||
.Pp
|
||||
All other input characters except the NUL character (Ctrl-@) are
|
||||
bound to
|
||||
.Ic ed-insert .
|
||||
.Pp
|
||||
In vi command mode, input characters are bound to the following
|
||||
editor commands by default:
|
||||
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
|
||||
.It Ctrl-A Ta Ic ed-move-to-beg
|
||||
.It Ctrl-C, INT Ta Ic ed-tty-sigint
|
||||
.It Ctrl-E Ta Ic ed-move-to-end
|
||||
.It Ctrl-H, BS Ta Ic ed-delete-prev-char
|
||||
.It Ctrl-J, LF Ta Ic ed-newline
|
||||
.It Ctrl-K Ta Ic ed-kill-line
|
||||
.It Ctrl-L, FF Ta Ic ed-clear-screen
|
||||
.It Ctrl-M, CR Ta Ic ed-newline
|
||||
.It Ctrl-N Ta Ic ed-next-history
|
||||
.It Ctrl-O Ta Ic ed-tty-flush-output
|
||||
.It Ctrl-P Ta Ic ed-prev-history
|
||||
.It Ctrl-Q Ta Ic ed-tty-start-output
|
||||
.It Ctrl-R Ta Ic ed-redisplay
|
||||
.It Ctrl-S Ta Ic ed-tty-stop-output
|
||||
.It Ctrl-U Ta Ic vi-kill-line-prev
|
||||
.It Ctrl-W Ta Ic ed-delete-prev-word
|
||||
.It Ctrl-[, ESC Ta Ic em-meta-next
|
||||
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
|
||||
.It Space Ta Ic ed-next-char
|
||||
.It # Ta Ic vi-comment-out
|
||||
.It $ Ta Ic ed-move-to-end
|
||||
.It % Ta Ic vi-match
|
||||
.It + Ta Ic ed-next-history
|
||||
.It \&, Ta Ic vi-repeat-prev-char
|
||||
.It - Ta Ic ed-prev-history
|
||||
.It \&. Ta Ic vi-redo
|
||||
.It / Ta Ic vi-search-prev
|
||||
.It 0 Ta Ic vi-zero
|
||||
.It 1 to 9 Ta Ic ed-argument-digit
|
||||
.It \&: Ta Ic ed-command
|
||||
.It \&; Ta Ic vi-repeat-next-char
|
||||
.It \&? Ta Ic vi-search-next
|
||||
.It @ Ta Ic vi-alias
|
||||
.It A Ta Ic vi-add-at-eol
|
||||
.It B Ta Ic vi-prev-big-word
|
||||
.It C Ta Ic vi-change-to-eol
|
||||
.It D Ta Ic ed-kill-line
|
||||
.It E Ta Ic vi-end-big-word
|
||||
.It F Ta Ic vi-prev-char
|
||||
.It G Ta Ic vi-to-history-line
|
||||
.It I Ta Ic vi-insert-at-bol
|
||||
.It J Ta Ic ed-search-next-history
|
||||
.It K Ta Ic ed-search-prev-history
|
||||
.It N Ta Ic vi-repeat-search-prev
|
||||
.It O Ta Ic ed-sequence-lead-in
|
||||
.It P Ta Ic vi-paste-prev
|
||||
.It R Ta Ic vi-replace-mode
|
||||
.It S Ta Ic vi-substitute-line
|
||||
.It T Ta Ic vi-to-prev-char
|
||||
.It U Ta Ic vi-undo-line
|
||||
.It W Ta Ic vi-next-big-word
|
||||
.It X Ta Ic ed-delete-prev-char
|
||||
.It Y Ta Ic vi-yank-end
|
||||
.It \&[ Ta Ic ed-sequence-lead-in
|
||||
.It ^ Ta Ic ed-move-to-beg
|
||||
.It _ Ta Ic vi-history-word
|
||||
.It a Ta Ic vi-add
|
||||
.It b Ta Ic vi-prev-word
|
||||
.It c Ta Ic vi-change-meta
|
||||
.It d Ta Ic vi-delete-meta
|
||||
.It e Ta Ic vi-end-word
|
||||
.It f Ta Ic vi-next-char
|
||||
.It h Ta Ic ed-prev-char
|
||||
.It i Ta Ic vi-insert
|
||||
.It j Ta Ic ed-next-history
|
||||
.It k Ta Ic ed-prev-history
|
||||
.It l Ta Ic ed-next-char
|
||||
.It n Ta Ic vi-repeat-search-next
|
||||
.It p Ta Ic vi-paste-next
|
||||
.It r Ta Ic vi-replace-char
|
||||
.It s Ta Ic vi-substitute-char
|
||||
.It t Ta Ic vi-to-next-char
|
||||
.It u Ta Ic vi-undo
|
||||
.It v Ta Ic vi-histedit
|
||||
.It w Ta Ic vi-next-word
|
||||
.It x Ta Ic ed-delete-next-char
|
||||
.It y Ta Ic vi-yank
|
||||
.It \&| Ta Ic vi-to-column
|
||||
.It ~ Ta Ic vi-change-case
|
||||
.It Ctrl-?, DEL Ta Ic ed-delete-prev-char
|
||||
.It Meta-O Ta Ic ed-sequence-lead-in
|
||||
.It Meta-[ Ta Ic ed-sequence-lead-in
|
||||
.El
|
||||
.Pp
|
||||
In emacs mode, input characters are bound to the following editor
|
||||
commands by default:
|
||||
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
|
||||
.It 0 to 9 Ta Ic ed-digit
|
||||
.It Ctrl-@, NUL Ta Ic em-set-mark
|
||||
.It Ctrl-A Ta Ic ed-move-to-beg
|
||||
.It Ctrl-B Ta Ic ed-prev-char
|
||||
.It Ctrl-C, INT Ta Ic ed-tty-sigint
|
||||
.It Ctrl-D, EOF Ta Ic em-delete-or-list
|
||||
.It Ctrl-E Ta Ic ed-move-to-end
|
||||
.It Ctrl-F Ta Ic ed-next-char
|
||||
.It Ctrl-H, BS Ta Ic em-delete-prev-char
|
||||
.It Ctrl-J, LF Ta Ic ed-newline
|
||||
.It Ctrl-K Ta Ic ed-kill-line
|
||||
.It Ctrl-L, FF Ta Ic ed-clear-screen
|
||||
.It Ctrl-M, CR Ta Ic ed-newline
|
||||
.It Ctrl-N Ta Ic ed-next-history
|
||||
.It Ctrl-O Ta Ic ed-tty-flush-output
|
||||
.It Ctrl-P Ta Ic ed-prev-history
|
||||
.It Ctrl-Q Ta Ic ed-tty-start-output
|
||||
.It Ctrl-R Ta Ic ed-redisplay
|
||||
.It Ctrl-S Ta Ic ed-tty-stop-output
|
||||
.It Ctrl-T Ta Ic ed-transpose-chars
|
||||
.It Ctrl-U Ta Ic ed-kill-line
|
||||
.It Ctrl-V Ta Ic ed-quoted-insert
|
||||
.It Ctrl-W Ta Ic em-kill-region
|
||||
.It Ctrl-X Ta Ic ed-sequence-lead-in
|
||||
.It Ctrl-Y Ta Ic em-yank
|
||||
.It Ctrl-Z, TSTP Ta Ic ed-tty-sigtstp
|
||||
.It Ctrl-[, ESC Ta Ic em-meta-next
|
||||
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
|
||||
.It Ctrl-] Ta Ic ed-tty-dsusp
|
||||
.It Ctrl-?, DEL Ta Ic em-delete-prev-char
|
||||
.It Ctrl-Meta-H Ta Ic ed-delete-prev-word
|
||||
.It Ctrl-Meta-L Ta Ic ed-clear-screen
|
||||
.It Ctrl-Meta-_ Ta Ic em-copy-prev-word
|
||||
.It Meta-0 to 9 Ta Ic ed-argument-digit
|
||||
.It Meta-B Ta Ic ed-prev-word
|
||||
.It Meta-C Ta Ic em-capitol-case
|
||||
.It Meta-D Ta Ic em-delete-next-word
|
||||
.It Meta-F Ta Ic em-next-word
|
||||
.It Meta-L Ta Ic em-lower-case
|
||||
.It Meta-N Ta Ic ed-search-next-history
|
||||
.It Meta-O Ta Ic ed-sequence-lead-in
|
||||
.It Meta-P Ta Ic ed-search-prev-history
|
||||
.It Meta-U Ta Ic em-upper-case
|
||||
.It Meta-W Ta Ic em-copy-region
|
||||
.It Meta-X Ta Ic ed-command
|
||||
.It Meta-[ Ta Ic ed-sequence-lead-in
|
||||
.It Meta-b Ta Ic ed-prev-word
|
||||
.It Meta-c Ta Ic em-capitol-case
|
||||
.It Meta-d Ta Ic em-delete-next-word
|
||||
.It Meta-f Ta Ic em-next-word
|
||||
.It Meta-l Ta Ic em-lower-case
|
||||
.It Meta-n Ta Ic ed-search-next-history
|
||||
.It Meta-p Ta Ic ed-search-prev-history
|
||||
.It Meta-u Ta Ic em-upper-case
|
||||
.It Meta-w Ta Ic em-copy-region
|
||||
.It Meta-x Ta Ic ed-command
|
||||
.It Ctrl-Meta-? Ta Ic ed-delete-prev-word
|
||||
.El
|
||||
.Pp
|
||||
The remaining
|
||||
.Xr ascii 7
|
||||
characters in the range 0x20 to 0x7e are bound to
|
||||
.Ic ed-insert .
|
||||
.Pp
|
||||
If standard output is not connected to a terminal device
|
||||
or
|
||||
.Xr el_set 3
|
||||
was used to set
|
||||
.Dv EL_EDITMODE
|
||||
to 0, all input character bindings are disabled and all characters
|
||||
typed are appended to the edit buffer.
|
||||
In that case, the edit buffer is returned to the program after a
|
||||
newline or carriage return character is typed, or after the first
|
||||
character typed if
|
||||
.Xr el_set 3
|
||||
was used to set
|
||||
.Dv EL_UNBUFFERED
|
||||
to non-zero.
|
||||
.Ss Editor commands
|
||||
Most editor commands accept an optional argument.
|
||||
The argument is entered by prefixing the editor command with one
|
||||
or more of the editor commands
|
||||
.Ic ed-argument-digit ,
|
||||
.Ic ed-digit ,
|
||||
.Ic em-universal-argument ,
|
||||
or
|
||||
.Ic vi-zero .
|
||||
When an argument is not provided, it defaults to 1.
|
||||
For most editor commands, the effect of an argument is to repeatedly
|
||||
execute the command that number of times.
|
||||
.Pp
|
||||
When talking about a character string from a left character to a
|
||||
right character, the left character is included in the string, while
|
||||
the right character is not included.
|
||||
.Pp
|
||||
If an editor command causes an error, the input character is discarded,
|
||||
no action occurs, and the terminal bell is rung.
|
||||
In case of a non-fatal error, the terminal bell is also rung,
|
||||
but the editor command takes effect anyway.
|
||||
.Pp
|
||||
In the following list, the default key bindings are listed after
|
||||
each editor command.
|
||||
.Bl -tag -width 4n
|
||||
.It Ic ed-argument-digit Pq vi command: 1 to 9; emacs: Meta-0 to Meta-9
|
||||
If in argument input mode, append the input digit to the argument
|
||||
being read.
|
||||
Otherwise, switch to argument input mode and use the input digit
|
||||
as the most significant digit of the argument.
|
||||
It is an error if the input character is not a digit or if the
|
||||
existing argument is already greater than a million.
|
||||
.It Ic ed-clear-screen Pq vi command: Ctrl-L; emacs: Ctrl-L, Ctrl-Meta-L
|
||||
Clear the screen and display the edit buffer at the top.
|
||||
Ignore any argument.
|
||||
.It Ic ed-command Pq vi command: So \&: Sc ; emacs: Meta-X, Meta-x
|
||||
Read a line from the terminal bypassing the normal line editing
|
||||
functionality and execute that line as an
|
||||
.Xr editrc 5
|
||||
builtin command.
|
||||
If in vi command mode, also switch back to vi insert mode.
|
||||
Ignore any argument.
|
||||
.It Ic ed-delete-next-char Pq vi command: x
|
||||
Delete the character at the cursor position.
|
||||
With an argument, delete that number of characters.
|
||||
In emacs mode, it is an error if the cursor is at the end of the
|
||||
edit buffer.
|
||||
In vi mode, the last character in the edit buffer is deleted in
|
||||
that case, and it is an error if the buffer is empty.
|
||||
.It Ic ed-delete-prev-char Pq vi command: X, Ctrl-H, BS, Ctrl-?, DEL
|
||||
Delete the character to the left of the cursor position.
|
||||
With an argument, delete that number of characters.
|
||||
It is an error if the cursor is at the beginning of the edit buffer.
|
||||
.It Ic ed-delete-prev-word Pq vi: Ctrl-W; emacs: Ctrl-Meta-H, Ctrl-Meta-?
|
||||
Move to the left to the closest beginning of a word, delete the
|
||||
string from that position to the cursor, and save it to the cut
|
||||
buffer.
|
||||
With an argument, delete that number of words.
|
||||
It is an error if the cursor is at the beginning of the edit buffer.
|
||||
.It Ic ed-digit Pq emacs: 0 to 9
|
||||
If in argument input mode, append the input digit to the argument
|
||||
being read.
|
||||
Otherwise, call
|
||||
.Ic ed-insert .
|
||||
It is an error if the input character is not a digit or if the
|
||||
existing argument is already greater than a million.
|
||||
.It Ic ed-end-of-file Pq not bound by default
|
||||
Discard the edit buffer and indicate end of file to the program.
|
||||
Ignore any argument.
|
||||
.It Ic ed-ignore Pq various
|
||||
Discard the input character and do nothing.
|
||||
.It Ic ed-insert Pq vi input: almost all; emacs: printable characters
|
||||
In insert mode, insert the input character left of the cursor
|
||||
position.
|
||||
In replace mode, overwrite the character at the cursor and move the
|
||||
cursor to the right by one character position.
|
||||
Accept an argument to do this repeatedly.
|
||||
It is an error if the input character is the NUL character (Ctrl-@).
|
||||
Failure to enlarge the edit buffer also results in an error.
|
||||
.It Ic ed-kill-line Pq vi command: D, Ctrl-K; emacs: Ctrl-K, Ctrl-U
|
||||
Delete the string from the cursor position to the end of the line
|
||||
and save it to the cut buffer.
|
||||
Ignore any argument.
|
||||
.It Ic ed-move-to-beg Pq vi command: ^, Ctrl-A; emacs: Ctrl-A
|
||||
In vi mode, move the cursor to the first non-space character in the
|
||||
edit buffer.
|
||||
In emacs mode, move the cursor to the beginning of the edit buffer.
|
||||
Ignore any argument.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.It Ic ed-move-to-end Pq vi command: $, Ctrl-E; emacs: Ctrl-E
|
||||
Move the cursor to the end of the edit buffer.
|
||||
Ignore any argument.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.It Ic ed-newline Pq all modes: Ctrl-J, LF, Ctrl-M, CR
|
||||
Append a newline character to the edit buffer and return the edit
|
||||
buffer to the program.
|
||||
Ignore any argument.
|
||||
.It Ic ed-next-char Pq vi command: Space, l; emacs: Ctrl-F
|
||||
Move the cursor one character position to the right.
|
||||
With an argument, move by that number of characters.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer.
|
||||
.It Ic ed-next-history Pq vi command: j, +, Ctrl-N; emacs: Ctrl-N
|
||||
Replace the edit buffer with the next history line.
|
||||
That line is older than the current line.
|
||||
With an argument, go forward by that number of history lines.
|
||||
It is a non-fatal error to advance by more lines than are available.
|
||||
.It Ic ed-next-line Pq not bound by default
|
||||
Move the cursor down one line.
|
||||
With an argument, move down by that number of lines.
|
||||
It is an error if the edit buffer does not contain enough newline
|
||||
characters to the right of the cursor position.
|
||||
.It Ic ed-prev-char Pq vi command: h; emacs: Ctrl-B
|
||||
Move the cursor one character position to the left.
|
||||
With an argument, move by that number of characters.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the beginning of the
|
||||
edit buffer.
|
||||
.It Ic ed-prev-history Pq vi command: k, -, Ctrl-P; emacs: Ctrl-P
|
||||
Replace the edit buffer with the previous history line.
|
||||
That line is newer than the current line.
|
||||
With an argument, go back by that number of lines.
|
||||
It is a non-fatal error to back up by more lines than are available.
|
||||
.It Ic ed-prev-line Pq not bound by default
|
||||
Move the cursor up one line.
|
||||
With an argument, move up by that number of lines.
|
||||
It is an error if the edit buffer does not contain enough newline
|
||||
characters to the left of the cursor position.
|
||||
.It Ic ed-prev-word Pq emacs: Meta-B, Meta-b
|
||||
Move the cursor to the left to the closest beginning of a word.
|
||||
With an argument, repeat that number of times.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the beginning of the
|
||||
edit buffer.
|
||||
.It Ic ed-quoted-insert Pq vi insert, emacs: Ctrl-V
|
||||
Read one character from the terminal bypassing the normal line
|
||||
editing functionality and call
|
||||
.Ic ed-insert
|
||||
on it.
|
||||
If trying to read the character returns end of file or an error,
|
||||
call
|
||||
.Ic ed-end-of-file
|
||||
instead.
|
||||
.It Ic ed-redisplay Pq vi command, emacs: Ctrl-R
|
||||
Redisplay everything.
|
||||
Ignore any argument.
|
||||
.It Ic ed-search-next-history Pq vi command: J; emacs: Meta-N, Meta-n
|
||||
Replace the edit buffer with the next matching history entry.
|
||||
.It Ic ed-search-prev-history Pq vi command: K; emacs: Meta-P, Meta-p
|
||||
Replace the edit buffer with the previous matching history entry.
|
||||
.It Ic ed-sequence-lead-in Pq vi cmd: O, \&[; emacs: Ctrl-X;\
|
||||
both: Meta-O, Meta-[
|
||||
Call a macro.
|
||||
See the section about
|
||||
.Sx Macros
|
||||
below for details.
|
||||
.It Ic ed-start-over Pq not bound by default
|
||||
Discard the contents of the edit buffer and start from scratch.
|
||||
Ignore any argument.
|
||||
.It Ic ed-transpose-chars Pq emacs: Ctrl-T
|
||||
Exchange the character at the cursor position with the one to the
|
||||
left of it and move the cursor to the character to the right of the
|
||||
two exchanged characters.
|
||||
Ignore any argument.
|
||||
It is an error if the cursor is at the beginning of the edit buffer
|
||||
or if the edit buffer contains less than two characters.
|
||||
.It Ic ed-unassigned Pq all characters not listed
|
||||
This editor command always results in an error.
|
||||
.It Ic em-capitol-case Pq emacs: Meta-C, Meta-c
|
||||
Capitalize the string from the cursor to the end of the current
|
||||
word.
|
||||
That is, if it contains at least one alphabetic character, convert
|
||||
the first alphabetic character to upper case, and convert all
|
||||
characters to the right of it to lower case.
|
||||
In any case, move the cursor to the next character after the end
|
||||
of the current word.
|
||||
.It Ic em-copy-prev-word Pq emacs: Ctrl-Meta-_
|
||||
Copy the string from the beginning of the current word to the cursor
|
||||
and insert it to the left of the cursor.
|
||||
Move the cursor to the character after the inserted string.
|
||||
It is an error if the cursor is at the beginning of the edit buffer.
|
||||
.It Ic em-copy-region Pq emacs: Meta-W, Meta-w
|
||||
Copy the string from the cursor to the mark to the cut buffer.
|
||||
It is an error if the mark is not set.
|
||||
.It Ic em-delete-next-word Pq emacs: Meta-D, Meta-d
|
||||
Delete the string from the cursor to the end of the current word
|
||||
and save it to the cut buffer.
|
||||
It is an error if the cursor is at the end of the edit buffer.
|
||||
.It Ic em-delete-or-list Pq emacs: Ctrl-D, EOF
|
||||
If the cursor is not at the end of the line, delete the character
|
||||
at the cursor.
|
||||
If the edit buffer is empty, indicate end of file to the program.
|
||||
It is an error if the cursor is at the end of the edit buffer and
|
||||
the edit buffer is not empty.
|
||||
.It Ic em-delete-prev-char Pq emacs: Ctrl-H, BS, Ctrl-?, DEL
|
||||
Delete the character to the left of the cursor.
|
||||
It is an error if the cursor is at the beginning of the edit buffer.
|
||||
.It Ic em-exchange-mark Pq not bound by default
|
||||
Exchange the cursor and the mark.
|
||||
.It Ic em-gosmacs-transpose Pq not bound by default
|
||||
Exchange the two characters to the left of the cursor.
|
||||
It is an error if the cursor is on the first or second character
|
||||
of the edit buffer.
|
||||
.It Ic em-inc-search-next Pq not bound by default
|
||||
Emacs incremental next search.
|
||||
.It Ic em-inc-search-prev Pq not bound by default
|
||||
Emacs incremental reverse search.
|
||||
.It Ic em-kill-line Pq not bound by default
|
||||
Delete the entire contents of the edit buffer and save it to the
|
||||
cut buffer.
|
||||
.It Ic em-kill-region Pq emacs: Ctrl-W
|
||||
Delete the string from the cursor to the mark and save it to the
|
||||
cut buffer.
|
||||
It is an error if the mark is not set.
|
||||
.It Ic em-lower-case Pq emacs: Meta-L, Meta-l
|
||||
Convert the characters from the cursor to the end of the current
|
||||
word to lower case.
|
||||
.It Ic em-meta-next Pq vi command, emacs: Ctrl-[, ESC
|
||||
Set the bit 0x80 on the next character typed.
|
||||
Unless the resulting code point is printable, holding down the
|
||||
.Sq Meta-
|
||||
key while typing that character is a simpler way to achieve the
|
||||
same effect.
|
||||
.It Ic em-next-word Pq Meta-F, Meta-f
|
||||
Move the cursor to the end of the current word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer.
|
||||
.It Ic em-set-mark Pq emacs: Ctrl-Q, NUL
|
||||
Set the mark at the current cursor position.
|
||||
.It Ic em-toggle-overwrite Pq not bound by default
|
||||
Switch from insert to overwrite mode or vice versa.
|
||||
.It Ic em-universal-argument Pq not bound by default
|
||||
If in argument input mode, multiply the argument by 4.
|
||||
Otherwise, switch to argument input mode and set the argument to 4.
|
||||
It is an error if the existing argument is already greater than a
|
||||
million.
|
||||
.It Ic em-upper-case Pq emacs: Meta-U, Meta-u
|
||||
Convert the characters from the cursor to the end of the current
|
||||
word to upper case.
|
||||
.It Ic em-yank Pq emacs: Ctrl-Y
|
||||
Paste the cut buffer to the left of the cursor.
|
||||
.It Ic vi-add Pq vi command: a
|
||||
Switch to vi insert mode.
|
||||
Unless the cursor is already at the end of the edit buffer, move
|
||||
it one character position to the right.
|
||||
.It Ic vi-add-at-eol Pq vi command: A
|
||||
Switch to vi insert mode and move the cursor to the end of the edit
|
||||
buffer.
|
||||
.It Ic vi-alias Pq vi command: @
|
||||
If an alias function was defined by calling the
|
||||
.Xr el_set 3
|
||||
or
|
||||
.Xr el_wset 3
|
||||
function with the argument
|
||||
.Dv EL_ALIAS_TEXT ,
|
||||
read one character from the terminal bypassing the normal line
|
||||
editing functionality, call the alias function passing the argument that was specified with
|
||||
.Dv EL_ALIAS_TEXT
|
||||
as the first argument and the character read, with an underscore
|
||||
prepended, as the second argument, and pass the string returned
|
||||
from the alias function to
|
||||
.Xr el_wpush 3 .
|
||||
It is an error if no alias function is defined or if trying to read
|
||||
the character results in end of file or an error.
|
||||
.It Ic vi-change-case Pq vi command: ~
|
||||
Change the case of the character at the cursor and move the cursor
|
||||
one character position to the right.
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer.
|
||||
.It Ic vi-change-meta Pq vi command: c
|
||||
Delete the string from the cursor to the position specified by the
|
||||
following movement command and save a copy of it to the cut buffer.
|
||||
When given twice in a row, instead delete the whole contents of the
|
||||
edit buffer and save a copy of it to the cut buffer.
|
||||
In either case, switch to vi insert mode after that.
|
||||
.It Ic vi-change-to-eol Pq vi command: C
|
||||
Delete the string from the cursor position to the end of the line
|
||||
and save it to the cut buffer, then switch to vi insert mode.
|
||||
.It Ic vi-command-mode Pq vi insert: Ctrl-[, ESC
|
||||
Discard pending actions and arguments and switch to vi command mode.
|
||||
Unless the cursor is already at the beginning of the edit buffer,
|
||||
move it to the left by one character position.
|
||||
.It Ic vi-comment-out Pq vi command: #
|
||||
Insert a
|
||||
.Sq #
|
||||
character at the beginning of the edit buffer and return the edit
|
||||
buffer to the program.
|
||||
.It Ic vi-delete-meta Pq vi command: d
|
||||
Delete the string from the cursor to the position specified by the
|
||||
following movement command and save a copy of it to the cut buffer.
|
||||
When given twice in a row, instead delete the whole contents of the
|
||||
edit buffer and save a copy of it to the cut buffer.
|
||||
.It Ic vi-delete-prev-char Pq vi insert: Ctrl-H, BS, Ctrl-?, DEL
|
||||
Delete the character to the left of the cursor.
|
||||
It is an error if the cursor is already at the beginning of the
|
||||
edit buffer.
|
||||
.It Ic vi-end-big-word Pq vi command: E
|
||||
Move the cursor to the end of the current space delimited word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer.
|
||||
.It Ic vi-end-word Pq vi command: e
|
||||
Move the cursor to the end of the current word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer.
|
||||
.It Ic vi-history-word Pq vi command: _
|
||||
Insert the first word from the most recent history entry after the
|
||||
cursor, move the cursor after to the character after the inserted
|
||||
word, and switch to vi insert mode.
|
||||
It is an error if there is no history entry or the most recent
|
||||
history entry is empty.
|
||||
.It Ic vi-insert Pq vi command: i
|
||||
Enter insert mode.
|
||||
.It Ic vi-insert-at-bol Pq vi command: I
|
||||
Move the cursor to the beginning of the edit buffer and switch to
|
||||
vi insert mode.
|
||||
.It Ic vi-kill-line-prev Pq vi: Ctrl-U
|
||||
Delete the string from the beginning of the edit buffer to the
|
||||
cursor and save it to the cut buffer.
|
||||
.It Ic vi-list-or-eof Pq vi insert: Ctrl-D, EOF
|
||||
If the edit buffer is empty, indicate end of file to the program.
|
||||
It is an error if the edit buffer is not empty.
|
||||
.It Ic vi-match Pq vi command: %
|
||||
Consider opening and closing parentheses, braces, and brackets as
|
||||
delimiters.
|
||||
If the cursor is not at a delimiter, move it to the right until it
|
||||
gets to one, then move it to the matching delimiter.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if there is no delimiter at the cursor or in the
|
||||
string to the right of the cursor, or if the first such delimiter
|
||||
has no matching delimiter.
|
||||
.It Ic vi-next-big-word Pq vi command: W
|
||||
Move the cursor to the right to the beginning of the next space
|
||||
delimited word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer or on its last character.
|
||||
.It Ic vi-next-char Pq vi command: f
|
||||
Read one character from the terminal bypassing the normal line
|
||||
editing functionality and move the cursor to the right to the next
|
||||
instance of that character in the edit buffer.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
If trying to read the character results in end of file or an error,
|
||||
call
|
||||
.Ic ed-end-of-file
|
||||
instead.
|
||||
It is an error if the character is not found searching to the right
|
||||
in the edit buffer.
|
||||
.It Ic vi-next-word Pq vi command: w
|
||||
Move the cursor to the right to the beginning of the next word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the end of the edit
|
||||
buffer or on its last character.
|
||||
.It Ic vi-paste-next Pq vi command: p
|
||||
Insert a copy of the cut buffer to the right of the cursor.
|
||||
It is an error if the cut buffer is empty.
|
||||
.It Ic vi-paste-prev Pq vi command: P
|
||||
Insert a copy of the cut buffer to the left of the cursor.
|
||||
It is an error if the cut buffer is empty.
|
||||
.It Ic vi-prev-big-word Pq vi command: B
|
||||
Move the cursor to the left to the next beginning of a space delimited
|
||||
word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the beginning of the
|
||||
edit buffer.
|
||||
.It Ic vi-prev-char Pq vi command: F
|
||||
Read one character from the terminal bypassing the normal line
|
||||
editing functionality and move the cursor to the left to the next
|
||||
instance of that character in the edit buffer.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
If trying to read the character results in end of file or an error,
|
||||
call
|
||||
.Ic ed-end-of-file
|
||||
instead.
|
||||
It is an error if the character is not found searching to the left
|
||||
in the edit buffer.
|
||||
.It Ic vi-prev-word Pq vi command: b
|
||||
Move the cursor to the left to the next beginning of a word.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
It is an error if the cursor is already at the beginning of the
|
||||
edit buffer.
|
||||
.It Ic vi-redo Pq vi command: Sq \&.
|
||||
Redo the last non-motion command.
|
||||
.It Ic vi-repeat-next-char Pq vi command: Sq \&;
|
||||
Repeat the most recent character search in the same search direction.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.It Ic vi-repeat-prev-char Pq vi command: Sq \&,
|
||||
Repeat the most recent character search in the opposite search
|
||||
direction.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.It Ic vi-repeat-search-next Pq vi command: n
|
||||
Repeat the most recent history search in the same search direction.
|
||||
.It Ic vi-repeat-search-prev Pq vi command: N
|
||||
Repeat the most recent history search in the opposite search
|
||||
direction.
|
||||
.It Ic vi-replace-char Pq vi command: r
|
||||
Switch to vi replace mode, and automatically switch back to vi
|
||||
command mode after the next character typed.
|
||||
See
|
||||
.Ic ed-insert
|
||||
for a description of replace mode.
|
||||
It is an error if the cursor is at the end of the edit buffer.
|
||||
.It Ic vi-replace-mode Pq vi command: R
|
||||
Switch to vi replace mode.
|
||||
This is a variant of vi insert mode; see
|
||||
.Ic ed-insert
|
||||
for the difference.
|
||||
.It Ic vi-search-next Pq vi command: \&?
|
||||
Replace the edit buffer with the next matching history entry.
|
||||
.It Ic vi-search-prev Pq vi command: /
|
||||
Replace the edit buffer with the previous matching history entry.
|
||||
.It Ic vi-substitute-char Pq vi command: s
|
||||
Delete the character at the cursor and switch to vi insert mode.
|
||||
.It Ic vi-substitute-line Pq vi command: S
|
||||
Delete the entire contents of the edit buffer, save a copy of it
|
||||
in the cut buffer, and enter vi insert mode.
|
||||
.It Ic vi-to-column Pq vi command: \&|
|
||||
Move the cursor to the column specified as the argument.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.It Ic vi-to-history-line Pq vi command: G
|
||||
Replace the edit buffer with the specified history entry.
|
||||
.It Ic vi-to-next-char Pq vi command: t
|
||||
Read one character from the terminal bypassing the normal line
|
||||
editing functionality and move the cursor to the right to the
|
||||
character before the next instance of that character in the edit
|
||||
buffer.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
If trying to read the character results in end of file or an error,
|
||||
call
|
||||
.Ic ed-end-of-file
|
||||
instead.
|
||||
It is an error if the character is not found searching to the right
|
||||
in the edit buffer.
|
||||
.It Ic vi-to-prev-char Pq vi command: T
|
||||
Read one character from the terminal bypassing the normal line
|
||||
editing functionality and move the cursor to the left to the character
|
||||
after the next instance of that character in the edit buffer.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
If trying to read the character results in end of file or an error,
|
||||
call
|
||||
.Ic ed-end-of-file
|
||||
instead.
|
||||
It is an error if the character is not found searching to the left
|
||||
in the edit buffer.
|
||||
.It Ic vi-undo Pq vi command: u
|
||||
Undo the last change.
|
||||
.It Ic vi-undo-line Pq vi command: U
|
||||
Undo all changes to the edit buffer.
|
||||
.It Ic vi-yank Pq vi command: y
|
||||
Copy the string from the cursor to the position specified by the
|
||||
following movement command to the cut buffer.
|
||||
When given twice in a row, instead copy the whole contents of the
|
||||
edit buffer to the cut buffer.
|
||||
.It Ic vi-yank-end Pq vi command: Y
|
||||
Copy the string from the cursor to the end of the edit buffer to
|
||||
the cut buffer.
|
||||
.It Ic vi-zero Pq vi command: 0
|
||||
If in argument input mode, multiply the argument by ten.
|
||||
Otherwise, move the cursor to the beginning of the edit buffer.
|
||||
Can be used as a movement command after
|
||||
.Ic vi_change_meta ,
|
||||
.Ic vi_delete_meta ,
|
||||
or
|
||||
.Ic vi_yank .
|
||||
.El
|
||||
.Ss Macros
|
||||
If an input character is bound to the editor command
|
||||
.Ic ed-sequence-lead-in ,
|
||||
.Nm
|
||||
attempts to call a macro.
|
||||
If the input character by itself forms the name of a macro, that
|
||||
macro is executed.
|
||||
Otherwise, additional input characters are read until the string
|
||||
read forms the name of a macro, in which case that macro is executed,
|
||||
or until the string read matches the beginning of none of the existing
|
||||
macro names, in which case the string including the final, mismatching
|
||||
character is discarded and the terminal bell is rung.
|
||||
.Pp
|
||||
There are two kinds of macros.
|
||||
Command macros execute a single editor command.
|
||||
Keyboard macros return a string of characters that is appended
|
||||
as a new line to the
|
||||
.Sx Input Queue .
|
||||
.Pp
|
||||
The following command macros are defined by default in vi command
|
||||
mode and in emacs mode:
|
||||
.Bl -column -offset indent "Esc O A, Esc O A" "em-exchange-mark"
|
||||
.It Esc \&[ A, Esc O A Ta Ic ed-prev-history
|
||||
.It Esc \&[ B, Esc O B Ta Ic ed-next-history
|
||||
.It Esc \&[ C, Esc O C Ta Ic ed-next-char
|
||||
.It Esc \&[ D, Esc O D Ta Ic ed-prev-char
|
||||
.It Esc \&[ F, Esc O F Ta Ic ed-move-to-end
|
||||
.It Esc \&[ H, Esc O H Ta Ic ed-move-to-beg
|
||||
.El
|
||||
.Pp
|
||||
In vi command mode, they are also defined by default without the
|
||||
initial escape character.
|
||||
.Pp
|
||||
In addition, the
|
||||
.Nm
|
||||
library tries to bind the strings generated by the arrow keys
|
||||
as reported by the
|
||||
.Xr terminfo 5
|
||||
database to these editor commands, unless that would clobber
|
||||
user settings.
|
||||
.Pp
|
||||
In emacs mode, the two-character string
|
||||
.Dq Ctrl-X Ctrl-X
|
||||
is bound to the
|
||||
.Ic em-exchange-mark
|
||||
editor command.
|
||||
.Ss Input Queue
|
||||
The
|
||||
.Nm
|
||||
library maintains an input queue operated in FIFO mode.
|
||||
Whenever it needs an input character, it takes the first character
|
||||
from the first line of the input queue.
|
||||
When the queue is empty, it reads from the terminal.
|
||||
.Pp
|
||||
A line can be appended to the end of the input queue in several ways:
|
||||
.Bl -dash -offset indent
|
||||
.It
|
||||
By calling one of the keyboard
|
||||
.Sx Macros .
|
||||
.It
|
||||
By calling the editor command
|
||||
.Ic vi-redo .
|
||||
.It
|
||||
By calling the editor command
|
||||
.Ic vi-alias .
|
||||
.It
|
||||
By pressing a key in emacs incremental search mode that doesn't
|
||||
have a special meaning in that mode but returns to normal emacs
|
||||
mode.
|
||||
.It
|
||||
If an application program directly calls the functions
|
||||
.Xr el_push 3
|
||||
or
|
||||
.Xr el_wpush 3 ,
|
||||
it can provide additional, program-specific ways
|
||||
of appending to the input queue.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mg 1 ,
|
||||
.Xr vi 1 ,
|
||||
.Xr editline 3 ,
|
||||
.Xr el_wgets 3 ,
|
||||
.Xr el_wpush 3 ,
|
||||
.Xr el_wset 3 ,
|
||||
.Xr editrc 5
|
||||
.Sh HISTORY
|
||||
This manual page first appeared in
|
||||
.Ox 6.0
|
||||
and
|
||||
.Nx 8 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
This manual page was written by
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
325
contrib/libedit/editrc.5
Normal file
325
contrib/libedit/editrc.5
Normal file
@ -0,0 +1,325 @@
|
||||
.\" $NetBSD: editrc.5,v 1.33 2017/06/27 01:22:58 kre Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
|
||||
.\"
|
||||
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
.\"
|
||||
.Dd May 22, 2016
|
||||
.Dt EDITRC 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm editrc
|
||||
.Nd configuration file for editline library
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
file defines various settings to be used by the
|
||||
.Xr editline 3
|
||||
library.
|
||||
.Pp
|
||||
The format of each line is:
|
||||
.Pp
|
||||
.Dl [prog:]command [arg ...]
|
||||
.Pp
|
||||
.Ar command
|
||||
is one of the
|
||||
.Xr editline 3
|
||||
builtin commands.
|
||||
Refer to
|
||||
.Sx BUILTIN COMMANDS
|
||||
for more information.
|
||||
.Pp
|
||||
.Ar prog
|
||||
is the program name string that a program defines when it calls
|
||||
.Xr el_init 3
|
||||
to set up
|
||||
.Xr editline 3 ,
|
||||
which is usually
|
||||
.Va argv[0] .
|
||||
.Ar command
|
||||
will be executed for any program which matches
|
||||
.Ar prog .
|
||||
.Pp
|
||||
.Ar prog
|
||||
may also be a
|
||||
.Xr regex 3
|
||||
style
|
||||
regular expression, in which case
|
||||
.Ar command
|
||||
will be executed for any program that matches the regular expression.
|
||||
.Pp
|
||||
If
|
||||
.Ar prog
|
||||
is absent,
|
||||
.Ar command
|
||||
is executed for all programs.
|
||||
.Sh BUILTIN COMMANDS
|
||||
The
|
||||
.Nm editline
|
||||
library has some builtin commands, which affect the way
|
||||
that the line editing and history functions operate.
|
||||
These are based on similar named builtins present in the
|
||||
.Xr tcsh 1
|
||||
shell.
|
||||
.Pp
|
||||
The following builtin commands are available:
|
||||
.Bl -tag -width 4n
|
||||
.It Ic bind Oo Fl aeklrsv Oc Op Ar key Op Ar command
|
||||
Without options and arguments, list all bound keys and macros, and
|
||||
the editor command or input string to which each one is bound.
|
||||
If only
|
||||
.Ar key
|
||||
is supplied, show the binding for that key or macro.
|
||||
If
|
||||
.Ar key command
|
||||
is supplied, bind the editor
|
||||
.Ar command
|
||||
to that key or macro.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It Fl a
|
||||
List or change key bindings in the
|
||||
.Xr vi 1
|
||||
mode alternate (command mode) key map.
|
||||
.It Fl e
|
||||
Bind all keys to the standard GNU Emacs-like bindings.
|
||||
.It Fl k
|
||||
.Ar key
|
||||
is interpreted as a symbolic arrow key name, which may be one of
|
||||
.Sq up ,
|
||||
.Sq down ,
|
||||
.Sq left
|
||||
or
|
||||
.Sq right .
|
||||
.It Fl l
|
||||
List all editor commands and a short description of each.
|
||||
.It Fl r
|
||||
Remove the binding of the key or macro
|
||||
.Ar key .
|
||||
.It Fl s
|
||||
Define a keyboard macro rather than a key binding or command macro:
|
||||
.Ar command
|
||||
is taken as a literal string and appended to the input queue whenever
|
||||
.Ar key
|
||||
is typed.
|
||||
Bound keys and macros in
|
||||
.Ar command
|
||||
are themselves reinterpreted, and this continues for ten levels of
|
||||
interpretation.
|
||||
.It Fl v
|
||||
Bind all keys to the standard
|
||||
.Xr vi 1 Ns -like
|
||||
bindings.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Xr editline 7
|
||||
manual documents all editor commands and contains more information
|
||||
about macros and the input queue.
|
||||
.Pp
|
||||
.Ar key
|
||||
and
|
||||
.Ar command
|
||||
can contain control characters of the form
|
||||
.Sm off
|
||||
.Sq No ^ Ar character
|
||||
.Sm on
|
||||
.Po
|
||||
e.g.\&
|
||||
.Sq ^A
|
||||
.Pc ,
|
||||
and the following backslashed escape sequences:
|
||||
.Pp
|
||||
.Bl -tag -compact -offset indent -width 4n
|
||||
.It Ic \ea
|
||||
Bell
|
||||
.It Ic \eb
|
||||
Backspace
|
||||
.It Ic \ee
|
||||
Escape
|
||||
.It Ic \ef
|
||||
Formfeed
|
||||
.It Ic \en
|
||||
Newline
|
||||
.It Ic \er
|
||||
Carriage return
|
||||
.It Ic \et
|
||||
Horizontal tab
|
||||
.It Ic \ev
|
||||
Vertical tab
|
||||
.Sm off
|
||||
.It Sy \e Ar nnn
|
||||
.Sm on
|
||||
The ASCII character corresponding to the octal number
|
||||
.Ar nnn .
|
||||
.El
|
||||
.Pp
|
||||
.Sq \e
|
||||
nullifies the special meaning of the following character,
|
||||
if it has any, notably
|
||||
.Sq \e
|
||||
and
|
||||
.Sq ^ .
|
||||
.It Ic echotc Oo Fl sv Oc Ar arg Ar ...
|
||||
Exercise terminal capabilities given in
|
||||
.Ar arg ... .
|
||||
If
|
||||
.Ar arg
|
||||
is
|
||||
.Sq baud ,
|
||||
.Sq cols ,
|
||||
.Sq lines ,
|
||||
.Sq rows ,
|
||||
.Sq meta ,
|
||||
or
|
||||
.Sq tabs ,
|
||||
the value of that capability is printed, with
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no
|
||||
indicating that the terminal does or does not have that capability.
|
||||
.Pp
|
||||
.Fl s
|
||||
returns an empty string for non-existent capabilities, rather than
|
||||
causing an error.
|
||||
.Fl v
|
||||
causes messages to be verbose.
|
||||
.It Ic edit Op Li on | Li off
|
||||
Enable or disable the
|
||||
.Nm editline
|
||||
functionality in a program.
|
||||
.It Ic history Ar list | Ar size Dv n | Ar unique Dv n
|
||||
The
|
||||
.Ar list
|
||||
command lists all entries in the history.
|
||||
The
|
||||
.Ar size
|
||||
command sets the history size to
|
||||
.Dv n
|
||||
entries.
|
||||
The
|
||||
.Ar unique
|
||||
command controls if history should keep duplicate entries.
|
||||
If
|
||||
.Dv n
|
||||
is non zero, only keep unique history entries.
|
||||
If
|
||||
.Dv n
|
||||
is zero, then keep all entries (the default).
|
||||
.It Ic settc Ar cap Ar val
|
||||
Set the terminal capability
|
||||
.Ar cap
|
||||
to
|
||||
.Ar val ,
|
||||
as defined in
|
||||
.Xr termcap 5 .
|
||||
No sanity checking is done.
|
||||
.It Ic setty Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
|
||||
Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
|
||||
Control which tty modes that
|
||||
.Nm
|
||||
won't allow the user to change.
|
||||
.Fl d ,
|
||||
.Fl q
|
||||
or
|
||||
.Fl x
|
||||
tells
|
||||
.Ic setty
|
||||
to act on the
|
||||
.Sq edit ,
|
||||
.Sq quote
|
||||
or
|
||||
.Sq execute
|
||||
set of tty modes respectively; defaulting to
|
||||
.Fl x .
|
||||
.Pp
|
||||
Without other arguments,
|
||||
.Ic setty
|
||||
lists the modes in the chosen set which are fixed on
|
||||
.Po
|
||||
.Sq +mode
|
||||
.Pc
|
||||
or off
|
||||
.Po
|
||||
.Sq -mode
|
||||
.Pc .
|
||||
.Fl a
|
||||
lists all tty modes in the chosen set regardless of the setting.
|
||||
With
|
||||
.Ar +mode ,
|
||||
.Ar -mode
|
||||
or
|
||||
.Ar mode ,
|
||||
fixes
|
||||
.Ar mode
|
||||
on or off or removes control of
|
||||
.Ar mode
|
||||
in the chosen set.
|
||||
.Pp
|
||||
.Ic Setty
|
||||
can also be used to set tty characters to particular values using
|
||||
.Ar char=value .
|
||||
If
|
||||
.Ar value
|
||||
is empty
|
||||
then the character is set to
|
||||
.Dv _POSIX_VDISABLE .
|
||||
.It Ic telltc
|
||||
List the values of all the terminal capabilities (see
|
||||
.Xr termcap 5 ) .
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width "~/.editrcXXX"
|
||||
.It Ev EDITRC
|
||||
Names the default configuration file for the
|
||||
.Xr editline 3
|
||||
library.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "~/.editrcXXX"
|
||||
.It Pa ~/.editrc
|
||||
Last resort, if no other file is specified,
|
||||
user configuration file for the
|
||||
.Xr editline 3
|
||||
library.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr editline 3 ,
|
||||
.Xr regex 3 ,
|
||||
.Xr termcap 5 ,
|
||||
.Xr editline 7
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm editline
|
||||
library was written by
|
||||
.An Christos Zoulas ,
|
||||
and this manual was written by
|
||||
.An Luke Mewburn ,
|
||||
with some sections inspired by
|
||||
.Xr tcsh 1 .
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: el.c,v 1.83 2016/02/24 17:13:22 christos Exp $ */
|
||||
/* $NetBSD: el.c,v 1.99 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: el.c,v 1.83 2016/02/24 17:13:22 christos Exp $");
|
||||
__RCSID("$NetBSD: el.c,v 1.99 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* el.c: EditLine interface functions
|
||||
@ -49,38 +47,35 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef WIDECHAR
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
#include "el.h"
|
||||
#include "parse.h"
|
||||
#include "read.h"
|
||||
|
||||
/* el_init():
|
||||
* Initialize editline and set default parameters.
|
||||
*/
|
||||
public EditLine *
|
||||
EditLine *
|
||||
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
|
||||
{
|
||||
return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
|
||||
fileno(ferr));
|
||||
}
|
||||
|
||||
public EditLine *
|
||||
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
|
||||
int fdin, int fdout, int fderr)
|
||||
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;
|
||||
@ -89,7 +84,7 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
|
||||
el->el_outfd = fdout;
|
||||
el->el_errfd = fderr;
|
||||
|
||||
el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
|
||||
el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
|
||||
if (el->el_prog == NULL) {
|
||||
el_free(el);
|
||||
return NULL;
|
||||
@ -98,7 +93,7 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
|
||||
/*
|
||||
* Initialize all the modules. Order is important!!!
|
||||
*/
|
||||
el->el_flags = 0;
|
||||
el->el_flags = flags;
|
||||
|
||||
if (terminal_init(el) == -1) {
|
||||
el_free(el->el_prog);
|
||||
@ -114,16 +109,25 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
|
||||
(void) hist_init(el);
|
||||
(void) prompt_init(el);
|
||||
(void) sig_init(el);
|
||||
(void) read_init(el);
|
||||
|
||||
(void) literal_init(el);
|
||||
if (read_init(el) == -1) {
|
||||
el_end(el);
|
||||
return NULL;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
EditLine *
|
||||
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
|
||||
int fdin, int fdout, int fderr)
|
||||
{
|
||||
return el_init_internal(prog, fin, fout, ferr, fdin, fdout, fderr, 0);
|
||||
}
|
||||
|
||||
/* el_end():
|
||||
* Clean up.
|
||||
*/
|
||||
public void
|
||||
void
|
||||
el_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -136,20 +140,22 @@ 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);
|
||||
hist_end(el);
|
||||
prompt_end(el);
|
||||
sig_end(el);
|
||||
literal_end(el);
|
||||
|
||||
el_free(el->el_prog);
|
||||
#ifdef WIDECHAR
|
||||
el_free(el->el_visual.cbuff);
|
||||
el_free(el->el_visual.wbuff);
|
||||
el_free(el->el_scratch.cbuff);
|
||||
el_free(el->el_scratch.wbuff);
|
||||
el_free(el->el_lgcyconv.cbuff);
|
||||
el_free(el->el_lgcyconv.wbuff);
|
||||
#endif
|
||||
el_free(el);
|
||||
}
|
||||
|
||||
@ -157,20 +163,20 @@ el_end(EditLine *el)
|
||||
/* el_reset():
|
||||
* Reset the tty and the parser
|
||||
*/
|
||||
public void
|
||||
void
|
||||
el_reset(EditLine *el)
|
||||
{
|
||||
|
||||
tty_cookedmode(el);
|
||||
ch_reset(el, 0); /* XXX: Do we want that? */
|
||||
ch_reset(el); /* XXX: Do we want that? */
|
||||
}
|
||||
|
||||
|
||||
/* el_set():
|
||||
* set the editline parameters
|
||||
*/
|
||||
public int
|
||||
FUN(el,set)(EditLine *el, int op, ...)
|
||||
int
|
||||
el_wset(EditLine *el, int op, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rv = 0;
|
||||
@ -207,7 +213,7 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
el_pfunc_t p = va_arg(ap, el_pfunc_t);
|
||||
int c = va_arg(ap, int);
|
||||
|
||||
rv = prompt_set(el, p, (Char)c, op, 1);
|
||||
rv = prompt_set(el, p, (wchar_t)c, op, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -216,7 +222,7 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
break;
|
||||
|
||||
case EL_EDITOR:
|
||||
rv = map_set_editor(el, va_arg(ap, Char *));
|
||||
rv = map_set_editor(el, va_arg(ap, wchar_t *));
|
||||
break;
|
||||
|
||||
case EL_SIGNAL:
|
||||
@ -232,36 +238,36 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
case EL_ECHOTC:
|
||||
case EL_SETTY:
|
||||
{
|
||||
const Char *argv[20];
|
||||
const wchar_t *argv[20];
|
||||
int i;
|
||||
|
||||
for (i = 1; i < (int)__arraycount(argv); i++)
|
||||
if ((argv[i] = va_arg(ap, Char *)) == NULL)
|
||||
if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)
|
||||
break;
|
||||
|
||||
switch (op) {
|
||||
case EL_BIND:
|
||||
argv[0] = STR("bind");
|
||||
argv[0] = L"bind";
|
||||
rv = map_bind(el, i, argv);
|
||||
break;
|
||||
|
||||
case EL_TELLTC:
|
||||
argv[0] = STR("telltc");
|
||||
argv[0] = L"telltc";
|
||||
rv = terminal_telltc(el, i, argv);
|
||||
break;
|
||||
|
||||
case EL_SETTC:
|
||||
argv[0] = STR("settc");
|
||||
argv[0] = L"settc";
|
||||
rv = terminal_settc(el, i, argv);
|
||||
break;
|
||||
|
||||
case EL_ECHOTC:
|
||||
argv[0] = STR("echotc");
|
||||
argv[0] = L"echotc";
|
||||
rv = terminal_echotc(el, i, argv);
|
||||
break;
|
||||
|
||||
case EL_SETTY:
|
||||
argv[0] = STR("setty");
|
||||
argv[0] = L"setty";
|
||||
rv = tty_stty(el, i, argv);
|
||||
break;
|
||||
|
||||
@ -275,8 +281,8 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
|
||||
case EL_ADDFN:
|
||||
{
|
||||
Char *name = va_arg(ap, Char *);
|
||||
Char *help = va_arg(ap, Char *);
|
||||
wchar_t *name = va_arg(ap, wchar_t *);
|
||||
wchar_t *help = va_arg(ap, wchar_t *);
|
||||
el_func_t func = va_arg(ap, el_func_t);
|
||||
|
||||
rv = map_addfunc(el, name, help, func);
|
||||
@ -305,7 +311,7 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
case EL_GETCFN:
|
||||
{
|
||||
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
|
||||
rv = el_read_setfn(el, rc);
|
||||
rv = el_read_setfn(el->el_read, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -382,8 +388,8 @@ FUN(el,set)(EditLine *el, int op, ...)
|
||||
/* el_get():
|
||||
* retrieve the editline parameters
|
||||
*/
|
||||
public int
|
||||
FUN(el,get)(EditLine *el, int op, ...)
|
||||
int
|
||||
el_wget(EditLine *el, int op, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rv;
|
||||
@ -403,14 +409,14 @@ FUN(el,get)(EditLine *el, int op, ...)
|
||||
case EL_PROMPT_ESC:
|
||||
case EL_RPROMPT_ESC: {
|
||||
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
|
||||
Char *c = va_arg(ap, Char *);
|
||||
wchar_t *c = va_arg(ap, wchar_t *);
|
||||
|
||||
rv = prompt_get(el, p, c, op);
|
||||
break;
|
||||
}
|
||||
|
||||
case EL_EDITOR:
|
||||
rv = map_get_editor(el, va_arg(ap, const Char **));
|
||||
rv = map_get_editor(el, va_arg(ap, const wchar_t **));
|
||||
break;
|
||||
|
||||
case EL_SIGNAL:
|
||||
@ -431,20 +437,16 @@ FUN(el,get)(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;
|
||||
}
|
||||
|
||||
case EL_GETCFN:
|
||||
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
|
||||
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
|
||||
rv = 0;
|
||||
break;
|
||||
|
||||
@ -495,18 +497,18 @@ FUN(el,get)(EditLine *el, int op, ...)
|
||||
/* el_line():
|
||||
* Return editing info
|
||||
*/
|
||||
public const TYPE(LineInfo) *
|
||||
FUN(el,line)(EditLine *el)
|
||||
const LineInfoW *
|
||||
el_wline(EditLine *el)
|
||||
{
|
||||
|
||||
return (const TYPE(LineInfo) *)(void *)&el->el_line;
|
||||
return (const LineInfoW *)(void *)&el->el_line;
|
||||
}
|
||||
|
||||
|
||||
/* el_source():
|
||||
* Source a file
|
||||
*/
|
||||
public int
|
||||
int
|
||||
el_source(EditLine *el, const char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
@ -514,24 +516,28 @@ el_source(EditLine *el, const char *fname)
|
||||
ssize_t slen;
|
||||
char *ptr;
|
||||
char *path = NULL;
|
||||
const Char *dptr;
|
||||
const wchar_t *dptr;
|
||||
int error = 0;
|
||||
|
||||
fp = NULL;
|
||||
if (fname == NULL) {
|
||||
#ifdef HAVE_ISSETUGID
|
||||
static const char elpath[] = "/.editrc";
|
||||
size_t plen = sizeof(elpath);
|
||||
|
||||
if (issetugid())
|
||||
return -1;
|
||||
if ((ptr = getenv("HOME")) == NULL)
|
||||
return -1;
|
||||
plen += strlen(ptr);
|
||||
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
|
||||
return -1;
|
||||
(void)snprintf(path, plen, "%s%s", ptr, elpath);
|
||||
fname = path;
|
||||
|
||||
if ((fname = getenv("EDITRC")) == NULL) {
|
||||
static const char elpath[] = "/.editrc";
|
||||
size_t plen = sizeof(elpath);
|
||||
|
||||
if ((ptr = getenv("HOME")) == NULL)
|
||||
return -1;
|
||||
plen += strlen(ptr);
|
||||
if ((path = el_calloc(plen, sizeof(*path))) == NULL)
|
||||
return -1;
|
||||
(void)snprintf(path, plen, "%s%s", ptr,
|
||||
elpath + (*ptr == '\0'));
|
||||
fname = path;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* If issetugid() is missing, always return an error, in order
|
||||
@ -541,6 +547,9 @@ el_source(EditLine *el, const char *fname)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
if (fname[0] == '\0')
|
||||
return -1;
|
||||
|
||||
if (fp == NULL)
|
||||
fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
@ -560,7 +569,7 @@ el_source(EditLine *el, const char *fname)
|
||||
if (!dptr)
|
||||
continue;
|
||||
/* loop until first non-space char or EOL */
|
||||
while (*dptr != '\0' && Isspace(*dptr))
|
||||
while (*dptr != '\0' && iswspace(*dptr))
|
||||
dptr++;
|
||||
if (*dptr == '#')
|
||||
continue; /* ignore, this is a comment line */
|
||||
@ -578,7 +587,7 @@ el_source(EditLine *el, const char *fname)
|
||||
/* el_resize():
|
||||
* Called from program when terminal is resized
|
||||
*/
|
||||
public void
|
||||
void
|
||||
el_resize(EditLine *el)
|
||||
{
|
||||
int lins, cols;
|
||||
@ -599,7 +608,7 @@ el_resize(EditLine *el)
|
||||
/* el_beep():
|
||||
* Called from the program to beep
|
||||
*/
|
||||
public void
|
||||
void
|
||||
el_beep(EditLine *el)
|
||||
{
|
||||
|
||||
@ -610,25 +619,25 @@ el_beep(EditLine *el)
|
||||
/* el_editmode()
|
||||
* Set the state of EDIT_DISABLED from the `edit' command.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
el_editmode(EditLine *el, int argc, const Char **argv)
|
||||
el_editmode(EditLine *el, int argc, const wchar_t **argv)
|
||||
{
|
||||
const Char *how;
|
||||
const wchar_t *how;
|
||||
|
||||
if (argv == NULL || argc != 2 || argv[1] == NULL)
|
||||
return -1;
|
||||
|
||||
how = argv[1];
|
||||
if (Strcmp(how, STR("on")) == 0) {
|
||||
if (wcscmp(how, L"on") == 0) {
|
||||
el->el_flags &= ~EDIT_DISABLED;
|
||||
tty_rawmode(el);
|
||||
} else if (Strcmp(how, STR("off")) == 0) {
|
||||
} else if (wcscmp(how, L"off") == 0) {
|
||||
tty_cookedmode(el);
|
||||
el->el_flags |= EDIT_DISABLED;
|
||||
}
|
||||
else {
|
||||
(void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
|
||||
(void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
|
||||
how);
|
||||
return -1;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: el.h,v 1.34 2016/02/24 17:13:22 christos Exp $ */
|
||||
/* $NetBSD: el.h,v 1.45 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)el.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -57,6 +56,7 @@
|
||||
#define EDIT_DISABLED 0x04
|
||||
#define UNBUFFERED 0x08
|
||||
#define NARROW_HISTORY 0x40
|
||||
#define NO_RESET 0x80
|
||||
|
||||
typedef unsigned char el_action_t; /* Index to command array */
|
||||
|
||||
@ -66,10 +66,10 @@ typedef struct coord_t { /* Position on the screen */
|
||||
} coord_t;
|
||||
|
||||
typedef struct el_line_t {
|
||||
Char *buffer; /* Input line */
|
||||
Char *cursor; /* Cursor position */
|
||||
Char *lastchar; /* Last character */
|
||||
const Char *limit; /* Max position */
|
||||
wchar_t *buffer; /* Input line */
|
||||
wchar_t *cursor; /* Cursor position */
|
||||
wchar_t *lastchar; /* Last character */
|
||||
const wchar_t *limit; /* Max position */
|
||||
} el_line_t;
|
||||
|
||||
/*
|
||||
@ -82,31 +82,33 @@ typedef struct el_state_t {
|
||||
int metanext; /* Is the next char a meta char */
|
||||
el_action_t lastcmd; /* Previous command */
|
||||
el_action_t thiscmd; /* this command */
|
||||
Char thisch; /* char that generated it */
|
||||
wchar_t thisch; /* char that generated it */
|
||||
} 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)
|
||||
|
||||
#include "tty.h"
|
||||
#include "prompt.h"
|
||||
#include "literal.h"
|
||||
#include "keymacro.h"
|
||||
#include "terminal.h"
|
||||
#include "refresh.h"
|
||||
#include "chared.h"
|
||||
#include "search.h"
|
||||
#include "hist.h"
|
||||
#include "fcns.h" /* el_func_t is needed for map.h */
|
||||
#include "map.h"
|
||||
#include "sig.h"
|
||||
#include "read.h"
|
||||
|
||||
struct el_read_t;
|
||||
|
||||
struct editline {
|
||||
Char *el_prog; /* the program name */
|
||||
wchar_t *el_prog; /* the program name */
|
||||
FILE *el_infile; /* Stdio stuff */
|
||||
FILE *el_outfile; /* Stdio stuff */
|
||||
FILE *el_errfile; /* Stdio stuff */
|
||||
@ -114,10 +116,9 @@ struct editline {
|
||||
int el_outfd; /* Output file descriptor */
|
||||
int el_errfd; /* Error file descriptor */
|
||||
int el_flags; /* Various flags. */
|
||||
int el_errno; /* Local copy of errno */
|
||||
coord_t el_cursor; /* Cursor location */
|
||||
Char **el_display; /* Real screen image = what is there */
|
||||
Char **el_vdisplay; /* Virtual screen image = what we see */
|
||||
wint_t **el_display; /* Real screen image = what is there */
|
||||
wint_t **el_vdisplay; /* Virtual screen image = what we see */
|
||||
void *el_data; /* Client data */
|
||||
el_line_t el_line; /* The current line information */
|
||||
el_state_t el_state; /* Current editor state */
|
||||
@ -126,21 +127,23 @@ struct editline {
|
||||
el_refresh_t el_refresh; /* Refresh stuff */
|
||||
el_prompt_t el_prompt; /* Prompt stuff */
|
||||
el_prompt_t el_rprompt; /* Prompt stuff */
|
||||
el_literal_t el_literal; /* prompt literal bits */
|
||||
el_chared_t el_chared; /* Characted editor stuff */
|
||||
el_map_t el_map; /* Key mapping stuff */
|
||||
el_keymacro_t el_keymacro; /* Key binding stuff */
|
||||
el_history_t el_history; /* History stuff */
|
||||
el_search_t el_search; /* Search stuff */
|
||||
el_signal_t el_signal; /* Signal handling stuff */
|
||||
el_read_t el_read; /* Character reading stuff */
|
||||
#ifdef WIDECHAR
|
||||
struct el_read_t *el_read; /* Character reading stuff */
|
||||
ct_buffer_t el_visual; /* Buffer for displayable str */
|
||||
ct_buffer_t el_scratch; /* Scratch conversion buffer */
|
||||
ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */
|
||||
LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */
|
||||
#endif
|
||||
};
|
||||
|
||||
protected int el_editmode(EditLine *, int, const Char **);
|
||||
libedit_private int el_editmode(EditLine *, int, const wchar_t **);
|
||||
libedit_private EditLine *el_init_internal(const char *, FILE *, FILE *,
|
||||
FILE *, int, int, int, int);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define EL_ABORT(a) do { \
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $ */
|
||||
/* $NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
@ -27,10 +27,8 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $");
|
||||
__RCSID("$NetBSD: eln.c,v 1.35 2019/04/26 16:56:57 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
@ -39,7 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
|
||||
public int
|
||||
int
|
||||
el_getc(EditLine *el, char *cp)
|
||||
{
|
||||
int num_read;
|
||||
@ -49,7 +47,7 @@ el_getc(EditLine *el, char *cp)
|
||||
*cp = '\0';
|
||||
if (num_read <= 0)
|
||||
return num_read;
|
||||
num_read = ct_wctob(wc);
|
||||
num_read = wctob(wc);
|
||||
if (num_read == EOF) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
@ -60,8 +58,7 @@ el_getc(EditLine *el, char *cp)
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIDECHAR
|
||||
public void
|
||||
void
|
||||
el_push(EditLine *el, const char *str)
|
||||
{
|
||||
/* Using multibyte->wide string decoding works fine under single-byte
|
||||
@ -70,7 +67,7 @@ el_push(EditLine *el, const char *str)
|
||||
}
|
||||
|
||||
|
||||
public const char *
|
||||
const char *
|
||||
el_gets(EditLine *el, int *nread)
|
||||
{
|
||||
const wchar_t *tmp;
|
||||
@ -88,24 +85,23 @@ el_gets(EditLine *el, int *nread)
|
||||
}
|
||||
|
||||
|
||||
public int
|
||||
int
|
||||
el_parse(EditLine *el, int argc, const char *argv[])
|
||||
{
|
||||
int ret;
|
||||
const wchar_t **wargv;
|
||||
|
||||
wargv = (const wchar_t **)
|
||||
ct_decode_argv(argc, argv, &el->el_lgcyconv);
|
||||
wargv = (void *)ct_decode_argv(argc, argv, &el->el_lgcyconv);
|
||||
if (!wargv)
|
||||
return -1;
|
||||
ret = el_wparse(el, argc, wargv);
|
||||
ct_free_argv(wargv);
|
||||
el_free(wargv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public int
|
||||
int
|
||||
el_set(EditLine *el, int op, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -174,8 +170,7 @@ el_set(EditLine *el, int op, ...)
|
||||
if ((argv[i] = va_arg(ap, const char *)) == NULL)
|
||||
break;
|
||||
argv[0] = argv[i] = NULL;
|
||||
wargv = (const wchar_t **)
|
||||
ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
|
||||
wargv = (void *)ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
|
||||
if (!wargv) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
@ -187,29 +182,29 @@ el_set(EditLine *el, int op, ...)
|
||||
*/
|
||||
switch (op) {
|
||||
case EL_BIND:
|
||||
wargv[0] = STR("bind");
|
||||
wargv[0] = L"bind";
|
||||
ret = map_bind(el, i, wargv);
|
||||
break;
|
||||
case EL_TELLTC:
|
||||
wargv[0] = STR("telltc");
|
||||
wargv[0] = L"telltc";
|
||||
ret = terminal_telltc(el, i, wargv);
|
||||
break;
|
||||
case EL_SETTC:
|
||||
wargv[0] = STR("settc");
|
||||
wargv[0] = L"settc";
|
||||
ret = terminal_settc(el, i, wargv);
|
||||
break;
|
||||
case EL_ECHOTC:
|
||||
wargv[0] = STR("echotc");
|
||||
wargv[0] = L"echotc";
|
||||
ret = terminal_echotc(el, i, wargv);
|
||||
break;
|
||||
case EL_SETTY:
|
||||
wargv[0] = STR("setty");
|
||||
wargv[0] = L"setty";
|
||||
ret = tty_stty(el, i, wargv);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
ct_free_argv(wargv);
|
||||
el_free(wargv);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -229,9 +224,9 @@ el_set(EditLine *el, int op, ...)
|
||||
goto out;
|
||||
}
|
||||
/* XXX: The two strdup's leak */
|
||||
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
|
||||
ret = map_addfunc(el, wcsdup(wargv[0]), wcsdup(wargv[1]),
|
||||
func);
|
||||
ct_free_argv(wargv);
|
||||
el_free(wargv);
|
||||
break;
|
||||
}
|
||||
case EL_HIST: { /* hist_fun_t, const char * */
|
||||
@ -275,7 +270,7 @@ out:
|
||||
}
|
||||
|
||||
|
||||
public int
|
||||
int
|
||||
el_get(EditLine *el, int op, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -326,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;
|
||||
}
|
||||
|
||||
@ -368,7 +361,7 @@ el_line(EditLine *el)
|
||||
const LineInfoW *winfo = el_wline(el);
|
||||
LineInfo *info = &el->el_lgcylinfo;
|
||||
size_t offset;
|
||||
const Char *p;
|
||||
const wchar_t *p;
|
||||
|
||||
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
|
||||
|
||||
@ -391,4 +384,3 @@ el_insertstr(EditLine *el, const char *str)
|
||||
{
|
||||
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
|
||||
}
|
||||
#endif /* WIDECHAR */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $ */
|
||||
/* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $");
|
||||
__RCSID("$NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* emacs.c: Emacs functions
|
||||
@ -50,12 +48,13 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
#include "emacs.h"
|
||||
#include "fcns.h"
|
||||
|
||||
/* em_delete_or_list():
|
||||
* Delete character under cursor or list completions if at end of line
|
||||
* [^D]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_delete_or_list(EditLine *el, wint_t c)
|
||||
{
|
||||
@ -91,11 +90,11 @@ em_delete_or_list(EditLine *el, wint_t c)
|
||||
* Cut from cursor to end of current word
|
||||
* [M-d]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *p, *kp;
|
||||
wchar_t *cp, *p, *kp;
|
||||
|
||||
if (el->el_line.cursor == el->el_line.lastchar)
|
||||
return CC_ERROR;
|
||||
@ -120,11 +119,11 @@ em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Paste cut buffer at cursor position
|
||||
* [^Y]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
|
||||
return CC_NORM;
|
||||
@ -156,11 +155,11 @@ em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Cut the entire line and save in cut buffer
|
||||
* [^U]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
cp = el->el_line.buffer;
|
||||
kp = el->el_chared.c_kill.buf;
|
||||
@ -178,11 +177,11 @@ em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Cut area between mark and cursor and save in cut buffer
|
||||
* [^W]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
if (!el->el_chared.c_kill.mark)
|
||||
return CC_ERROR;
|
||||
@ -211,11 +210,11 @@ em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Copy area between mark and cursor to cut buffer
|
||||
* [M-W]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
if (!el->el_chared.c_kill.mark)
|
||||
return CC_ERROR;
|
||||
@ -241,7 +240,7 @@ em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Exchange the two characters before the cursor
|
||||
* Gosling emacs transpose chars [^T]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
em_gosmacs_transpose(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
@ -249,7 +248,7 @@ em_gosmacs_transpose(EditLine *el, wint_t c)
|
||||
/* must have at least two chars entered */
|
||||
c = el->el_line.cursor[-2];
|
||||
el->el_line.cursor[-2] = el->el_line.cursor[-1];
|
||||
el->el_line.cursor[-1] = (Char)c;
|
||||
el->el_line.cursor[-1] = c;
|
||||
return CC_REFRESH;
|
||||
} else
|
||||
return CC_ERROR;
|
||||
@ -260,7 +259,7 @@ em_gosmacs_transpose(EditLine *el, wint_t c)
|
||||
* Move next to end of current word
|
||||
* [M-f]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -285,18 +284,18 @@ em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Uppercase the characters from cursor to end of current word
|
||||
* [M-u]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *ep;
|
||||
wchar_t *cp, *ep;
|
||||
|
||||
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||
el->el_state.argument, ce__isword);
|
||||
|
||||
for (cp = el->el_line.cursor; cp < ep; cp++)
|
||||
if (Islower(*cp))
|
||||
*cp = Toupper(*cp);
|
||||
if (iswlower(*cp))
|
||||
*cp = towupper(*cp);
|
||||
|
||||
el->el_line.cursor = ep;
|
||||
if (el->el_line.cursor > el->el_line.lastchar)
|
||||
@ -309,26 +308,26 @@ em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Capitalize the characters from cursor to end of current word
|
||||
* [M-c]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *ep;
|
||||
wchar_t *cp, *ep;
|
||||
|
||||
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||
el->el_state.argument, ce__isword);
|
||||
|
||||
for (cp = el->el_line.cursor; cp < ep; cp++) {
|
||||
if (Isalpha(*cp)) {
|
||||
if (Islower(*cp))
|
||||
*cp = Toupper(*cp);
|
||||
if (iswalpha(*cp)) {
|
||||
if (iswlower(*cp))
|
||||
*cp = towupper(*cp);
|
||||
cp++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; cp < ep; cp++)
|
||||
if (Isupper(*cp))
|
||||
*cp = Tolower(*cp);
|
||||
if (iswupper(*cp))
|
||||
*cp = towlower(*cp);
|
||||
|
||||
el->el_line.cursor = ep;
|
||||
if (el->el_line.cursor > el->el_line.lastchar)
|
||||
@ -341,18 +340,18 @@ em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Lowercase the characters from cursor to end of current word
|
||||
* [M-l]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *ep;
|
||||
wchar_t *cp, *ep;
|
||||
|
||||
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||
el->el_state.argument, ce__isword);
|
||||
|
||||
for (cp = el->el_line.cursor; cp < ep; cp++)
|
||||
if (Isupper(*cp))
|
||||
*cp = Tolower(*cp);
|
||||
if (iswupper(*cp))
|
||||
*cp = towlower(*cp);
|
||||
|
||||
el->el_line.cursor = ep;
|
||||
if (el->el_line.cursor > el->el_line.lastchar)
|
||||
@ -365,7 +364,7 @@ em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Set the mark at cursor
|
||||
* [^@]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -379,11 +378,11 @@ em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Exchange the cursor and mark
|
||||
* [^X^X]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
cp = el->el_line.cursor;
|
||||
el->el_line.cursor = el->el_chared.c_kill.mark;
|
||||
@ -396,7 +395,7 @@ em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Universal argument (argument times 4)
|
||||
* [^U]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{ /* multiply current argument by 4 */
|
||||
@ -413,7 +412,7 @@ em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Add 8th bit to next character typed
|
||||
* [<ESC>]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -426,7 +425,7 @@ em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
/* em_toggle_overwrite():
|
||||
* Switch from insert to overwrite mode or vice versa
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -440,11 +439,11 @@ em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
/* em_copy_prev_word():
|
||||
* Copy current word to cursor
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *cp, *oldc, *dp;
|
||||
wchar_t *cp, *oldc, *dp;
|
||||
|
||||
if (el->el_line.cursor == el->el_line.buffer)
|
||||
return CC_ERROR;
|
||||
@ -467,7 +466,7 @@ em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
/* em_inc_search_next():
|
||||
* Emacs incremental next search
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -480,7 +479,7 @@ em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
/* em_inc_search_prev():
|
||||
* Emacs incremental reverse search
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -494,7 +493,7 @@ em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Delete the character to the left of the cursor
|
||||
* [^?]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: filecomplete.c,v 1.40 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -31,10 +31,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: filecomplete.c,v 1.40 2016/02/17 19:47:49 christos Exp $");
|
||||
__RCSID("$NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -51,11 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "el.h"
|
||||
#include "filecomplete.h"
|
||||
|
||||
static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
|
||||
'$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
|
||||
/* Tilde is deliberately omitted here, we treat it specially. */
|
||||
static const Char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\0' };
|
||||
|
||||
static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
|
||||
|
||||
/********************************/
|
||||
/* completion functions */
|
||||
@ -89,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);
|
||||
@ -124,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);
|
||||
@ -132,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
|
||||
@ -248,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);
|
||||
@ -324,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;
|
||||
@ -360,10 +540,13 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
|
||||
* num, so the strings are matches[1] *through* matches[num-1].
|
||||
*/
|
||||
void
|
||||
fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
|
||||
fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
|
||||
const char *(*app_func) (const char *))
|
||||
{
|
||||
size_t line, lines, col, cols, thisguy;
|
||||
int screenwidth = el->el_terminal.t_size.h;
|
||||
if (app_func == NULL)
|
||||
app_func = append_char_function;
|
||||
|
||||
/* Ignore matches[0]. Avoid 1-based array logic below. */
|
||||
matches++;
|
||||
@ -373,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;
|
||||
|
||||
@ -391,13 +574,70 @@ fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
|
||||
thisguy = line + col * lines;
|
||||
if (thisguy >= num)
|
||||
break;
|
||||
(void)fprintf(el->el_outfile, "%s%-*s",
|
||||
col == 0 ? "" : " ", (int)width, matches[thisguy]);
|
||||
(void)fprintf(el->el_outfile, "%s%s%s",
|
||||
col == 0 ? "" : " ", matches[thisguy],
|
||||
(*app_func)(matches[thisguy]));
|
||||
(void)fprintf(el->el_outfile, "%-*s",
|
||||
(int) (width - strlen(matches[thisguy])), "");
|
||||
}
|
||||
(void)fprintf(el->el_outfile, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
@ -414,18 +654,14 @@ int
|
||||
fn_complete(EditLine *el,
|
||||
char *(*complet_func)(const char *, int),
|
||||
char **(*attempted_completion_function)(const char *, int, int),
|
||||
const Char *word_break, const Char *special_prefixes,
|
||||
const wchar_t *word_break, const wchar_t *special_prefixes,
|
||||
const char *(*app_func)(const char *), size_t query_items,
|
||||
int *completion_type, int *over, int *point, int *end,
|
||||
const Char *(*find_word_start_func)(const Char *, const Char *),
|
||||
Char *(*dequoting_func)(const Char *),
|
||||
char *(*quoting_func)(const char *))
|
||||
int *completion_type, int *over, int *point, int *end)
|
||||
{
|
||||
const TYPE(LineInfo) *li;
|
||||
Char *temp;
|
||||
Char *dequoted_temp;
|
||||
char **matches;
|
||||
const Char *ctemp;
|
||||
const LineInfoW *li;
|
||||
wchar_t *temp;
|
||||
char **matches;
|
||||
char *completion;
|
||||
size_t len;
|
||||
int what_to_do = '\t';
|
||||
int retval = CC_NORM;
|
||||
@ -442,29 +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 = FUN(el,line)(el);
|
||||
if (find_word_start_func)
|
||||
ctemp = find_word_start_func(li->buffer, li->cursor);
|
||||
else {
|
||||
ctemp = li->cursor;
|
||||
while (ctemp > li->buffer
|
||||
&& !Strchr(word_break, ctemp[-1])
|
||||
&& (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
|
||||
ctemp--;
|
||||
}
|
||||
|
||||
len = (size_t)(li->cursor - ctemp);
|
||||
temp = el_malloc((len + 1) * sizeof(*temp));
|
||||
(void)Strncpy(temp, ctemp, len);
|
||||
temp[len] = '\0';
|
||||
|
||||
if (dequoting_func) {
|
||||
dequoted_temp = dequoting_func(temp);
|
||||
if (dequoted_temp == NULL)
|
||||
return retval;
|
||||
} else
|
||||
dequoted_temp = NULL;
|
||||
li = el_wline(el);
|
||||
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,16 +694,14 @@ fn_complete(EditLine *el,
|
||||
if (attempted_completion_function) {
|
||||
int cur_off = (int)(li->cursor - li->buffer);
|
||||
matches = (*attempted_completion_function)(
|
||||
ct_encode_string(dequoted_temp ? dequoted_temp : temp,
|
||||
&el->el_scratch),
|
||||
ct_encode_string(temp, &el->el_scratch),
|
||||
cur_off - (int)len, cur_off);
|
||||
} else
|
||||
matches = NULL;
|
||||
if (!attempted_completion_function ||
|
||||
(over != NULL && !*over && !matches))
|
||||
matches = completion_matches(
|
||||
ct_encode_string(dequoted_temp ? dequoted_temp : temp,
|
||||
&el->el_scratch), complet_func);
|
||||
ct_encode_string(temp, &el->el_scratch), complet_func);
|
||||
|
||||
if (over != NULL)
|
||||
*over = 0;
|
||||
@ -493,41 +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') {
|
||||
char *quoted_match;
|
||||
if (quoting_func) {
|
||||
quoted_match = quoting_func(matches[0]);
|
||||
if (quoted_match == NULL)
|
||||
goto free_matches;
|
||||
} else
|
||||
quoted_match = NULL;
|
||||
el_deletestr(el, (int) len);
|
||||
FUN(el,insertstr)(el,
|
||||
ct_decode_string(quoted_match ? quoted_match :
|
||||
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 (what_to_do == '?')
|
||||
goto display_matches;
|
||||
|
||||
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.
|
||||
*/
|
||||
FUN(el,insertstr)(el,
|
||||
ct_decode_string((*app_func)(matches[0]),
|
||||
&el->el_scratch));
|
||||
} else if (what_to_do == '!') {
|
||||
display_matches:
|
||||
if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
|
||||
/*
|
||||
* More than one match and requested to list possible
|
||||
* matches.
|
||||
@ -567,7 +783,7 @@ fn_complete(EditLine *el,
|
||||
* add 1 to matches_num for the call.
|
||||
*/
|
||||
fn_display_match_list(el, matches,
|
||||
matches_num+1, maxlen);
|
||||
matches_num+1, maxlen, app_func);
|
||||
}
|
||||
retval = CC_REDISPLAY;
|
||||
} else if (matches[0][0]) {
|
||||
@ -584,14 +800,14 @@ fn_complete(EditLine *el,
|
||||
retval = CC_NORM;
|
||||
}
|
||||
|
||||
free_matches:
|
||||
/* free elements of array and the array itself */
|
||||
for (i = 0; matches[i]; i++)
|
||||
el_free(matches[i]);
|
||||
el_free(matches);
|
||||
matches = NULL;
|
||||
}
|
||||
free(dequoted_temp);
|
||||
|
||||
out:
|
||||
el_free(temp);
|
||||
return retval;
|
||||
}
|
||||
@ -605,93 +821,15 @@ _el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
|
||||
{
|
||||
return (unsigned char)fn_complete(el, NULL, NULL,
|
||||
break_chars, NULL, NULL, (size_t)100,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static const Char *
|
||||
sh_find_word_start(const Char *buffer, const Char *cursor)
|
||||
{
|
||||
const Char *word_start = buffer;
|
||||
|
||||
while (buffer < cursor) {
|
||||
if (*buffer == '\\')
|
||||
buffer++;
|
||||
else if (Strchr(break_chars, *buffer))
|
||||
word_start = buffer + 1;
|
||||
buffer++;
|
||||
}
|
||||
return word_start;
|
||||
}
|
||||
|
||||
static char *
|
||||
sh_quote(const char *str)
|
||||
{
|
||||
const char *src;
|
||||
int extra_len = 0;
|
||||
char *quoted_str, *dst;
|
||||
|
||||
for (src = str; *src != '\0'; src++)
|
||||
if (Strchr(break_chars, *src) ||
|
||||
Strchr(extra_quote_chars, *src))
|
||||
extra_len++;
|
||||
|
||||
quoted_str = malloc(sizeof(*quoted_str) *
|
||||
(strlen(str) + extra_len + 1));
|
||||
if (quoted_str == NULL)
|
||||
return NULL;
|
||||
|
||||
dst = quoted_str;
|
||||
for (src = str; *src != '\0'; src++) {
|
||||
if (Strchr(break_chars, *src) ||
|
||||
Strchr(extra_quote_chars, *src))
|
||||
*dst++ = '\\';
|
||||
*dst++ = *src;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return quoted_str;
|
||||
}
|
||||
|
||||
static Char *
|
||||
sh_dequote(const Char *str)
|
||||
{
|
||||
Char *dequoted_str, *dst;
|
||||
|
||||
/* save extra space to replace \~ with ./~ */
|
||||
dequoted_str = malloc(sizeof(*dequoted_str) * (Strlen(str) + 1 + 1));
|
||||
if (dequoted_str == NULL)
|
||||
return NULL;
|
||||
|
||||
dst = dequoted_str;
|
||||
|
||||
/* dequote \~ at start as ./~ */
|
||||
if (*str == '\\' && str[1] == '~') {
|
||||
str++;
|
||||
*dst++ = '.';
|
||||
*dst++ = '/';
|
||||
}
|
||||
|
||||
while (*str) {
|
||||
if (*str == '\\')
|
||||
str++;
|
||||
if (*str)
|
||||
*dst++ = *str++;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return dequoted_str;
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* completion function using sh quoting rules; for key binding
|
||||
* el-compatible wrapper around rl_complete; needed for key binding
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
unsigned char
|
||||
_el_fn_sh_complete(EditLine *el, int ch __attribute__((__unused__)))
|
||||
_el_fn_sh_complete(EditLine *el, int ch)
|
||||
{
|
||||
return (unsigned char)fn_complete(el, NULL, NULL,
|
||||
break_chars, NULL, NULL, 100,
|
||||
NULL, NULL, NULL, NULL,
|
||||
sh_find_word_start, sh_dequote, sh_quote);
|
||||
return _el_fn_complete(el, ch);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
|
||||
/* $NetBSD: filecomplete.h,v 1.11 2017/04/21 05:38:03 abhinav Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -27,8 +27,6 @@
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _FILECOMPLETE_H_
|
||||
#define _FILECOMPLETE_H_
|
||||
@ -36,13 +34,11 @@
|
||||
int fn_complete(EditLine *,
|
||||
char *(*)(const char *, int),
|
||||
char **(*)(const char *, int, int),
|
||||
const Char *, const Char *, const char *(*)(const char *), size_t,
|
||||
int *, int *, int *, int *,
|
||||
const Char *(*)(const Char *, const Char *),
|
||||
Char *(*)(const Char *),
|
||||
char *(*)(const char *));
|
||||
const wchar_t *, const wchar_t *, const char *(*)(const char *), size_t,
|
||||
int *, int *, int *, int *);
|
||||
|
||||
void fn_display_match_list(EditLine *, char **, size_t, size_t);
|
||||
void fn_display_match_list(EditLine *, char **, size_t, size_t,
|
||||
const char *(*)(const char *));
|
||||
char *fn_tilde_expand(const char *);
|
||||
char *fn_filename_completion_function(const char *, int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hist.c,v 1.24 2016/02/16 22:53:14 christos Exp $ */
|
||||
/* $NetBSD: hist.c,v 1.34 2019/07/23 10:19:35 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,33 +37,32 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: hist.c,v 1.24 2016/02/16 22:53:14 christos Exp $");
|
||||
__RCSID("$NetBSD: hist.c,v 1.34 2019/07/23 10:19:35 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* hist.c: History access functions
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "el.h"
|
||||
|
||||
/* hist_init():
|
||||
* Initialization function.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
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;
|
||||
}
|
||||
@ -72,7 +71,7 @@ hist_init(EditLine *el)
|
||||
/* hist_end():
|
||||
* clean up history;
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
hist_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -84,7 +83,7 @@ hist_end(EditLine *el)
|
||||
/* hist_set():
|
||||
* Set new history interface
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
hist_set(EditLine *el, hist_fun_t fun, void *ptr)
|
||||
{
|
||||
|
||||
@ -98,14 +97,15 @@ hist_set(EditLine *el, hist_fun_t fun, void *ptr)
|
||||
* Get a history line and update it in the buffer.
|
||||
* eventno tells us the event to get.
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
hist_get(EditLine *el)
|
||||
{
|
||||
const Char *hp;
|
||||
const wchar_t *hp;
|
||||
int h;
|
||||
size_t blen, hlen;
|
||||
|
||||
if (el->el_history.eventno == 0) { /* if really the current line */
|
||||
(void) Strncpy(el->el_line.buffer, el->el_history.buf,
|
||||
(void) wcsncpy(el->el_line.buffer, el->el_history.buf,
|
||||
el->el_history.sz);
|
||||
el->el_line.lastchar = el->el_line.buffer +
|
||||
(el->el_history.last - el->el_history.buf);
|
||||
@ -128,14 +128,16 @@ hist_get(EditLine *el)
|
||||
return CC_ERROR;
|
||||
|
||||
for (h = 1; h < el->el_history.eventno; h++)
|
||||
if ((hp = HIST_NEXT(el)) == NULL) {
|
||||
el->el_history.eventno = h;
|
||||
return CC_ERROR;
|
||||
}
|
||||
(void) Strncpy(el->el_line.buffer, hp,
|
||||
(size_t)(el->el_line.limit - el->el_line.buffer));
|
||||
el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
|
||||
el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
|
||||
if ((hp = HIST_NEXT(el)) == NULL)
|
||||
goto out;
|
||||
|
||||
hlen = wcslen(hp) + 1;
|
||||
blen = (size_t)(el->el_line.limit - el->el_line.buffer);
|
||||
if (hlen > blen && !ch_enlargebufs(el, hlen))
|
||||
goto out;
|
||||
|
||||
memcpy(el->el_line.buffer, hp, hlen * sizeof(*hp));
|
||||
el->el_line.lastchar = el->el_line.buffer + hlen - 1;
|
||||
|
||||
if (el->el_line.lastchar > el->el_line.buffer
|
||||
&& el->el_line.lastchar[-1] == '\n')
|
||||
@ -151,41 +153,66 @@ hist_get(EditLine *el)
|
||||
el->el_line.cursor = el->el_line.lastchar;
|
||||
|
||||
return CC_REFRESH;
|
||||
out:
|
||||
el->el_history.eventno = h;
|
||||
return CC_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* hist_command()
|
||||
* process a history command
|
||||
*/
|
||||
protected int
|
||||
hist_command(EditLine *el, int argc, const Char **argv)
|
||||
libedit_private int
|
||||
hist_command(EditLine *el, int argc, const wchar_t **argv)
|
||||
{
|
||||
const Char *str;
|
||||
const wchar_t *str;
|
||||
int num;
|
||||
TYPE(HistEvent) ev;
|
||||
HistEventW ev;
|
||||
|
||||
if (el->el_history.ref == NULL)
|
||||
return -1;
|
||||
|
||||
if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
|
||||
if (argc == 1 || wcscmp(argv[1], L"list") == 0) {
|
||||
size_t maxlen = 0;
|
||||
char *buf = NULL;
|
||||
int hno = 1;
|
||||
/* List history entries */
|
||||
|
||||
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
|
||||
(void) fprintf(el->el_outfile, "%d %s",
|
||||
el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
|
||||
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) {
|
||||
char *ptr =
|
||||
ct_encode_string(str, &el->el_scratch);
|
||||
size_t len = strlen(ptr);
|
||||
if (len > 0 && ptr[len - 1] == '\n')
|
||||
ptr[--len] = '\0';
|
||||
len = len * 4 + 1;
|
||||
if (len >= maxlen) {
|
||||
maxlen = len + 1024;
|
||||
char *nbuf = el_realloc(buf, maxlen);
|
||||
if (nbuf == NULL) {
|
||||
el_free(buf);
|
||||
return -1;
|
||||
}
|
||||
buf = nbuf;
|
||||
}
|
||||
strvis(buf, ptr, VIS_NL);
|
||||
(void) fprintf(el->el_outfile, "%d\t%s\n",
|
||||
hno++, buf);
|
||||
}
|
||||
el_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc != 3)
|
||||
return -1;
|
||||
|
||||
num = (int)Strtol(argv[2], NULL, 0);
|
||||
num = (int)wcstol(argv[2], NULL, 0);
|
||||
|
||||
if (Strcmp(argv[1], STR("size")) == 0)
|
||||
return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num);
|
||||
if (wcscmp(argv[1], L"size") == 0)
|
||||
return history_w(el->el_history.ref, &ev, H_SETSIZE, num);
|
||||
|
||||
if (Strcmp(argv[1], STR("unique")) == 0)
|
||||
return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num);
|
||||
if (wcscmp(argv[1], L"unique") == 0)
|
||||
return history_w(el->el_history.ref, &ev, H_SETUNIQUE, num);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -194,11 +221,11 @@ hist_command(EditLine *el, int argc, const Char **argv)
|
||||
* Enlarge history buffer to specified value. Called from el_enlargebufs().
|
||||
* Return 0 for failure, 1 for success.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
|
||||
{
|
||||
Char *newbuf;
|
||||
wchar_t *newbuf;
|
||||
|
||||
newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
|
||||
if (!newbuf)
|
||||
@ -214,8 +241,7 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef WIDECHAR
|
||||
protected wchar_t *
|
||||
libedit_private wchar_t *
|
||||
hist_convert(EditLine *el, int fn, void *arg)
|
||||
{
|
||||
HistEventW ev;
|
||||
@ -224,4 +250,3 @@ hist_convert(EditLine *el, int fn, void *arg)
|
||||
return ct_decode_string((const char *)(const void *)ev.str,
|
||||
&el->el_scratch);
|
||||
}
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hist.h,v 1.18 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: hist.h,v 1.23 2017/09/01 10:19:10 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)hist.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,47 +40,41 @@
|
||||
#ifndef _h_el_hist
|
||||
#define _h_el_hist
|
||||
|
||||
typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
|
||||
typedef int (*hist_fun_t)(void *, HistEventW *, int, ...);
|
||||
|
||||
typedef struct el_history_t {
|
||||
Char *buf; /* The history buffer */
|
||||
wchar_t *buf; /* The history buffer */
|
||||
size_t sz; /* Size of history buffer */
|
||||
Char *last; /* The last character */
|
||||
wchar_t *last; /* The last character */
|
||||
int eventno; /* Event we are looking for */
|
||||
void *ref; /* Argument for history fcns */
|
||||
hist_fun_t fun; /* Event access */
|
||||
TYPE(HistEvent) ev; /* Event cookie */
|
||||
HistEventW ev; /* Event cookie */
|
||||
} el_history_t;
|
||||
|
||||
#define HIST_FUN_INTERNAL(el, fn, arg) \
|
||||
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
|
||||
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
|
||||
#ifdef WIDECHAR
|
||||
#define HIST_FUN(el, fn, arg) \
|
||||
(((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \
|
||||
HIST_FUN_INTERNAL(el, fn, arg))
|
||||
#else
|
||||
#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg)
|
||||
#endif
|
||||
|
||||
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
|
||||
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
|
||||
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
|
||||
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
|
||||
#define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
|
||||
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
|
||||
#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
|
||||
#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP, fp)
|
||||
#define HIST_NSAVE_FP(el, n, fp) HIST_FUN(el, H_NSAVE_FP, n, fp)
|
||||
|
||||
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
|
||||
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
|
||||
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
|
||||
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
|
||||
#define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
|
||||
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
|
||||
#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
|
||||
#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp)
|
||||
|
||||
protected int hist_init(EditLine *);
|
||||
protected void hist_end(EditLine *);
|
||||
protected el_action_t hist_get(EditLine *);
|
||||
protected int hist_set(EditLine *, hist_fun_t, void *);
|
||||
protected int hist_command(EditLine *, int, const Char **);
|
||||
protected int hist_enlargebuf(EditLine *, size_t, size_t);
|
||||
#ifdef WIDECHAR
|
||||
protected wchar_t *hist_convert(EditLine *, int, void *);
|
||||
#endif
|
||||
libedit_private int hist_init(EditLine *);
|
||||
libedit_private void hist_end(EditLine *);
|
||||
libedit_private el_action_t hist_get(EditLine *);
|
||||
libedit_private int hist_set(EditLine *, hist_fun_t, void *);
|
||||
libedit_private int hist_command(EditLine *, int, const wchar_t **);
|
||||
libedit_private int hist_enlargebuf(EditLine *, size_t, size_t);
|
||||
libedit_private wchar_t *hist_convert(EditLine *, int, void *);
|
||||
|
||||
#endif /* _h_el_hist */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: histedit.h,v 1.55 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: histedit.h,v 1.57 2017/09/01 10:19:10 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)histedit.h 8.2 (Berkeley) 1/3/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -228,6 +227,7 @@ int history(History *, HistEvent *, int, ...);
|
||||
#define H_DELDATA 24 /* , int, histdata_t *);*/
|
||||
#define H_REPLACE 25 /* , const char *, histdata_t); */
|
||||
#define H_SAVE_FP 26 /* , FILE *); */
|
||||
#define H_NSAVE_FP 27 /* , size_t, FILE *); */
|
||||
|
||||
|
||||
|
||||
@ -263,6 +263,8 @@ typedef struct lineinfow {
|
||||
const wchar_t *lastchar;
|
||||
} LineInfoW;
|
||||
|
||||
typedef int (*el_rfunc_t)(EditLine *, wchar_t *);
|
||||
|
||||
const wchar_t *el_wgets(EditLine *, int *);
|
||||
int el_wgetc(EditLine *, wchar_t *);
|
||||
void el_wpush(EditLine *, const wchar_t *);
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: history.c,v 1.52 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: history.c,v 1.52 2016/02/17 19:47:49 christos Exp $");
|
||||
__RCSID("$NetBSD: history.c,v 1.62 2018/09/13 09:03:40 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* hist.c: TYPE(History) access functions
|
||||
@ -55,8 +53,44 @@ __FBSDID("$FreeBSD$");
|
||||
static const char hist_cookie[] = "_HiStOrY_V2_\n";
|
||||
|
||||
#include "histedit.h"
|
||||
|
||||
|
||||
#ifdef NARROWCHAR
|
||||
|
||||
#define Char char
|
||||
#define FUN(prefix, rest) prefix ## _ ## rest
|
||||
#define FUNW(type) type
|
||||
#define TYPE(type) type
|
||||
#define STR(x) x
|
||||
|
||||
#define Strlen(s) strlen(s)
|
||||
#define Strdup(s) strdup(s)
|
||||
#define Strcmp(d, s) strcmp(d, s)
|
||||
#define Strncmp(d, s, n) strncmp(d, s, n)
|
||||
#define Strncpy(d, s, n) strncpy(d, s, n)
|
||||
#define Strncat(d, s, n) strncat(d, s, n)
|
||||
#define ct_decode_string(s, b) (s)
|
||||
#define ct_encode_string(s, b) (s)
|
||||
|
||||
#else
|
||||
#include "chartype.h"
|
||||
|
||||
#define Char wchar_t
|
||||
#define FUN(prefix, rest) prefix ## _w ## rest
|
||||
#define FUNW(type) type ## _w
|
||||
#define TYPE(type) type ## W
|
||||
#define STR(x) L ## x
|
||||
|
||||
#define Strlen(s) wcslen(s)
|
||||
#define Strdup(s) wcsdup(s)
|
||||
#define Strcmp(d, s) wcscmp(d, s)
|
||||
#define Strncmp(d, s, n) wcsncmp(d, s, n)
|
||||
#define Strncpy(d, s, n) wcsncpy(d, s, n)
|
||||
#define Strncat(d, s, n) wcsncat(d, s, n)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *);
|
||||
typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *);
|
||||
typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *);
|
||||
@ -99,19 +133,20 @@ typedef struct {
|
||||
} HistEventPrivate;
|
||||
|
||||
|
||||
|
||||
private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
private int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
|
||||
private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
private int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
|
||||
private int history_set_fun(TYPE(History) *, TYPE(History) *);
|
||||
private int history_load(TYPE(History) *, const char *);
|
||||
private int history_save(TYPE(History) *, const char *);
|
||||
private int history_save_fp(TYPE(History) *, FILE *);
|
||||
private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
|
||||
private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
|
||||
static int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
static int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
|
||||
static int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
static int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
|
||||
static int history_set_fun(TYPE(History) *, TYPE(History) *);
|
||||
static int history_load(TYPE(History) *, const char *);
|
||||
static int history_save(TYPE(History) *, const char *);
|
||||
static int history_save_fp(TYPE(History) *, size_t, FILE *);
|
||||
static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
|
||||
static int history_next_string(TYPE(History) *, TYPE(HistEvent) *,
|
||||
const Char *);
|
||||
static int history_prev_string(TYPE(History) *, TYPE(HistEvent) *,
|
||||
const Char *);
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
@ -136,23 +171,23 @@ typedef struct history_t {
|
||||
#define H_UNIQUE 1 /* Store only unique elements */
|
||||
} history_t;
|
||||
|
||||
private int history_def_next(void *, TYPE(HistEvent) *);
|
||||
private int history_def_first(void *, TYPE(HistEvent) *);
|
||||
private int history_def_prev(void *, TYPE(HistEvent) *);
|
||||
private int history_def_last(void *, TYPE(HistEvent) *);
|
||||
private int history_def_curr(void *, TYPE(HistEvent) *);
|
||||
private int history_def_set(void *, TYPE(HistEvent) *, const int);
|
||||
private void history_def_clear(void *, TYPE(HistEvent) *);
|
||||
private int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
|
||||
private int history_def_add(void *, TYPE(HistEvent) *, const Char *);
|
||||
private int history_def_del(void *, TYPE(HistEvent) *, const int);
|
||||
static int history_def_next(void *, TYPE(HistEvent) *);
|
||||
static int history_def_first(void *, TYPE(HistEvent) *);
|
||||
static int history_def_prev(void *, TYPE(HistEvent) *);
|
||||
static int history_def_last(void *, TYPE(HistEvent) *);
|
||||
static int history_def_curr(void *, TYPE(HistEvent) *);
|
||||
static int history_def_set(void *, TYPE(HistEvent) *, const int);
|
||||
static void history_def_clear(void *, TYPE(HistEvent) *);
|
||||
static int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
|
||||
static int history_def_add(void *, TYPE(HistEvent) *, const Char *);
|
||||
static int history_def_del(void *, TYPE(HistEvent) *, const int);
|
||||
|
||||
private int history_def_init(void **, TYPE(HistEvent) *, int);
|
||||
private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
|
||||
private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
|
||||
static int history_def_init(void **, TYPE(HistEvent) *, int);
|
||||
static int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
|
||||
static void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
|
||||
|
||||
private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
|
||||
private int history_set_nth(void *, TYPE(HistEvent) *, int);
|
||||
static int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
|
||||
static int history_set_nth(void *, TYPE(HistEvent) *, int);
|
||||
|
||||
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
|
||||
#define history_def_getsize(p) (((history_t *)p)->cur)
|
||||
@ -209,7 +244,7 @@ static const Char *const he_errlist[] = {
|
||||
/* history_def_first():
|
||||
* Default function to return the first event in the history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_first(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -229,7 +264,7 @@ history_def_first(void *p, TYPE(HistEvent) *ev)
|
||||
/* history_def_last():
|
||||
* Default function to return the last event in the history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_last(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -249,7 +284,7 @@ history_def_last(void *p, TYPE(HistEvent) *ev)
|
||||
/* history_def_next():
|
||||
* Default function to return the next event in the history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_next(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -274,7 +309,7 @@ history_def_next(void *p, TYPE(HistEvent) *ev)
|
||||
/* history_def_prev():
|
||||
* Default function to return the previous event in the history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_prev(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -300,7 +335,7 @@ history_def_prev(void *p, TYPE(HistEvent) *ev)
|
||||
/* history_def_curr():
|
||||
* Default function to return the current event in the history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_curr(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -321,7 +356,7 @@ history_def_curr(void *p, TYPE(HistEvent) *ev)
|
||||
* Default function to set the current event in the history to the
|
||||
* given one.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -348,7 +383,7 @@ history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
|
||||
* Default function to set the current event in the history to the
|
||||
* n-th one.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -372,7 +407,7 @@ history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
|
||||
/* history_def_add():
|
||||
* Append string to element
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -398,7 +433,7 @@ history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
|
||||
}
|
||||
|
||||
|
||||
private int
|
||||
static int
|
||||
history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
|
||||
int num, void **data)
|
||||
{
|
||||
@ -420,7 +455,7 @@ history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
|
||||
* Delete element hp of the h list
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
private int
|
||||
static int
|
||||
history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
|
||||
const int num)
|
||||
{
|
||||
@ -438,7 +473,7 @@ history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
|
||||
* Delete element hp of the h list
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
private void
|
||||
static void
|
||||
history_def_delete(history_t *h,
|
||||
TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp)
|
||||
{
|
||||
@ -461,7 +496,7 @@ history_def_delete(history_t *h,
|
||||
/* history_def_insert():
|
||||
* Insert element with string str in the h list
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
|
||||
{
|
||||
hentry_t *c;
|
||||
@ -493,7 +528,7 @@ oomem:
|
||||
/* history_def_enter():
|
||||
* Default function to enter an item in the history
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -520,7 +555,7 @@ history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
|
||||
* Default history initialization function
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
private int
|
||||
static int
|
||||
history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
|
||||
{
|
||||
history_t *h = (history_t *) h_malloc(sizeof(*h));
|
||||
@ -545,7 +580,7 @@ history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
|
||||
/* history_def_clear():
|
||||
* Default history cleanup function
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
history_def_clear(void *p, TYPE(HistEvent) *ev)
|
||||
{
|
||||
history_t *h = (history_t *) p;
|
||||
@ -565,7 +600,7 @@ history_def_clear(void *p, TYPE(HistEvent) *ev)
|
||||
/* history_init():
|
||||
* Initialization function.
|
||||
*/
|
||||
public TYPE(History) *
|
||||
TYPE(History) *
|
||||
FUN(history,init)(void)
|
||||
{
|
||||
TYPE(HistEvent) ev;
|
||||
@ -596,7 +631,7 @@ FUN(history,init)(void)
|
||||
/* history_end():
|
||||
* clean up history;
|
||||
*/
|
||||
public void
|
||||
void
|
||||
FUN(history,end)(TYPE(History) *h)
|
||||
{
|
||||
TYPE(HistEvent) ev;
|
||||
@ -612,7 +647,7 @@ FUN(history,end)(TYPE(History) *h)
|
||||
/* history_setsize():
|
||||
* Set history number of events
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
{
|
||||
|
||||
@ -632,7 +667,7 @@ history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
/* history_getsize():
|
||||
* Get number of events currently in history
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
|
||||
{
|
||||
if (h->h_next != history_def_next) {
|
||||
@ -651,7 +686,7 @@ history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
|
||||
/* history_setunique():
|
||||
* Set if adjacent equal events should not be entered in history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
|
||||
{
|
||||
|
||||
@ -667,7 +702,7 @@ history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
|
||||
/* history_getunique():
|
||||
* Get if adjacent equal events should not be entered in history.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
|
||||
{
|
||||
if (h->h_next != history_def_next) {
|
||||
@ -682,7 +717,7 @@ history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
|
||||
/* history_set_fun():
|
||||
* Set history functions
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_set_fun(TYPE(History) *h, TYPE(History) *nh)
|
||||
{
|
||||
TYPE(HistEvent) ev;
|
||||
@ -729,7 +764,7 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
|
||||
/* history_load():
|
||||
* TYPE(History) load function
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_load(TYPE(History) *h, const char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
@ -740,7 +775,8 @@ history_load(TYPE(History) *h, const char *fname)
|
||||
char *ptr;
|
||||
int i = -1;
|
||||
TYPE(HistEvent) ev;
|
||||
#ifdef WIDECHAR
|
||||
Char *decode_result;
|
||||
#ifndef NARROWCHAR
|
||||
static ct_buffer_t conv;
|
||||
#endif
|
||||
|
||||
@ -772,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;
|
||||
}
|
||||
@ -789,28 +828,36 @@ done:
|
||||
/* history_save_fp():
|
||||
* TYPE(History) save function
|
||||
*/
|
||||
private int
|
||||
history_save_fp(TYPE(History) *h, FILE *fp)
|
||||
static int
|
||||
history_save_fp(TYPE(History) *h, size_t nelem, FILE *fp)
|
||||
{
|
||||
TYPE(HistEvent) ev;
|
||||
int i = -1, retval;
|
||||
size_t len, max_size;
|
||||
char *ptr;
|
||||
const char *str;
|
||||
#ifdef WIDECHAR
|
||||
#ifndef NARROWCHAR
|
||||
static ct_buffer_t conv;
|
||||
#endif
|
||||
|
||||
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
|
||||
goto done;
|
||||
if (fputs(hist_cookie, fp) == EOF)
|
||||
if (ftell(fp) == 0 && fputs(hist_cookie, fp) == EOF)
|
||||
goto done;
|
||||
ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
|
||||
if (ptr == NULL)
|
||||
goto done;
|
||||
for (i = 0, retval = HLAST(h, &ev);
|
||||
retval != -1;
|
||||
retval = HPREV(h, &ev), i++) {
|
||||
if (nelem != (size_t)-1) {
|
||||
for (retval = HFIRST(h, &ev); retval != -1 && nelem-- > 0;
|
||||
retval = HNEXT(h, &ev))
|
||||
continue;
|
||||
} else
|
||||
retval = -1;
|
||||
|
||||
if (retval == -1)
|
||||
retval = HLAST(h, &ev);
|
||||
|
||||
for (i = 0; retval != -1; retval = HPREV(h, &ev), i++) {
|
||||
str = ct_encode_string(ev.str, &conv);
|
||||
len = strlen(str) * 4 + 1;
|
||||
if (len > max_size) {
|
||||
@ -836,7 +883,7 @@ done:
|
||||
/* history_save():
|
||||
* History save function
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_save(TYPE(History) *h, const char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
@ -845,7 +892,7 @@ history_save(TYPE(History) *h, const char *fname)
|
||||
if ((fp = fopen(fname, "w")) == NULL)
|
||||
return -1;
|
||||
|
||||
i = history_save_fp(h, fp);
|
||||
i = history_save_fp(h, (size_t)-1, fp);
|
||||
|
||||
(void) fclose(fp);
|
||||
return i;
|
||||
@ -855,7 +902,7 @@ history_save(TYPE(History) *h, const char *fname)
|
||||
/* history_prev_event():
|
||||
* Find the previous event, with number given
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
{
|
||||
int retval;
|
||||
@ -869,7 +916,7 @@ history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
}
|
||||
|
||||
|
||||
private int
|
||||
static int
|
||||
history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
|
||||
{
|
||||
int retval;
|
||||
@ -889,7 +936,7 @@ history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
|
||||
/* history_next_event():
|
||||
* Find the next event, with number given
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
{
|
||||
int retval;
|
||||
@ -906,7 +953,7 @@ history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
|
||||
/* history_prev_string():
|
||||
* Find the previous event beginning with string
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
|
||||
{
|
||||
size_t len = Strlen(str);
|
||||
@ -924,7 +971,7 @@ history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
|
||||
/* history_next_string():
|
||||
* Find the next event beginning with string
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
|
||||
{
|
||||
size_t len = Strlen(str);
|
||||
@ -1033,11 +1080,20 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
|
||||
break;
|
||||
|
||||
case H_SAVE_FP:
|
||||
retval = history_save_fp(h, va_arg(va, FILE *));
|
||||
retval = history_save_fp(h, (size_t)-1, va_arg(va, FILE *));
|
||||
if (retval == -1)
|
||||
he_seterrev(ev, _HE_HIST_WRITE);
|
||||
break;
|
||||
|
||||
case H_NSAVE_FP:
|
||||
{
|
||||
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));
|
||||
break;
|
3
contrib/libedit/historyn.c
Normal file
3
contrib/libedit/historyn.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include "config.h"
|
||||
#define NARROWCHAR
|
||||
#include "history.c"
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $ */
|
||||
/* $NetBSD: keymacro.c,v 1.24 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $");
|
||||
__RCSID("$NetBSD: keymacro.c,v 1.24 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* keymacro.c: This module contains the procedures for maintaining
|
||||
@ -52,7 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
* number of characters. This module maintains a map (the
|
||||
* el->el_keymacro.map)
|
||||
* to convert these extended-key sequences into input strs
|
||||
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
|
||||
* (XK_STR) or editor functions (XK_CMD).
|
||||
*
|
||||
* Warning:
|
||||
* If key is a substr of some other keys, then the longer
|
||||
@ -69,13 +67,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
|
||||
#include "el.h"
|
||||
#include "fcns.h"
|
||||
|
||||
/*
|
||||
* The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
|
||||
* linked list of these node elements
|
||||
*/
|
||||
struct keymacro_node_t {
|
||||
Char ch; /* single character of key */
|
||||
wchar_t ch; /* single character of key */
|
||||
int type; /* node type */
|
||||
keymacro_value_t val; /* command code or pointer to str, */
|
||||
/* if this is a leaf */
|
||||
@ -83,18 +82,18 @@ struct keymacro_node_t {
|
||||
struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
|
||||
};
|
||||
|
||||
private int node_trav(EditLine *, keymacro_node_t *, Char *,
|
||||
static int node_trav(EditLine *, keymacro_node_t *, wchar_t *,
|
||||
keymacro_value_t *);
|
||||
private int node__try(EditLine *, keymacro_node_t *, const Char *,
|
||||
keymacro_value_t *, int);
|
||||
private keymacro_node_t *node__get(wint_t);
|
||||
private void node__free(keymacro_node_t *);
|
||||
private void node__put(EditLine *, keymacro_node_t *);
|
||||
private int node__delete(EditLine *, keymacro_node_t **,
|
||||
const Char *);
|
||||
private int node_lookup(EditLine *, const Char *,
|
||||
static int node__try(EditLine *, keymacro_node_t *,
|
||||
const wchar_t *, keymacro_value_t *, int);
|
||||
static keymacro_node_t *node__get(wint_t);
|
||||
static void node__free(keymacro_node_t *);
|
||||
static void node__put(EditLine *, keymacro_node_t *);
|
||||
static int node__delete(EditLine *, keymacro_node_t **,
|
||||
const wchar_t *);
|
||||
static int node_lookup(EditLine *, const wchar_t *,
|
||||
keymacro_node_t *, size_t);
|
||||
private int node_enum(EditLine *, keymacro_node_t *, size_t);
|
||||
static int node_enum(EditLine *, keymacro_node_t *, size_t);
|
||||
|
||||
#define KEY_BUFSIZ EL_BUFSIZ
|
||||
|
||||
@ -102,11 +101,11 @@ private int node_enum(EditLine *, keymacro_node_t *, size_t);
|
||||
/* keymacro_init():
|
||||
* Initialize the key maps
|
||||
*/
|
||||
protected int
|
||||
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;
|
||||
@ -118,7 +117,7 @@ keymacro_init(EditLine *el)
|
||||
/* keymacro_end():
|
||||
* Free the key maps
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
keymacro_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -131,7 +130,7 @@ keymacro_end(EditLine *el)
|
||||
/* keymacro_map_cmd():
|
||||
* Associate cmd with a key value
|
||||
*/
|
||||
protected keymacro_value_t *
|
||||
libedit_private keymacro_value_t *
|
||||
keymacro_map_cmd(EditLine *el, int cmd)
|
||||
{
|
||||
|
||||
@ -143,8 +142,8 @@ keymacro_map_cmd(EditLine *el, int cmd)
|
||||
/* keymacro_map_str():
|
||||
* Associate str with a key value
|
||||
*/
|
||||
protected keymacro_value_t *
|
||||
keymacro_map_str(EditLine *el, Char *str)
|
||||
libedit_private keymacro_value_t *
|
||||
keymacro_map_str(EditLine *el, wchar_t *str)
|
||||
{
|
||||
|
||||
el->el_keymacro.val.str = str;
|
||||
@ -157,7 +156,7 @@ keymacro_map_str(EditLine *el, Char *str)
|
||||
* Then initializes el->el_keymacro.map with arrow keys
|
||||
* [Always bind the ansi arrow keys?]
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
keymacro_reset(EditLine *el)
|
||||
{
|
||||
|
||||
@ -171,12 +170,13 @@ keymacro_reset(EditLine *el)
|
||||
* Calls the recursive function with entry point el->el_keymacro.map
|
||||
* Looks up *ch in map and then reads characters until a
|
||||
* complete match is found or a mismatch occurs. Returns the
|
||||
* type of the match found (XK_STR, XK_CMD, or XK_EXE).
|
||||
* type of the match found (XK_STR or XK_CMD).
|
||||
* Returns NULL in val.str and XK_STR for no match.
|
||||
* Returns XK_NOD for end of file or read error.
|
||||
* The last character read is returned in *ch.
|
||||
*/
|
||||
protected int
|
||||
keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
|
||||
libedit_private int
|
||||
keymacro_get(EditLine *el, wchar_t *ch, keymacro_value_t *val)
|
||||
{
|
||||
|
||||
return node_trav(el, el->el_keymacro.map, ch, val);
|
||||
@ -189,8 +189,9 @@ keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
|
||||
* code is applied to the existing key. Ntype specifies if code is a
|
||||
* command, an out str or a unix command.
|
||||
*/
|
||||
protected void
|
||||
keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
libedit_private void
|
||||
keymacro_add(EditLine *el, const wchar_t *key, keymacro_value_t *val,
|
||||
int ntype)
|
||||
{
|
||||
|
||||
if (key[0] == '\0') {
|
||||
@ -217,13 +218,11 @@ keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
/* keymacro_clear():
|
||||
*
|
||||
*/
|
||||
protected void
|
||||
keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
|
||||
libedit_private void
|
||||
keymacro_clear(EditLine *el, el_action_t *map, const wchar_t *in)
|
||||
{
|
||||
#ifdef WIDECHAR
|
||||
if (*in > N_KEYS) /* can't be in the map */
|
||||
return;
|
||||
#endif
|
||||
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
|
||||
((map == el->el_map.key &&
|
||||
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
|
||||
@ -237,8 +236,8 @@ keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
|
||||
* Delete the key and all longer keys staring with key, if
|
||||
* they exists.
|
||||
*/
|
||||
protected int
|
||||
keymacro_delete(EditLine *el, const Char *key)
|
||||
libedit_private int
|
||||
keymacro_delete(EditLine *el, const wchar_t *key)
|
||||
{
|
||||
|
||||
if (key[0] == '\0') {
|
||||
@ -258,8 +257,8 @@ keymacro_delete(EditLine *el, const Char *key)
|
||||
* Print the binding associated with key key.
|
||||
* Print entire el->el_keymacro.map if null
|
||||
*/
|
||||
protected void
|
||||
keymacro_print(EditLine *el, const Char *key)
|
||||
libedit_private void
|
||||
keymacro_print(EditLine *el, const wchar_t *key)
|
||||
{
|
||||
|
||||
/* do nothing if el->el_keymacro.map is empty and null key specified */
|
||||
@ -269,7 +268,7 @@ keymacro_print(EditLine *el, const Char *key)
|
||||
el->el_keymacro.buf[0] = '"';
|
||||
if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1)
|
||||
/* key is not bound */
|
||||
(void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR
|
||||
(void) fprintf(el->el_errfile, "Unbound extended key \"%ls"
|
||||
"\"\n", key);
|
||||
return;
|
||||
}
|
||||
@ -279,21 +278,17 @@ keymacro_print(EditLine *el, const Char *key)
|
||||
* recursively traverses node in tree until match or mismatch is
|
||||
* found. May read in more characters.
|
||||
*/
|
||||
private int
|
||||
node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
|
||||
static int
|
||||
node_trav(EditLine *el, keymacro_node_t *ptr, wchar_t *ch,
|
||||
keymacro_value_t *val)
|
||||
{
|
||||
wchar_t wc;
|
||||
|
||||
if (ptr->ch == *ch) {
|
||||
/* match found */
|
||||
if (ptr->next) {
|
||||
/* key not complete so get next char */
|
||||
if (el_wgetc(el, &wc) != 1) {/* if EOF or error */
|
||||
val->cmd = ED_END_OF_FILE;
|
||||
return XK_CMD;
|
||||
/* PWP: Pretend we just read an end-of-file */
|
||||
}
|
||||
*ch = (Char)wc;
|
||||
if (el_wgetc(el, ch) != 1)
|
||||
return XK_NOD;
|
||||
return node_trav(el, ptr->next, ch, val);
|
||||
} else {
|
||||
*val = ptr->val;
|
||||
@ -318,8 +313,8 @@ node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
|
||||
/* node__try():
|
||||
* Find a node that matches *str or allocate a new one
|
||||
*/
|
||||
private int
|
||||
node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
|
||||
static int
|
||||
node__try(EditLine *el, keymacro_node_t *ptr, const wchar_t *str,
|
||||
keymacro_value_t *val, int ntype)
|
||||
{
|
||||
|
||||
@ -345,7 +340,6 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
|
||||
case XK_NOD:
|
||||
break;
|
||||
case XK_STR:
|
||||
case XK_EXE:
|
||||
if (ptr->val.str)
|
||||
el_free(ptr->val.str);
|
||||
break;
|
||||
@ -360,8 +354,7 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
|
||||
ptr->val = *val;
|
||||
break;
|
||||
case XK_STR:
|
||||
case XK_EXE:
|
||||
if ((ptr->val.str = Strdup(val->str)) == NULL)
|
||||
if ((ptr->val.str = wcsdup(val->str)) == NULL)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
@ -381,8 +374,8 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
|
||||
/* node__delete():
|
||||
* Delete node that matches str
|
||||
*/
|
||||
private int
|
||||
node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
|
||||
static int
|
||||
node__delete(EditLine *el, keymacro_node_t **inptr, const wchar_t *str)
|
||||
{
|
||||
keymacro_node_t *ptr;
|
||||
keymacro_node_t *prev_ptr = NULL;
|
||||
@ -429,7 +422,7 @@ node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
|
||||
/* node__put():
|
||||
* Puts a tree of nodes onto free list using free(3).
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
node__put(EditLine *el, keymacro_node_t *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
@ -445,7 +438,6 @@ node__put(EditLine *el, keymacro_node_t *ptr)
|
||||
case XK_CMD:
|
||||
case XK_NOD:
|
||||
break;
|
||||
case XK_EXE:
|
||||
case XK_STR:
|
||||
if (ptr->val.str != NULL)
|
||||
el_free(ptr->val.str);
|
||||
@ -461,7 +453,7 @@ node__put(EditLine *el, keymacro_node_t *ptr)
|
||||
/* node__get():
|
||||
* Returns pointer to a keymacro_node_t for ch.
|
||||
*/
|
||||
private keymacro_node_t *
|
||||
static keymacro_node_t *
|
||||
node__get(wint_t ch)
|
||||
{
|
||||
keymacro_node_t *ptr;
|
||||
@ -469,7 +461,7 @@ node__get(wint_t ch)
|
||||
ptr = el_malloc(sizeof(*ptr));
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
ptr->ch = (Char)ch;
|
||||
ptr->ch = ch;
|
||||
ptr->type = XK_NOD;
|
||||
ptr->val.str = NULL;
|
||||
ptr->next = NULL;
|
||||
@ -477,7 +469,7 @@ node__get(wint_t ch)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private void
|
||||
static void
|
||||
node__free(keymacro_node_t *k)
|
||||
{
|
||||
if (k == NULL)
|
||||
@ -491,8 +483,9 @@ node__free(keymacro_node_t *k)
|
||||
* look for the str starting at node ptr.
|
||||
* Print if last node
|
||||
*/
|
||||
private int
|
||||
node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
|
||||
static int
|
||||
node_lookup(EditLine *el, const wchar_t *str, keymacro_node_t *ptr,
|
||||
size_t cnt)
|
||||
{
|
||||
ssize_t used;
|
||||
|
||||
@ -543,7 +536,7 @@ node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
|
||||
/* node_enum():
|
||||
* Traverse the node printing the characters it is bound in buffer
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
|
||||
{
|
||||
ssize_t used;
|
||||
@ -553,7 +546,7 @@ node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
|
||||
el->el_keymacro.buf[++cnt] = '\0';
|
||||
(void) fprintf(el->el_errfile,
|
||||
"Some extended keys too long for internal print buffer");
|
||||
(void) fprintf(el->el_errfile, " \"" FSTR "...\"\n",
|
||||
(void) fprintf(el->el_errfile, " \"%ls...\"\n",
|
||||
el->el_keymacro.buf);
|
||||
return 0;
|
||||
}
|
||||
@ -586,8 +579,9 @@ node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
|
||||
* Print the specified key and its associated
|
||||
* function specified by val
|
||||
*/
|
||||
protected void
|
||||
keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
libedit_private void
|
||||
keymacro_kprint(EditLine *el, const wchar_t *key, keymacro_value_t *val,
|
||||
int ntype)
|
||||
{
|
||||
el_bindings_t *fp;
|
||||
char unparsbuf[EL_BUFSIZ];
|
||||
@ -596,7 +590,6 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
if (val != NULL)
|
||||
switch (ntype) {
|
||||
case XK_STR:
|
||||
case XK_EXE:
|
||||
(void) keymacro__decode_str(val->str, unparsbuf,
|
||||
sizeof(unparsbuf),
|
||||
ntype == XK_STR ? "\"\"" : "[]");
|
||||
@ -606,7 +599,7 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
case XK_CMD:
|
||||
for (fp = el->el_map.help; fp->name; fp++)
|
||||
if (val->cmd == fp->func) {
|
||||
ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
|
||||
wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
|
||||
unparsbuf[sizeof(unparsbuf) -1] = '\0';
|
||||
(void) fprintf(el->el_outfile, fmt,
|
||||
ct_encode_string(key, &el->el_scratch), unparsbuf);
|
||||
@ -637,11 +630,12 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
|
||||
/* keymacro__decode_str():
|
||||
* Make a printable version of the ey
|
||||
*/
|
||||
protected size_t
|
||||
keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
|
||||
libedit_private size_t
|
||||
keymacro__decode_str(const wchar_t *str, char *buf, size_t len,
|
||||
const char *sep)
|
||||
{
|
||||
char *b = buf, *eb = b + len;
|
||||
const Char *p;
|
||||
const wchar_t *p;
|
||||
|
||||
b = buf;
|
||||
if (sep[0] != '\0') {
|
||||
@ -653,8 +647,8 @@ keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
|
||||
goto add_endsep;
|
||||
}
|
||||
for (p = str; *p != 0; p++) {
|
||||
Char dbuf[VISUAL_WIDTH_MAX];
|
||||
Char *p2 = dbuf;
|
||||
wchar_t dbuf[VISUAL_WIDTH_MAX];
|
||||
wchar_t *p2 = dbuf;
|
||||
ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
|
||||
while (l-- > 0) {
|
||||
ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++);
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: keymacro.h,v 1.3 2016/01/29 19:59:11 christos Exp $ */
|
||||
/* $NetBSD: keymacro.h,v 1.6 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)key.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -43,13 +42,13 @@
|
||||
|
||||
typedef union keymacro_value_t {
|
||||
el_action_t cmd; /* If it is a command the # */
|
||||
Char *str; /* If it is a string... */
|
||||
wchar_t *str; /* If it is a string... */
|
||||
} keymacro_value_t;
|
||||
|
||||
typedef struct keymacro_node_t keymacro_node_t;
|
||||
|
||||
typedef struct el_keymacro_t {
|
||||
Char *buf; /* Key print buffer */
|
||||
wchar_t *buf; /* Key print buffer */
|
||||
keymacro_node_t *map; /* Key map */
|
||||
keymacro_value_t val; /* Local conversion buffer */
|
||||
} el_keymacro_t;
|
||||
@ -57,21 +56,21 @@ typedef struct el_keymacro_t {
|
||||
#define XK_CMD 0
|
||||
#define XK_STR 1
|
||||
#define XK_NOD 2
|
||||
#define XK_EXE 3
|
||||
|
||||
protected int keymacro_init(EditLine *);
|
||||
protected void keymacro_end(EditLine *);
|
||||
protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
|
||||
protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
|
||||
protected void keymacro_reset(EditLine *);
|
||||
protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
|
||||
protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
|
||||
protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
|
||||
protected int keymacro_delete(EditLine *, const Char *);
|
||||
protected void keymacro_print(EditLine *, const Char *);
|
||||
protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
|
||||
int);
|
||||
protected size_t keymacro__decode_str(const Char *, char *, size_t,
|
||||
libedit_private int keymacro_init(EditLine *);
|
||||
libedit_private void keymacro_end(EditLine *);
|
||||
libedit_private keymacro_value_t *keymacro_map_cmd(EditLine *, int);
|
||||
libedit_private keymacro_value_t *keymacro_map_str(EditLine *, wchar_t *);
|
||||
libedit_private void keymacro_reset(EditLine *);
|
||||
libedit_private int keymacro_get(EditLine *, wchar_t *, keymacro_value_t *);
|
||||
libedit_private void keymacro_add(EditLine *, const wchar_t *,
|
||||
keymacro_value_t *, int);
|
||||
libedit_private void keymacro_clear(EditLine *, el_action_t *, const wchar_t *);
|
||||
libedit_private int keymacro_delete(EditLine *, const wchar_t *);
|
||||
libedit_private void keymacro_print(EditLine *, const wchar_t *);
|
||||
libedit_private void keymacro_kprint(EditLine *, const wchar_t *,
|
||||
keymacro_value_t *, int);
|
||||
libedit_private size_t keymacro__decode_str(const wchar_t *, char *, size_t,
|
||||
const char *);
|
||||
|
||||
#endif /* _h_el_keymacro */
|
136
contrib/libedit/literal.c
Normal file
136
contrib/libedit/literal.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* $NetBSD: literal.c,v 1.5 2019/07/23 13:10:11 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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 REGENTS 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 REGENTS 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"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: literal.c,v 1.5 2019/07/23 13:10:11 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
/*
|
||||
* literal.c: Literal sequences handling.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "el.h"
|
||||
|
||||
libedit_private void
|
||||
literal_init(EditLine *el)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
|
||||
memset(l, 0, sizeof(*l));
|
||||
}
|
||||
|
||||
libedit_private void
|
||||
literal_end(EditLine *el)
|
||||
{
|
||||
literal_clear(el);
|
||||
}
|
||||
|
||||
libedit_private void
|
||||
literal_clear(EditLine *el)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
size_t i;
|
||||
|
||||
if (l->l_len == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < l->l_idx; i++)
|
||||
el_free(l->l_buf[i]);
|
||||
el_free(l->l_buf);
|
||||
l->l_buf = NULL;
|
||||
l->l_len = 0;
|
||||
l->l_idx = 0;
|
||||
}
|
||||
|
||||
libedit_private wint_t
|
||||
literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
size_t i, len;
|
||||
ssize_t w, n;
|
||||
char *b;
|
||||
|
||||
w = wcwidth(end[1]); /* column width of the visible char */
|
||||
*wp = (int)w;
|
||||
|
||||
if (w <= 0) /* we require something to be printed */
|
||||
return 0;
|
||||
|
||||
len = (size_t)(end - buf);
|
||||
for (w = 0, i = 0; i < len; i++)
|
||||
w += ct_enc_width(buf[i]);
|
||||
w += ct_enc_width(end[1]);
|
||||
|
||||
b = el_malloc((size_t)(w + 1));
|
||||
if (b == NULL)
|
||||
return 0;
|
||||
|
||||
for (n = 0, i = 0; i < len; i++)
|
||||
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';
|
||||
|
||||
/*
|
||||
* Then save this literal string in the list of such strings,
|
||||
* and return a "magic character" to put into the terminal buffer.
|
||||
* When that magic char is 'printed' the saved string (which includes
|
||||
* the char that belongs in that position) gets sent instead.
|
||||
*/
|
||||
if (l->l_idx == l->l_len) {
|
||||
char **bp;
|
||||
|
||||
l->l_len += 4;
|
||||
bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
|
||||
if (bp == NULL) {
|
||||
free(b);
|
||||
l->l_len -= 4;
|
||||
return 0;
|
||||
}
|
||||
l->l_buf = bp;
|
||||
}
|
||||
l->l_buf[l->l_idx++] = b;
|
||||
return EL_LITERAL | (wint_t)(l->l_idx - 1);
|
||||
}
|
||||
|
||||
libedit_private const char *
|
||||
literal_get(EditLine *el, wint_t idx)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
|
||||
assert(idx & EL_LITERAL);
|
||||
idx &= ~EL_LITERAL;
|
||||
assert(l->l_idx > (size_t)idx);
|
||||
return l->l_buf[idx];
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
/* $NetBSD: literal.h,v 1.2 2017/06/30 20:26:52 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright (c) 2017 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Paul Borman at Krystal Technologies.
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -15,9 +15,6 @@
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
@ -30,26 +27,27 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#)ldef.h 8.1 (Berkeley) 6/6/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "runefile.h"
|
||||
|
||||
/*
|
||||
* This should look a LOT like a _RuneEntry
|
||||
* el.literal.h: Literal character
|
||||
*/
|
||||
typedef struct rune_list {
|
||||
int32_t min;
|
||||
int32_t max;
|
||||
int32_t map;
|
||||
uint32_t *types;
|
||||
struct rune_list *next;
|
||||
} rune_list;
|
||||
#ifndef _h_el_literal
|
||||
#define _h_el_literal
|
||||
|
||||
typedef struct rune_map {
|
||||
uint32_t map[_CACHED_RUNES];
|
||||
rune_list *root;
|
||||
} rune_map;
|
||||
#define EL_LITERAL ((wint_t)0x80000000)
|
||||
|
||||
typedef struct el_literal_t {
|
||||
char **l_buf; /* array of buffers */
|
||||
size_t l_idx; /* max in use */
|
||||
size_t l_len; /* max allocated */
|
||||
} el_literal_t;
|
||||
|
||||
libedit_private void literal_init(EditLine *);
|
||||
libedit_private void literal_end(EditLine *);
|
||||
libedit_private void literal_clear(EditLine *);
|
||||
libedit_private wint_t literal_add(EditLine *, const wchar_t *,
|
||||
const wchar_t *, int *);
|
||||
libedit_private const char *literal_get(EditLine *, wint_t);
|
||||
|
||||
#endif /* _h_el_literal */
|
@ -1,6 +1,5 @@
|
||||
#!/bin/sh -
|
||||
# $FreeBSD$
|
||||
# $NetBSD: makelist,v 1.18 2012/03/21 05:34:54 matt Exp $
|
||||
# $NetBSD: makelist,v 1.29 2016/05/09 21:46:56 christos Exp $
|
||||
#
|
||||
# Copyright (c) 1992, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
@ -37,7 +36,7 @@
|
||||
# makelist.sh: Automatically generate header files...
|
||||
|
||||
AWK=awk
|
||||
USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
|
||||
USAGE="Usage: $0 -h|-fc|-fh|-bh <filenames>"
|
||||
|
||||
if [ "x$1" = "x" ]
|
||||
then
|
||||
@ -52,17 +51,6 @@ FILES="$@"
|
||||
|
||||
case $FLAG in
|
||||
|
||||
# generate foo.h file from foo.c
|
||||
#
|
||||
-n)
|
||||
cat << _EOF
|
||||
#include "config.h"
|
||||
#undef WIDECHAR
|
||||
#define NARROWCHAR
|
||||
#include "${FILES}"
|
||||
_EOF
|
||||
;;
|
||||
|
||||
-h)
|
||||
set - `echo $FILES | sed -e 's/\\./_/g'`
|
||||
hdr="_h_`basename $1`"
|
||||
@ -79,7 +67,7 @@ _EOF
|
||||
# XXX: need a space between name and prototype so that -fc and -fh
|
||||
# parsing is much easier
|
||||
#
|
||||
printf("protected el_action_t\t%s (EditLine *, wint_t);\n",
|
||||
printf("libedit_private el_action_t\t%s (EditLine *, wint_t);\n",
|
||||
name);
|
||||
}
|
||||
}
|
||||
@ -88,15 +76,13 @@ _EOF
|
||||
}'
|
||||
;;
|
||||
|
||||
# generate help.c from various .c files
|
||||
# generate help.h from various .c files
|
||||
#
|
||||
-bc)
|
||||
-bh)
|
||||
cat $FILES | $AWK '
|
||||
BEGIN {
|
||||
printf("/* Automatically generated file, do not edit */\n");
|
||||
printf("#include \"config.h\"\n#include \"el.h\"\n");
|
||||
printf("#include \"help.h\"\n");
|
||||
printf("private const struct el_bindings_t el_func_help[] = {\n");
|
||||
printf("static const struct el_bindings_t el_func_help[] = {\n");
|
||||
low = "abcdefghijklmnopqrstuvwxyz_";
|
||||
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
|
||||
for (i = 1; i <= length(low); i++)
|
||||
@ -116,38 +102,24 @@ _EOF
|
||||
fname = fname s;
|
||||
}
|
||||
|
||||
printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
|
||||
printf(" { %-30.30s %-30.30s\n","L\"" fname "\",", uname ",");
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
/^ \*/ {
|
||||
if (ok) {
|
||||
printf(" STR(\"");
|
||||
printf(" L\"");
|
||||
for (i = 2; i < NF; i++)
|
||||
printf("%s ", $i);
|
||||
printf("%s\") },\n", $i);
|
||||
printf("%s\" },\n", $i);
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
END {
|
||||
printf("};\n");
|
||||
printf("\nprotected const el_bindings_t* help__get(void)");
|
||||
printf("{ return el_func_help; }\n");
|
||||
}'
|
||||
;;
|
||||
|
||||
# generate help.h from various .c files
|
||||
#
|
||||
-bh)
|
||||
$AWK '
|
||||
BEGIN {
|
||||
printf("/* Automatically generated file, do not edit */\n");
|
||||
printf("#ifndef _h_help_c\n#define _h_help_c\n");
|
||||
printf("protected const el_bindings_t *help__get(void);\n");
|
||||
printf("#endif /* _h_help_c */\n");
|
||||
}' /dev/null
|
||||
;;
|
||||
|
||||
# generate fcns.h from various .h files
|
||||
#
|
||||
-fh)
|
||||
@ -155,7 +127,6 @@ _EOF
|
||||
sort | tr '[:lower:]' '[:upper:]' | $AWK '
|
||||
BEGIN {
|
||||
printf("/* Automatically generated file, do not edit */\n");
|
||||
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
|
||||
count = 0;
|
||||
}
|
||||
{
|
||||
@ -163,24 +134,16 @@ _EOF
|
||||
}
|
||||
END {
|
||||
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
|
||||
|
||||
printf("typedef el_action_t (*el_func_t)(EditLine *, wint_t);");
|
||||
printf("\nprotected const el_func_t* func__get(void);\n");
|
||||
printf("#endif /* _h_fcns_c */\n");
|
||||
}'
|
||||
;;
|
||||
|
||||
# generate fcns.c from various .h files
|
||||
# generate func.h from various .h files
|
||||
#
|
||||
-fc)
|
||||
cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
|
||||
BEGIN {
|
||||
printf("/* Automatically generated file, do not edit */\n");
|
||||
printf("#include \"config.h\"\n#include \"el.h\"\n");
|
||||
printf("#include \"common.h\"\n");
|
||||
printf("#include \"emacs.h\"\n");
|
||||
printf("#include \"vi.h\"\n");
|
||||
printf("private const el_func_t el_func[] = {");
|
||||
printf("static const el_func_t el_func[] = {");
|
||||
maxlen = 80;
|
||||
needn = 1;
|
||||
len = 0;
|
||||
@ -200,59 +163,6 @@ _EOF
|
||||
}
|
||||
END {
|
||||
printf("\n};\n");
|
||||
printf("\nprotected const el_func_t* func__get(void) { return el_func; }\n");
|
||||
}'
|
||||
;;
|
||||
|
||||
# generate editline.c from various .c files
|
||||
#
|
||||
-e)
|
||||
echo "$FILES" | tr ' ' '\012' | $AWK '
|
||||
BEGIN {
|
||||
printf("/* Automatically generated file, do not edit */\n");
|
||||
printf("#define protected static\n");
|
||||
printf("#define SCCSID\n");
|
||||
}
|
||||
{
|
||||
printf("#include \"%s\"\n", $1);
|
||||
}'
|
||||
;;
|
||||
|
||||
# generate man page fragment from various .c files
|
||||
#
|
||||
-m)
|
||||
cat $FILES | $AWK '
|
||||
BEGIN {
|
||||
printf(".\\\" Section automatically generated with makelist\n");
|
||||
printf(".Bl -tag -width 4n\n");
|
||||
}
|
||||
/\(\):/ {
|
||||
pr = substr($2, 1, 2);
|
||||
if (pr == "vi" || pr == "em" || pr == "ed") {
|
||||
name = substr($2, 1, length($2) - 3);
|
||||
fname = "";
|
||||
for (i = 1; i <= length(name); i++) {
|
||||
s = substr(name, i, 1);
|
||||
if (s == "_")
|
||||
s = "-";
|
||||
fname = fname s;
|
||||
}
|
||||
|
||||
printf(".It Ic %s\n", fname);
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
/^ \*/ {
|
||||
if (ok) {
|
||||
for (i = 2; i < NF; i++)
|
||||
printf("%s ", $i);
|
||||
printf("%s.\n", $i);
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
END {
|
||||
printf(".El\n");
|
||||
printf(".\\\" End of section automatically generated with makelist\n");
|
||||
}'
|
||||
;;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: map.c,v 1.43 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: map.c,v 1.52 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: map.c,v 1.43 2016/02/17 19:47:49 christos Exp $");
|
||||
__RCSID("$NetBSD: map.c,v 1.52 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* map.c: Editor function definitions
|
||||
@ -51,23 +49,28 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
#include "emacs.h"
|
||||
#include "vi.h"
|
||||
#include "fcns.h"
|
||||
#include "func.h"
|
||||
#include "help.h"
|
||||
#include "parse.h"
|
||||
|
||||
private void map_print_key(EditLine *, el_action_t *, const Char *);
|
||||
private void map_print_some_keys(EditLine *, el_action_t *, wint_t, wint_t);
|
||||
private void map_print_all_keys(EditLine *);
|
||||
private void map_init_nls(EditLine *);
|
||||
private void map_init_meta(EditLine *);
|
||||
static void map_print_key(EditLine *, el_action_t *, const wchar_t *);
|
||||
static void map_print_some_keys(EditLine *, el_action_t *, wint_t, wint_t);
|
||||
static void map_print_all_keys(EditLine *);
|
||||
static void map_init_nls(EditLine *);
|
||||
static void map_init_meta(EditLine *);
|
||||
|
||||
/* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */
|
||||
|
||||
|
||||
private const el_action_t el_map_emacs[] = {
|
||||
static const el_action_t el_map_emacs[] = {
|
||||
/* 0 */ EM_SET_MARK, /* ^@ */
|
||||
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
|
||||
/* 2 */ ED_PREV_CHAR, /* ^B */
|
||||
/* 3 */ ED_TTY_SIGINT, /* ^C */
|
||||
/* 3 */ ED_IGNORE, /* ^C */
|
||||
/* 4 */ EM_DELETE_OR_LIST, /* ^D */
|
||||
/* 5 */ ED_MOVE_TO_END, /* ^E */
|
||||
/* 6 */ ED_NEXT_CHAR, /* ^F */
|
||||
@ -79,21 +82,21 @@ private const el_action_t el_map_emacs[] = {
|
||||
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
|
||||
/* 13 */ ED_NEWLINE, /* ^M */
|
||||
/* 14 */ ED_NEXT_HISTORY, /* ^N */
|
||||
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
|
||||
/* 15 */ ED_IGNORE, /* ^O */
|
||||
/* 16 */ ED_PREV_HISTORY, /* ^P */
|
||||
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
|
||||
/* 17 */ ED_IGNORE, /* ^Q */
|
||||
/* 18 */ ED_REDISPLAY, /* ^R */
|
||||
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
|
||||
/* 19 */ ED_IGNORE, /* ^S */
|
||||
/* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
|
||||
/* 21 */ EM_KILL_LINE, /* ^U */
|
||||
/* 22 */ ED_QUOTED_INSERT, /* ^V */
|
||||
/* 23 */ EM_KILL_REGION, /* ^W */
|
||||
/* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */
|
||||
/* 25 */ EM_YANK, /* ^Y */
|
||||
/* 26 */ ED_TTY_SIGTSTP, /* ^Z */
|
||||
/* 26 */ ED_IGNORE, /* ^Z */
|
||||
/* 27 */ EM_META_NEXT, /* ^[ */
|
||||
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
|
||||
/* 29 */ ED_TTY_DSUSP, /* ^] */
|
||||
/* 28 */ ED_IGNORE, /* ^\ */
|
||||
/* 29 */ ED_IGNORE, /* ^] */
|
||||
/* 30 */ ED_UNASSIGNED, /* ^^ */
|
||||
/* 31 */ ED_UNASSIGNED, /* ^_ */
|
||||
/* 32 */ ED_INSERT, /* SPACE */
|
||||
@ -330,7 +333,7 @@ private const el_action_t el_map_emacs[] = {
|
||||
* insert mode characters are in the normal keymap, and command mode
|
||||
* in the extended keymap.
|
||||
*/
|
||||
private const el_action_t el_map_vi_insert[] = {
|
||||
static const el_action_t el_map_vi_insert[] = {
|
||||
#ifdef KSHVI
|
||||
/* 0 */ ED_UNASSIGNED, /* ^@ */
|
||||
/* 1 */ ED_INSERT, /* ^A */
|
||||
@ -349,9 +352,9 @@ private const el_action_t el_map_vi_insert[] = {
|
||||
/* 14 */ ED_INSERT, /* ^N */
|
||||
/* 15 */ ED_INSERT, /* ^O */
|
||||
/* 16 */ ED_INSERT, /* ^P */
|
||||
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
|
||||
/* 17 */ ED_IGNORE, /* ^Q */
|
||||
/* 18 */ ED_INSERT, /* ^R */
|
||||
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
|
||||
/* 19 */ ED_IGNORE, /* ^S */
|
||||
/* 20 */ ED_INSERT, /* ^T */
|
||||
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
|
||||
/* 22 */ ED_QUOTED_INSERT, /* ^V */
|
||||
@ -361,7 +364,7 @@ private const el_action_t el_map_vi_insert[] = {
|
||||
/* 25 */ ED_INSERT, /* ^Y */
|
||||
/* 26 */ ED_INSERT, /* ^Z */
|
||||
/* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */
|
||||
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
|
||||
/* 28 */ ED_IGNORE, /* ^\ */
|
||||
/* 29 */ ED_INSERT, /* ^] */
|
||||
/* 30 */ ED_INSERT, /* ^^ */
|
||||
/* 31 */ ED_INSERT, /* ^_ */
|
||||
@ -370,12 +373,12 @@ private const el_action_t el_map_vi_insert[] = {
|
||||
* NOTE: These mappings do NOT Correspond well
|
||||
* to the KSH VI editing assignments.
|
||||
* On the other and they are convenient and
|
||||
* many people have gotten used to them.
|
||||
* many people have have gotten used to them.
|
||||
*/
|
||||
/* 0 */ ED_UNASSIGNED, /* ^@ */
|
||||
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
|
||||
/* 2 */ ED_PREV_CHAR, /* ^B */
|
||||
/* 3 */ ED_TTY_SIGINT, /* ^C */
|
||||
/* 3 */ ED_IGNORE, /* ^C */
|
||||
/* 4 */ VI_LIST_OR_EOF, /* ^D */
|
||||
/* 5 */ ED_MOVE_TO_END, /* ^E */
|
||||
/* 6 */ ED_NEXT_CHAR, /* ^F */
|
||||
@ -387,20 +390,20 @@ private const el_action_t el_map_vi_insert[] = {
|
||||
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
|
||||
/* 13 */ ED_NEWLINE, /* ^M */
|
||||
/* 14 */ ED_NEXT_HISTORY, /* ^N */
|
||||
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
|
||||
/* 15 */ ED_IGNORE, /* ^O */
|
||||
/* 16 */ ED_PREV_HISTORY, /* ^P */
|
||||
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
|
||||
/* 17 */ ED_IGNORE, /* ^Q */
|
||||
/* 18 */ ED_REDISPLAY, /* ^R */
|
||||
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
|
||||
/* 19 */ ED_IGNORE, /* ^S */
|
||||
/* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
|
||||
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
|
||||
/* 22 */ ED_QUOTED_INSERT, /* ^V */
|
||||
/* 23 */ ED_DELETE_PREV_WORD, /* ^W */
|
||||
/* 24 */ ED_UNASSIGNED, /* ^X */
|
||||
/* 25 */ ED_TTY_DSUSP, /* ^Y */
|
||||
/* 26 */ ED_TTY_SIGTSTP, /* ^Z */
|
||||
/* 25 */ ED_IGNORE, /* ^Y */
|
||||
/* 26 */ ED_IGNORE, /* ^Z */
|
||||
/* 27 */ VI_COMMAND_MODE, /* ^[ */
|
||||
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
|
||||
/* 28 */ ED_IGNORE, /* ^\ */
|
||||
/* 29 */ ED_UNASSIGNED, /* ^] */
|
||||
/* 30 */ ED_UNASSIGNED, /* ^^ */
|
||||
/* 31 */ ED_UNASSIGNED, /* ^_ */
|
||||
@ -631,11 +634,11 @@ private const el_action_t el_map_vi_insert[] = {
|
||||
/* 255 */ ED_INSERT /* M-^? */
|
||||
};
|
||||
|
||||
private const el_action_t el_map_vi_command[] = {
|
||||
static const el_action_t el_map_vi_command[] = {
|
||||
/* 0 */ ED_UNASSIGNED, /* ^@ */
|
||||
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
|
||||
/* 2 */ ED_UNASSIGNED, /* ^B */
|
||||
/* 3 */ ED_TTY_SIGINT, /* ^C */
|
||||
/* 3 */ ED_IGNORE, /* ^C */
|
||||
/* 4 */ ED_UNASSIGNED, /* ^D */
|
||||
/* 5 */ ED_MOVE_TO_END, /* ^E */
|
||||
/* 6 */ ED_UNASSIGNED, /* ^F */
|
||||
@ -647,11 +650,11 @@ private const el_action_t el_map_vi_command[] = {
|
||||
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
|
||||
/* 13 */ ED_NEWLINE, /* ^M */
|
||||
/* 14 */ ED_NEXT_HISTORY, /* ^N */
|
||||
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
|
||||
/* 15 */ ED_IGNORE, /* ^O */
|
||||
/* 16 */ ED_PREV_HISTORY, /* ^P */
|
||||
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
|
||||
/* 17 */ ED_IGNORE, /* ^Q */
|
||||
/* 18 */ ED_REDISPLAY, /* ^R */
|
||||
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
|
||||
/* 19 */ ED_IGNORE, /* ^S */
|
||||
/* 20 */ ED_UNASSIGNED, /* ^T */
|
||||
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
|
||||
/* 22 */ ED_UNASSIGNED, /* ^V */
|
||||
@ -660,7 +663,7 @@ private const el_action_t el_map_vi_command[] = {
|
||||
/* 25 */ ED_UNASSIGNED, /* ^Y */
|
||||
/* 26 */ ED_UNASSIGNED, /* ^Z */
|
||||
/* 27 */ EM_META_NEXT, /* ^[ */
|
||||
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
|
||||
/* 28 */ ED_IGNORE, /* ^\ */
|
||||
/* 29 */ ED_UNASSIGNED, /* ^] */
|
||||
/* 30 */ ED_UNASSIGNED, /* ^^ */
|
||||
/* 31 */ ED_UNASSIGNED, /* ^_ */
|
||||
@ -894,7 +897,7 @@ private const el_action_t el_map_vi_command[] = {
|
||||
/* map_init():
|
||||
* Initialize and allocate the maps
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
map_init(EditLine *el)
|
||||
{
|
||||
|
||||
@ -910,24 +913,24 @@ 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, help__get(),
|
||||
(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, func__get(), sizeof(*el->el_map.func)
|
||||
memcpy(el->el_map.func, el_func, sizeof(*el->el_map.func)
|
||||
* EL_NUM_FCNS);
|
||||
el->el_map.nfunc = EL_NUM_FCNS;
|
||||
|
||||
@ -943,7 +946,7 @@ map_init(EditLine *el)
|
||||
/* map_end():
|
||||
* Free the space taken by the editor maps
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
map_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -964,7 +967,7 @@ map_end(EditLine *el)
|
||||
/* map_init_nls():
|
||||
* Find all the printable keys and bind them to self insert
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
map_init_nls(EditLine *el)
|
||||
{
|
||||
int i;
|
||||
@ -972,7 +975,7 @@ map_init_nls(EditLine *el)
|
||||
el_action_t *map = el->el_map.key;
|
||||
|
||||
for (i = 0200; i <= 0377; i++)
|
||||
if (Isprint(i))
|
||||
if (iswprint(i))
|
||||
map[i] = ED_INSERT;
|
||||
}
|
||||
|
||||
@ -980,10 +983,10 @@ map_init_nls(EditLine *el)
|
||||
/* map_init_meta():
|
||||
* Bind all the meta keys to the appropriate ESC-<key> sequence
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
map_init_meta(EditLine *el)
|
||||
{
|
||||
Char buf[3];
|
||||
wchar_t buf[3];
|
||||
int i;
|
||||
el_action_t *map = el->el_map.key;
|
||||
el_action_t *alt = el->el_map.alt;
|
||||
@ -1001,7 +1004,7 @@ map_init_meta(EditLine *el)
|
||||
} else
|
||||
map = alt;
|
||||
}
|
||||
buf[0] = (Char) i;
|
||||
buf[0] = (wchar_t)i;
|
||||
buf[2] = 0;
|
||||
for (i = 0200; i <= 0377; i++)
|
||||
switch (map[i]) {
|
||||
@ -1021,7 +1024,7 @@ map_init_meta(EditLine *el)
|
||||
/* map_init_vi():
|
||||
* Initialize the vi bindings
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
map_init_vi(EditLine *el)
|
||||
{
|
||||
int i;
|
||||
@ -1051,11 +1054,11 @@ map_init_vi(EditLine *el)
|
||||
/* map_init_emacs():
|
||||
* Initialize the emacs bindings
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
map_init_emacs(EditLine *el)
|
||||
{
|
||||
int i;
|
||||
Char buf[3];
|
||||
wchar_t buf[3];
|
||||
el_action_t *key = el->el_map.key;
|
||||
el_action_t *alt = el->el_map.alt;
|
||||
const el_action_t *emacs = el->el_map.emacs;
|
||||
@ -1085,15 +1088,15 @@ map_init_emacs(EditLine *el)
|
||||
/* map_set_editor():
|
||||
* Set the editor
|
||||
*/
|
||||
protected int
|
||||
map_set_editor(EditLine *el, Char *editor)
|
||||
libedit_private int
|
||||
map_set_editor(EditLine *el, wchar_t *editor)
|
||||
{
|
||||
|
||||
if (Strcmp(editor, STR("emacs")) == 0) {
|
||||
if (wcscmp(editor, L"emacs") == 0) {
|
||||
map_init_emacs(el);
|
||||
return 0;
|
||||
}
|
||||
if (Strcmp(editor, STR("vi")) == 0) {
|
||||
if (wcscmp(editor, L"vi") == 0) {
|
||||
map_init_vi(el);
|
||||
return 0;
|
||||
}
|
||||
@ -1104,18 +1107,18 @@ map_set_editor(EditLine *el, Char *editor)
|
||||
/* map_get_editor():
|
||||
* Retrieve the editor
|
||||
*/
|
||||
protected int
|
||||
map_get_editor(EditLine *el, const Char **editor)
|
||||
libedit_private int
|
||||
map_get_editor(EditLine *el, const wchar_t **editor)
|
||||
{
|
||||
|
||||
if (editor == NULL)
|
||||
return -1;
|
||||
switch (el->el_map.type) {
|
||||
case MAP_EMACS:
|
||||
*editor = STR("emacs");
|
||||
*editor = L"emacs";
|
||||
return 0;
|
||||
case MAP_VI:
|
||||
*editor = STR("vi");
|
||||
*editor = L"vi";
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
@ -1125,8 +1128,8 @@ map_get_editor(EditLine *el, const Char **editor)
|
||||
/* map_print_key():
|
||||
* Print the function description for 1 key
|
||||
*/
|
||||
private void
|
||||
map_print_key(EditLine *el, el_action_t *map, const Char *in)
|
||||
static void
|
||||
map_print_key(EditLine *el, el_action_t *map, const wchar_t *in)
|
||||
{
|
||||
char outbuf[EL_BUFSIZ];
|
||||
el_bindings_t *bp, *ep;
|
||||
@ -1137,7 +1140,7 @@ map_print_key(EditLine *el, el_action_t *map, const Char *in)
|
||||
for (bp = el->el_map.help; bp < ep; bp++)
|
||||
if (bp->func == map[(unsigned char) *in]) {
|
||||
(void) fprintf(el->el_outfile,
|
||||
"%s\t->\t" FSTR "\n", outbuf, bp->name);
|
||||
"%s\t->\t%ls\n", outbuf, bp->name);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
@ -1148,16 +1151,16 @@ map_print_key(EditLine *el, el_action_t *map, const Char *in)
|
||||
/* map_print_some_keys():
|
||||
* Print keys from first to last
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
|
||||
{
|
||||
el_bindings_t *bp, *ep;
|
||||
Char firstbuf[2], lastbuf[2];
|
||||
wchar_t firstbuf[2], lastbuf[2];
|
||||
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
|
||||
|
||||
firstbuf[0] = (Char)first;
|
||||
firstbuf[0] = first;
|
||||
firstbuf[1] = 0;
|
||||
lastbuf[0] = (Char)last;
|
||||
lastbuf[0] = last;
|
||||
lastbuf[1] = 0;
|
||||
if (map[first] == ED_UNASSIGNED) {
|
||||
if (first == last) {
|
||||
@ -1174,7 +1177,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
|
||||
if (first == last) {
|
||||
(void) keymacro__decode_str(firstbuf, unparsbuf,
|
||||
sizeof(unparsbuf), STRQQ);
|
||||
(void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
|
||||
(void) fprintf(el->el_outfile, "%-15s-> %ls\n",
|
||||
unparsbuf, bp->name);
|
||||
} else {
|
||||
(void) keymacro__decode_str(firstbuf, unparsbuf,
|
||||
@ -1182,7 +1185,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
|
||||
(void) keymacro__decode_str(lastbuf, extrabuf,
|
||||
sizeof(extrabuf), STRQQ);
|
||||
(void) fprintf(el->el_outfile,
|
||||
"%-4s to %-7s-> " FSTR "\n",
|
||||
"%-4s to %-7s-> %ls\n",
|
||||
unparsbuf, extrabuf, bp->name);
|
||||
}
|
||||
return;
|
||||
@ -1212,7 +1215,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
|
||||
/* map_print_all_keys():
|
||||
* Print the function description for all keys.
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
map_print_all_keys(EditLine *el)
|
||||
{
|
||||
int prev, i;
|
||||
@ -1238,25 +1241,25 @@ map_print_all_keys(EditLine *el)
|
||||
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
|
||||
|
||||
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
|
||||
keymacro_print(el, STR(""));
|
||||
keymacro_print(el, L"");
|
||||
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
|
||||
terminal_print_arrow(el, STR(""));
|
||||
terminal_print_arrow(el, L"");
|
||||
}
|
||||
|
||||
|
||||
/* map_bind():
|
||||
* Add/remove/change bindings
|
||||
*/
|
||||
protected int
|
||||
map_bind(EditLine *el, int argc, const Char **argv)
|
||||
libedit_private int
|
||||
map_bind(EditLine *el, int argc, const wchar_t **argv)
|
||||
{
|
||||
el_action_t *map;
|
||||
int ntype, rem;
|
||||
const Char *p;
|
||||
Char inbuf[EL_BUFSIZ];
|
||||
Char outbuf[EL_BUFSIZ];
|
||||
const Char *in = NULL;
|
||||
Char *out;
|
||||
const wchar_t *p;
|
||||
wchar_t inbuf[EL_BUFSIZ];
|
||||
wchar_t outbuf[EL_BUFSIZ];
|
||||
const wchar_t *in = NULL;
|
||||
wchar_t *out;
|
||||
el_bindings_t *bp, *ep;
|
||||
int cmd;
|
||||
int key;
|
||||
@ -1277,11 +1280,6 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
case 's':
|
||||
ntype = XK_STR;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'c':
|
||||
ntype = XK_EXE;
|
||||
break;
|
||||
#endif
|
||||
case 'k':
|
||||
key = 1;
|
||||
break;
|
||||
@ -1302,12 +1300,12 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
ep = &el->el_map.help[el->el_map.nfunc];
|
||||
for (bp = el->el_map.help; bp < ep; bp++)
|
||||
(void) fprintf(el->el_outfile,
|
||||
"" FSTR "\n\t" FSTR "\n",
|
||||
"%ls\n\t%ls\n",
|
||||
bp->name, bp->description);
|
||||
return 0;
|
||||
default:
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Invalid switch `%lc'.\n",
|
||||
"%ls: Invalid switch `%lc'.\n",
|
||||
argv[0], (wint_t)p[1]);
|
||||
}
|
||||
else
|
||||
@ -1321,7 +1319,7 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
in = argv[argc++];
|
||||
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Invalid \\ or ^ in instring.\n",
|
||||
"%ls: Invalid \\ or ^ in instring.\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
@ -1354,10 +1352,9 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
|
||||
switch (ntype) {
|
||||
case XK_STR:
|
||||
case XK_EXE:
|
||||
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
|
||||
"%ls: Invalid \\ or ^ in outstring.\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (key)
|
||||
@ -1370,7 +1367,7 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
case XK_CMD:
|
||||
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Invalid command `" FSTR "'.\n",
|
||||
"%ls: Invalid command `%ls'.\n",
|
||||
argv[0], argv[argc]);
|
||||
return -1;
|
||||
}
|
||||
@ -1399,8 +1396,9 @@ map_bind(EditLine *el, int argc, const Char **argv)
|
||||
/* map_addfunc():
|
||||
* add a user defined function
|
||||
*/
|
||||
protected int
|
||||
map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func)
|
||||
libedit_private int
|
||||
map_addfunc(EditLine *el, const wchar_t *name, const wchar_t *help,
|
||||
el_func_t func)
|
||||
{
|
||||
void *p;
|
||||
size_t nf = el->el_map.nfunc + 1;
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: map.h,v 1.10 2014/07/06 18:15:34 christos Exp $ */
|
||||
/* $NetBSD: map.h,v 1.13 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)map.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,12 +40,13 @@
|
||||
#ifndef _h_el_map
|
||||
#define _h_el_map
|
||||
|
||||
typedef struct el_bindings_t { /* for the "bind" shell command */
|
||||
const Char *name; /* function name for bind command */
|
||||
int func; /* function numeric value */
|
||||
const Char *description; /* description of function */
|
||||
} el_bindings_t;
|
||||
typedef el_action_t (*el_func_t)(EditLine *, wint_t);
|
||||
|
||||
typedef struct el_bindings_t { /* for the "bind" shell command */
|
||||
const wchar_t *name; /* function name for bind command */
|
||||
int func; /* function numeric value */
|
||||
const wchar_t *description; /* description of function */
|
||||
} el_bindings_t;
|
||||
|
||||
typedef struct el_map_t {
|
||||
el_action_t *alt; /* The current alternate key map */
|
||||
@ -66,13 +66,14 @@ typedef struct el_map_t {
|
||||
|
||||
#define N_KEYS 256
|
||||
|
||||
protected int map_bind(EditLine *, int, const Char **);
|
||||
protected int map_init(EditLine *);
|
||||
protected void map_end(EditLine *);
|
||||
protected void map_init_vi(EditLine *);
|
||||
protected void map_init_emacs(EditLine *);
|
||||
protected int map_set_editor(EditLine *, Char *);
|
||||
protected int map_get_editor(EditLine *, const Char **);
|
||||
protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t);
|
||||
libedit_private int map_bind(EditLine *, int, const wchar_t **);
|
||||
libedit_private int map_init(EditLine *);
|
||||
libedit_private void map_end(EditLine *);
|
||||
libedit_private void map_init_vi(EditLine *);
|
||||
libedit_private void map_init_emacs(EditLine *);
|
||||
libedit_private int map_set_editor(EditLine *, wchar_t *);
|
||||
libedit_private int map_get_editor(EditLine *, const wchar_t **);
|
||||
libedit_private int map_addfunc(EditLine *, const wchar_t *, const wchar_t *,
|
||||
el_func_t);
|
||||
|
||||
#endif /* _h_el_map */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.c,v 1.35 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: parse.c,v 1.35 2016/02/17 19:47:49 christos Exp $");
|
||||
__RCSID("$NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* parse.c: parse an editline extended command
|
||||
@ -62,35 +60,35 @@ __FBSDID("$FreeBSD$");
|
||||
#include "el.h"
|
||||
#include "parse.h"
|
||||
|
||||
private const struct {
|
||||
const Char *name;
|
||||
int (*func)(EditLine *, int, const Char **);
|
||||
static const struct {
|
||||
const wchar_t *name;
|
||||
int (*func)(EditLine *, int, const wchar_t **);
|
||||
} cmds[] = {
|
||||
{ STR("bind"), map_bind },
|
||||
{ STR("echotc"), terminal_echotc },
|
||||
{ STR("edit"), el_editmode },
|
||||
{ STR("history"), hist_command },
|
||||
{ STR("telltc"), terminal_telltc },
|
||||
{ STR("settc"), terminal_settc },
|
||||
{ STR("setty"), tty_stty },
|
||||
{ NULL, NULL }
|
||||
{ L"bind", map_bind },
|
||||
{ L"echotc", terminal_echotc },
|
||||
{ L"edit", el_editmode },
|
||||
{ L"history", hist_command },
|
||||
{ L"telltc", terminal_telltc },
|
||||
{ L"settc", terminal_settc },
|
||||
{ L"setty", tty_stty },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
/* parse_line():
|
||||
* Parse a line and dispatch it
|
||||
*/
|
||||
protected int
|
||||
parse_line(EditLine *el, const Char *line)
|
||||
libedit_private int
|
||||
parse_line(EditLine *el, const wchar_t *line)
|
||||
{
|
||||
const Char **argv;
|
||||
const wchar_t **argv;
|
||||
int argc;
|
||||
TYPE(Tokenizer) *tok;
|
||||
TokenizerW *tok;
|
||||
|
||||
tok = FUN(tok,init)(NULL);
|
||||
FUN(tok,str)(tok, line, &argc, &argv);
|
||||
argc = FUN(el,parse)(el, argc, argv);
|
||||
FUN(tok,end)(tok);
|
||||
tok = tok_winit(NULL);
|
||||
tok_wstr(tok, line, &argc, &argv);
|
||||
argc = el_wparse(el, argc, argv);
|
||||
tok_wend(tok);
|
||||
return argc;
|
||||
}
|
||||
|
||||
@ -98,26 +96,26 @@ parse_line(EditLine *el, const Char *line)
|
||||
/* el_parse():
|
||||
* Command dispatcher
|
||||
*/
|
||||
public int
|
||||
FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
|
||||
int
|
||||
el_wparse(EditLine *el, int argc, const wchar_t *argv[])
|
||||
{
|
||||
const Char *ptr;
|
||||
const wchar_t *ptr;
|
||||
int i;
|
||||
|
||||
if (argc < 1)
|
||||
return -1;
|
||||
ptr = Strchr(argv[0], ':');
|
||||
ptr = wcschr(argv[0], L':');
|
||||
if (ptr != NULL) {
|
||||
Char *tprog;
|
||||
wchar_t *tprog;
|
||||
size_t l;
|
||||
|
||||
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) Strncpy(tprog, argv[0], l);
|
||||
(void) wcsncpy(tprog, argv[0], l);
|
||||
tprog[l] = '\0';
|
||||
ptr++;
|
||||
l = (size_t)el_match(el->el_prog, tprog);
|
||||
@ -128,7 +126,7 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
|
||||
ptr = argv[0];
|
||||
|
||||
for (i = 0; cmds[i].name != NULL; i++)
|
||||
if (Strcmp(cmds[i].name, ptr) == 0) {
|
||||
if (wcscmp(cmds[i].name, ptr) == 0) {
|
||||
i = (*cmds[i].func) (el, argc, argv);
|
||||
return -i;
|
||||
}
|
||||
@ -140,10 +138,10 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
|
||||
* Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
|
||||
* the appropriate character or -1 if the escape is not valid
|
||||
*/
|
||||
protected int
|
||||
parse__escape(const Char **ptr)
|
||||
libedit_private int
|
||||
parse__escape(const wchar_t **ptr)
|
||||
{
|
||||
const Char *p;
|
||||
const wchar_t *p;
|
||||
wint_t c;
|
||||
|
||||
p = *ptr;
|
||||
@ -178,28 +176,28 @@ parse__escape(const Char **ptr)
|
||||
case 'e':
|
||||
c = '\033'; /* Escape */
|
||||
break;
|
||||
case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
|
||||
{
|
||||
int i;
|
||||
const Char hex[] = STR("0123456789ABCDEF");
|
||||
const Char *h;
|
||||
++p;
|
||||
if (*p++ != '+')
|
||||
return -1;
|
||||
case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
|
||||
{
|
||||
int i;
|
||||
const wchar_t hex[] = L"0123456789ABCDEF";
|
||||
const wchar_t *h;
|
||||
++p;
|
||||
if (*p++ != '+')
|
||||
return -1;
|
||||
c = 0;
|
||||
for (i = 0; i < 5; ++i) {
|
||||
h = Strchr(hex, *p++);
|
||||
if (!h && i < 4)
|
||||
return -1;
|
||||
else if (h)
|
||||
c = (c << 4) | ((int)(h - hex));
|
||||
else
|
||||
--p;
|
||||
}
|
||||
if (c > 0x10FFFF) /* outside valid character range */
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 5; ++i) {
|
||||
h = wcschr(hex, *p++);
|
||||
if (!h && i < 4)
|
||||
return -1;
|
||||
else if (h)
|
||||
c = (c << 4) | ((int)(h - hex));
|
||||
else
|
||||
--p;
|
||||
}
|
||||
if (c > 0x10FFFF) /* outside valid character range */
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
@ -240,10 +238,10 @@ parse__escape(const Char **ptr)
|
||||
/* parse__string():
|
||||
* Parse the escapes from in and put the raw string out
|
||||
*/
|
||||
protected Char *
|
||||
parse__string(Char *out, const Char *in)
|
||||
libedit_private wchar_t *
|
||||
parse__string(wchar_t *out, const wchar_t *in)
|
||||
{
|
||||
Char *rv = out;
|
||||
wchar_t *rv = out;
|
||||
int n;
|
||||
|
||||
for (;;)
|
||||
@ -256,7 +254,7 @@ parse__string(Char *out, const Char *in)
|
||||
case '^':
|
||||
if ((n = parse__escape(&in)) == -1)
|
||||
return NULL;
|
||||
*out++ = (Char)n;
|
||||
*out++ = (wchar_t)n;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
@ -278,14 +276,14 @@ parse__string(Char *out, const Char *in)
|
||||
* Return the command number for the command string given
|
||||
* or -1 if one is not found
|
||||
*/
|
||||
protected int
|
||||
parse_cmd(EditLine *el, const Char *cmd)
|
||||
libedit_private int
|
||||
parse_cmd(EditLine *el, const wchar_t *cmd)
|
||||
{
|
||||
el_bindings_t *b = el->el_map.help;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < el->el_map.nfunc; i++)
|
||||
if (Strcmp(b[i].name, cmd) == 0)
|
||||
if (wcscmp(b[i].name, cmd) == 0)
|
||||
return b[i].func;
|
||||
return -1;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
|
||||
/* $NetBSD: parse.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)parse.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,9 +40,9 @@
|
||||
#ifndef _h_el_parse
|
||||
#define _h_el_parse
|
||||
|
||||
protected int parse_line(EditLine *, const Char *);
|
||||
protected int parse__escape(const Char **);
|
||||
protected Char *parse__string(Char *, const Char *);
|
||||
protected int parse_cmd(EditLine *, const Char *);
|
||||
libedit_private int parse_line(EditLine *, const wchar_t *);
|
||||
libedit_private int parse__escape(const wchar_t **);
|
||||
libedit_private wchar_t *parse__string(wchar_t *, const wchar_t *);
|
||||
libedit_private int parse_cmd(EditLine *, const wchar_t *);
|
||||
|
||||
#endif /* _h_el_parse */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: prompt.c,v 1.23 2016/02/16 15:53:48 christos Exp $ */
|
||||
/* $NetBSD: prompt.c,v 1.27 2017/06/27 23:25:13 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: prompt.c,v 1.23 2016/02/16 15:53:48 christos Exp $");
|
||||
__RCSID("$NetBSD: prompt.c,v 1.27 2017/06/27 23:25:13 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* prompt.c: Prompt printing functions
|
||||
@ -49,17 +47,17 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include "el.h"
|
||||
|
||||
private Char *prompt_default(EditLine *);
|
||||
private Char *prompt_default_r(EditLine *);
|
||||
static wchar_t *prompt_default(EditLine *);
|
||||
static wchar_t *prompt_default_r(EditLine *);
|
||||
|
||||
/* prompt_default():
|
||||
* Just a default prompt, in case the user did not provide one
|
||||
*/
|
||||
private Char *
|
||||
static wchar_t *
|
||||
/*ARGSUSED*/
|
||||
prompt_default(EditLine *el __attribute__((__unused__)))
|
||||
{
|
||||
static Char a[3] = {'?', ' ', '\0'};
|
||||
static wchar_t a[3] = L"? ";
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -68,11 +66,11 @@ prompt_default(EditLine *el __attribute__((__unused__)))
|
||||
/* prompt_default_r():
|
||||
* Just a default rprompt, in case the user did not provide one
|
||||
*/
|
||||
private Char *
|
||||
static wchar_t *
|
||||
/*ARGSUSED*/
|
||||
prompt_default_r(EditLine *el __attribute__((__unused__)))
|
||||
{
|
||||
static Char a[1] = {'\0'};
|
||||
static wchar_t a[1] = L"";
|
||||
|
||||
return a;
|
||||
}
|
||||
@ -81,12 +79,11 @@ prompt_default_r(EditLine *el __attribute__((__unused__)))
|
||||
/* prompt_print():
|
||||
* Print the prompt and update the prompt position.
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
prompt_print(EditLine *el, int op)
|
||||
{
|
||||
el_prompt_t *elp;
|
||||
Char *p;
|
||||
int ignore = 0;
|
||||
wchar_t *p;
|
||||
|
||||
if (op == EL_PROMPT)
|
||||
elp = &el->el_prompt;
|
||||
@ -101,13 +98,17 @@ prompt_print(EditLine *el, int op)
|
||||
|
||||
for (; *p; p++) {
|
||||
if (elp->p_ignore == *p) {
|
||||
ignore = !ignore;
|
||||
wchar_t *litstart = ++p;
|
||||
while (*p && *p != elp->p_ignore)
|
||||
p++;
|
||||
if (!*p || !p[1]) {
|
||||
// XXX: We lose the last literal
|
||||
break;
|
||||
}
|
||||
re_putliteral(el, litstart, p++);
|
||||
continue;
|
||||
}
|
||||
if (ignore)
|
||||
terminal__putc(el, *p);
|
||||
else
|
||||
re_putc(el, *p, 1);
|
||||
re_putc(el, *p, 1);
|
||||
}
|
||||
|
||||
elp->p_pos.v = el->el_refresh.r_cursor.v;
|
||||
@ -118,7 +119,7 @@ prompt_print(EditLine *el, int op)
|
||||
/* prompt_init():
|
||||
* Initialize the prompt stuff
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
prompt_init(EditLine *el)
|
||||
{
|
||||
|
||||
@ -137,7 +138,7 @@ prompt_init(EditLine *el)
|
||||
/* prompt_end():
|
||||
* Clean up the prompt stuff
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
/*ARGSUSED*/
|
||||
prompt_end(EditLine *el __attribute__((__unused__)))
|
||||
{
|
||||
@ -147,8 +148,8 @@ prompt_end(EditLine *el __attribute__((__unused__)))
|
||||
/* prompt_set():
|
||||
* Install a prompt printing function
|
||||
*/
|
||||
protected int
|
||||
prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
|
||||
libedit_private int
|
||||
prompt_set(EditLine *el, el_pfunc_t prf, wchar_t c, int op, int wide)
|
||||
{
|
||||
el_prompt_t *p;
|
||||
|
||||
@ -179,8 +180,8 @@ prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
|
||||
/* prompt_get():
|
||||
* Retrieve the prompt printing function
|
||||
*/
|
||||
protected int
|
||||
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
|
||||
libedit_private int
|
||||
prompt_get(EditLine *el, el_pfunc_t *prf, wchar_t *c, int op)
|
||||
{
|
||||
el_prompt_t *p;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: prompt.h,v 1.13 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: prompt.h,v 1.15 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)prompt.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -41,19 +40,19 @@
|
||||
#ifndef _h_el_prompt
|
||||
#define _h_el_prompt
|
||||
|
||||
typedef Char *(*el_pfunc_t)(EditLine *);
|
||||
typedef wchar_t *(*el_pfunc_t)(EditLine *);
|
||||
|
||||
typedef struct el_prompt_t {
|
||||
el_pfunc_t p_func; /* Function to return the prompt */
|
||||
coord_t p_pos; /* position in the line after prompt */
|
||||
Char p_ignore; /* character to start/end literal */
|
||||
wchar_t p_ignore; /* character to start/end literal */
|
||||
int p_wide;
|
||||
} el_prompt_t;
|
||||
|
||||
protected void prompt_print(EditLine *, int);
|
||||
protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
|
||||
protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
|
||||
protected int prompt_init(EditLine *);
|
||||
protected void prompt_end(EditLine *);
|
||||
libedit_private void prompt_print(EditLine *, int);
|
||||
libedit_private int prompt_set(EditLine *, el_pfunc_t, wchar_t, int, int);
|
||||
libedit_private int prompt_get(EditLine *, el_pfunc_t *, wchar_t *, int);
|
||||
libedit_private int prompt_init(EditLine *);
|
||||
libedit_private void prompt_end(EditLine *);
|
||||
|
||||
#endif /* _h_el_prompt */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: read.c,v 1.86 2016/03/02 19:24:20 christos Exp $ */
|
||||
/* $NetBSD: read.c,v 1.106 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,15 +37,12 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: read.c,v 1.86 2016/03/02 19:24:20 christos Exp $");
|
||||
__RCSID("$NetBSD: read.c,v 1.106 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* read.c: Clean this junk up! This is horrible code.
|
||||
* Terminal read functions
|
||||
* read.c: Terminal read functions
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -56,35 +53,74 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h>
|
||||
|
||||
#include "el.h"
|
||||
#include "fcns.h"
|
||||
#include "read.h"
|
||||
|
||||
#define OKCMD -1 /* must be -1! */
|
||||
#define EL_MAXMACRO 10
|
||||
|
||||
private int read__fixio(int, int);
|
||||
private int read_preread(EditLine *);
|
||||
private int read_char(EditLine *, wchar_t *);
|
||||
private int read_getcmd(EditLine *, el_action_t *, Char *);
|
||||
private void read_pop(c_macro_t *);
|
||||
struct macros {
|
||||
wchar_t **macro;
|
||||
int level;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct el_read_t {
|
||||
struct macros macros;
|
||||
el_rfunc_t read_char; /* Function to read a character. */
|
||||
int read_errno;
|
||||
};
|
||||
|
||||
static int read__fixio(int, int);
|
||||
static int read_char(EditLine *, wchar_t *);
|
||||
static int read_getcmd(EditLine *, el_action_t *, wchar_t *);
|
||||
static void read_clearmacros(struct macros *);
|
||||
static void read_pop(struct macros *);
|
||||
static const wchar_t *noedit_wgets(EditLine *, int *);
|
||||
|
||||
/* read_init():
|
||||
* Initialize the read stuff
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
read_init(EditLine *el)
|
||||
{
|
||||
struct macros *ma;
|
||||
|
||||
if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
|
||||
return -1;
|
||||
|
||||
ma = &el->el_read->macros;
|
||||
if ((ma->macro = el_calloc(EL_MAXMACRO, sizeof(*ma->macro))) == NULL) {
|
||||
free(el->el_read);
|
||||
return -1;
|
||||
}
|
||||
ma->level = -1;
|
||||
ma->offset = 0;
|
||||
|
||||
/* builtin read_char */
|
||||
el->el_read.read_char = read_char;
|
||||
el->el_read->read_char = read_char;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* el_read_end():
|
||||
* Free the data structures used by the read stuff.
|
||||
*/
|
||||
libedit_private void
|
||||
read_end(struct el_read_t *el_read)
|
||||
{
|
||||
read_clearmacros(&el_read->macros);
|
||||
el_free(el_read->macros.macro);
|
||||
el_read->macros.macro = NULL;
|
||||
el_free(el_read);
|
||||
}
|
||||
|
||||
/* el_read_setfn():
|
||||
* Set the read char function to the one provided.
|
||||
* If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
|
||||
*/
|
||||
protected int
|
||||
el_read_setfn(EditLine *el, el_rfunc_t rc)
|
||||
libedit_private int
|
||||
el_read_setfn(struct el_read_t *el_read, el_rfunc_t rc)
|
||||
{
|
||||
el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
|
||||
el_read->read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -93,42 +129,19 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
|
||||
* return the current read char function, or EL_BUILTIN_GETCFN
|
||||
* if it is the default one
|
||||
*/
|
||||
protected el_rfunc_t
|
||||
el_read_getfn(EditLine *el)
|
||||
libedit_private el_rfunc_t
|
||||
el_read_getfn(struct el_read_t *el_read)
|
||||
{
|
||||
return el->el_read.read_char == read_char ?
|
||||
EL_BUILTIN_GETCFN : el->el_read.read_char;
|
||||
return el_read->read_char == read_char ?
|
||||
EL_BUILTIN_GETCFN : el_read->read_char;
|
||||
}
|
||||
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(A,B) ((A) < (B) ? (A) : (B))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_EDIT
|
||||
private void
|
||||
read_debug(EditLine *el)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor > el->el_line.lastchar)
|
||||
(void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
|
||||
if (el->el_line.cursor < el->el_line.buffer)
|
||||
(void) fprintf(el->el_errfile, "cursor < buffer\r\n");
|
||||
if (el->el_line.cursor > el->el_line.limit)
|
||||
(void) fprintf(el->el_errfile, "cursor > limit\r\n");
|
||||
if (el->el_line.lastchar > el->el_line.limit)
|
||||
(void) fprintf(el->el_errfile, "lastchar > limit\r\n");
|
||||
if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
|
||||
(void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
|
||||
}
|
||||
#endif /* DEBUG_EDIT */
|
||||
|
||||
|
||||
/* read__fixio():
|
||||
* Try to recover from a read error
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
private int
|
||||
static int
|
||||
read__fixio(int fd __attribute__((__unused__)), int e)
|
||||
{
|
||||
|
||||
@ -186,49 +199,17 @@ read__fixio(int fd __attribute__((__unused__)), int e)
|
||||
}
|
||||
|
||||
|
||||
/* read_preread():
|
||||
* Try to read the stuff in the input queue;
|
||||
*/
|
||||
private int
|
||||
read_preread(EditLine *el)
|
||||
{
|
||||
int chrs = 0;
|
||||
|
||||
if (el->el_tty.t_mode == ED_IO)
|
||||
return 0;
|
||||
|
||||
#ifndef WIDECHAR
|
||||
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
|
||||
* properly with partial wide/UTF-8 characters would need some careful work. */
|
||||
#ifdef FIONREAD
|
||||
(void) ioctl(el->el_infd, FIONREAD, &chrs);
|
||||
if (chrs > 0) {
|
||||
char buf[EL_BUFSIZ];
|
||||
|
||||
chrs = read(el->el_infd, buf,
|
||||
(size_t) MIN(chrs, EL_BUFSIZ - 1));
|
||||
if (chrs > 0) {
|
||||
buf[chrs] = '\0';
|
||||
el_push(el, buf);
|
||||
}
|
||||
}
|
||||
#endif /* FIONREAD */
|
||||
#endif
|
||||
return chrs > 0;
|
||||
}
|
||||
|
||||
|
||||
/* el_push():
|
||||
* Push a macro
|
||||
*/
|
||||
public void
|
||||
FUN(el,push)(EditLine *el, const Char *str)
|
||||
void
|
||||
el_wpush(EditLine *el, const wchar_t *str)
|
||||
{
|
||||
c_macro_t *ma = &el->el_chared.c_macro;
|
||||
struct macros *ma = &el->el_read->macros;
|
||||
|
||||
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
|
||||
ma->level++;
|
||||
if ((ma->macro[ma->level] = Strdup(str)) != NULL)
|
||||
if ((ma->macro[ma->level] = wcsdup(str)) != NULL)
|
||||
return;
|
||||
ma->level--;
|
||||
}
|
||||
@ -238,24 +219,19 @@ FUN(el,push)(EditLine *el, const Char *str)
|
||||
|
||||
|
||||
/* read_getcmd():
|
||||
* Get next command from the input stream, return OKCMD on success.
|
||||
* Get next command from the input stream,
|
||||
* return 0 on success or -1 on EOF or error.
|
||||
* Character values > 255 are not looked up in the map, but inserted.
|
||||
*/
|
||||
private int
|
||||
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
|
||||
static int
|
||||
read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
|
||||
{
|
||||
static const Char meta = (Char)0x80;
|
||||
static const wchar_t meta = (wchar_t)0x80;
|
||||
el_action_t cmd;
|
||||
wchar_t wc;
|
||||
int num;
|
||||
|
||||
el->el_errno = 0;
|
||||
do {
|
||||
if ((num = el_wgetc(el, &wc)) != 1) {/* if EOF or error */
|
||||
el->el_errno = num == 0 ? 0 : errno;
|
||||
return 0; /* not OKCMD */
|
||||
}
|
||||
*ch = (Char)wc;
|
||||
if (el_wgetc(el, ch) != 1)
|
||||
return -1;
|
||||
|
||||
#ifdef KANJI
|
||||
if ((*ch & meta)) {
|
||||
@ -269,11 +245,9 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
|
||||
el->el_state.metanext = 0;
|
||||
*ch |= meta;
|
||||
}
|
||||
#ifdef WIDECHAR
|
||||
if (*ch >= N_KEYS)
|
||||
cmd = ED_INSERT;
|
||||
else
|
||||
#endif
|
||||
cmd = el->el_map.current[(unsigned char) *ch];
|
||||
if (cmd == ED_SEQUENCE_LEAD_IN) {
|
||||
keymacro_value_t val;
|
||||
@ -282,30 +256,24 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
|
||||
cmd = val.cmd;
|
||||
break;
|
||||
case XK_STR:
|
||||
FUN(el,push)(el, val.str);
|
||||
el_wpush(el, val.str);
|
||||
break;
|
||||
#ifdef notyet
|
||||
case XK_EXE:
|
||||
/* XXX: In the future to run a user function */
|
||||
RunCommand(val.str);
|
||||
break;
|
||||
#endif
|
||||
case XK_NOD:
|
||||
return -1;
|
||||
default:
|
||||
EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (el->el_map.alt == NULL)
|
||||
el->el_map.current = el->el_map.key;
|
||||
} while (cmd == ED_SEQUENCE_LEAD_IN);
|
||||
*cmdnum = cmd;
|
||||
return OKCMD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read_char():
|
||||
* Read a character from the tty.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
read_char(EditLine *el, wchar_t *cp)
|
||||
{
|
||||
ssize_t num_read;
|
||||
@ -320,7 +288,7 @@ read_char(EditLine *el, wchar_t *cp)
|
||||
int e = errno;
|
||||
switch (el->el_signal->sig_no) {
|
||||
case SIGCONT:
|
||||
FUN(el,set)(el, EL_REFRESH);
|
||||
el_wset(el, EL_REFRESH);
|
||||
/*FALLTHROUGH*/
|
||||
case SIGWINCH:
|
||||
sig_set(el);
|
||||
@ -345,9 +313,12 @@ read_char(EditLine *el, wchar_t *cp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
mbstate_t mbs;
|
||||
|
||||
++cbp;
|
||||
switch (ct_mbrtowc(cp, cbuf, cbp)) {
|
||||
/* This only works because UTF8 is stateless. */
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
switch (mbrtowc(cp, cbuf, cbp, &mbs)) {
|
||||
case (size_t)-1:
|
||||
if (cbp > 1) {
|
||||
/*
|
||||
@ -380,8 +351,8 @@ read_char(EditLine *el, wchar_t *cp)
|
||||
/* read_pop():
|
||||
* Pop a macro from the stack
|
||||
*/
|
||||
private void
|
||||
read_pop(c_macro_t *ma)
|
||||
static void
|
||||
read_pop(struct macros *ma)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -392,22 +363,25 @@ read_pop(c_macro_t *ma)
|
||||
ma->offset = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
read_clearmacros(struct macros *ma)
|
||||
{
|
||||
while (ma->level >= 0)
|
||||
el_free(ma->macro[ma->level--]);
|
||||
ma->offset = 0;
|
||||
}
|
||||
|
||||
/* el_wgetc():
|
||||
* Read a wide character
|
||||
*/
|
||||
public int
|
||||
int
|
||||
el_wgetc(EditLine *el, wchar_t *cp)
|
||||
{
|
||||
struct macros *ma = &el->el_read->macros;
|
||||
int num_read;
|
||||
c_macro_t *ma = &el->el_chared.c_macro;
|
||||
|
||||
terminal__flush(el);
|
||||
for (;;) {
|
||||
if (ma->level < 0) {
|
||||
if (!read_preread(el))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ma->level < 0)
|
||||
break;
|
||||
|
||||
@ -426,25 +400,23 @@ el_wgetc(EditLine *el, wchar_t *cp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile, "Turning raw mode on\n");
|
||||
#endif /* DEBUG_READ */
|
||||
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile, "Reading a character\n");
|
||||
#endif /* DEBUG_READ */
|
||||
num_read = (*el->el_read.read_char)(el, cp);
|
||||
num_read = (*el->el_read->read_char)(el, cp);
|
||||
|
||||
/*
|
||||
* Remember the original reason of a read failure
|
||||
* such that el_wgets() can restore it after doing
|
||||
* various cleanup operation that might change errno.
|
||||
*/
|
||||
if (num_read < 0)
|
||||
el->el_errno = errno;
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile, "Got it %lc\n", *cp);
|
||||
#endif /* DEBUG_READ */
|
||||
el->el_read->read_errno = errno;
|
||||
|
||||
return num_read;
|
||||
}
|
||||
|
||||
protected void
|
||||
libedit_private void
|
||||
read_prepare(EditLine *el)
|
||||
{
|
||||
if (el->el_flags & HANDLE_SIGNALS)
|
||||
@ -458,14 +430,14 @@ read_prepare(EditLine *el)
|
||||
we have the wrong size. */
|
||||
el_resize(el);
|
||||
re_clear_display(el); /* reset the display stuff */
|
||||
ch_reset(el, 0);
|
||||
ch_reset(el);
|
||||
re_refresh(el); /* print the prompt */
|
||||
|
||||
if (el->el_flags & UNBUFFERED)
|
||||
terminal__flush(el);
|
||||
}
|
||||
|
||||
protected void
|
||||
libedit_private void
|
||||
read_finish(EditLine *el)
|
||||
{
|
||||
if ((el->el_flags & UNBUFFERED) == 0)
|
||||
@ -474,56 +446,52 @@ read_finish(EditLine *el)
|
||||
sig_clr(el);
|
||||
}
|
||||
|
||||
public const Char *
|
||||
FUN(el,gets)(EditLine *el, int *nread)
|
||||
static const wchar_t *
|
||||
noedit_wgets(EditLine *el, int *nread)
|
||||
{
|
||||
el_line_t *lp = &el->el_line;
|
||||
int num;
|
||||
|
||||
while ((num = (*el->el_read->read_char)(el, lp->lastchar)) == 1) {
|
||||
if (lp->lastchar + 1 >= lp->limit &&
|
||||
!ch_enlargebufs(el, (size_t)2))
|
||||
break;
|
||||
lp->lastchar++;
|
||||
if (el->el_flags & UNBUFFERED ||
|
||||
lp->lastchar[-1] == '\r' ||
|
||||
lp->lastchar[-1] == '\n')
|
||||
break;
|
||||
}
|
||||
if (num == -1 && errno == EINTR)
|
||||
lp->lastchar = lp->buffer;
|
||||
lp->cursor = lp->lastchar;
|
||||
*lp->lastchar = '\0';
|
||||
*nread = (int)(lp->lastchar - lp->buffer);
|
||||
return *nread ? lp->buffer : NULL;
|
||||
}
|
||||
|
||||
const wchar_t *
|
||||
el_wgets(EditLine *el, int *nread)
|
||||
{
|
||||
int retval;
|
||||
el_action_t cmdnum = 0;
|
||||
int num; /* how many chars we have read at NL */
|
||||
wchar_t wc;
|
||||
Char ch, *cp;
|
||||
int crlf = 0;
|
||||
wchar_t ch;
|
||||
int nrb;
|
||||
#ifdef FIONREAD
|
||||
c_macro_t *ma = &el->el_chared.c_macro;
|
||||
#endif /* FIONREAD */
|
||||
|
||||
if (nread == NULL)
|
||||
nread = &nrb;
|
||||
*nread = 0;
|
||||
el->el_read->read_errno = 0;
|
||||
|
||||
if (el->el_flags & NO_TTY) {
|
||||
size_t idx;
|
||||
|
||||
cp = el->el_line.buffer;
|
||||
while ((num = (*el->el_read.read_char)(el, &wc)) == 1) {
|
||||
*cp = (Char)wc;
|
||||
/* make sure there is space for next character */
|
||||
if (cp + 1 >= el->el_line.limit) {
|
||||
idx = (size_t)(cp - el->el_line.buffer);
|
||||
if (!ch_enlargebufs(el, (size_t)2))
|
||||
break;
|
||||
cp = &el->el_line.buffer[idx];
|
||||
}
|
||||
cp++;
|
||||
if (el->el_flags & UNBUFFERED)
|
||||
break;
|
||||
if (cp[-1] == '\r' || cp[-1] == '\n')
|
||||
break;
|
||||
}
|
||||
if (num == -1) {
|
||||
if (errno == EINTR)
|
||||
cp = el->el_line.buffer;
|
||||
el->el_errno = errno;
|
||||
}
|
||||
|
||||
goto noedit;
|
||||
el->el_line.lastchar = el->el_line.buffer;
|
||||
return noedit_wgets(el, nread);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FIONREAD
|
||||
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
|
||||
long chrs = 0;
|
||||
if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) {
|
||||
int chrs = 0;
|
||||
|
||||
(void) ioctl(el->el_infd, FIONREAD, &chrs);
|
||||
if (chrs == 0) {
|
||||
@ -540,83 +508,19 @@ FUN(el,gets)(EditLine *el, int *nread)
|
||||
read_prepare(el);
|
||||
|
||||
if (el->el_flags & EDIT_DISABLED) {
|
||||
size_t idx;
|
||||
|
||||
if ((el->el_flags & UNBUFFERED) == 0)
|
||||
cp = el->el_line.buffer;
|
||||
else
|
||||
cp = el->el_line.lastchar;
|
||||
|
||||
el->el_line.lastchar = el->el_line.buffer;
|
||||
terminal__flush(el);
|
||||
|
||||
while ((num = (*el->el_read.read_char)(el, &wc)) == 1) {
|
||||
*cp = (Char)wc;
|
||||
/* make sure there is space next character */
|
||||
if (cp + 1 >= el->el_line.limit) {
|
||||
idx = (size_t)(cp - el->el_line.buffer);
|
||||
if (!ch_enlargebufs(el, (size_t)2))
|
||||
break;
|
||||
cp = &el->el_line.buffer[idx];
|
||||
}
|
||||
cp++;
|
||||
crlf = cp[-1] == '\r' || cp[-1] == '\n';
|
||||
if (el->el_flags & UNBUFFERED)
|
||||
break;
|
||||
if (crlf)
|
||||
break;
|
||||
}
|
||||
|
||||
if (num == -1) {
|
||||
if (errno == EINTR)
|
||||
cp = el->el_line.buffer;
|
||||
el->el_errno = errno;
|
||||
}
|
||||
|
||||
goto noedit;
|
||||
return noedit_wgets(el, nread);
|
||||
}
|
||||
|
||||
for (num = OKCMD; num == OKCMD;) { /* while still editing this
|
||||
* line */
|
||||
#ifdef DEBUG_EDIT
|
||||
read_debug(el);
|
||||
#endif /* DEBUG_EDIT */
|
||||
for (num = -1; num == -1;) { /* while still editing this line */
|
||||
/* if EOF or error */
|
||||
if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
|
||||
num = -1;
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile,
|
||||
"Returning from el_gets %d\n", num);
|
||||
#endif /* DEBUG_READ */
|
||||
if (read_getcmd(el, &cmdnum, &ch) == -1)
|
||||
break;
|
||||
}
|
||||
if (el->el_errno == EINTR) {
|
||||
el->el_line.buffer[0] = '\0';
|
||||
el->el_line.lastchar =
|
||||
el->el_line.cursor = el->el_line.buffer;
|
||||
break;
|
||||
}
|
||||
if ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
|
||||
#ifdef DEBUG_EDIT
|
||||
(void) fprintf(el->el_errfile,
|
||||
"ERROR: illegal command from key 0%o\r\n", ch);
|
||||
#endif /* DEBUG_EDIT */
|
||||
if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
|
||||
continue; /* try again */
|
||||
}
|
||||
/* now do the real command */
|
||||
#ifdef DEBUG_READ
|
||||
{
|
||||
el_bindings_t *b;
|
||||
for (b = el->el_map.help; b->name; b++)
|
||||
if (b->func == cmdnum)
|
||||
break;
|
||||
if (b->name)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"Executing " FSTR "\n", b->name);
|
||||
else
|
||||
(void) fprintf(el->el_errfile,
|
||||
"Error command = %d\n", cmdnum);
|
||||
}
|
||||
#endif /* DEBUG_READ */
|
||||
/* vi redo needs these way down the levels... */
|
||||
el->el_state.thiscmd = cmdnum;
|
||||
el->el_state.thisch = ch;
|
||||
@ -625,16 +529,12 @@ FUN(el,gets)(EditLine *el, int *nread)
|
||||
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
|
||||
if (cmdnum == VI_DELETE_PREV_CHAR &&
|
||||
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
|
||||
&& Isprint(el->el_chared.c_redo.pos[-1]))
|
||||
&& iswprint(el->el_chared.c_redo.pos[-1]))
|
||||
el->el_chared.c_redo.pos--;
|
||||
else
|
||||
*el->el_chared.c_redo.pos++ = ch;
|
||||
}
|
||||
retval = (*el->el_map.func[cmdnum]) (el, ch);
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile,
|
||||
"Returned state %d\n", retval );
|
||||
#endif /* DEBUG_READ */
|
||||
|
||||
/* save the last command here */
|
||||
el->el_state.lastcmd = cmdnum;
|
||||
@ -681,22 +581,15 @@ FUN(el,gets)(EditLine *el, int *nread)
|
||||
break;
|
||||
|
||||
case CC_FATAL: /* fatal error, reset to known state */
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile,
|
||||
"*** editor fatal ERROR ***\r\n\n");
|
||||
#endif /* DEBUG_READ */
|
||||
/* put (real) cursor in a known place */
|
||||
re_clear_display(el); /* reset the display stuff */
|
||||
ch_reset(el, 1); /* reset the input pointers */
|
||||
ch_reset(el); /* reset the input pointers */
|
||||
read_clearmacros(&el->el_read->macros);
|
||||
re_refresh(el); /* print the prompt again */
|
||||
break;
|
||||
|
||||
case CC_ERROR:
|
||||
default: /* functions we don't know about */
|
||||
#ifdef DEBUG_READ
|
||||
(void) fprintf(el->el_errfile,
|
||||
"*** editor ERROR ***\r\n\n");
|
||||
#endif /* DEBUG_READ */
|
||||
terminal_beep(el);
|
||||
terminal__flush(el);
|
||||
break;
|
||||
@ -713,19 +606,14 @@ FUN(el,gets)(EditLine *el, int *nread)
|
||||
if ((el->el_flags & UNBUFFERED) == 0) {
|
||||
read_finish(el);
|
||||
*nread = num != -1 ? num : 0;
|
||||
} else {
|
||||
} else
|
||||
*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
|
||||
}
|
||||
goto done;
|
||||
noedit:
|
||||
el->el_line.cursor = el->el_line.lastchar = cp;
|
||||
*cp = '\0';
|
||||
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
|
||||
done:
|
||||
|
||||
if (*nread == 0) {
|
||||
if (num == -1) {
|
||||
*nread = -1;
|
||||
errno = el->el_errno;
|
||||
if (el->el_read->read_errno)
|
||||
errno = el->el_read->read_errno;
|
||||
}
|
||||
return NULL;
|
||||
} else
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: read.h,v 1.9 2016/02/24 17:13:22 christos Exp $ */
|
||||
/* $NetBSD: read.h,v 1.12 2016/05/22 19:44:26 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -27,8 +27,6 @@
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -37,16 +35,11 @@
|
||||
#ifndef _h_el_read
|
||||
#define _h_el_read
|
||||
|
||||
typedef int (*el_rfunc_t)(EditLine *, wchar_t *);
|
||||
|
||||
typedef struct el_read_t {
|
||||
el_rfunc_t read_char; /* Function to read a character */
|
||||
} el_read_t;
|
||||
|
||||
protected int read_init(EditLine *);
|
||||
protected void read_prepare(EditLine *);
|
||||
protected void read_finish(EditLine *);
|
||||
protected int el_read_setfn(EditLine *, el_rfunc_t);
|
||||
protected el_rfunc_t el_read_getfn(EditLine *);
|
||||
libedit_private int read_init(EditLine *);
|
||||
libedit_private void read_end(struct el_read_t *);
|
||||
libedit_private void read_prepare(EditLine *);
|
||||
libedit_private void read_finish(EditLine *);
|
||||
libedit_private int el_read_setfn(struct el_read_t *, el_rfunc_t);
|
||||
libedit_private el_rfunc_t el_read_getfn(struct el_read_t *);
|
||||
|
||||
#endif /* _h_el_read */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $ */
|
||||
/* $NetBSD: readline.c,v 1.157 2019/08/21 11:11:48 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -31,10 +31,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $");
|
||||
__RCSID("$NetBSD: readline.c,v 1.157 2019/08/21 11:11:48 christos Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -54,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "readline/readline.h"
|
||||
#include "el.h"
|
||||
#include "fcns.h"
|
||||
#include "filecomplete.h"
|
||||
|
||||
void rl_prep_terminal(int);
|
||||
@ -73,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;
|
||||
@ -81,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;
|
||||
@ -96,6 +95,7 @@ int rl_catch_sigwinch = 1;
|
||||
|
||||
int history_base = 1; /* probably never subject to change */
|
||||
int history_length = 0;
|
||||
int history_offset = 0;
|
||||
int max_input_history = 0;
|
||||
char history_expansion_char = '!';
|
||||
char history_subst_char = '^';
|
||||
@ -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;
|
||||
@ -122,6 +122,7 @@ int readline_echoing_p = 1;
|
||||
int _rl_print_completions_horizontally = 0;
|
||||
VFunction *rl_redisplay_function = NULL;
|
||||
Function *rl_startup_hook = NULL;
|
||||
int rl_did_startup_hook = 0;
|
||||
VFunction *rl_completion_display_matches_hook = NULL;
|
||||
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
|
||||
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
|
||||
@ -149,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
|
||||
@ -169,7 +170,6 @@ static unsigned char _el_rl_complete(EditLine *, int);
|
||||
static unsigned char _el_rl_tstp(EditLine *, int);
|
||||
static char *_get_prompt(EditLine *);
|
||||
static int _getc_function(EditLine *, wchar_t *);
|
||||
static HIST_ENTRY *_move_history(int);
|
||||
static int _history_expand_command(const char *, size_t, size_t,
|
||||
char **);
|
||||
static char *_rl_compat_sub(const char *, const char *,
|
||||
@ -177,6 +177,7 @@ static char *_rl_compat_sub(const char *, const char *,
|
||||
static int _rl_event_read_char(EditLine *, wchar_t *);
|
||||
static void _rl_update_pos(void);
|
||||
|
||||
static HIST_ENTRY rl_he;
|
||||
|
||||
/* ARGSUSED */
|
||||
static char *
|
||||
@ -187,25 +188,6 @@ _get_prompt(EditLine *el __attribute__((__unused__)))
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generic function for moving around history
|
||||
*/
|
||||
static HIST_ENTRY *
|
||||
_move_history(int op)
|
||||
{
|
||||
HistEvent ev;
|
||||
static HIST_ENTRY rl_he;
|
||||
|
||||
if (history(h, &ev, op) != 0)
|
||||
return NULL;
|
||||
|
||||
rl_he.line = ev.str;
|
||||
rl_he.data = NULL;
|
||||
|
||||
return &rl_he;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read one key from user defined input function
|
||||
*/
|
||||
@ -215,7 +197,7 @@ _getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = (*rl_getc_function)(NULL);
|
||||
i = (*rl_getc_function)(rl_instream);
|
||||
if (i == -1)
|
||||
return 0;
|
||||
*c = (wchar_t)i;
|
||||
@ -276,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;
|
||||
}
|
||||
@ -308,7 +296,9 @@ rl_initialize(void)
|
||||
if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
|
||||
editmode = 0;
|
||||
|
||||
e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
|
||||
e = el_init_internal(rl_readline_name, rl_instream, rl_outstream,
|
||||
stderr, fileno(rl_instream), fileno(rl_outstream), fileno(stderr),
|
||||
NO_RESET);
|
||||
|
||||
if (!editmode)
|
||||
el_set(e, EL_EDITMODE, 0);
|
||||
@ -335,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 */
|
||||
@ -404,8 +394,7 @@ rl_initialize(void)
|
||||
_resize_fun(e, &rl_line_buffer);
|
||||
_rl_update_pos();
|
||||
|
||||
if (rl_startup_hook)
|
||||
(*rl_startup_hook)(NULL, 0);
|
||||
tty_end(e, TCSADRAIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -427,19 +416,26 @@ readline(const char *p)
|
||||
|
||||
if (e == NULL || h == NULL)
|
||||
rl_initialize();
|
||||
if (rl_did_startup_hook == 0 && rl_startup_hook) {
|
||||
rl_did_startup_hook = 1;
|
||||
(*rl_startup_hook)(NULL, 0);
|
||||
}
|
||||
tty_init(e);
|
||||
|
||||
|
||||
rl_done = 0;
|
||||
|
||||
(void)setjmp(topbuf);
|
||||
buf = NULL;
|
||||
|
||||
/* update prompt accordingly to what has been passed */
|
||||
if (rl_set_prompt(prompt) == -1)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -459,7 +455,7 @@ readline(const char *p)
|
||||
|
||||
buf = strdup(ret);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
goto out;
|
||||
lastidx = count - 1;
|
||||
if (buf[lastidx] == '\n')
|
||||
buf[lastidx] = '\0';
|
||||
@ -469,6 +465,8 @@ readline(const char *p)
|
||||
history(h, &ev, H_GETSIZE);
|
||||
history_length = ev.num;
|
||||
|
||||
out:
|
||||
tty_end(e, TCSADRAIN);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -485,6 +483,7 @@ using_history(void)
|
||||
{
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
history_offset = history_length;
|
||||
}
|
||||
|
||||
|
||||
@ -516,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;
|
||||
@ -566,7 +565,7 @@ get_history_event(const char *cmd, int *cindex, int qchar)
|
||||
}
|
||||
|
||||
if ('0' <= cmd[idx] && cmd[idx] <= '9') {
|
||||
HIST_ENTRY *rl_he;
|
||||
HIST_ENTRY *he;
|
||||
|
||||
num = 0;
|
||||
while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
|
||||
@ -574,13 +573,13 @@ get_history_event(const char *cmd, int *cindex, int qchar)
|
||||
idx++;
|
||||
}
|
||||
if (sign)
|
||||
num = history_length - num + 1;
|
||||
num = history_length - num + history_base;
|
||||
|
||||
if (!(rl_he = history_get(num)))
|
||||
if (!(he = history_get(num)))
|
||||
return NULL;
|
||||
|
||||
*cindex = idx;
|
||||
return rl_he->line;
|
||||
return he->line;
|
||||
}
|
||||
sub = 0;
|
||||
if (cmd[idx] == '?') {
|
||||
@ -606,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';
|
||||
@ -700,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);
|
||||
@ -934,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;
|
||||
@ -1082,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;
|
||||
|
||||
@ -1144,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]);
|
||||
@ -1169,12 +1168,22 @@ void
|
||||
stifle_history(int max)
|
||||
{
|
||||
HistEvent ev;
|
||||
HIST_ENTRY *he;
|
||||
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
|
||||
if (history(h, &ev, H_SETSIZE, max) == 0)
|
||||
if (history(h, &ev, H_SETSIZE, max) == 0) {
|
||||
max_input_history = max;
|
||||
if (history_length > max)
|
||||
history_base = history_length - max;
|
||||
while (history_length > max) {
|
||||
he = remove_history(0);
|
||||
el_free(he->data);
|
||||
el_free((void *)(unsigned long)he->line);
|
||||
el_free(he);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1352,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;
|
||||
}
|
||||
|
||||
|
||||
@ -1373,6 +1388,28 @@ write_history(const char *filename)
|
||||
(errno ? errno : EINVAL) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
append_history(int n, const char *filename)
|
||||
{
|
||||
HistEvent ev;
|
||||
FILE *fp;
|
||||
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
if (filename == NULL && (filename = _default_history_file()) == NULL)
|
||||
return errno;
|
||||
|
||||
if ((fp = fopen(filename, "a")) == NULL)
|
||||
return errno;
|
||||
|
||||
if (history(h, &ev, H_NSAVE_FP, (size_t)n, fp) == -1) {
|
||||
int serrno = errno ? errno : EINVAL;
|
||||
fclose(fp);
|
||||
return serrno;
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns history ``num''th event
|
||||
@ -1389,25 +1426,37 @@ history_get(int num)
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
|
||||
if (num < history_base)
|
||||
return NULL;
|
||||
|
||||
/* save current position */
|
||||
if (history(h, &ev, H_CURR) != 0)
|
||||
return NULL;
|
||||
curr_num = ev.num;
|
||||
|
||||
/* start from the oldest */
|
||||
if (history(h, &ev, H_LAST) != 0)
|
||||
return NULL; /* error */
|
||||
|
||||
/* look forwards for event matching specified offset */
|
||||
if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
|
||||
return NULL;
|
||||
/*
|
||||
* use H_DELDATA to set to nth history (without delete) by passing
|
||||
* (void **)-1 -- as in history_set_pos
|
||||
*/
|
||||
if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0)
|
||||
goto out;
|
||||
|
||||
/* get current entry */
|
||||
if (history(h, &ev, H_CURR) != 0)
|
||||
goto out;
|
||||
if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0)
|
||||
goto out;
|
||||
she.line = ev.str;
|
||||
|
||||
/* restore pointer to where it was */
|
||||
(void)history(h, &ev, H_SET, curr_num);
|
||||
|
||||
return &she;
|
||||
|
||||
out:
|
||||
/* restore pointer to where it was */
|
||||
(void)history(h, &ev, H_SET, curr_num);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1419,17 +1468,20 @@ add_history(const char *line)
|
||||
{
|
||||
HistEvent ev;
|
||||
|
||||
if (line == NULL)
|
||||
return 0;
|
||||
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
|
||||
(void)history(h, &ev, H_ENTER, line);
|
||||
if (history(h, &ev, H_GETSIZE) == 0)
|
||||
history_length = ev.num;
|
||||
if (history(h, &ev, H_ENTER, line) == -1)
|
||||
return 0;
|
||||
|
||||
return !(history_length > 0); /* return 0 if all is okay */
|
||||
(void)history(h, &ev, H_GETSIZE);
|
||||
if (ev.num == history_length)
|
||||
history_base++;
|
||||
else {
|
||||
history_offset++;
|
||||
history_length = ev.num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1519,7 +1571,7 @@ clear_history(void)
|
||||
rl_initialize();
|
||||
|
||||
(void)history(h, &ev, H_CLEAR);
|
||||
history_length = 0;
|
||||
history_offset = history_length = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1529,21 +1581,43 @@ clear_history(void)
|
||||
int
|
||||
where_history(void)
|
||||
{
|
||||
HistEvent ev;
|
||||
int curr_num, off;
|
||||
|
||||
if (history(h, &ev, H_CURR) != 0)
|
||||
return 0;
|
||||
curr_num = ev.num;
|
||||
|
||||
(void)history(h, &ev, H_FIRST);
|
||||
off = 1;
|
||||
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
|
||||
off++;
|
||||
|
||||
return off;
|
||||
return history_offset;
|
||||
}
|
||||
|
||||
static HIST_ENTRY **_history_listp;
|
||||
static HIST_ENTRY *_history_list;
|
||||
|
||||
HIST_ENTRY **
|
||||
history_list(void)
|
||||
{
|
||||
HistEvent ev;
|
||||
HIST_ENTRY **nlp, *nl;
|
||||
int i;
|
||||
|
||||
if (history(h, &ev, H_LAST) != 0)
|
||||
return NULL;
|
||||
|
||||
if ((nlp = el_realloc(_history_listp,
|
||||
((size_t)history_length + 1) * sizeof(*nlp))) == NULL)
|
||||
return NULL;
|
||||
_history_listp = nlp;
|
||||
|
||||
if ((nl = el_realloc(_history_list,
|
||||
(size_t)history_length * sizeof(*nl))) == NULL)
|
||||
return NULL;
|
||||
_history_list = nl;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
_history_listp[i] = &_history_list[i];
|
||||
_history_list[i].line = ev.str;
|
||||
_history_list[i].data = NULL;
|
||||
if (i++ == history_length)
|
||||
abort();
|
||||
} while (history(h, &ev, H_PREV) == 0);
|
||||
_history_listp[i] = NULL;
|
||||
return _history_listp;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns current history event or NULL if there is no such event
|
||||
@ -1551,8 +1625,14 @@ where_history(void)
|
||||
HIST_ENTRY *
|
||||
current_history(void)
|
||||
{
|
||||
HistEvent ev;
|
||||
|
||||
return _move_history(H_CURR);
|
||||
if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0)
|
||||
return NULL;
|
||||
|
||||
rl_he.line = ev.str;
|
||||
rl_he.data = NULL;
|
||||
return &rl_he;
|
||||
}
|
||||
|
||||
|
||||
@ -1589,35 +1669,31 @@ history_total_bytes(void)
|
||||
int
|
||||
history_set_pos(int pos)
|
||||
{
|
||||
HistEvent ev;
|
||||
int curr_num;
|
||||
|
||||
if (pos >= history_length || pos < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
(void)history(h, &ev, H_CURR);
|
||||
curr_num = ev.num;
|
||||
|
||||
/*
|
||||
* use H_DELDATA to set to nth history (without delete) by passing
|
||||
* (void **)-1
|
||||
*/
|
||||
if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
|
||||
(void)history(h, &ev, H_SET, curr_num);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
history_offset = pos;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns previous event in history and shifts pointer accordingly
|
||||
* Note that readline and editline define directions in opposite ways.
|
||||
*/
|
||||
HIST_ENTRY *
|
||||
previous_history(void)
|
||||
{
|
||||
HistEvent ev;
|
||||
|
||||
return _move_history(H_PREV);
|
||||
if (history_offset == 0)
|
||||
return NULL;
|
||||
|
||||
if (history(h, &ev, H_LAST) != 0)
|
||||
return NULL;
|
||||
|
||||
history_offset--;
|
||||
return current_history();
|
||||
}
|
||||
|
||||
|
||||
@ -1627,8 +1703,16 @@ previous_history(void)
|
||||
HIST_ENTRY *
|
||||
next_history(void)
|
||||
{
|
||||
HistEvent ev;
|
||||
|
||||
return _move_history(H_NEXT);
|
||||
if (history_offset >= history_length)
|
||||
return NULL;
|
||||
|
||||
if (history(h, &ev, H_LAST) != 0)
|
||||
return NULL;
|
||||
|
||||
history_offset++;
|
||||
return current_history();
|
||||
}
|
||||
|
||||
|
||||
@ -1689,7 +1773,7 @@ history_search_pos(const char *str,
|
||||
return -1;
|
||||
curr_num = ev.num;
|
||||
|
||||
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
|
||||
if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
|
||||
return -1;
|
||||
|
||||
for (;;) {
|
||||
@ -1776,18 +1860,6 @@ _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__un
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display list of strings in columnar format on readline's output stream.
|
||||
* 'matches' is list of strings, 'len' is number of strings in 'matches',
|
||||
* 'max' is maximum length of string in 'matches'.
|
||||
*/
|
||||
void
|
||||
rl_display_match_list(char **matches, int len, int max)
|
||||
{
|
||||
|
||||
fn_display_match_list(e, matches, (size_t)len, (size_t)max);
|
||||
}
|
||||
|
||||
static const char *
|
||||
/*ARGSUSED*/
|
||||
_rl_completion_append_character_function(const char *dummy
|
||||
@ -1800,6 +1872,19 @@ _rl_completion_append_character_function(const char *dummy
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Display list of strings in columnar format on readline's output stream.
|
||||
* 'matches' is list of strings, 'len' is number of strings in 'matches',
|
||||
* 'max' is maximum length of string in 'matches'.
|
||||
*/
|
||||
void
|
||||
rl_display_match_list(char **matches, int len, int max)
|
||||
{
|
||||
|
||||
fn_display_match_list(e, matches, (size_t)len, (size_t)max,
|
||||
_rl_completion_append_character_function);
|
||||
}
|
||||
|
||||
/*
|
||||
* complete word at current point
|
||||
*/
|
||||
@ -1807,10 +1892,8 @@ _rl_completion_append_character_function(const char *dummy
|
||||
int
|
||||
rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
|
||||
{
|
||||
#ifdef WIDECHAR
|
||||
static ct_buffer_t wbreak_conv, sprefix_conv;
|
||||
#endif
|
||||
char *breakchars;
|
||||
const char *breakchars;
|
||||
|
||||
if (h == NULL || e == NULL)
|
||||
rl_initialize();
|
||||
@ -1839,7 +1922,7 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
|
||||
_rl_completion_append_character_function,
|
||||
(size_t)rl_completion_query_items,
|
||||
&rl_completion_type, &rl_attempted_completion_over,
|
||||
&rl_point, &rl_end, NULL, NULL, NULL);
|
||||
&rl_point, &rl_end);
|
||||
|
||||
|
||||
}
|
||||
@ -1896,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;
|
||||
}
|
||||
|
||||
|
||||
@ -2000,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);
|
||||
@ -2023,8 +2107,9 @@ rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
|
||||
void
|
||||
rl_callback_handler_remove(void)
|
||||
{
|
||||
el_set(e, EL_UNBUFFERED, 0);
|
||||
rl_linefunc = NULL;
|
||||
el_end(e);
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2090,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];
|
||||
@ -2098,6 +2183,7 @@ rl_stuff_char(int c)
|
||||
buf[0] = (char)c;
|
||||
buf[1] = '\0';
|
||||
el_insertstr(e, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2153,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
|
||||
@ -2182,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) {
|
||||
@ -2217,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';
|
||||
@ -2334,3 +2421,25 @@ rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
13
contrib/libedit/readline/Makefile
Normal file
13
contrib/libedit/readline/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# $NetBSD: Makefile,v 1.8 2016/02/17 19:47:49 christos Exp $
|
||||
|
||||
NOOBJ= # defined
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.PATH: ${NETBSDSRCDIR}/lib/libedit
|
||||
|
||||
INCS= readline.h
|
||||
INCSDIR= /usr/include/readline
|
||||
INCSYMLINKS= readline.h ${INCSDIR}/history.h
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: readline.h,v 1.39 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: readline.h,v 1.46 2019/06/07 15:19:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -27,8 +27,6 @@
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _READLINE_H_
|
||||
#define _READLINE_H_
|
||||
@ -40,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 {
|
||||
@ -99,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;
|
||||
@ -123,6 +123,7 @@ extern Function *rl_startup_hook;
|
||||
extern char *rl_terminal_name;
|
||||
extern int rl_already_prompted;
|
||||
extern char *rl_prompt;
|
||||
extern int rl_done;
|
||||
/*
|
||||
* The following is not implemented
|
||||
*/
|
||||
@ -138,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;
|
||||
|
||||
@ -148,6 +150,7 @@ int rl_initialize(void);
|
||||
void using_history(void);
|
||||
int add_history(const char *);
|
||||
void clear_history(void);
|
||||
int append_history(int, const char *);
|
||||
void stifle_history(int);
|
||||
int unstifle_history(void);
|
||||
int history_is_stifled(void);
|
||||
@ -160,6 +163,7 @@ int history_total_bytes(void);
|
||||
int history_set_pos(int);
|
||||
HIST_ENTRY *previous_history(void);
|
||||
HIST_ENTRY *next_history(void);
|
||||
HIST_ENTRY **history_list(void);
|
||||
int history_search(const char *, int);
|
||||
int history_search_prefix(const char *, int);
|
||||
int history_search_pos(const char *, int, int);
|
||||
@ -176,12 +180,13 @@ 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);
|
||||
void rl_callback_read_char(void);
|
||||
@ -194,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 *);
|
||||
@ -206,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
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: refresh.c,v 1.45 2016/03/02 19:24:20 christos Exp $ */
|
||||
/* $NetBSD: refresh.c,v 1.56 2019/01/04 03:03:44 uwe Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: refresh.c,v 1.45 2016/03/02 19:24:20 christos Exp $");
|
||||
__RCSID("$NetBSD: refresh.c,v 1.56 2019/01/04 03:03:44 uwe Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* refresh.c: Lower level screen refreshing functions
|
||||
@ -52,18 +50,18 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
|
||||
private void re_nextline(EditLine *);
|
||||
private void re_addc(EditLine *, wint_t);
|
||||
private void re_update_line(EditLine *, Char *, Char *, int);
|
||||
private void re_insert (EditLine *, Char *, int, int, Char *, int);
|
||||
private void re_delete(EditLine *, Char *, int, int, int);
|
||||
private void re_fastputc(EditLine *, wint_t);
|
||||
private void re_clear_eol(EditLine *, int, int, int);
|
||||
private void re__strncopy(Char *, Char *, size_t);
|
||||
private void re__copy_and_pad(Char *, const Char *, size_t);
|
||||
static void re_nextline(EditLine *);
|
||||
static void re_addc(EditLine *, wint_t);
|
||||
static void re_update_line(EditLine *, wchar_t *, wchar_t *, int);
|
||||
static void re_insert (EditLine *, wchar_t *, int, int, wchar_t *, int);
|
||||
static void re_delete(EditLine *, wchar_t *, int, int, int);
|
||||
static void re_fastputc(EditLine *, wint_t);
|
||||
static void re_clear_eol(EditLine *, int, int, int);
|
||||
static void re__strncopy(wchar_t *, wchar_t *, size_t);
|
||||
static void re__copy_and_pad(wchar_t *, const wchar_t *, size_t);
|
||||
|
||||
#ifdef DEBUG_REFRESH
|
||||
private void re_printstr(EditLine *, const char *, Char *, Char *);
|
||||
static void re_printstr(EditLine *, const char *, wchar_t *, wchar_t *);
|
||||
#define __F el->el_errfile
|
||||
#define ELRE_ASSERT(a, b, c) do \
|
||||
if (/*CONSTCOND*/ a) { \
|
||||
@ -76,8 +74,8 @@ private void re_printstr(EditLine *, const char *, Char *, Char *);
|
||||
/* re_printstr():
|
||||
* Print a string on the debugging pty
|
||||
*/
|
||||
private void
|
||||
re_printstr(EditLine *el, const char *str, Char *f, Char *t)
|
||||
static void
|
||||
re_printstr(EditLine *el, const char *str, wchar_t *f, wchar_t *t)
|
||||
{
|
||||
|
||||
ELRE_DEBUG(1, (__F, "%s:\"", str));
|
||||
@ -93,7 +91,7 @@ re_printstr(EditLine *el, const char *str, Char *f, Char *t)
|
||||
/* re_nextline():
|
||||
* Move to the next line or scroll
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
re_nextline(EditLine *el)
|
||||
{
|
||||
el->el_refresh.r_cursor.h = 0; /* reset it. */
|
||||
@ -106,7 +104,7 @@ re_nextline(EditLine *el)
|
||||
*/
|
||||
if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
|
||||
int i, lins = el->el_terminal.t_size.v;
|
||||
Char *firstline = el->el_vdisplay[0];
|
||||
wchar_t *firstline = el->el_vdisplay[0];
|
||||
|
||||
for(i = 1; i < lins; i++)
|
||||
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
|
||||
@ -125,10 +123,10 @@ re_nextline(EditLine *el)
|
||||
/* re_addc():
|
||||
* Draw c, expanding tabs, control chars etc.
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
re_addc(EditLine *el, wint_t c)
|
||||
{
|
||||
switch (ct_chr_class((Char)c)) {
|
||||
switch (ct_chr_class(c)) {
|
||||
case CHTYPE_TAB: /* expand the tab */
|
||||
for (;;) {
|
||||
re_putc(el, ' ', 1);
|
||||
@ -147,9 +145,9 @@ re_addc(EditLine *el, wint_t c)
|
||||
re_putc(el, c, 1);
|
||||
break;
|
||||
default: {
|
||||
Char visbuf[VISUAL_WIDTH_MAX];
|
||||
wchar_t visbuf[VISUAL_WIDTH_MAX];
|
||||
ssize_t i, n =
|
||||
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
|
||||
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
|
||||
for (i = 0; n-- > 0; ++i)
|
||||
re_putc(el, visbuf[i], 1);
|
||||
break;
|
||||
@ -157,35 +155,66 @@ re_addc(EditLine *el, wint_t c)
|
||||
}
|
||||
}
|
||||
|
||||
/* re_putliteral():
|
||||
* Place the literal string given
|
||||
*/
|
||||
libedit_private void
|
||||
re_putliteral(EditLine *el, const wchar_t *begin, const wchar_t *end)
|
||||
{
|
||||
coord_t *cur = &el->el_refresh.r_cursor;
|
||||
wint_t c;
|
||||
int sizeh = el->el_terminal.t_size.h;
|
||||
int i, w;
|
||||
|
||||
c = literal_add(el, begin, end, &w);
|
||||
if (c == 0 || w <= 0)
|
||||
return;
|
||||
el->el_vdisplay[cur->v][cur->h] = c;
|
||||
|
||||
i = w;
|
||||
if (i > sizeh - cur->h) /* avoid overflow */
|
||||
i = sizeh - cur->h;
|
||||
while (--i > 0)
|
||||
el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
|
||||
|
||||
cur->h += w;
|
||||
if (cur->h >= sizeh) {
|
||||
/* assure end of line */
|
||||
el->el_vdisplay[cur->v][sizeh] = '\0';
|
||||
re_nextline(el);
|
||||
}
|
||||
}
|
||||
|
||||
/* re_putc():
|
||||
* Draw the character given
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_putc(EditLine *el, wint_t c, int shift)
|
||||
{
|
||||
int i, w = Width(c);
|
||||
ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
|
||||
coord_t *cur = &el->el_refresh.r_cursor;
|
||||
int i, w = wcwidth(c);
|
||||
int sizeh = el->el_terminal.t_size.h;
|
||||
|
||||
while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
|
||||
ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
|
||||
if (w == -1)
|
||||
w = 0;
|
||||
|
||||
while (shift && (cur->h + w > sizeh))
|
||||
re_putc(el, ' ', 1);
|
||||
|
||||
el->el_vdisplay[el->el_refresh.r_cursor.v]
|
||||
[el->el_refresh.r_cursor.h] = (Char)c;
|
||||
el->el_vdisplay[cur->v][cur->h] = c;
|
||||
/* assumes !shift is only used for single-column chars */
|
||||
i = w;
|
||||
while (--i > 0)
|
||||
el->el_vdisplay[el->el_refresh.r_cursor.v]
|
||||
[el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
|
||||
el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
|
||||
|
||||
if (!shift)
|
||||
return;
|
||||
|
||||
el->el_refresh.r_cursor.h += w; /* advance to next place */
|
||||
if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
|
||||
cur->h += w; /* advance to next place */
|
||||
if (cur->h >= sizeh) {
|
||||
/* assure end of line */
|
||||
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
|
||||
= '\0';
|
||||
el->el_vdisplay[cur->v][sizeh] = '\0';
|
||||
re_nextline(el);
|
||||
}
|
||||
}
|
||||
@ -197,23 +226,26 @@ re_putc(EditLine *el, wint_t c, int shift)
|
||||
* virtual image. The routine to re-draw a line can be replaced
|
||||
* easily in hopes of a smarter one being placed there.
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_refresh(EditLine *el)
|
||||
{
|
||||
int i, rhdiff;
|
||||
Char *cp, *st;
|
||||
wchar_t *cp, *st;
|
||||
coord_t cur;
|
||||
#ifdef notyet
|
||||
size_t termsz;
|
||||
#endif
|
||||
|
||||
ELRE_DEBUG(1, (__F, "el->el_line.buffer = :" FSTR ":\r\n",
|
||||
ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n",
|
||||
el->el_line.buffer));
|
||||
|
||||
literal_clear(el);
|
||||
/* reset the Drawing cursor */
|
||||
el->el_refresh.r_cursor.h = 0;
|
||||
el->el_refresh.r_cursor.v = 0;
|
||||
|
||||
terminal_move_to_char(el, 0);
|
||||
|
||||
/* temporarily draw rprompt to calculate its size */
|
||||
prompt_print(el, EL_RPROMPT);
|
||||
|
||||
@ -253,7 +285,7 @@ re_refresh(EditLine *el)
|
||||
|
||||
for (cp = st; cp < el->el_line.lastchar; cp++) {
|
||||
if (cp == el->el_line.cursor) {
|
||||
int w = Width(*cp);
|
||||
int w = wcwidth(*cp);
|
||||
/* save for later */
|
||||
cur.h = el->el_refresh.r_cursor.h;
|
||||
cur.v = el->el_refresh.r_cursor.v;
|
||||
@ -321,10 +353,10 @@ re_refresh(EditLine *el)
|
||||
for (; i <= el->el_refresh.r_oldcv; i++) {
|
||||
terminal_move_to_line(el, i);
|
||||
terminal_move_to_char(el, 0);
|
||||
/* This Strlen should be safe even with MB_FILL_CHARs */
|
||||
terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
|
||||
/* This wcslen should be safe even with MB_FILL_CHARs */
|
||||
terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
|
||||
#ifdef DEBUG_REFRESH
|
||||
terminal_overwrite(el, STR("C\b"), 2);
|
||||
terminal_overwrite(el, L"C\b", 2);
|
||||
#endif /* DEBUG_REFRESH */
|
||||
el->el_display[i][0] = '\0';
|
||||
}
|
||||
@ -342,7 +374,7 @@ re_refresh(EditLine *el)
|
||||
/* re_goto_bottom():
|
||||
* used to go to last used screen line
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_goto_bottom(EditLine *el)
|
||||
{
|
||||
|
||||
@ -357,12 +389,12 @@ re_goto_bottom(EditLine *el)
|
||||
* insert num characters of s into d (in front of the character)
|
||||
* at dat, maximum length of d is dlen
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
re_insert(EditLine *el __attribute__((__unused__)),
|
||||
Char *d, int dat, int dlen, Char *s, int num)
|
||||
wchar_t *d, int dat, int dlen, wchar_t *s, int num)
|
||||
{
|
||||
Char *a, *b;
|
||||
wchar_t *a, *b;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
@ -408,12 +440,12 @@ re_insert(EditLine *el __attribute__((__unused__)),
|
||||
/* re_delete():
|
||||
* delete num characters d at dat, maximum length of d is dlen
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
re_delete(EditLine *el __attribute__((__unused__)),
|
||||
Char *d, int dat, int dlen, int num)
|
||||
wchar_t *d, int dat, int dlen, int num)
|
||||
{
|
||||
Char *a, *b;
|
||||
wchar_t *a, *b;
|
||||
|
||||
if (num <= 0)
|
||||
return;
|
||||
@ -442,8 +474,8 @@ re_delete(EditLine *el __attribute__((__unused__)),
|
||||
/* re__strncopy():
|
||||
* Like strncpy without padding.
|
||||
*/
|
||||
private void
|
||||
re__strncopy(Char *a, Char *b, size_t n)
|
||||
static void
|
||||
re__strncopy(wchar_t *a, wchar_t *b, size_t n)
|
||||
{
|
||||
|
||||
while (n-- && *b)
|
||||
@ -457,7 +489,7 @@ re__strncopy(Char *a, Char *b, size_t n)
|
||||
* in the first or second diff, diff is the difference between the
|
||||
* number of characters between the new and old line.
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
re_clear_eol(EditLine *el, int fx, int sx, int diff)
|
||||
{
|
||||
|
||||
@ -501,12 +533,12 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
|
||||
*/
|
||||
#define MIN_END_KEEP 4
|
||||
|
||||
private void
|
||||
re_update_line(EditLine *el, Char *old, Char *new, int i)
|
||||
static void
|
||||
re_update_line(EditLine *el, wchar_t *old, wchar_t *new, int i)
|
||||
{
|
||||
Char *o, *n, *p, c;
|
||||
Char *ofd, *ols, *oe, *nfd, *nls, *ne;
|
||||
Char *osb, *ose, *nsb, *nse;
|
||||
wchar_t *o, *n, *p, c;
|
||||
wchar_t *ofd, *ols, *oe, *nfd, *nls, *ne;
|
||||
wchar_t *osb, *ose, *nsb, *nse;
|
||||
int fx, sx;
|
||||
size_t len;
|
||||
|
||||
@ -971,8 +1003,8 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
|
||||
/* re__copy_and_pad():
|
||||
* Copy string and pad with spaces
|
||||
*/
|
||||
private void
|
||||
re__copy_and_pad(Char *dst, const Char *src, size_t width)
|
||||
static void
|
||||
re__copy_and_pad(wchar_t *dst, const wchar_t *src, size_t width)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@ -992,10 +1024,10 @@ re__copy_and_pad(Char *dst, const Char *src, size_t width)
|
||||
/* re_refresh_cursor():
|
||||
* Move to the new cursor position
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_refresh_cursor(EditLine *el)
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
int h, v, th, w;
|
||||
|
||||
if (el->el_line.cursor >= el->el_line.lastchar) {
|
||||
@ -1023,7 +1055,7 @@ re_refresh_cursor(EditLine *el)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
w = Width(*cp);
|
||||
w = wcwidth(*cp);
|
||||
if (w > 1 && h + w > th) { /* won't fit on line */
|
||||
h = 0;
|
||||
v++;
|
||||
@ -1039,7 +1071,7 @@ re_refresh_cursor(EditLine *el)
|
||||
}
|
||||
/* if we have a next character, and it's a doublewidth one, we need to
|
||||
* check whether we need to linebreak for it to fit */
|
||||
if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
|
||||
if (cp < el->el_line.lastchar && (w = wcwidth(*cp)) > 1)
|
||||
if (h + w > th) {
|
||||
h = 0;
|
||||
v++;
|
||||
@ -1055,15 +1087,18 @@ re_refresh_cursor(EditLine *el)
|
||||
/* re_fastputc():
|
||||
* Add a character fast.
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
re_fastputc(EditLine *el, wint_t c)
|
||||
{
|
||||
int w = Width((Char)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, ' ');
|
||||
|
||||
terminal__putc(el, c);
|
||||
el->el_display[el->el_cursor.v][el->el_cursor.h++] = (Char)c;
|
||||
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
|
||||
while (--w > 0)
|
||||
el->el_display[el->el_cursor.v][el->el_cursor.h++]
|
||||
= MB_FILL_CHAR;
|
||||
@ -1080,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;
|
||||
Char *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, STR(""), (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, ' ');
|
||||
@ -1108,10 +1144,10 @@ re_fastputc(EditLine *el, wint_t c)
|
||||
* we added just one char, handle it fast.
|
||||
* Assumes that screen cursor == real cursor
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_fastaddc(EditLine *el)
|
||||
{
|
||||
Char c;
|
||||
wchar_t c;
|
||||
int rhdiff;
|
||||
|
||||
c = el->el_line.cursor[-1];
|
||||
@ -1135,9 +1171,9 @@ re_fastaddc(EditLine *el)
|
||||
break;
|
||||
case CHTYPE_ASCIICTL:
|
||||
case CHTYPE_NONPRINT: {
|
||||
Char visbuf[VISUAL_WIDTH_MAX];
|
||||
wchar_t visbuf[VISUAL_WIDTH_MAX];
|
||||
ssize_t i, n =
|
||||
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
|
||||
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
|
||||
for (i = 0; n-- > 0; ++i)
|
||||
re_fastputc(el, visbuf[i]);
|
||||
break;
|
||||
@ -1148,9 +1184,9 @@ re_fastaddc(EditLine *el)
|
||||
|
||||
|
||||
/* re_clear_display():
|
||||
* clear the screen buffers so that new prompt starts fresh.
|
||||
* clear the screen buffers so that new new prompt starts fresh.
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_clear_display(EditLine *el)
|
||||
{
|
||||
int i;
|
||||
@ -1166,7 +1202,7 @@ re_clear_display(EditLine *el)
|
||||
/* re_clear_lines():
|
||||
* Make sure all lines are *really* blank
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
re_clear_lines(EditLine *el)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: refresh.h,v 1.9 2016/02/16 15:53:48 christos Exp $ */
|
||||
/* $NetBSD: refresh.h,v 1.11 2017/06/27 23:23:48 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)refresh.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -47,12 +46,14 @@ typedef struct {
|
||||
int r_newcv;
|
||||
} el_refresh_t;
|
||||
|
||||
protected void re_putc(EditLine *, wint_t, int);
|
||||
protected void re_clear_lines(EditLine *);
|
||||
protected void re_clear_display(EditLine *);
|
||||
protected void re_refresh(EditLine *);
|
||||
protected void re_refresh_cursor(EditLine *);
|
||||
protected void re_fastaddc(EditLine *);
|
||||
protected void re_goto_bottom(EditLine *);
|
||||
libedit_private void re_putc(EditLine *, wint_t, int);
|
||||
libedit_private void re_putliteral(EditLine *, const wchar_t *,
|
||||
const wchar_t *);
|
||||
libedit_private void re_clear_lines(EditLine *);
|
||||
libedit_private void re_clear_display(EditLine *);
|
||||
libedit_private void re_refresh(EditLine *);
|
||||
libedit_private void re_refresh_cursor(EditLine *);
|
||||
libedit_private void re_fastaddc(EditLine *);
|
||||
libedit_private void re_goto_bottom(EditLine *);
|
||||
|
||||
#endif /* _h_el_refresh */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: search.c,v 1.39 2016/02/24 14:25:38 christos Exp $ */
|
||||
/* $NetBSD: search.c,v 1.49 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: search.c,v 1.39 2016/02/24 14:25:38 christos Exp $");
|
||||
__RCSID("$NetBSD: search.c,v 1.49 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* search.c: History and character search functions
|
||||
@ -56,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
#include "fcns.h"
|
||||
|
||||
/*
|
||||
* Adjust cursor in vi mode to include the character under it
|
||||
@ -67,17 +66,18 @@ __FBSDID("$FreeBSD$");
|
||||
/* search_init():
|
||||
* Initialize the search stuff
|
||||
*/
|
||||
protected int
|
||||
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;
|
||||
el->el_search.patbuf[0] = L'\0';
|
||||
el->el_search.patlen = 0;
|
||||
el->el_search.patdir = -1;
|
||||
el->el_search.chacha = '\0';
|
||||
el->el_search.chacha = L'\0';
|
||||
el->el_search.chadir = CHAR_FWD;
|
||||
el->el_search.chatflg = 0;
|
||||
return 0;
|
||||
@ -87,7 +87,7 @@ search_init(EditLine *el)
|
||||
/* search_end():
|
||||
* Initialize the search stuff
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
search_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -100,7 +100,7 @@ search_end(EditLine *el)
|
||||
/* regerror():
|
||||
* Handle regular expression errors
|
||||
*/
|
||||
public void
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
regerror(const char *msg)
|
||||
{
|
||||
@ -111,12 +111,10 @@ regerror(const char *msg)
|
||||
/* el_match():
|
||||
* Return if string matches pattern
|
||||
*/
|
||||
protected int
|
||||
el_match(const Char *str, const Char *pat)
|
||||
libedit_private int
|
||||
el_match(const wchar_t *str, const wchar_t *pat)
|
||||
{
|
||||
#ifdef WIDECHAR
|
||||
static ct_buffer_t conv;
|
||||
#endif
|
||||
#if defined (REGEX)
|
||||
regex_t re;
|
||||
int rv;
|
||||
@ -128,7 +126,7 @@ el_match(const Char *str, const Char *pat)
|
||||
extern int re_exec(const char *);
|
||||
#endif
|
||||
|
||||
if (Strstr(str, pat) != 0)
|
||||
if (wcsstr(str, pat) != 0)
|
||||
return 1;
|
||||
|
||||
#if defined(REGEX)
|
||||
@ -160,8 +158,8 @@ el_match(const Char *str, const Char *pat)
|
||||
/* c_hmatch():
|
||||
* return True if the pattern matches the prefix
|
||||
*/
|
||||
protected int
|
||||
c_hmatch(EditLine *el, const Char *str)
|
||||
libedit_private int
|
||||
c_hmatch(EditLine *el, const wchar_t *str)
|
||||
{
|
||||
#ifdef SDEBUG
|
||||
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
|
||||
@ -175,7 +173,7 @@ c_hmatch(EditLine *el, const Char *str)
|
||||
/* c_setpat():
|
||||
* Set the history seatch pattern
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
c_setpat(EditLine *el)
|
||||
{
|
||||
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
|
||||
@ -185,11 +183,11 @@ c_setpat(EditLine *el)
|
||||
if (el->el_search.patlen >= EL_BUFSIZ)
|
||||
el->el_search.patlen = EL_BUFSIZ - 1;
|
||||
if (el->el_search.patlen != 0) {
|
||||
(void) Strncpy(el->el_search.patbuf, el->el_line.buffer,
|
||||
(void) wcsncpy(el->el_search.patbuf, el->el_line.buffer,
|
||||
el->el_search.patlen);
|
||||
el->el_search.patbuf[el->el_search.patlen] = '\0';
|
||||
} else
|
||||
el->el_search.patlen = Strlen(el->el_search.patbuf);
|
||||
el->el_search.patlen = wcslen(el->el_search.patbuf);
|
||||
}
|
||||
#ifdef SDEBUG
|
||||
(void) fprintf(el->el_errfile, "\neventno = %d\n",
|
||||
@ -207,16 +205,14 @@ c_setpat(EditLine *el)
|
||||
/* ce_inc_search():
|
||||
* Emacs incremental search
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ce_inc_search(EditLine *el, int dir)
|
||||
{
|
||||
static const Char STRfwd[] = {'f', 'w', 'd', '\0'},
|
||||
STRbck[] = {'b', 'c', 'k', '\0'};
|
||||
static Char pchar = ':';/* ':' = normal, '?' = failed */
|
||||
static Char endcmd[2] = {'\0', '\0'};
|
||||
Char *ocursor = el->el_line.cursor, oldpchar = pchar, ch;
|
||||
const Char *cp;
|
||||
wchar_t wch;
|
||||
static const wchar_t STRfwd[] = L"fwd", STRbck[] = L"bck";
|
||||
static wchar_t pchar = L':'; /* ':' = normal, '?' = failed */
|
||||
static wchar_t endcmd[2] = {'\0', '\0'};
|
||||
wchar_t *ocursor = el->el_line.cursor, oldpchar = pchar, ch;
|
||||
const wchar_t *cp;
|
||||
|
||||
el_action_t ret = CC_NORM;
|
||||
|
||||
@ -255,11 +251,9 @@ ce_inc_search(EditLine *el, int dir)
|
||||
*el->el_line.lastchar = '\0';
|
||||
re_refresh(el);
|
||||
|
||||
if (el_wgetc(el, &wch) != 1)
|
||||
if (el_wgetc(el, &ch) != 1)
|
||||
return ed_end_of_file(el, 0);
|
||||
|
||||
ch = (Char)wch;
|
||||
|
||||
switch (el->el_map.current[(unsigned char) ch]) {
|
||||
case ED_INSERT:
|
||||
case ED_DIGIT:
|
||||
@ -333,7 +327,7 @@ ce_inc_search(EditLine *el, int dir)
|
||||
|
||||
default: /* Terminate and execute cmd */
|
||||
endcmd[0] = ch;
|
||||
FUN(el,push)(el, endcmd);
|
||||
el_wpush(el, endcmd);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0033: /* ESC: Terminate */
|
||||
@ -458,11 +452,11 @@ ce_inc_search(EditLine *el, int dir)
|
||||
/* cv_search():
|
||||
* Vi search.
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
cv_search(EditLine *el, int dir)
|
||||
{
|
||||
Char ch;
|
||||
Char tmpbuf[EL_BUFSIZ];
|
||||
wchar_t ch;
|
||||
wchar_t tmpbuf[EL_BUFSIZ];
|
||||
ssize_t tmplen;
|
||||
|
||||
#ifdef ANCHOR
|
||||
@ -474,7 +468,7 @@ cv_search(EditLine *el, int dir)
|
||||
el->el_search.patdir = dir;
|
||||
|
||||
tmplen = c_gets(el, &tmpbuf[LEN],
|
||||
dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
|
||||
dir == ED_SEARCH_PREV_HISTORY ? L"\n/" : L"\n?" );
|
||||
if (tmplen == -1)
|
||||
return CC_REFRESH;
|
||||
|
||||
@ -493,11 +487,11 @@ cv_search(EditLine *el, int dir)
|
||||
#ifdef ANCHOR
|
||||
if (el->el_search.patbuf[0] != '.' &&
|
||||
el->el_search.patbuf[0] != '*') {
|
||||
(void) Strncpy(tmpbuf, el->el_search.patbuf,
|
||||
(void) wcsncpy(tmpbuf, el->el_search.patbuf,
|
||||
sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
|
||||
el->el_search.patbuf[0] = '.';
|
||||
el->el_search.patbuf[1] = '*';
|
||||
(void) Strncpy(&el->el_search.patbuf[2], tmpbuf,
|
||||
(void) wcsncpy(&el->el_search.patbuf[2], tmpbuf,
|
||||
EL_BUFSIZ - 3);
|
||||
el->el_search.patlen++;
|
||||
el->el_search.patbuf[el->el_search.patlen++] = '.';
|
||||
@ -511,7 +505,7 @@ cv_search(EditLine *el, int dir)
|
||||
tmpbuf[tmplen++] = '*';
|
||||
#endif
|
||||
tmpbuf[tmplen] = '\0';
|
||||
(void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
|
||||
(void) wcsncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
|
||||
el->el_search.patlen = (size_t)tmplen;
|
||||
}
|
||||
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
|
||||
@ -532,12 +526,12 @@ cv_search(EditLine *el, int dir)
|
||||
/* ce_search_line():
|
||||
* Look for a pattern inside a line
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
ce_search_line(EditLine *el, int dir)
|
||||
{
|
||||
Char *cp = el->el_line.cursor;
|
||||
Char *pattern = el->el_search.patbuf;
|
||||
Char oc, *ocp;
|
||||
wchar_t *cp = el->el_line.cursor;
|
||||
wchar_t *pattern = el->el_search.patbuf;
|
||||
wchar_t oc, *ocp;
|
||||
#ifdef ANCHOR
|
||||
ocp = &pattern[1];
|
||||
oc = *ocp;
|
||||
@ -574,7 +568,7 @@ ce_search_line(EditLine *el, int dir)
|
||||
/* cv_repeat_srch():
|
||||
* Vi repeat search
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
cv_repeat_srch(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
@ -600,21 +594,23 @@ cv_repeat_srch(EditLine *el, wint_t c)
|
||||
/* cv_csearch():
|
||||
* Vi character search
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag)
|
||||
{
|
||||
Char *cp;
|
||||
wchar_t *cp;
|
||||
|
||||
if (ch == 0)
|
||||
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 */
|
||||
el->el_search.chacha = (Char)ch;
|
||||
el->el_search.chacha = ch;
|
||||
el->el_search.chadir = direction;
|
||||
el->el_search.chatflg = (char)tflag;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: search.h,v 1.12 2016/02/16 15:53:48 christos Exp $ */
|
||||
/* $NetBSD: search.h,v 1.14 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)search.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -42,24 +41,24 @@
|
||||
#define _h_el_search
|
||||
|
||||
typedef struct el_search_t {
|
||||
Char *patbuf; /* The pattern buffer */
|
||||
wchar_t *patbuf; /* The pattern buffer */
|
||||
size_t patlen; /* Length of the pattern buffer */
|
||||
int patdir; /* Direction of the last search */
|
||||
int chadir; /* Character search direction */
|
||||
Char chacha; /* Character we are looking for */
|
||||
wchar_t chacha; /* Character we are looking for */
|
||||
char chatflg; /* 0 if f, 1 if t */
|
||||
} el_search_t;
|
||||
|
||||
|
||||
protected int el_match(const Char *, const Char *);
|
||||
protected int search_init(EditLine *);
|
||||
protected void search_end(EditLine *);
|
||||
protected int c_hmatch(EditLine *, const Char *);
|
||||
protected void c_setpat(EditLine *);
|
||||
protected el_action_t ce_inc_search(EditLine *, int);
|
||||
protected el_action_t cv_search(EditLine *, int);
|
||||
protected el_action_t ce_search_line(EditLine *, int);
|
||||
protected el_action_t cv_repeat_srch(EditLine *, wint_t);
|
||||
protected el_action_t cv_csearch(EditLine *, int, wint_t, int, int);
|
||||
libedit_private int el_match(const wchar_t *, const wchar_t *);
|
||||
libedit_private int search_init(EditLine *);
|
||||
libedit_private void search_end(EditLine *);
|
||||
libedit_private int c_hmatch(EditLine *, const wchar_t *);
|
||||
libedit_private void c_setpat(EditLine *);
|
||||
libedit_private el_action_t ce_inc_search(EditLine *, int);
|
||||
libedit_private el_action_t cv_search(EditLine *, int);
|
||||
libedit_private el_action_t ce_search_line(EditLine *, int);
|
||||
libedit_private el_action_t cv_repeat_srch(EditLine *, wint_t);
|
||||
libedit_private el_action_t cv_csearch(EditLine *, int, wint_t, int, int);
|
||||
|
||||
#endif /* _h_el_search */
|
5
contrib/libedit/shlib_version
Normal file
5
contrib/libedit/shlib_version
Normal file
@ -0,0 +1,5 @@
|
||||
# $NetBSD: shlib_version,v 1.19 2013/01/22 20:23:21 christos Exp $
|
||||
# Remember to update distrib/sets/lists/base/shl.* when changing
|
||||
#
|
||||
major=3
|
||||
minor=1
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 christos Exp $ */
|
||||
/* $NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 christos Exp $");
|
||||
__RCSID("$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* sig.c: Signal handling stuff.
|
||||
@ -54,23 +52,23 @@ __FBSDID("$FreeBSD$");
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
|
||||
private EditLine *sel = NULL;
|
||||
static EditLine *sel = NULL;
|
||||
|
||||
private const int sighdl[] = {
|
||||
static const int sighdl[] = {
|
||||
#define _DO(a) (a),
|
||||
ALLSIGS
|
||||
#undef _DO
|
||||
- 1
|
||||
};
|
||||
|
||||
private void sig_handler(int);
|
||||
static void sig_handler(int);
|
||||
|
||||
/* sig_handler():
|
||||
* This is the handler called for all signals
|
||||
* XXX: we cannot pass any data so we just store the old editline
|
||||
* state in a private variable
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
sig_handler(int signo)
|
||||
{
|
||||
int i, save_errno;
|
||||
@ -117,7 +115,7 @@ sig_handler(int signo)
|
||||
/* sig_init():
|
||||
* Initialize all signal stuff
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
sig_init(EditLine *el)
|
||||
{
|
||||
size_t i;
|
||||
@ -149,7 +147,7 @@ sig_init(EditLine *el)
|
||||
/* sig_end():
|
||||
* Clear all signal stuff
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
sig_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -161,7 +159,7 @@ sig_end(EditLine *el)
|
||||
/* sig_set():
|
||||
* set all the signal handlers
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
sig_set(EditLine *el)
|
||||
{
|
||||
size_t i;
|
||||
@ -188,7 +186,7 @@ sig_set(EditLine *el)
|
||||
/* sig_clr():
|
||||
* clear all the signal handlers
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
sig_clr(EditLine *el)
|
||||
{
|
||||
size_t i;
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sig.h,v 1.10 2016/02/16 15:53:48 christos Exp $ */
|
||||
/* $NetBSD: sig.h,v 1.11 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sig.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -63,9 +62,9 @@ typedef struct {
|
||||
volatile sig_atomic_t sig_no;
|
||||
} *el_signal_t;
|
||||
|
||||
protected void sig_end(EditLine*);
|
||||
protected int sig_init(EditLine*);
|
||||
protected void sig_set(EditLine*);
|
||||
protected void sig_clr(EditLine*);
|
||||
libedit_private void sig_end(EditLine*);
|
||||
libedit_private int sig_init(EditLine*);
|
||||
libedit_private void sig_set(EditLine*);
|
||||
libedit_private void sig_clr(EditLine*);
|
||||
|
||||
#endif /* _h_el_sig */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sys.h,v 1.23 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: sys.h,v 1.27 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sys.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -59,18 +58,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef public
|
||||
# define public /* Externally visible functions/variables */
|
||||
#endif
|
||||
|
||||
#ifndef private
|
||||
# define private static /* Always hidden internals */
|
||||
#endif
|
||||
|
||||
#ifndef protected
|
||||
# define protected /* Redefined from elsewhere to "static" */
|
||||
/* When we want to hide everything */
|
||||
#endif
|
||||
/* If your compiler does not support this, define it to be empty. */
|
||||
#define libedit_private __attribute__((__visibility__("hidden")))
|
||||
|
||||
#ifndef __arraycount
|
||||
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
|
||||
@ -112,11 +101,6 @@ typedef unsigned int u_int32_t;
|
||||
#define REGEX /* Use POSIX.2 regular expression functions */
|
||||
#undef REGEXP /* Use UNIX V8 regular expression functions */
|
||||
|
||||
#ifndef WIDECHAR
|
||||
#define setlocale(c, l) /*LINTED*/NULL
|
||||
#define nl_langinfo(i) ""
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
extern int tgetent(char *, const char *);
|
||||
extern int tgetflag(char *);
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $ */
|
||||
/* $NetBSD: terminal.c,v 1.39 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $");
|
||||
__RCSID("$NetBSD: terminal.c,v 1.39 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* terminal.c: Editor/termcap-curses interface
|
||||
@ -75,6 +73,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include "el.h"
|
||||
#include "fcns.h"
|
||||
|
||||
/*
|
||||
* IMPORTANT NOTE: these routines are allowed to look at the current screen
|
||||
@ -90,7 +89,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define Str(a) el->el_terminal.t_str[a]
|
||||
#define Val(a) el->el_terminal.t_val[a]
|
||||
|
||||
private const struct termcapstr {
|
||||
static const struct termcapstr {
|
||||
const char *name;
|
||||
const char *long_name;
|
||||
} tstr[] = {
|
||||
@ -176,7 +175,7 @@ private const struct termcapstr {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
private const struct termcapval {
|
||||
static const struct termcapval {
|
||||
const char *name;
|
||||
const char *long_name;
|
||||
} tval[] = {
|
||||
@ -201,27 +200,27 @@ private const struct termcapval {
|
||||
};
|
||||
/* do two or more of the attributes use me */
|
||||
|
||||
private void terminal_setflags(EditLine *);
|
||||
private int terminal_rebuffer_display(EditLine *);
|
||||
private void terminal_free_display(EditLine *);
|
||||
private int terminal_alloc_display(EditLine *);
|
||||
private void terminal_alloc(EditLine *, const struct termcapstr *,
|
||||
static void terminal_setflags(EditLine *);
|
||||
static int terminal_rebuffer_display(EditLine *);
|
||||
static void terminal_free_display(EditLine *);
|
||||
static int terminal_alloc_display(EditLine *);
|
||||
static void terminal_alloc(EditLine *, const struct termcapstr *,
|
||||
const char *);
|
||||
private void terminal_init_arrow(EditLine *);
|
||||
private void terminal_reset_arrow(EditLine *);
|
||||
private int terminal_putc(int);
|
||||
private void terminal_tputs(EditLine *, const char *, int);
|
||||
static void terminal_init_arrow(EditLine *);
|
||||
static void terminal_reset_arrow(EditLine *);
|
||||
static int terminal_putc(int);
|
||||
static void terminal_tputs(EditLine *, const char *, int);
|
||||
|
||||
#ifdef _REENTRANT
|
||||
private pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
private FILE *terminal_outfile = NULL;
|
||||
static FILE *terminal_outfile = NULL;
|
||||
|
||||
|
||||
/* terminal_setflags():
|
||||
* Set the terminal capability flags
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
terminal_setflags(EditLine *el)
|
||||
{
|
||||
EL_FLAGS = 0;
|
||||
@ -266,35 +265,31 @@ terminal_setflags(EditLine *el)
|
||||
/* terminal_init():
|
||||
* Initialize the terminal stuff
|
||||
*/
|
||||
protected int
|
||||
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;
|
||||
@ -317,7 +312,7 @@ fail1:
|
||||
/* terminal_end():
|
||||
* Clean up the terminal stuff
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_end(EditLine *el)
|
||||
{
|
||||
|
||||
@ -339,7 +334,7 @@ terminal_end(EditLine *el)
|
||||
/* terminal_alloc():
|
||||
* Maintain a string pool for termcap strings
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
|
||||
{
|
||||
char termbuf[TC_BUFSIZE];
|
||||
@ -405,7 +400,7 @@ terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
|
||||
/* terminal_rebuffer_display():
|
||||
* Rebuffer the display after the screen changed size
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
terminal_rebuffer_display(EditLine *el)
|
||||
{
|
||||
coord_t *c = &el->el_terminal.t_size;
|
||||
@ -420,46 +415,58 @@ terminal_rebuffer_display(EditLine *el)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static wint_t **
|
||||
terminal_alloc_buffer(EditLine *el)
|
||||
{
|
||||
wint_t **b;
|
||||
coord_t *c = &el->el_terminal.t_size;
|
||||
int i;
|
||||
|
||||
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_calloc((size_t)(c->h + 1), sizeof(**b));
|
||||
if (b[i] == NULL) {
|
||||
while (--i >= 0)
|
||||
el_free(b[i]);
|
||||
el_free(b);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
b[c->v] = NULL;
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
terminal_free_buffer(wint_t ***bp)
|
||||
{
|
||||
wint_t **b;
|
||||
wint_t **bufp;
|
||||
|
||||
if (*bp == NULL)
|
||||
return;
|
||||
|
||||
b = *bp;
|
||||
*bp = NULL;
|
||||
|
||||
for (bufp = b; *bufp != NULL; bufp++)
|
||||
el_free(*bufp);
|
||||
el_free(b);
|
||||
}
|
||||
|
||||
/* terminal_alloc_display():
|
||||
* Allocate a new display.
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
terminal_alloc_display(EditLine *el)
|
||||
{
|
||||
int i;
|
||||
Char **b;
|
||||
coord_t *c = &el->el_terminal.t_size;
|
||||
|
||||
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
|
||||
if (b == NULL)
|
||||
el->el_display = terminal_alloc_buffer(el);
|
||||
if (el->el_display == NULL)
|
||||
goto done;
|
||||
for (i = 0; i < c->v; i++) {
|
||||
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
|
||||
if (b[i] == NULL) {
|
||||
while (--i >= 0)
|
||||
el_free(b[i]);
|
||||
el_free(b);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
b[c->v] = NULL;
|
||||
el->el_display = b;
|
||||
|
||||
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
|
||||
if (b == NULL)
|
||||
el->el_vdisplay = terminal_alloc_buffer(el);
|
||||
if (el->el_vdisplay == NULL)
|
||||
goto done;
|
||||
for (i = 0; i < c->v; i++) {
|
||||
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
|
||||
if (b[i] == NULL) {
|
||||
while (--i >= 0)
|
||||
el_free(b[i]);
|
||||
el_free(b);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
b[c->v] = NULL;
|
||||
el->el_vdisplay = b;
|
||||
return 0;
|
||||
done:
|
||||
terminal_free_display(el);
|
||||
@ -470,26 +477,11 @@ done:
|
||||
/* terminal_free_display():
|
||||
* Free the display buffers
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
terminal_free_display(EditLine *el)
|
||||
{
|
||||
Char **b;
|
||||
Char **bufp;
|
||||
|
||||
b = el->el_display;
|
||||
el->el_display = NULL;
|
||||
if (b != NULL) {
|
||||
for (bufp = b; *bufp != NULL; bufp++)
|
||||
el_free(*bufp);
|
||||
el_free(b);
|
||||
}
|
||||
b = el->el_vdisplay;
|
||||
el->el_vdisplay = NULL;
|
||||
if (b != NULL) {
|
||||
for (bufp = b; *bufp != NULL; bufp++)
|
||||
el_free(*bufp);
|
||||
el_free(b);
|
||||
}
|
||||
terminal_free_buffer(&el->el_display);
|
||||
terminal_free_buffer(&el->el_vdisplay);
|
||||
}
|
||||
|
||||
|
||||
@ -497,7 +489,7 @@ terminal_free_display(EditLine *el)
|
||||
* move to line <where> (first line == 0)
|
||||
* as efficiently as possible
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_move_to_line(EditLine *el, int where)
|
||||
{
|
||||
int del;
|
||||
@ -513,39 +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);
|
||||
#ifdef WIDECHAR
|
||||
for (; h > 0 &&
|
||||
el->el_display[el->el_cursor.v][h] ==
|
||||
MB_FILL_CHAR;
|
||||
h--)
|
||||
continue;
|
||||
#endif
|
||||
/* 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);
|
||||
@ -562,7 +529,7 @@ terminal_move_to_line(EditLine *el, int where)
|
||||
/* terminal_move_to_char():
|
||||
* Move to the character position specified
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_move_to_char(EditLine *el, int where)
|
||||
{
|
||||
int del, i;
|
||||
@ -598,11 +565,9 @@ mc_again:
|
||||
if (EL_CAN_TAB) {
|
||||
if ((el->el_cursor.h & 0370) !=
|
||||
(where & ~0x7)
|
||||
#ifdef WIDECHAR
|
||||
&& (el->el_display[
|
||||
el->el_cursor.v][where & 0370] !=
|
||||
MB_FILL_CHAR)
|
||||
#endif
|
||||
) {
|
||||
/* if not within tab stop */
|
||||
for (i =
|
||||
@ -659,8 +624,8 @@ mc_again:
|
||||
* Overstrike num characters
|
||||
* Assumes MB_FILL_CHARs are present to keep the column count correct
|
||||
*/
|
||||
protected void
|
||||
terminal_overwrite(EditLine *el, const Char *cp, size_t n)
|
||||
libedit_private void
|
||||
terminal_overwrite(EditLine *el, const wchar_t *cp, size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
return;
|
||||
@ -686,15 +651,13 @@ terminal_overwrite(EditLine *el, const Char *cp, size_t n)
|
||||
if (EL_HAS_MAGIC_MARGINS) {
|
||||
/* force the wrap to avoid the "magic"
|
||||
* situation */
|
||||
Char c;
|
||||
wchar_t c;
|
||||
if ((c = el->el_display[el->el_cursor.v]
|
||||
[el->el_cursor.h]) != '\0') {
|
||||
terminal_overwrite(el, &c, (size_t)1);
|
||||
#ifdef WIDECHAR
|
||||
while (el->el_display[el->el_cursor.v]
|
||||
[el->el_cursor.h] == MB_FILL_CHAR)
|
||||
el->el_cursor.h++;
|
||||
#endif
|
||||
} else {
|
||||
terminal__putc(el, ' ');
|
||||
el->el_cursor.h = 1;
|
||||
@ -709,7 +672,7 @@ terminal_overwrite(EditLine *el, const Char *cp, size_t n)
|
||||
/* terminal_deletechars():
|
||||
* Delete num characters
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_deletechars(EditLine *el, int num)
|
||||
{
|
||||
if (num <= 0)
|
||||
@ -751,8 +714,8 @@ terminal_deletechars(EditLine *el, int num)
|
||||
* characters in the line
|
||||
* Assumes MB_FILL_CHARs are present to keep column count correct
|
||||
*/
|
||||
protected void
|
||||
terminal_insertwrite(EditLine *el, Char *cp, int num)
|
||||
libedit_private void
|
||||
terminal_insertwrite(EditLine *el, wchar_t *cp, int num)
|
||||
{
|
||||
if (num <= 0)
|
||||
return;
|
||||
@ -810,7 +773,7 @@ terminal_insertwrite(EditLine *el, Char *cp, int num)
|
||||
/* terminal_clear_EOL():
|
||||
* clear to end of line. There are num characters to clear
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_clear_EOL(EditLine *el, int num)
|
||||
{
|
||||
int i;
|
||||
@ -828,7 +791,7 @@ terminal_clear_EOL(EditLine *el, int num)
|
||||
/* terminal_clear_screen():
|
||||
* Clear the screen
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_clear_screen(EditLine *el)
|
||||
{ /* clear the whole screen and home */
|
||||
|
||||
@ -849,7 +812,7 @@ terminal_clear_screen(EditLine *el)
|
||||
/* terminal_beep():
|
||||
* Beep the way the terminal wants us
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_beep(EditLine *el)
|
||||
{
|
||||
if (GoodStr(T_bl))
|
||||
@ -860,7 +823,7 @@ terminal_beep(EditLine *el)
|
||||
}
|
||||
|
||||
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_get(EditLine *el, const char **term)
|
||||
{
|
||||
*term = el->el_terminal.t_name;
|
||||
@ -870,7 +833,7 @@ terminal_get(EditLine *el, const char **term)
|
||||
/* terminal_set():
|
||||
* Read in the terminal capabilities from the requested terminal
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
terminal_set(EditLine *el, const char *term)
|
||||
{
|
||||
int i;
|
||||
@ -959,7 +922,7 @@ terminal_set(EditLine *el, const char *term)
|
||||
* Return the new window size in lines and cols, and
|
||||
* true if the size was changed.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
terminal_get_size(EditLine *el, int *lins, int *cols)
|
||||
{
|
||||
|
||||
@ -995,12 +958,13 @@ terminal_get_size(EditLine *el, int *lins, int *cols)
|
||||
/* terminal_change_size():
|
||||
* Change the size of the terminal
|
||||
*/
|
||||
protected int
|
||||
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;
|
||||
|
||||
@ -1008,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;
|
||||
}
|
||||
|
||||
@ -1015,42 +980,42 @@ terminal_change_size(EditLine *el, int lins, int cols)
|
||||
/* terminal_init_arrow():
|
||||
* Initialize the arrow key bindings from termcap
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
terminal_init_arrow(EditLine *el)
|
||||
{
|
||||
funckey_t *arrow = el->el_terminal.t_fkey;
|
||||
|
||||
arrow[A_K_DN].name = STR("down");
|
||||
arrow[A_K_DN].name = L"down";
|
||||
arrow[A_K_DN].key = T_kd;
|
||||
arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY;
|
||||
arrow[A_K_DN].type = XK_CMD;
|
||||
|
||||
arrow[A_K_UP].name = STR("up");
|
||||
arrow[A_K_UP].name = L"up";
|
||||
arrow[A_K_UP].key = T_ku;
|
||||
arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY;
|
||||
arrow[A_K_UP].type = XK_CMD;
|
||||
|
||||
arrow[A_K_LT].name = STR("left");
|
||||
arrow[A_K_LT].name = L"left";
|
||||
arrow[A_K_LT].key = T_kl;
|
||||
arrow[A_K_LT].fun.cmd = ED_PREV_CHAR;
|
||||
arrow[A_K_LT].type = XK_CMD;
|
||||
|
||||
arrow[A_K_RT].name = STR("right");
|
||||
arrow[A_K_RT].name = L"right";
|
||||
arrow[A_K_RT].key = T_kr;
|
||||
arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR;
|
||||
arrow[A_K_RT].type = XK_CMD;
|
||||
|
||||
arrow[A_K_HO].name = STR("home");
|
||||
arrow[A_K_HO].name = L"home";
|
||||
arrow[A_K_HO].key = T_kh;
|
||||
arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG;
|
||||
arrow[A_K_HO].type = XK_CMD;
|
||||
|
||||
arrow[A_K_EN].name = STR("end");
|
||||
arrow[A_K_EN].name = L"end";
|
||||
arrow[A_K_EN].key = T_at7;
|
||||
arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END;
|
||||
arrow[A_K_EN].type = XK_CMD;
|
||||
|
||||
arrow[A_K_DE].name = STR("delete");
|
||||
arrow[A_K_DE].name = L"delete";
|
||||
arrow[A_K_DE].key = T_kD;
|
||||
arrow[A_K_DE].fun.cmd = ED_DELETE_NEXT_CHAR;
|
||||
arrow[A_K_DE].type = XK_CMD;
|
||||
@ -1060,22 +1025,22 @@ terminal_init_arrow(EditLine *el)
|
||||
/* terminal_reset_arrow():
|
||||
* Reset arrow key bindings
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
terminal_reset_arrow(EditLine *el)
|
||||
{
|
||||
funckey_t *arrow = el->el_terminal.t_fkey;
|
||||
static const Char strA[] = {033, '[', 'A', '\0'};
|
||||
static const Char strB[] = {033, '[', 'B', '\0'};
|
||||
static const Char strC[] = {033, '[', 'C', '\0'};
|
||||
static const Char strD[] = {033, '[', 'D', '\0'};
|
||||
static const Char strH[] = {033, '[', 'H', '\0'};
|
||||
static const Char strF[] = {033, '[', 'F', '\0'};
|
||||
static const Char stOA[] = {033, 'O', 'A', '\0'};
|
||||
static const Char stOB[] = {033, 'O', 'B', '\0'};
|
||||
static const Char stOC[] = {033, 'O', 'C', '\0'};
|
||||
static const Char stOD[] = {033, 'O', 'D', '\0'};
|
||||
static const Char stOH[] = {033, 'O', 'H', '\0'};
|
||||
static const Char stOF[] = {033, 'O', 'F', '\0'};
|
||||
static const wchar_t strA[] = L"\033[A";
|
||||
static const wchar_t strB[] = L"\033[B";
|
||||
static const wchar_t strC[] = L"\033[C";
|
||||
static const wchar_t strD[] = L"\033[D";
|
||||
static const wchar_t strH[] = L"\033[H";
|
||||
static const wchar_t strF[] = L"\033[F";
|
||||
static const wchar_t stOA[] = L"\033OA";
|
||||
static const wchar_t stOB[] = L"\033OB";
|
||||
static const wchar_t stOC[] = L"\033OC";
|
||||
static const wchar_t stOD[] = L"\033OD";
|
||||
static const wchar_t stOH[] = L"\033OH";
|
||||
static const wchar_t stOF[] = L"\033OF";
|
||||
|
||||
keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
|
||||
keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
|
||||
@ -1110,15 +1075,15 @@ terminal_reset_arrow(EditLine *el)
|
||||
/* terminal_set_arrow():
|
||||
* Set an arrow key binding
|
||||
*/
|
||||
protected int
|
||||
terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
|
||||
libedit_private int
|
||||
terminal_set_arrow(EditLine *el, const wchar_t *name, keymacro_value_t *fun,
|
||||
int type)
|
||||
{
|
||||
funckey_t *arrow = el->el_terminal.t_fkey;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < A_K_NKEYS; i++)
|
||||
if (Strcmp(name, arrow[i].name) == 0) {
|
||||
if (wcscmp(name, arrow[i].name) == 0) {
|
||||
arrow[i].fun = *fun;
|
||||
arrow[i].type = type;
|
||||
return 0;
|
||||
@ -1130,14 +1095,14 @@ terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
|
||||
/* terminal_clear_arrow():
|
||||
* Clear an arrow key binding
|
||||
*/
|
||||
protected int
|
||||
terminal_clear_arrow(EditLine *el, const Char *name)
|
||||
libedit_private int
|
||||
terminal_clear_arrow(EditLine *el, const wchar_t *name)
|
||||
{
|
||||
funckey_t *arrow = el->el_terminal.t_fkey;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < A_K_NKEYS; i++)
|
||||
if (Strcmp(name, arrow[i].name) == 0) {
|
||||
if (wcscmp(name, arrow[i].name) == 0) {
|
||||
arrow[i].type = XK_NOD;
|
||||
return 0;
|
||||
}
|
||||
@ -1148,14 +1113,14 @@ terminal_clear_arrow(EditLine *el, const Char *name)
|
||||
/* terminal_print_arrow():
|
||||
* Print the arrow key bindings
|
||||
*/
|
||||
protected void
|
||||
terminal_print_arrow(EditLine *el, const Char *name)
|
||||
libedit_private void
|
||||
terminal_print_arrow(EditLine *el, const wchar_t *name)
|
||||
{
|
||||
int i;
|
||||
funckey_t *arrow = el->el_terminal.t_fkey;
|
||||
|
||||
for (i = 0; i < A_K_NKEYS; i++)
|
||||
if (*name == '\0' || Strcmp(name, arrow[i].name) == 0)
|
||||
if (*name == '\0' || wcscmp(name, arrow[i].name) == 0)
|
||||
if (arrow[i].type != XK_NOD)
|
||||
keymacro_kprint(el, arrow[i].name,
|
||||
&arrow[i].fun, arrow[i].type);
|
||||
@ -1165,7 +1130,7 @@ terminal_print_arrow(EditLine *el, const Char *name)
|
||||
/* terminal_bind_arrow():
|
||||
* Bind the arrow keys
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_bind_arrow(EditLine *el)
|
||||
{
|
||||
el_action_t *map;
|
||||
@ -1184,8 +1149,8 @@ terminal_bind_arrow(EditLine *el)
|
||||
terminal_reset_arrow(el);
|
||||
|
||||
for (i = 0; i < A_K_NKEYS; i++) {
|
||||
Char wt_str[VISUAL_WIDTH_MAX];
|
||||
Char *px;
|
||||
wchar_t wt_str[VISUAL_WIDTH_MAX];
|
||||
wchar_t *px;
|
||||
size_t n;
|
||||
|
||||
p = el->el_terminal.t_str[arrow[i].key];
|
||||
@ -1230,7 +1195,7 @@ terminal_bind_arrow(EditLine *el)
|
||||
/* terminal_putc():
|
||||
* Add a character
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
terminal_putc(int c)
|
||||
{
|
||||
if (terminal_outfile == NULL)
|
||||
@ -1238,7 +1203,7 @@ terminal_putc(int c)
|
||||
return fputc(c, terminal_outfile);
|
||||
}
|
||||
|
||||
private void
|
||||
static void
|
||||
terminal_tputs(EditLine *el, const char *cap, int affcnt)
|
||||
{
|
||||
#ifdef _REENTRANT
|
||||
@ -1254,14 +1219,16 @@ terminal_tputs(EditLine *el, const char *cap, int affcnt)
|
||||
/* terminal__putc():
|
||||
* Add a character
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
terminal__putc(EditLine *el, wint_t c)
|
||||
{
|
||||
char buf[MB_LEN_MAX +1];
|
||||
ssize_t i;
|
||||
if (c == (wint_t)MB_FILL_CHAR)
|
||||
return 0;
|
||||
i = ct_encode_char(buf, (size_t)MB_LEN_MAX, (Char)c);
|
||||
if (c & EL_LITERAL)
|
||||
return fputs(literal_get(el, c), el->el_outfile);
|
||||
i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c);
|
||||
if (i <= 0)
|
||||
return (int)i;
|
||||
buf[i] = '\0';
|
||||
@ -1271,7 +1238,7 @@ terminal__putc(EditLine *el, wint_t c)
|
||||
/* terminal__flush():
|
||||
* Flush output
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal__flush(EditLine *el)
|
||||
{
|
||||
|
||||
@ -1281,11 +1248,11 @@ terminal__flush(EditLine *el)
|
||||
/* terminal_writec():
|
||||
* Write the given character out, in a human readable form
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
terminal_writec(EditLine *el, wint_t c)
|
||||
{
|
||||
Char visbuf[VISUAL_WIDTH_MAX +1];
|
||||
ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
|
||||
wchar_t visbuf[VISUAL_WIDTH_MAX +1];
|
||||
ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
|
||||
if (vcnt < 0)
|
||||
vcnt = 0;
|
||||
visbuf[vcnt] = '\0';
|
||||
@ -1297,10 +1264,10 @@ terminal_writec(EditLine *el, wint_t c)
|
||||
/* terminal_telltc():
|
||||
* Print the current termcap characteristics
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
const Char **argv __attribute__((__unused__)))
|
||||
const wchar_t **argv __attribute__((__unused__)))
|
||||
{
|
||||
const struct termcapstr *t;
|
||||
char **ts;
|
||||
@ -1323,8 +1290,8 @@ terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
const char *ub;
|
||||
if (*ts && **ts) {
|
||||
ub = ct_encode_string(ct_visual_string(
|
||||
ct_decode_string(*ts, &el->el_scratch)),
|
||||
&el->el_scratch);
|
||||
ct_decode_string(*ts, &el->el_scratch),
|
||||
&el->el_visual), &el->el_scratch);
|
||||
} else {
|
||||
ub = "(empty)";
|
||||
}
|
||||
@ -1339,10 +1306,10 @@ terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
/* terminal_settc():
|
||||
* Change the current terminal characteristics
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
const Char **argv)
|
||||
const wchar_t **argv)
|
||||
{
|
||||
const struct termcapstr *ts;
|
||||
const struct termcapval *tv;
|
||||
@ -1386,7 +1353,7 @@ terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
el->el_terminal.t_val[tv - tval] = 0;
|
||||
else {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Bad value `%s'.\n", argv[0], how);
|
||||
"%ls: Bad value `%s'.\n", argv[0], how);
|
||||
return -1;
|
||||
}
|
||||
terminal_setflags(el);
|
||||
@ -1400,7 +1367,7 @@ terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
i = strtol(how, &ep, 10);
|
||||
if (*ep != '\0') {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"" FSTR ": Bad value `%s'.\n", argv[0], how);
|
||||
"%ls: Bad value `%s'.\n", argv[0], how);
|
||||
return -1;
|
||||
}
|
||||
el->el_terminal.t_val[tv - tval] = (int) i;
|
||||
@ -1418,7 +1385,7 @@ terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
/* terminal_gettc():
|
||||
* Get the current terminal characteristics
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
|
||||
{
|
||||
@ -1472,13 +1439,13 @@ terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
|
||||
/* terminal_echotc():
|
||||
* Print the termcap string out with variable substitution
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
const Char **argv)
|
||||
const wchar_t **argv)
|
||||
{
|
||||
char *cap, *scap;
|
||||
Char *ep;
|
||||
wchar_t *ep;
|
||||
int arg_need, arg_cols, arg_rows;
|
||||
int verbose = 0, silent = 0;
|
||||
char *area;
|
||||
@ -1509,28 +1476,28 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
}
|
||||
if (!*argv || *argv[0] == '\0')
|
||||
return 0;
|
||||
if (Strcmp(*argv, STR("tabs")) == 0) {
|
||||
if (wcscmp(*argv, L"tabs") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("meta")) == 0) {
|
||||
} else if (wcscmp(*argv, L"meta") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("xn")) == 0) {
|
||||
} else if (wcscmp(*argv, L"xn") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ?
|
||||
"yes" : "no");
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("am")) == 0) {
|
||||
} else if (wcscmp(*argv, L"am") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ?
|
||||
"yes" : "no");
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("baud")) == 0) {
|
||||
} else if (wcscmp(*argv, L"baud") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("rows")) == 0 ||
|
||||
Strcmp(*argv, STR("lines")) == 0) {
|
||||
} else if (wcscmp(*argv, L"rows") == 0 ||
|
||||
wcscmp(*argv, L"lines") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmtd, Val(T_li));
|
||||
return 0;
|
||||
} else if (Strcmp(*argv, STR("cols")) == 0) {
|
||||
} else if (wcscmp(*argv, L"cols") == 0) {
|
||||
(void) fprintf(el->el_outfile, fmtd, Val(T_co));
|
||||
return 0;
|
||||
}
|
||||
@ -1551,7 +1518,7 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
if (!scap || scap[0] == '\0') {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Termcap parameter `" FSTR "' not found.\n",
|
||||
"echotc: Termcap parameter `%ls' not found.\n",
|
||||
*argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1594,7 +1561,7 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
if (*argv && *argv[0]) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Warning: Extra argument `" FSTR "'.\n",
|
||||
"echotc: Warning: Extra argument `%ls'.\n",
|
||||
*argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1609,11 +1576,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
return -1;
|
||||
}
|
||||
arg_cols = 0;
|
||||
i = Strtol(*argv, &ep, 10);
|
||||
i = wcstol(*argv, &ep, 10);
|
||||
if (*ep != '\0' || i < 0) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Bad value `" FSTR "' for rows.\n",
|
||||
"echotc: Bad value `%ls' for rows.\n",
|
||||
*argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1622,7 +1589,7 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
if (*argv && *argv[0]) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Warning: Extra argument `" FSTR
|
||||
"echotc: Warning: Extra argument `%ls"
|
||||
"'.\n", *argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1643,11 +1610,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
"echotc: Warning: Missing argument.\n");
|
||||
return -1;
|
||||
}
|
||||
i = Strtol(*argv, &ep, 10);
|
||||
i = wcstol(*argv, &ep, 10);
|
||||
if (*ep != '\0' || i < 0) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Bad value `" FSTR "' for cols.\n",
|
||||
"echotc: Bad value `%ls' for cols.\n",
|
||||
*argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1659,11 +1626,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
"echotc: Warning: Missing argument.\n");
|
||||
return -1;
|
||||
}
|
||||
i = Strtol(*argv, &ep, 10);
|
||||
i = wcstol(*argv, &ep, 10);
|
||||
if (*ep != '\0' || i < 0) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Bad value `" FSTR "' for rows.\n",
|
||||
"echotc: Bad value `%ls' for rows.\n",
|
||||
*argv);
|
||||
return -1;
|
||||
}
|
||||
@ -1671,14 +1638,14 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
|
||||
if (*ep != '\0') {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Bad value `" FSTR "'.\n", *argv);
|
||||
"echotc: Bad value `%ls'.\n", *argv);
|
||||
return -1;
|
||||
}
|
||||
argv++;
|
||||
if (*argv && *argv[0]) {
|
||||
if (!silent)
|
||||
(void) fprintf(el->el_errfile,
|
||||
"echotc: Warning: Extra argument `" FSTR
|
||||
"echotc: Warning: Extra argument `%ls"
|
||||
"'.\n", *argv);
|
||||
return -1;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: terminal.h,v 1.7 2016/02/16 15:53:48 christos Exp $ */
|
||||
/* $NetBSD: terminal.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)term.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -42,7 +41,7 @@
|
||||
#define _h_el_terminal
|
||||
|
||||
typedef struct { /* Symbolic function key bindings */
|
||||
const Char *name; /* name of the key */
|
||||
const wchar_t *name; /* name of the key */
|
||||
int key; /* Index in termcap table */
|
||||
keymacro_value_t fun; /* Function bound to it */
|
||||
int type; /* Type of function */
|
||||
@ -81,31 +80,32 @@ typedef struct {
|
||||
#define A_K_DE 6
|
||||
#define A_K_NKEYS 7
|
||||
|
||||
protected void terminal_move_to_line(EditLine *, int);
|
||||
protected void terminal_move_to_char(EditLine *, int);
|
||||
protected void terminal_clear_EOL(EditLine *, int);
|
||||
protected void terminal_overwrite(EditLine *, const Char *, size_t);
|
||||
protected void terminal_insertwrite(EditLine *, Char *, int);
|
||||
protected void terminal_deletechars(EditLine *, int);
|
||||
protected void terminal_clear_screen(EditLine *);
|
||||
protected void terminal_beep(EditLine *);
|
||||
protected int terminal_change_size(EditLine *, int, int);
|
||||
protected int terminal_get_size(EditLine *, int *, int *);
|
||||
protected int terminal_init(EditLine *);
|
||||
protected void terminal_bind_arrow(EditLine *);
|
||||
protected void terminal_print_arrow(EditLine *, const Char *);
|
||||
protected int terminal_clear_arrow(EditLine *, const Char *);
|
||||
protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
|
||||
protected void terminal_end(EditLine *);
|
||||
protected void terminal_get(EditLine *, const char **);
|
||||
protected int terminal_set(EditLine *, const char *);
|
||||
protected int terminal_settc(EditLine *, int, const Char **);
|
||||
protected int terminal_gettc(EditLine *, int, char **);
|
||||
protected int terminal_telltc(EditLine *, int, const Char **);
|
||||
protected int terminal_echotc(EditLine *, int, const Char **);
|
||||
protected void terminal_writec(EditLine *, wint_t);
|
||||
protected int terminal__putc(EditLine *, wint_t);
|
||||
protected void terminal__flush(EditLine *);
|
||||
libedit_private void terminal_move_to_line(EditLine *, int);
|
||||
libedit_private void terminal_move_to_char(EditLine *, int);
|
||||
libedit_private void terminal_clear_EOL(EditLine *, int);
|
||||
libedit_private void terminal_overwrite(EditLine *, const wchar_t *, size_t);
|
||||
libedit_private void terminal_insertwrite(EditLine *, wchar_t *, int);
|
||||
libedit_private void terminal_deletechars(EditLine *, int);
|
||||
libedit_private void terminal_clear_screen(EditLine *);
|
||||
libedit_private void terminal_beep(EditLine *);
|
||||
libedit_private int terminal_change_size(EditLine *, int, int);
|
||||
libedit_private int terminal_get_size(EditLine *, int *, int *);
|
||||
libedit_private int terminal_init(EditLine *);
|
||||
libedit_private void terminal_bind_arrow(EditLine *);
|
||||
libedit_private void terminal_print_arrow(EditLine *, const wchar_t *);
|
||||
libedit_private int terminal_clear_arrow(EditLine *, const wchar_t *);
|
||||
libedit_private int terminal_set_arrow(EditLine *, const wchar_t *,
|
||||
keymacro_value_t *, int);
|
||||
libedit_private void terminal_end(EditLine *);
|
||||
libedit_private void terminal_get(EditLine *, const char **);
|
||||
libedit_private int terminal_set(EditLine *, const char *);
|
||||
libedit_private int terminal_settc(EditLine *, int, const wchar_t **);
|
||||
libedit_private int terminal_gettc(EditLine *, int, char **);
|
||||
libedit_private int terminal_telltc(EditLine *, int, const wchar_t **);
|
||||
libedit_private int terminal_echotc(EditLine *, int, const wchar_t **);
|
||||
libedit_private void terminal_writec(EditLine *, wint_t);
|
||||
libedit_private int terminal__putc(EditLine *, wint_t);
|
||||
libedit_private void terminal__flush(EditLine *);
|
||||
|
||||
/*
|
||||
* Easy access macros
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tokenizer.c,v 1.24 2016/02/17 19:47:49 christos Exp $ */
|
||||
/* $NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tokenizer.c,v 1.24 2016/02/17 19:47:49 christos Exp $");
|
||||
__RCSID("$NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* We build this file twice, once as NARROW, once as WIDE. */
|
||||
/*
|
||||
@ -51,7 +49,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
|
||||
#include "histedit.h"
|
||||
#include "chartype.h"
|
||||
|
||||
typedef enum {
|
||||
Q_none, Q_single, Q_double, Q_one, Q_doubleone
|
||||
@ -68,8 +65,22 @@ typedef enum {
|
||||
#define tok_malloc(a) malloc(a)
|
||||
#define tok_free(a) free(a)
|
||||
#define tok_realloc(a, b) realloc(a, b)
|
||||
#define tok_strdup(a) Strdup(a)
|
||||
|
||||
#ifdef NARROWCHAR
|
||||
#define Char char
|
||||
#define FUN(prefix, rest) prefix ## _ ## rest
|
||||
#define TYPE(type) type
|
||||
#define STR(x) x
|
||||
#define Strchr(s, c) strchr(s, c)
|
||||
#define tok_strdup(s) strdup(s)
|
||||
#else
|
||||
#define Char wchar_t
|
||||
#define FUN(prefix, rest) prefix ## _w ## rest
|
||||
#define TYPE(type) type ## W
|
||||
#define STR(x) L ## x
|
||||
#define Strchr(s, c) wcschr(s, c)
|
||||
#define tok_strdup(s) wcsdup(s)
|
||||
#endif
|
||||
|
||||
struct TYPE(tokenizer) {
|
||||
Char *ifs; /* In field separator */
|
||||
@ -83,13 +94,13 @@ struct TYPE(tokenizer) {
|
||||
};
|
||||
|
||||
|
||||
private void FUN(tok,finish)(TYPE(Tokenizer) *);
|
||||
static void FUN(tok,finish)(TYPE(Tokenizer) *);
|
||||
|
||||
|
||||
/* FUN(tok,finish)():
|
||||
* Finish a word in the tokenizer.
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
FUN(tok,finish)(TYPE(Tokenizer) *tok)
|
||||
{
|
||||
|
||||
@ -106,7 +117,7 @@ FUN(tok,finish)(TYPE(Tokenizer) *tok)
|
||||
/* FUN(tok,init)():
|
||||
* Initialize the tokenizer
|
||||
*/
|
||||
public TYPE(Tokenizer) *
|
||||
TYPE(Tokenizer) *
|
||||
FUN(tok,init)(const Char *ifs)
|
||||
{
|
||||
TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok));
|
||||
@ -147,7 +158,7 @@ FUN(tok,init)(const Char *ifs)
|
||||
/* FUN(tok,reset)():
|
||||
* Reset the tokenizer
|
||||
*/
|
||||
public void
|
||||
void
|
||||
FUN(tok,reset)(TYPE(Tokenizer) *tok)
|
||||
{
|
||||
|
||||
@ -162,7 +173,7 @@ FUN(tok,reset)(TYPE(Tokenizer) *tok)
|
||||
/* FUN(tok,end)():
|
||||
* Clean up
|
||||
*/
|
||||
public void
|
||||
void
|
||||
FUN(tok,end)(TYPE(Tokenizer) *tok)
|
||||
{
|
||||
|
||||
@ -191,7 +202,7 @@ FUN(tok,end)(TYPE(Tokenizer) *tok)
|
||||
* cursorc if !NULL, argv element containing cursor
|
||||
* cursorv if !NULL, offset in argv[cursorc] of cursor
|
||||
*/
|
||||
public int
|
||||
int
|
||||
FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
|
||||
int *argc, const Char ***argv, int *cursorc, int *cursoro)
|
||||
{
|
||||
@ -442,7 +453,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
|
||||
* Simpler version of tok_line, taking a NUL terminated line
|
||||
* and splitting into words, ignoring cursor state.
|
||||
*/
|
||||
public int
|
||||
int
|
||||
FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
|
||||
const Char ***argv)
|
||||
{
|
3
contrib/libedit/tokenizern.c
Normal file
3
contrib/libedit/tokenizern.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include "config.h"
|
||||
#define NARROWCHAR
|
||||
#include "tokenizer.c"
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tty.c,v 1.59 2016/03/22 01:34:32 christos Exp $ */
|
||||
/* $NetBSD: tty.c,v 1.68 2018/12/02 16:58:13 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: tty.c,v 1.59 2016/03/22 01:34:32 christos Exp $");
|
||||
__RCSID("$NetBSD: tty.c,v 1.68 2018/12/02 16:58:13 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* tty.c: tty interface stuff
|
||||
@ -54,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <unistd.h> /* for isatty */
|
||||
|
||||
#include "el.h"
|
||||
#include "fcns.h"
|
||||
#include "parse.h"
|
||||
|
||||
typedef struct ttymodes_t {
|
||||
@ -68,7 +67,7 @@ typedef struct ttymap_t {
|
||||
} ttymap_t;
|
||||
|
||||
|
||||
private const ttyperm_t ttyperm = {
|
||||
static const ttyperm_t ttyperm = {
|
||||
{
|
||||
{"iflag:", ICRNL, (INLCR | IGNCR)},
|
||||
{"oflag:", (OPOST | ONLCR), ONLRET},
|
||||
@ -96,7 +95,7 @@ private const ttyperm_t ttyperm = {
|
||||
}
|
||||
};
|
||||
|
||||
private const ttychar_t ttychar = {
|
||||
static const ttychar_t ttychar = {
|
||||
{
|
||||
CINTR, CQUIT, CERASE, CKILL,
|
||||
CEOF, CEOL, CEOL2, CSWTCH,
|
||||
@ -126,7 +125,7 @@ private const ttychar_t ttychar = {
|
||||
}
|
||||
};
|
||||
|
||||
private const ttymap_t tty_map[] = {
|
||||
static const ttymap_t tty_map[] = {
|
||||
#ifdef VERASE
|
||||
{C_ERASE, VERASE,
|
||||
{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
|
||||
@ -163,7 +162,7 @@ private const ttymap_t tty_map[] = {
|
||||
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
|
||||
};
|
||||
|
||||
private const ttymodes_t ttymodes[] = {
|
||||
static const ttymodes_t ttymodes[] = {
|
||||
#ifdef IGNBRK
|
||||
{"ignbrk", IGNBRK, MD_INP},
|
||||
#endif /* IGNBRK */
|
||||
@ -457,21 +456,21 @@ private const ttymodes_t ttymodes[] = {
|
||||
#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
|
||||
#define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
|
||||
|
||||
private int tty_getty(EditLine *, struct termios *);
|
||||
private int tty_setty(EditLine *, int, const struct termios *);
|
||||
private int tty__getcharindex(int);
|
||||
private void tty__getchar(struct termios *, unsigned char *);
|
||||
private void tty__setchar(struct termios *, unsigned char *);
|
||||
private speed_t tty__getspeed(struct termios *);
|
||||
private int tty_setup(EditLine *);
|
||||
private void tty_setup_flags(EditLine *, struct termios *, int);
|
||||
static int tty_getty(EditLine *, struct termios *);
|
||||
static int tty_setty(EditLine *, int, const struct termios *);
|
||||
static int tty__getcharindex(int);
|
||||
static void tty__getchar(struct termios *, unsigned char *);
|
||||
static void tty__setchar(struct termios *, unsigned char *);
|
||||
static speed_t tty__getspeed(struct termios *);
|
||||
static int tty_setup(EditLine *);
|
||||
static void tty_setup_flags(EditLine *, struct termios *, int);
|
||||
|
||||
#define t_qu t_ts
|
||||
|
||||
/* tty_getty():
|
||||
* Wrapper for tcgetattr to handle EINTR
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
tty_getty(EditLine *el, struct termios *t)
|
||||
{
|
||||
int rv;
|
||||
@ -483,7 +482,7 @@ tty_getty(EditLine *el, struct termios *t)
|
||||
/* tty_setty():
|
||||
* Wrapper for tcsetattr to handle EINTR
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
tty_setty(EditLine *el, int action, const struct termios *t)
|
||||
{
|
||||
int rv;
|
||||
@ -495,10 +494,10 @@ tty_setty(EditLine *el, int action, const struct termios *t)
|
||||
/* tty_setup():
|
||||
* Get the tty parameters and initialize the editing state
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
tty_setup(EditLine *el)
|
||||
{
|
||||
int rst = 1;
|
||||
int rst = (el->el_flags & NO_RESET) == 0;
|
||||
|
||||
if (el->el_flags & EDIT_DISABLED)
|
||||
return 0;
|
||||
@ -569,7 +568,7 @@ tty_setup(EditLine *el)
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int
|
||||
libedit_private int
|
||||
tty_init(EditLine *el)
|
||||
{
|
||||
|
||||
@ -585,9 +584,9 @@ tty_init(EditLine *el)
|
||||
/* tty_end():
|
||||
* Restore the tty to its original settings
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
/*ARGSUSED*/
|
||||
tty_end(EditLine *el)
|
||||
tty_end(EditLine *el, int how)
|
||||
{
|
||||
if (el->el_flags & EDIT_DISABLED)
|
||||
return;
|
||||
@ -595,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));
|
||||
@ -607,7 +607,7 @@ tty_end(EditLine *el)
|
||||
/* tty__getspeed():
|
||||
* Get the tty speed
|
||||
*/
|
||||
private speed_t
|
||||
static speed_t
|
||||
tty__getspeed(struct termios *td)
|
||||
{
|
||||
speed_t spd;
|
||||
@ -620,7 +620,7 @@ tty__getspeed(struct termios *td)
|
||||
/* tty__getspeed():
|
||||
* Return the index of the asked char in the c_cc array
|
||||
*/
|
||||
private int
|
||||
static int
|
||||
tty__getcharindex(int i)
|
||||
{
|
||||
switch (i) {
|
||||
@ -728,7 +728,7 @@ tty__getcharindex(int i)
|
||||
/* tty__getchar():
|
||||
* Get the tty characters
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
tty__getchar(struct termios *td, unsigned char *s)
|
||||
{
|
||||
|
||||
@ -810,7 +810,7 @@ tty__getchar(struct termios *td, unsigned char *s)
|
||||
/* tty__setchar():
|
||||
* Set the tty characters
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
tty__setchar(struct termios *td, unsigned char *s)
|
||||
{
|
||||
|
||||
@ -892,13 +892,13 @@ tty__setchar(struct termios *td, unsigned char *s)
|
||||
/* tty_bind_char():
|
||||
* Rebind the editline functions
|
||||
*/
|
||||
protected void
|
||||
libedit_private void
|
||||
tty_bind_char(EditLine *el, int force)
|
||||
{
|
||||
|
||||
unsigned char *t_n = el->el_tty.t_c[ED_IO];
|
||||
unsigned char *t_o = el->el_tty.t_ed.c_cc;
|
||||
Char new[2], old[2];
|
||||
wchar_t new[2], old[2];
|
||||
const ttymap_t *tp;
|
||||
el_action_t *map, *alt;
|
||||
const el_action_t *dmap, *dalt;
|
||||
@ -915,27 +915,29 @@ tty_bind_char(EditLine *el, int force)
|
||||
}
|
||||
|
||||
for (tp = tty_map; tp->nch != (wint_t)-1; tp++) {
|
||||
new[0] = (Char)t_n[tp->nch];
|
||||
old[0] = (Char)t_o[tp->och];
|
||||
new[0] = (wchar_t)t_n[tp->nch];
|
||||
old[0] = (wchar_t)t_o[tp->och];
|
||||
if (new[0] == old[0] && !force)
|
||||
continue;
|
||||
/* Put the old default binding back, and set the new binding */
|
||||
keymacro_clear(el, map, old);
|
||||
map[UC(old[0])] = dmap[UC(old[0])];
|
||||
map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]];
|
||||
keymacro_clear(el, map, new);
|
||||
/* MAP_VI == 1, MAP_EMACS == 0... */
|
||||
map[UC(new[0])] = tp->bind[el->el_map.type];
|
||||
map[(unsigned char)new[0]] = tp->bind[el->el_map.type];
|
||||
if (dalt) {
|
||||
keymacro_clear(el, alt, old);
|
||||
alt[UC(old[0])] = dalt[UC(old[0])];
|
||||
alt[(unsigned char)old[0]] =
|
||||
dalt[(unsigned char)old[0]];
|
||||
keymacro_clear(el, alt, new);
|
||||
alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
|
||||
alt[(unsigned char)new[0]] =
|
||||
tp->bind[el->el_map.type + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private tcflag_t *
|
||||
static tcflag_t *
|
||||
tty__get_flag(struct termios *t, int kind) {
|
||||
switch (kind) {
|
||||
case MD_INP:
|
||||
@ -953,7 +955,7 @@ tty__get_flag(struct termios *t, int kind) {
|
||||
}
|
||||
|
||||
|
||||
private tcflag_t
|
||||
static tcflag_t
|
||||
tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
|
||||
{
|
||||
f &= ~el->el_tty.t_t[mode][kind].t_clrmask;
|
||||
@ -962,7 +964,7 @@ tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
|
||||
}
|
||||
|
||||
|
||||
private void
|
||||
static void
|
||||
tty_update_flags(EditLine *el, int kind)
|
||||
{
|
||||
tcflag_t *tt, *ed, *ex;
|
||||
@ -977,7 +979,7 @@ tty_update_flags(EditLine *el, int kind)
|
||||
}
|
||||
|
||||
|
||||
private void
|
||||
static void
|
||||
tty_update_char(EditLine *el, int mode, int c) {
|
||||
if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c)))
|
||||
&& (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c]))
|
||||
@ -990,7 +992,7 @@ tty_update_char(EditLine *el, int mode, int c) {
|
||||
/* tty_rawmode():
|
||||
* Set terminal into 1 character at a time mode.
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
tty_rawmode(EditLine *el)
|
||||
{
|
||||
|
||||
@ -1045,7 +1047,7 @@ tty_rawmode(EditLine *el)
|
||||
|
||||
if (i != C_NCC) {
|
||||
/*
|
||||
* Propagate changes only to the unprotected
|
||||
* Propagate changes only to the unlibedit_private
|
||||
* chars that have been modified just now.
|
||||
*/
|
||||
for (i = 0; i < C_NCC; i++)
|
||||
@ -1075,7 +1077,7 @@ tty_rawmode(EditLine *el)
|
||||
/* tty_cookedmode():
|
||||
* Set the tty back to normal mode
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
tty_cookedmode(EditLine *el)
|
||||
{ /* set tty in normal setup */
|
||||
|
||||
@ -1100,7 +1102,7 @@ tty_cookedmode(EditLine *el)
|
||||
/* tty_quotemode():
|
||||
* Turn on quote mode
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
tty_quotemode(EditLine *el)
|
||||
{
|
||||
if (el->el_tty.t_mode == QU_IO)
|
||||
@ -1125,7 +1127,7 @@ tty_quotemode(EditLine *el)
|
||||
/* tty_noquotemode():
|
||||
* Turn off quote mode
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
tty_noquotemode(EditLine *el)
|
||||
{
|
||||
|
||||
@ -1146,14 +1148,15 @@ tty_noquotemode(EditLine *el)
|
||||
/* tty_stty():
|
||||
* Stty builtin
|
||||
*/
|
||||
protected int
|
||||
libedit_private int
|
||||
/*ARGSUSED*/
|
||||
tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
|
||||
tty_stty(EditLine *el, int argc __attribute__((__unused__)),
|
||||
const wchar_t **argv)
|
||||
{
|
||||
const ttymodes_t *m;
|
||||
char x;
|
||||
int aflag = 0;
|
||||
const Char *s, *d;
|
||||
const wchar_t *s, *d;
|
||||
char name[EL_BUFSIZ];
|
||||
struct termios *tios = &el->el_tty.t_ex;
|
||||
int z = EX_IO;
|
||||
@ -1237,7 +1240,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
|
||||
return 0;
|
||||
}
|
||||
while (argv && (s = *argv++)) {
|
||||
const Char *p;
|
||||
const wchar_t *p;
|
||||
switch (*s) {
|
||||
case '+':
|
||||
case '-':
|
||||
@ -1248,7 +1251,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
|
||||
break;
|
||||
}
|
||||
d = s;
|
||||
p = Strchr(s, '=');
|
||||
p = wcschr(s, L'=');
|
||||
for (m = ttymodes; m->m_name; m++)
|
||||
if ((p ? strncmp(m->m_name, ct_encode_string(d,
|
||||
&el->el_scratch), (size_t)(p - d)) :
|
||||
@ -1259,7 +1262,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
|
||||
|
||||
if (!m->m_name) {
|
||||
(void) fprintf(el->el_errfile,
|
||||
"%s: Invalid argument `" FSTR "'.\n", name, d);
|
||||
"%s: Invalid argument `%ls'.\n", name, d);
|
||||
return -1;
|
||||
}
|
||||
if (p) {
|
||||
@ -1308,7 +1311,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
|
||||
/* tty_printchar():
|
||||
* DEbugging routine to print the tty characters
|
||||
*/
|
||||
private void
|
||||
static void
|
||||
tty_printchar(EditLine *el, unsigned char *s)
|
||||
{
|
||||
ttyperm_t *m;
|
||||
@ -1329,7 +1332,7 @@ tty_printchar(EditLine *el, unsigned char *s)
|
||||
#endif /* notyet */
|
||||
|
||||
|
||||
private void
|
||||
static void
|
||||
tty_setup_flags(EditLine *el, struct termios *tios, int mode)
|
||||
{
|
||||
int kind;
|
||||
@ -1338,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;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tty.h,v 1.19 2016/02/27 18:13:21 christos Exp $ */
|
||||
/* $NetBSD: tty.h,v 1.23 2018/12/02 16:58:13 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -32,7 +32,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tty.h 8.1 (Berkeley) 6/4/93
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -457,14 +456,15 @@ typedef struct {
|
||||
|
||||
typedef unsigned char ttychar_t[NN_IO][C_NCC];
|
||||
|
||||
protected int tty_init(EditLine *);
|
||||
protected void tty_end(EditLine *);
|
||||
protected int tty_stty(EditLine *, int, const Char **);
|
||||
protected int tty_rawmode(EditLine *);
|
||||
protected int tty_cookedmode(EditLine *);
|
||||
protected int tty_quotemode(EditLine *);
|
||||
protected int tty_noquotemode(EditLine *);
|
||||
protected void tty_bind_char(EditLine *, int);
|
||||
libedit_private int tty_init(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;
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vi.c,v 1.55 2016/03/02 19:24:20 christos Exp $ */
|
||||
/* $NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -37,11 +37,9 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: vi.c,v 1.55 2016/03/02 19:24:20 christos Exp $");
|
||||
__RCSID("$NetBSD: vi.c,v 1.63 2019/07/23 10:18:52 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* vi.c: Vi mode commands.
|
||||
@ -56,15 +54,16 @@ __FBSDID("$FreeBSD$");
|
||||
#include "el.h"
|
||||
#include "common.h"
|
||||
#include "emacs.h"
|
||||
#include "fcns.h"
|
||||
#include "vi.h"
|
||||
|
||||
private el_action_t cv_action(EditLine *, wint_t);
|
||||
private el_action_t cv_paste(EditLine *, wint_t);
|
||||
static el_action_t cv_action(EditLine *, wint_t);
|
||||
static el_action_t cv_paste(EditLine *, wint_t);
|
||||
|
||||
/* cv_action():
|
||||
* Handle vi actions.
|
||||
*/
|
||||
private el_action_t
|
||||
static el_action_t
|
||||
cv_action(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
@ -96,7 +95,7 @@ cv_action(EditLine *el, wint_t c)
|
||||
/* cv_paste():
|
||||
* Paste previous deletion before or after the cursor
|
||||
*/
|
||||
private el_action_t
|
||||
static el_action_t
|
||||
cv_paste(EditLine *el, wint_t c)
|
||||
{
|
||||
c_kill_t *k = &el->el_chared.c_kill;
|
||||
@ -105,7 +104,7 @@ cv_paste(EditLine *el, wint_t c)
|
||||
if (k->buf == NULL || len == 0)
|
||||
return CC_ERROR;
|
||||
#ifdef DEBUG_PASTE
|
||||
(void) fprintf(el->el_errfile, "Paste: \"" FSTARSTR "\"\n", (int)len,
|
||||
(void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len,
|
||||
k->buf);
|
||||
#endif
|
||||
|
||||
@ -128,7 +127,7 @@ cv_paste(EditLine *el, wint_t c)
|
||||
* Vi paste previous deletion to the right of the cursor
|
||||
* [p]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -141,7 +140,7 @@ vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi paste previous deletion to the left of the cursor
|
||||
* [P]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -154,7 +153,7 @@ vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the previous space delimited word
|
||||
* [B]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -179,7 +178,7 @@ vi_prev_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the previous word
|
||||
* [b]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -204,7 +203,7 @@ vi_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the next space delimited word
|
||||
* [W]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -228,7 +227,7 @@ vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the next word
|
||||
* [w]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -252,7 +251,7 @@ vi_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi change case of character under the cursor and advance one character
|
||||
* [~]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
vi_change_case(EditLine *el, wint_t c)
|
||||
{
|
||||
int i;
|
||||
@ -263,10 +262,10 @@ vi_change_case(EditLine *el, wint_t c)
|
||||
for (i = 0; i < el->el_state.argument; i++) {
|
||||
|
||||
c = *el->el_line.cursor;
|
||||
if (Isupper(c))
|
||||
*el->el_line.cursor = Tolower(c);
|
||||
else if (Islower(c))
|
||||
*el->el_line.cursor = Toupper(c);
|
||||
if (iswupper(c))
|
||||
*el->el_line.cursor = towlower(c);
|
||||
else if (iswlower(c))
|
||||
*el->el_line.cursor = towupper(c);
|
||||
|
||||
if (++el->el_line.cursor >= el->el_line.lastchar) {
|
||||
el->el_line.cursor--;
|
||||
@ -283,7 +282,7 @@ vi_change_case(EditLine *el, wint_t c)
|
||||
* Vi change prefix command
|
||||
* [c]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -300,7 +299,7 @@ vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter insert mode at the beginning of line
|
||||
* [I]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -316,7 +315,7 @@ vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi replace character under the cursor with the next character typed
|
||||
* [r]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -335,7 +334,7 @@ vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter replace mode
|
||||
* [R]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -351,7 +350,7 @@ vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi replace character under the cursor and enter insert mode
|
||||
* [s]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -366,7 +365,7 @@ vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi substitute entire line
|
||||
* [S]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -384,7 +383,7 @@ vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi change to end of line
|
||||
* [C]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -402,7 +401,7 @@ vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter insert mode
|
||||
* [i]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_insert(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -417,7 +416,7 @@ vi_insert(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter insert mode after the cursor
|
||||
* [a]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_add(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -442,7 +441,7 @@ vi_add(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter insert mode at end of line
|
||||
* [A]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -458,7 +457,7 @@ vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi delete prefix command
|
||||
* [d]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -471,7 +470,7 @@ vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the end of the current space delimited word
|
||||
* [E]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -495,7 +494,7 @@ vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the end of the current word
|
||||
* [e]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_end_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -519,7 +518,7 @@ vi_end_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi undo last change
|
||||
* [u]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -546,7 +545,7 @@ vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi enter command mode (use alternative key bindings)
|
||||
* [<ESC>]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -571,7 +570,7 @@ vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the beginning of line
|
||||
* [0]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
vi_zero(EditLine *el, wint_t c)
|
||||
{
|
||||
|
||||
@ -591,7 +590,7 @@ vi_zero(EditLine *el, wint_t c)
|
||||
* Vi move to previous character (backspace)
|
||||
* [^H] in insert mode only
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -609,7 +608,7 @@ vi_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi list choices for completion or indicate end of file if empty line
|
||||
* [^D]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_list_or_eof(EditLine *el, wint_t c)
|
||||
{
|
||||
@ -646,11 +645,11 @@ vi_list_or_eof(EditLine *el, wint_t c)
|
||||
* Vi cut from beginning of line to cursor
|
||||
* [^U]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
Char *kp, *cp;
|
||||
wchar_t *kp, *cp;
|
||||
|
||||
cp = el->el_line.buffer;
|
||||
kp = el->el_chared.c_kill.buf;
|
||||
@ -667,7 +666,7 @@ vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi search history previous
|
||||
* [?]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -680,7 +679,7 @@ vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi search history next
|
||||
* [/]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -693,7 +692,7 @@ vi_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi repeat current search in the same search direction
|
||||
* [n]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -710,7 +709,7 @@ vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* [N]
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
|
||||
@ -727,7 +726,7 @@ vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the character specified next
|
||||
* [f]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -739,7 +738,7 @@ vi_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move to the character specified previous
|
||||
* [F]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -751,7 +750,7 @@ vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move up to the character specified next
|
||||
* [t]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -763,7 +762,7 @@ vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi move up to the character specified previous
|
||||
* [T]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -775,7 +774,7 @@ vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi repeat current character search in the same search direction
|
||||
* [;]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -789,7 +788,7 @@ vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi repeat current character search in the opposite search direction
|
||||
* [,]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -807,22 +806,22 @@ vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi go to matching () {} or []
|
||||
* [%]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_match(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
const Char match_chars[] = STR("()[]{}");
|
||||
Char *cp;
|
||||
const wchar_t match_chars[] = L"()[]{}";
|
||||
wchar_t *cp;
|
||||
size_t delta, i, count;
|
||||
Char o_ch, c_ch;
|
||||
wchar_t o_ch, c_ch;
|
||||
|
||||
*el->el_line.lastchar = '\0'; /* just in case */
|
||||
|
||||
i = Strcspn(el->el_line.cursor, match_chars);
|
||||
i = wcscspn(el->el_line.cursor, match_chars);
|
||||
o_ch = el->el_line.cursor[i];
|
||||
if (o_ch == 0)
|
||||
return CC_ERROR;
|
||||
delta = (size_t)(Strchr(match_chars, o_ch) - match_chars);
|
||||
delta = (size_t)(wcschr(match_chars, o_ch) - match_chars);
|
||||
c_ch = match_chars[delta ^ 1];
|
||||
count = 1;
|
||||
delta = 1 - (delta & 1) * 2;
|
||||
@ -854,7 +853,7 @@ vi_match(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi undo all changes to line
|
||||
* [U]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -868,7 +867,7 @@ vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* [|]
|
||||
* NB netbsd vi goes to screen column 'n', posix says nth character
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_column(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -882,7 +881,7 @@ vi_to_column(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi yank to end of line
|
||||
* [Y]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -896,7 +895,7 @@ vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi yank
|
||||
* [y]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -908,7 +907,7 @@ vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi comment out current command
|
||||
* [#]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -926,7 +925,7 @@ vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* NB: posix implies that we should enter insert mode, however
|
||||
* this is against historical precedent...
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -944,7 +943,7 @@ vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg,
|
||||
alias_name);
|
||||
if (alias_text != NULL)
|
||||
FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
|
||||
el_wpush(el, ct_decode_string(alias_text, &el->el_scratch));
|
||||
return CC_NORM;
|
||||
}
|
||||
|
||||
@ -952,7 +951,7 @@ vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi go to specified history file line.
|
||||
* [G]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -961,7 +960,7 @@ vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
|
||||
|
||||
if (el->el_history.eventno == 0) {
|
||||
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
|
||||
(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
|
||||
EL_BUFSIZ);
|
||||
el->el_history.last = el->el_history.buf +
|
||||
(el->el_line.lastchar - el->el_line.buffer);
|
||||
@ -997,7 +996,7 @@ vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi edit history line with vi
|
||||
* [v]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -1008,7 +1007,7 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
|
||||
char *cp = NULL;
|
||||
size_t len;
|
||||
Char *line = NULL;
|
||||
wchar_t *line = NULL;
|
||||
|
||||
if (el->el_state.doingarg) {
|
||||
if (vi_to_history_line(el, 0) == CC_ERROR)
|
||||
@ -1020,15 +1019,15 @@ 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;
|
||||
Strncpy(line, el->el_line.buffer, len);
|
||||
wcsncpy(line, el->el_line.buffer, len);
|
||||
line[len] = '\0';
|
||||
ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
|
||||
wcstombs(cp, line, TMP_BUFSIZ - 1);
|
||||
cp[TMP_BUFSIZ - 1] = '\0';
|
||||
len = strlen(cp);
|
||||
write(fd, cp, len);
|
||||
@ -1050,7 +1049,7 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
if (st > 0) {
|
||||
cp[st] = '\0';
|
||||
len = (size_t)(el->el_line.limit - el->el_line.buffer);
|
||||
len = ct_mbstowcs(el->el_line.buffer, cp, len);
|
||||
len = mbstowcs(el->el_line.buffer, cp, len);
|
||||
if (len > 0 && el->el_line.buffer[len - 1] == '\n')
|
||||
--len;
|
||||
}
|
||||
@ -1081,27 +1080,27 @@ error:
|
||||
* Who knows where this one came from!
|
||||
* '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_history_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
const Char *wp = HIST_FIRST(el);
|
||||
const Char *wep, *wsp;
|
||||
const wchar_t *wp = HIST_FIRST(el);
|
||||
const wchar_t *wep, *wsp;
|
||||
int len;
|
||||
Char *cp;
|
||||
const Char *lim;
|
||||
wchar_t *cp;
|
||||
const wchar_t *lim;
|
||||
|
||||
if (wp == NULL)
|
||||
return CC_ERROR;
|
||||
|
||||
wep = wsp = NULL;
|
||||
do {
|
||||
while (Isspace(*wp))
|
||||
while (iswspace(*wp))
|
||||
wp++;
|
||||
if (*wp == 0)
|
||||
break;
|
||||
wsp = wp;
|
||||
while (*wp && !Isspace(*wp))
|
||||
while (*wp && !iswspace(*wp))
|
||||
wp++;
|
||||
wep = wp;
|
||||
} while ((!el->el_state.doingarg || --el->el_state.argument > 0)
|
||||
@ -1131,7 +1130,7 @@ vi_history_word(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
* Vi redo last non-motion command
|
||||
* [.]
|
||||
*/
|
||||
protected el_action_t
|
||||
libedit_private el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
{
|
||||
@ -1149,7 +1148,7 @@ vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
|
||||
/* sanity */
|
||||
r->pos = r->lim - 1;
|
||||
r->pos[0] = 0;
|
||||
FUN(el,push)(el, r->buf);
|
||||
el_wpush(el, r->buf);
|
||||
}
|
||||
|
||||
el->el_state.thiscmd = r->cmd;
|
@ -117,7 +117,7 @@ cwalk(FILE *fp)
|
||||
host[sizeof(host) - 1] = '\0';
|
||||
if ((user = getlogin()) == NULL) {
|
||||
struct passwd *pw;
|
||||
user = (pw = getpwuid(getuid())) == NULL ? pw->pw_name :
|
||||
user = (pw = getpwuid(getuid())) != NULL ? pw->pw_name :
|
||||
"<unknown>";
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: only.c,v 1.2 2013/02/05 00:59:03 christos Exp $ */
|
||||
/* $NetBSD: only.c,v 1.3 2017/09/07 04:04:13 nakayama Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
@ -38,7 +38,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
__RCSID("$NetBSD: only.c,v 1.2 2013/02/05 00:59:03 christos Exp $");
|
||||
__RCSID("$NetBSD: only.c,v 1.3 2017/09/07 04:04:13 nakayama Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -89,11 +89,14 @@ static void
|
||||
hash_insert(char *str, uint32_t h)
|
||||
{
|
||||
struct hentry *e;
|
||||
char *x;
|
||||
|
||||
if ((e = malloc(sizeof(*e))) == NULL)
|
||||
mtree_err("memory allocation error");
|
||||
if ((x = strdup(str)) == NULL)
|
||||
mtree_err("memory allocation error");
|
||||
|
||||
e->str = str;
|
||||
e->str = x;
|
||||
e->hash = h;
|
||||
e->next = table[h];
|
||||
table[h] = e;
|
||||
@ -110,10 +113,7 @@ fill(char *str)
|
||||
|
||||
*ptr = '\0';
|
||||
if (!hash_find(str, &h)) {
|
||||
char *x = strdup(str);
|
||||
if (x == NULL)
|
||||
mtree_err("memory allocation error");
|
||||
hash_insert(x, h);
|
||||
hash_insert(str, h);
|
||||
fill(str);
|
||||
}
|
||||
*ptr = '/';
|
||||
@ -135,6 +135,7 @@ load_only(const char *fname)
|
||||
err(1, "Duplicate entry %s", line);
|
||||
hash_insert(line, h);
|
||||
fill(line);
|
||||
free(line);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
@ -145,7 +145,7 @@ compare_nodes(NODE *n1, NODE *n2, char const *path)
|
||||
return (1);
|
||||
}
|
||||
if (n1->type != n2->type) {
|
||||
differs = 0;
|
||||
differs = F_TYPE;
|
||||
mismatch(n1, n2, differs, path);
|
||||
return (1);
|
||||
}
|
||||
|
@ -187,7 +187,8 @@ ATF_TC_BODY(regcomp_too_big, tc)
|
||||
struct rlimit limit;
|
||||
|
||||
#if defined(__i386__)
|
||||
atf_tc_skip("https://bugs.freebsd.org/237450");
|
||||
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
|
||||
atf_tc_skip("https://bugs.freebsd.org/237450");
|
||||
#endif
|
||||
|
||||
limit.rlim_cur = limit.rlim_max = 256 * 1024 * 1024;
|
||||
|
@ -411,6 +411,41 @@ netbsd6_nonemptydir_body()
|
||||
FLAVOR=netbsd6 nonemptydir_body
|
||||
}
|
||||
|
||||
atf_test_case mtree_specspec_type
|
||||
mtree_specspec_type_head()
|
||||
{
|
||||
atf_set "descr" "Test that spec comparisons detect type changes"
|
||||
}
|
||||
|
||||
mtree_specspec_type_body()
|
||||
{
|
||||
mkdir testdir
|
||||
|
||||
touch testdir/bar
|
||||
mtree -c -p testdir > mtree1.spec
|
||||
|
||||
if [ ! -f mtree1.spec ]; then
|
||||
atf_fail "mtree failed"
|
||||
fi
|
||||
|
||||
rm -f testdir/bar
|
||||
ln -s foo testdir/bar
|
||||
# uid change is expected to be ignored as done in -C
|
||||
chown -h operator testdir/bar
|
||||
mtree -c -p testdir > mtree2.spec
|
||||
|
||||
if [ ! -f mtree2.spec ]; then
|
||||
atf_fail "mtree failed"
|
||||
fi
|
||||
|
||||
atf_check -s ignore -o save:output \
|
||||
-x "mtree -f mtree1.spec -f mtree2.spec"
|
||||
|
||||
if ! cut -f 3 output | egrep -q "bar file" || \
|
||||
! cut -f 3 output | egrep -q "bar link"; then
|
||||
atf_fail "mtree did not detect type change"
|
||||
fi
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
@ -423,6 +458,7 @@ atf_init_test_cases()
|
||||
atf_add_test_case mtree_ignore
|
||||
atf_add_test_case mtree_merge
|
||||
atf_add_test_case mtree_nonemptydir
|
||||
atf_add_test_case mtree_specspec_type
|
||||
|
||||
atf_add_test_case netbsd6_create
|
||||
atf_add_test_case netbsd6_check
|
||||
|
@ -1,5 +1,80 @@
|
||||
News for the tz database
|
||||
|
||||
Release 2019c - 2019-09-11 08:59:48 -0700
|
||||
|
||||
Briefly:
|
||||
Fiji observes DST from 2019-11-10 to 2020-01-12.
|
||||
Norfolk Island starts observing Australian-style DST.
|
||||
|
||||
Changes to future timestamps
|
||||
|
||||
Fiji's next DST transitions will be 2019-11-10 and 2020-01-12
|
||||
instead of 2019-11-03 and 2020-01-19. (Thanks to Raymond Kumar.)
|
||||
Adjust future guesses accordingly.
|
||||
|
||||
Norfolk Island will observe Australian-style DST starting in
|
||||
spring 2019. The first transition is on 2019-10-06. (Thanks to
|
||||
Kyle Czech and Michael Deckers.)
|
||||
|
||||
Changes to past timestamps
|
||||
|
||||
Many corrections to time in Turkey from 1940 through 1985.
|
||||
(Thanks to Oya Vulaş via Alois Treindl, and to Kıvanç Yazan.)
|
||||
|
||||
The Norfolk Island 1975-03-02 transition was at 02:00 standard
|
||||
time, not 02:00 DST. (Thanks to Michael Deckers.)
|
||||
|
||||
South Korea observed DST from 1948 through 1951. Although this
|
||||
info was supposed to appear in release 2014j, a typo inadvertently
|
||||
suppressed the change. (Thanks to Alois Treindl.)
|
||||
|
||||
Detroit observed DST in 1967 and 1968 following the US DST rules,
|
||||
except that its 1967 DST began on June 14 at 00:01. (Thanks to
|
||||
Alois Treindl for pointing out that the old data entries were
|
||||
probably wrong.)
|
||||
|
||||
Fix several errors in pre-1970 transitions in Perry County, IN.
|
||||
(Thanks to Alois Triendl for pointing out the 1967/9 errors.)
|
||||
|
||||
Edmonton did not observe DST in 1967 or 1969. In 1946 Vancouver
|
||||
ended DST on 09-29 not 10-13, and Vienna ended DST on 10-07 not
|
||||
10-06. In 1945 Königsberg (now Kaliningrad) switched from +01/+02
|
||||
to +02/+03 on 04-10 not 01-01, and its +02/+03 is abbreviated
|
||||
EET/EEST, not CET/CEST. (Thanks to Alois Triendl.) In 1946
|
||||
Königsberg switched to +03 on 04-07 not 01-01.
|
||||
|
||||
In 1946 Louisville switched from CST to CDT on 04-28 at 00:01, not
|
||||
01-01 at 00:00. (Thanks to Alois Treindl and Michael Deckers.)
|
||||
Also, it switched from CST to CDT on 1950-04-30, not 1947-04-27.
|
||||
|
||||
The 1892-05-01 transition in Brussels was at 00:17:30, not at noon.
|
||||
(Thanks to Michael Deckers.)
|
||||
|
||||
Changes to past time zone abbreviations and DST flags
|
||||
|
||||
Hong Kong Winter Time, observed from 1941-10-01 to 1941-12-25,
|
||||
is now flagged as DST and is abbreviated HKWT not HKT.
|
||||
|
||||
Changes to code
|
||||
|
||||
leapseconds.awk now relies only on its input data, rather than
|
||||
also relying on its comments. (Inspired by code from Dennis
|
||||
Ferguson and Chris Woodbury.)
|
||||
|
||||
The code now defends against CRLFs in leap-seconds.list.
|
||||
(Thanks to Brian Inglis and Chris Woodbury.)
|
||||
|
||||
Changes to documentation and commentary
|
||||
|
||||
theory.html discusses leap seconds. (Thanks to Steve Summit.)
|
||||
|
||||
Nashville's newspapers dueled about the time of day in the 1950s.
|
||||
(Thanks to John Seigenthaler.)
|
||||
|
||||
Liechtenstein observed Swiss DST in 1941/2.
|
||||
(Thanks to Alois Treindl.)
|
||||
|
||||
|
||||
Release 2019b - 2019-07-01 00:09:53 -0700
|
||||
|
||||
Briefly:
|
||||
|
@ -8,7 +8,7 @@
|
||||
# tz@iana.org for general use in the future). For more, please see
|
||||
# the file CONTRIBUTING in the tz distribution.
|
||||
|
||||
# From Paul Eggert (2018-06-19):
|
||||
# From Paul Eggert (2019-07-11):
|
||||
#
|
||||
# Unless otherwise specified, the source for data through 1990 is:
|
||||
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
|
||||
@ -47,13 +47,13 @@
|
||||
# 7:00 WIB west Indonesia (Waktu Indonesia Barat)
|
||||
# 8:00 WITA central Indonesia (Waktu Indonesia Tengah)
|
||||
# 8:00 CST China
|
||||
# 8:00 PST PDT* Philippine Standard Time
|
||||
# 8:00 HKT HKST Hong Kong (HKWT* for Winter Time in late 1941)
|
||||
# 8:00 PST PDT* Philippines
|
||||
# 8:30 KST KDT Korea when at +0830
|
||||
# 9:00 WIT east Indonesia (Waktu Indonesia Timur)
|
||||
# 9:00 JST JDT Japan
|
||||
# 9:00 KST KDT Korea when at +09
|
||||
# 9:30 ACST Australian Central Standard Time
|
||||
# *I invented the abbreviation PDT; see "Philippines" below.
|
||||
# *I invented the abbreviations HKWT and PDT; see below.
|
||||
# Otherwise, these tables typically use numeric abbreviations like +03
|
||||
# and +0330 for integer hour and minute UT offsets. Although earlier
|
||||
# editions invented alphabetic time zone abbreviations for every
|
||||
@ -653,6 +653,15 @@ Zone Asia/Urumqi 5:50:20 - LMT 1928
|
||||
# * 1941-09-30, Hong Kong Daily Press, Winter Time Warning.
|
||||
# https://i.imgur.com/dge4kFJ.png
|
||||
|
||||
# From Paul Eggert (2019-07-11):
|
||||
# "Hong Kong winter time" is considered to be daylight saving.
|
||||
# "Hong Kong had adopted daylight saving on June 15 as a wartime measure,
|
||||
# clocks moving forward one hour until October 1, when they would be put back
|
||||
# by just half an hour for 'Hong Kong Winter time', so that daylight saving
|
||||
# operated year round." -- Low Z. The longest day: when wartime Hong Kong
|
||||
# introduced daylight saving. South China Morning Post. 2019-06-28.
|
||||
# https://www.scmp.com/magazines/post-magazine/short-reads/article/3016281/longest-day-when-wartime-hong-kong-introduced
|
||||
|
||||
# From P Chan (2018-12-31):
|
||||
# * According to the Hong Kong Daylight-Saving Regulations, 1941, the
|
||||
# 1941 spring-forward transition was at 03:00.
|
||||
@ -754,7 +763,7 @@ Rule HK 1979 only - Oct 21 3:30 0 -
|
||||
Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30 0:36:42
|
||||
8:00 - HKT 1941 Jun 15 3:00
|
||||
8:00 1:00 HKST 1941 Oct 1 4:00
|
||||
8:30 - HKT 1941 Dec 25
|
||||
8:00 0:30 HKWT 1941 Dec 25
|
||||
9:00 - JST 1945 Nov 18 2:00
|
||||
8:00 HK HK%sT
|
||||
|
||||
@ -2419,7 +2428,7 @@ Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
|
||||
Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1
|
||||
8:30 - KST 1912 Jan 1
|
||||
9:00 - JST 1945 Sep 8
|
||||
9:00 - KST 1954 Mar 21
|
||||
9:00 ROK K%sT 1954 Mar 21
|
||||
8:30 ROK K%sT 1961 Aug 10
|
||||
9:00 ROK K%sT
|
||||
Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1
|
||||
@ -3604,7 +3613,7 @@ Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
|
||||
# and in South Vietnam in particular (after 1954):
|
||||
# To 07:00 on 1911-05-01.
|
||||
# To 08:00 on 1942-12-31 at 23:00.
|
||||
# To 09:00 in 1945-03-14 at 23:00.
|
||||
# To 09:00 on 1945-03-14 at 23:00.
|
||||
# To 07:00 on 1945-09-02 in Vietnam.
|
||||
# To 08:00 on 1947-04-01 in French-controlled Indochina.
|
||||
# To 07:00 on 1955-07-01 in South Vietnam.
|
||||
|
@ -367,13 +367,18 @@ Zone Indian/Cocos 6:27:40 - LMT 1900
|
||||
# From Raymond Kumar (2018-07-13):
|
||||
# http://www.fijitimes.com/government-approves-2018-daylight-saving/
|
||||
# ... The daylight saving period will end at 3am on Sunday January 13, 2019.
|
||||
#
|
||||
# From Paul Eggert (2018-07-15):
|
||||
# For now, guess DST from 02:00 the first Sunday in November to 03:00
|
||||
# the first Sunday on or after January 13. January transitions reportedly
|
||||
|
||||
# From Paul Eggert (2019-08-06):
|
||||
# Today Raymond Kumar reported the Government of Fiji Gazette Supplement No. 27
|
||||
# (2019-08-02) said that Fiji observes DST "commencing at 2.00 am on
|
||||
# Sunday, 10 November 2019 and ending at 3.00 am on Sunday, 12 January 2020."
|
||||
# For now, guess DST from 02:00 the second Sunday in November to 03:00
|
||||
# the first Sunday on or after January 12. January transitions reportedly
|
||||
# depend on when school terms start. Although the guess is ad hoc, it matches
|
||||
# transitions since late 2014 and seems more likely to match future
|
||||
# practice than guessing no DST.
|
||||
# transitions planned this year and seems more likely to match future practice
|
||||
# than guessing no DST.
|
||||
# From Michael Deckers (2019-08-06):
|
||||
# https://www.laws.gov.fj/LawsAsMade/downloadfile/848
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 -
|
||||
@ -384,8 +389,9 @@ Rule Fiji 2010 2013 - Oct Sun>=21 2:00 1:00 -
|
||||
Rule Fiji 2011 only - Mar Sun>=1 3:00 0 -
|
||||
Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 -
|
||||
Rule Fiji 2014 only - Jan Sun>=18 2:00 0 -
|
||||
Rule Fiji 2014 max - Nov Sun>=1 2:00 1:00 -
|
||||
Rule Fiji 2015 max - Jan Sun>=13 3:00 0 -
|
||||
Rule Fiji 2014 2018 - Nov Sun>=1 2:00 1:00 -
|
||||
Rule Fiji 2015 max - Jan Sun>=12 3:00 0 -
|
||||
Rule Fiji 2019 max - Nov Sun>=8 2:00 1:00 -
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva
|
||||
12:00 Fiji +12/+13
|
||||
@ -604,10 +610,11 @@ Zone Pacific/Niue -11:19:40 - LMT 1901 # Alofi
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Pacific/Norfolk 11:11:52 - LMT 1901 # Kingston
|
||||
11:12 - +1112 1951
|
||||
11:30 - +1130 1974 Oct 27 02:00
|
||||
11:30 1:00 +1230 1975 Mar 2 02:00
|
||||
11:30 - +1130 2015 Oct 4 02:00
|
||||
11:00 - +11
|
||||
11:30 - +1130 1974 Oct 27 02:00s
|
||||
11:30 1:00 +1230 1975 Mar 2 02:00s
|
||||
11:30 - +1130 2015 Oct 4 02:00s
|
||||
11:00 - +11 2019 Jul
|
||||
11:00 AN +11/+12
|
||||
|
||||
# Palau (Belau)
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
@ -1875,12 +1882,21 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
|
||||
# ... at 12.30 am (by legal time in New South Wales) on 4 October 2015.
|
||||
# http://www.norfolkisland.gov.nf/nia/MediaRelease/Media%20Release%20Norfolk%20Island%20Standard%20Time%20Change.pdf
|
||||
|
||||
# From Paul Eggert (2015-09-23):
|
||||
# From Paul Eggert (2019-08-28):
|
||||
# Transitions before 2015 are from timeanddate.com, which consulted
|
||||
# the Norfolk Island Museum and the Australian Bureau of Meteorology's
|
||||
# Norfolk Island station, and found no record of Norfolk observing DST
|
||||
# other than in 1974/5. See:
|
||||
# https://www.timeanddate.com/time/australia/norfolk-island.html
|
||||
# However, disagree with timeanddate about the 1975-03-02 transition;
|
||||
# timeanddate has 02:00 but 02:00s corresponds to what the NSW law said
|
||||
# (thanks to Michael Deckers).
|
||||
|
||||
# Norfolk started observing Australian DST in spring 2019.
|
||||
# From Kyle Czech (2019-08-13):
|
||||
# https://www.legislation.gov.au/Details/F2018L01702
|
||||
# From Michael Deckers (2019-08-14):
|
||||
# https://www.legislation.gov.au/Details/F2019C00010
|
||||
|
||||
# Palau
|
||||
# See commentary for Micronesia.
|
||||
|
@ -507,19 +507,35 @@ Zone Asia/Muscat 3:54:24 - LMT 1920
|
||||
#Zone Asia/Panaji [not enough info to complete]
|
||||
|
||||
# Cambodia
|
||||
# From Paul Eggert (2014-10-11):
|
||||
# See Asia/Ho_Chi_Minh for the source for most of this data. Also, guess
|
||||
# (1) Cambodia reverted to UT +07 on 1945-09-02, when Vietnam did, and
|
||||
# (2) they also reverted to +07 on 1953-11-09, the date of independence.
|
||||
# These guesses are probably wrong but they're better than guessing no
|
||||
# transitions there.
|
||||
|
||||
# From an adoptive daughter of the late Cambodian ruler Prince Sihanouk,
|
||||
# via Alois Treindl (2019-08-08):
|
||||
#
|
||||
# King Sihanouk said that, during the Japanese occupation, starting with
|
||||
# what historians refer to as "le coup de force du 9 mars 1945", Cambodia,
|
||||
# like the entire French Indochina, used Tokyo time zone. After Japan
|
||||
# surrendered, 2 September 1945, Cambodia fell under French rule again and
|
||||
# adopted Hanoi time zone again.
|
||||
#
|
||||
# However, on 7 January 1946, Sihanouk and Tioulong managed to obtain a
|
||||
# status of "internal autonomy" from the government of Charles de Gaulle.
|
||||
# Although many fields remained under the administration of the French
|
||||
# (customs, taxes, justice, defence, foreign affairs, etc.), the Cambodian
|
||||
# administration was responsible for religious matters and traditional
|
||||
# celebrations, which included our calendar and time. The time zone was GMT
|
||||
# + 7 and _no_ DST was applied.
|
||||
#
|
||||
# After Sihanouk and Tioulong achieved full independence, on 9 November 1953,
|
||||
# GMT + 7 was maintained.
|
||||
|
||||
# From Paul Eggert (2019-08-26):
|
||||
# See Asia/Ho_Chi_Minh for the source for most of rest of this data.
|
||||
|
||||
Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jul 1
|
||||
7:06:30 - PLMT 1911 May 1
|
||||
7:00 - +07 1942 Dec 31 23:00
|
||||
8:00 - +08 1945 Mar 14 23:00
|
||||
9:00 - +09 1945 Sep 2
|
||||
7:00 - +07 1947 Apr 1
|
||||
8:00 - +08 1953 Nov 9
|
||||
7:00 - +07
|
||||
|
||||
# Israel
|
||||
@ -646,7 +662,7 @@ Zone Europe/Tiraspol 1:58:32 - LMT 1880
|
||||
|
||||
# Liechtenstein
|
||||
Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun
|
||||
1:00 - CET 1981
|
||||
1:00 Swiss CE%sT 1981
|
||||
1:00 EU CE%sT
|
||||
|
||||
# Croatia
|
||||
|
@ -821,11 +821,16 @@ Zone Europe/Andorra 0:06:04 - LMT 1901
|
||||
# Shanks & Pottenger give 02:00, the BEV 00:00. Go with the BEV,
|
||||
# and guess 02:00 for 1945-04-12.
|
||||
|
||||
# From Alois Triendl (2019-07-22):
|
||||
# In 1946 the end of DST was on Monday, 7 October 1946, at 3:00 am.
|
||||
# Shanks had this right. Source: Die Weltpresse, 5. Oktober 1946, page 5.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Austria 1920 only - Apr 5 2:00s 1:00 S
|
||||
Rule Austria 1920 only - Sep 13 2:00s 0 -
|
||||
Rule Austria 1946 only - Apr 14 2:00s 1:00 S
|
||||
Rule Austria 1946 1948 - Oct Sun>=1 2:00s 0 -
|
||||
Rule Austria 1946 only - Oct 7 2:00s 0 -
|
||||
Rule Austria 1947 1948 - Oct Sun>=1 2:00s 0 -
|
||||
Rule Austria 1947 only - Apr 6 2:00s 1:00 S
|
||||
Rule Austria 1948 only - Apr 18 2:00s 1:00 S
|
||||
Rule Austria 1980 only - Apr 6 0:00 1:00 S
|
||||
@ -875,15 +880,35 @@ Zone Europe/Minsk 1:50:16 - LMT 1880
|
||||
|
||||
# Belgium
|
||||
#
|
||||
# From Paul Eggert (1997-07-02):
|
||||
# From Michael Deckers (2019-08-25):
|
||||
# The exposition in the web page
|
||||
# https://www.bestor.be/wiki/index.php/Voyager_dans_le_temps._L%E2%80%99introduction_de_la_norme_de_Greenwich_en_Belgique
|
||||
# gives several contemporary sources from which one can conclude that
|
||||
# the switch in Europe/Brussels on 1892-05-01 was from 00:17:30 to 00:00:00.
|
||||
#
|
||||
# From Paul Eggert (2019-08-28):
|
||||
# This quote helps explain the late-1914 situation:
|
||||
# In early November 1914, the Germans imposed the time zone used in central
|
||||
# Europe and forced the inhabitants to set their watches and public clocks
|
||||
# sixty minutes ahead. Many were reluctant to accept "German time" and
|
||||
# continued to use "Belgian time" among themselves. Reflecting the spirit of
|
||||
# resistance that arose in the population, a song made fun of this change....
|
||||
# The song ended:
|
||||
# Putting your clock forward
|
||||
# Will but hasten the happy hour
|
||||
# When we kick out the Boches!
|
||||
# See: Pluvinage G. Brussels on German time. Cahiers Bruxellois -
|
||||
# Brusselse Cahiers. 2014;XLVI(1E):15-38.
|
||||
# https://www.cairn.info/revue-cahiers-bruxellois-2014-1E-page-15.htm
|
||||
#
|
||||
# Entries from 1914 through 1917 are taken from "De tijd in België"
|
||||
# <https://www.astro.oma.be/GENERAL/INFO/nli001a.html>.
|
||||
# Entries from 1918 through 1991 are taken from:
|
||||
# Annuaire de L'Observatoire Royal de Belgique,
|
||||
# Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe année, 1991
|
||||
# (Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
|
||||
# pp 8-9.
|
||||
# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
|
||||
# Moniteur Belge, Samedi 30 Avril 1892, N.121.
|
||||
# Thanks to Pascal Delmoitie for these references.
|
||||
# Thanks to Pascal Delmoitie for the 1918/1991 references.
|
||||
# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
|
||||
# Assume Brussels switched to WET in 1918 when the armistice took effect.
|
||||
#
|
||||
@ -928,7 +953,7 @@ Rule Belgium 1946 only - May 19 2:00s 1:00 S
|
||||
Rule Belgium 1946 only - Oct 7 2:00s 0 -
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Europe/Brussels 0:17:30 - LMT 1880
|
||||
0:17:30 - BMT 1892 May 1 12:00 # Brussels MT
|
||||
0:17:30 - BMT 1892 May 1 00:17:30
|
||||
0:00 - WET 1914 Nov 8
|
||||
1:00 - CET 1916 May 1 0:00
|
||||
1:00 C-Eur CE%sT 1918 Nov 11 11:00u
|
||||
@ -1627,6 +1652,13 @@ Zone Atlantic/Reykjavik -1:28 - LMT 1908
|
||||
# advanced to sixty minutes later starting at hour two on 1944-04-02; ...
|
||||
# Starting at hour three on the date 1944-09-17 standard time will be resumed.
|
||||
#
|
||||
# From Alois Triendl (2019-07-02):
|
||||
# I spent 6 Euros to buy two archive copies of Il Messaggero, a Roman paper,
|
||||
# for 1 and 2 April 1944. The edition of 2 April has this note: "Tonight at 2
|
||||
# am, put forward the clock by one hour. Remember that in the night between
|
||||
# today and Monday the 'ora legale' will come in force again." That makes it
|
||||
# clear that in Rome the change was on Monday, 3 April 1944 at 2 am.
|
||||
#
|
||||
# From Paul Eggert (2016-10-27):
|
||||
# Go with INRiM for DST rules, except as corrected by Inglis for 1944
|
||||
# for the Kingdom of Italy. This is consistent with Renzo Baldini.
|
||||
@ -1774,15 +1806,10 @@ Zone Europe/Riga 1:36:34 - LMT 1880
|
||||
# From Paul Eggert (2013-09-09):
|
||||
# Shanks & Pottenger say Vaduz is like Zurich.
|
||||
|
||||
# From Alois Treindl (2013-09-18):
|
||||
# http://www.eliechtensteinensia.li/LIJ/1978/1938-1978/1941.pdf
|
||||
# ... confirms on p. 6 that Liechtenstein followed Switzerland in 1941 and 1942.
|
||||
# I ... translate only the last two paragraphs:
|
||||
# ... during second world war, in the years 1941 and 1942, Liechtenstein
|
||||
# introduced daylight saving time, adapting to Switzerland. From 1943 on
|
||||
# central European time was in force throughout the year.
|
||||
# From a report of the duke's government to the high council,
|
||||
# regarding the introduction of a time law, of 31 May 1977.
|
||||
# From Alois Treindl (2019-07-04):
|
||||
# I was able to access the online archive of the Vaduz paper Vaterland ...
|
||||
# I could confirm from the paper that Liechtenstein did in fact follow
|
||||
# the same DST in 1941 and 1942 as Switzerland did.
|
||||
|
||||
Link Europe/Zurich Europe/Vaduz
|
||||
|
||||
@ -2490,6 +2517,12 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
|
||||
# Europe/Kaliningrad covers...
|
||||
# 39 RU-KGD Kaliningrad Oblast
|
||||
|
||||
# From Paul Eggert (2019-07-25):
|
||||
# Although Shanks lists 1945-01-01 as the date for transition from
|
||||
# +01/+02 to +02/+03, more likely this is a placeholder. Guess that
|
||||
# the transition occurred at 1945-04-10 00:00, which is about when
|
||||
# Königsberg surrendered to Soviet troops. (Thanks to Alois Triendl.)
|
||||
|
||||
# From Paul Eggert (2016-03-18):
|
||||
# The 1989 transition is from USSR act No. 227 (1989-03-14).
|
||||
|
||||
@ -2506,8 +2539,8 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
|
||||
# Moscow on 1991-11-03, switched to Moscow-1 on 1992-01-19.
|
||||
|
||||
Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
1:00 C-Eur CE%sT 1945
|
||||
2:00 Poland CE%sT 1946
|
||||
1:00 C-Eur CE%sT 1945 Apr 10
|
||||
2:00 Poland EE%sT 1946 Apr 7
|
||||
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
|
||||
2:00 Russia EE%sT 2011 Mar 27 2:00s
|
||||
3:00 - +03 2014 Oct 26 2:00s
|
||||
@ -3650,20 +3683,75 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment.
|
||||
|
||||
# Turkey
|
||||
|
||||
# From Alois Treindl (2019-08-12):
|
||||
# http://www.astrolojidergisi.com/yazsaati.htm has researched the time zone
|
||||
# history of Turkey, based on newspaper archives and official documents.
|
||||
# From Paul Eggert (2019-08-28):
|
||||
# That source (Oya Vulaş, "Türkiye'de Yaz Saati Uygulamaları")
|
||||
# is used for 1940/1972, where it seems more reliable than our other
|
||||
# sources.
|
||||
|
||||
# From Kıvanç Yazan (2019-08-12):
|
||||
# http://www.resmigazete.gov.tr/arsiv/14539.pdf#page=24
|
||||
# 1973-06-03 01:00 -> 02:00, 1973-11-04 02:00 -> 01:00
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/14829.pdf#page=1
|
||||
# 1974-03-31 02:00 -> 03:00, 1974-11-03 02:00 -> 01:00
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/15161.pdf#page=1
|
||||
# 1975-03-22 02:00 -> 03:00, 1975-11-02 02:00 -> 01:00
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/15535_1.pdf#page=1
|
||||
# 1976-03-21 02:00 -> 03:00, 1976-10-31 02:00 -> 01:00
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/15778.pdf#page=5
|
||||
# 1977-04-03 02:00 -> 03:00, 1977-10-16 02:00 -> 01:00,
|
||||
# 1978-04-02 02:00 -> 03:00 (not applied, see below)
|
||||
# 1978-10-15 02:00 -> 01:00 (not applied, see below)
|
||||
# 1979-04-01 02:00 -> 03:00 (not applied, see below)
|
||||
# 1979-10-14 02:00 -> 01:00 (not applied, see below)
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/16245.pdf#page=17
|
||||
# This cancels the previous decision, and repeats it only for 1978.
|
||||
# 1978-04-02 02:00 -> 03:00, 1978-10-15 02:00 -> 01:00
|
||||
# (not applied due to standard TZ change below)
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/16331.pdf#page=3
|
||||
# This decision changes the default longitude for Turkish time zone from 30
|
||||
# degrees East to 45 degrees East. This means a standard TZ change, from +2
|
||||
# to +3. This is published & applied on 1978-06-29. At that time, Turkey was
|
||||
# already on summer time (already on 45E). Hence, this new law just meant an
|
||||
# "continuous summer time". Note that this was reversed in a few years.
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/18119_1.pdf#page=1
|
||||
# 1983-07-31 02:00 -> 03:00 (note that this jumps TZ to +4)
|
||||
# 1983-10-02 02:00 -> 01:00 (back to +3)
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/18561.pdf (page 1 and 34)
|
||||
# At this time, Turkey is still on +3 with no spring-forward on early
|
||||
# 1984. This decision is published on 10/31/1984. Page 1 declares
|
||||
# the decision of reverting the "default longitude change". So the
|
||||
# standard time should go back to +3 (30E). And page 34 explains when
|
||||
# that will happen: 1984-11-01 02:00 -> 01:00. You can think of this
|
||||
# as "end of continuous summer time, change of standard time zone".
|
||||
#
|
||||
# http://www.resmigazete.gov.tr/arsiv/18713.pdf#page=1
|
||||
# 1985-04-20 01:00 -> 02:00, 1985-09-28 02:00 -> 01:00
|
||||
|
||||
# From Kıvanç Yazan (2016-09-25):
|
||||
# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with
|
||||
# no exceptions.
|
||||
# 2) 1994's lastSun was overridden with Mar 20 ...
|
||||
# Here are official papers:
|
||||
# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986
|
||||
# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987
|
||||
# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988
|
||||
# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989
|
||||
# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992
|
||||
# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995
|
||||
# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994
|
||||
# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997
|
||||
# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000
|
||||
# http://www.resmigazete.gov.tr/arsiv/19032.pdf#page=2 for 1986
|
||||
# http://www.resmigazete.gov.tr/arsiv/19400.pdf#page=4 for 1987
|
||||
# http://www.resmigazete.gov.tr/arsiv/19752.pdf#page=15 for 1988
|
||||
# http://www.resmigazete.gov.tr/arsiv/20102.pdf#page=6 for 1989
|
||||
# http://www.resmigazete.gov.tr/arsiv/20464.pdf#page=1 for 1990 - 1992
|
||||
# http://www.resmigazete.gov.tr/arsiv/21531.pdf#page=15 for 1993 - 1995
|
||||
# http://www.resmigazete.gov.tr/arsiv/21879.pdf#page=1 for overriding 1994
|
||||
# http://www.resmigazete.gov.tr/arsiv/22588.pdf#page=1 for 1996, 1997
|
||||
# http://www.resmigazete.gov.tr/arsiv/23286.pdf#page=10 for 1998 - 2000
|
||||
# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001
|
||||
# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006
|
||||
# From Paul Eggert (2016-09-25):
|
||||
@ -3747,46 +3835,36 @@ Rule Turkey 1922 only - Oct 8 0:00 0 -
|
||||
Rule Turkey 1924 only - May 13 0:00 1:00 S
|
||||
Rule Turkey 1924 1925 - Oct 1 0:00 0 -
|
||||
Rule Turkey 1925 only - May 1 0:00 1:00 S
|
||||
Rule Turkey 1940 only - Jun 30 0:00 1:00 S
|
||||
Rule Turkey 1940 only - Oct 5 0:00 0 -
|
||||
Rule Turkey 1940 only - Jul 1 0:00 1:00 S
|
||||
Rule Turkey 1940 only - Oct 6 0:00 0 -
|
||||
Rule Turkey 1940 only - Dec 1 0:00 1:00 S
|
||||
Rule Turkey 1941 only - Sep 21 0:00 0 -
|
||||
Rule Turkey 1942 only - Apr 1 0:00 1:00 S
|
||||
# Whitman omits the next two transition and gives 1945 Oct 1;
|
||||
# go with Shanks & Pottenger.
|
||||
Rule Turkey 1942 only - Nov 1 0:00 0 -
|
||||
Rule Turkey 1945 only - Apr 2 0:00 1:00 S
|
||||
Rule Turkey 1945 only - Oct 8 0:00 0 -
|
||||
Rule Turkey 1946 only - Jun 1 0:00 1:00 S
|
||||
Rule Turkey 1946 only - Oct 1 0:00 0 -
|
||||
Rule Turkey 1947 1948 - Apr Sun>=16 0:00 1:00 S
|
||||
Rule Turkey 1947 1950 - Oct Sun>=2 0:00 0 -
|
||||
Rule Turkey 1947 1951 - Oct Sun>=2 0:00 0 -
|
||||
Rule Turkey 1949 only - Apr 10 0:00 1:00 S
|
||||
Rule Turkey 1950 only - Apr 19 0:00 1:00 S
|
||||
Rule Turkey 1950 only - Apr 16 0:00 1:00 S
|
||||
Rule Turkey 1951 only - Apr 22 0:00 1:00 S
|
||||
Rule Turkey 1951 only - Oct 8 0:00 0 -
|
||||
# DST for 15 months; unusual but we'll let it pass.
|
||||
Rule Turkey 1962 only - Jul 15 0:00 1:00 S
|
||||
Rule Turkey 1962 only - Oct 8 0:00 0 -
|
||||
Rule Turkey 1963 only - Oct 30 0:00 0 -
|
||||
Rule Turkey 1964 only - May 15 0:00 1:00 S
|
||||
Rule Turkey 1964 only - Oct 1 0:00 0 -
|
||||
Rule Turkey 1970 1972 - May Sun>=2 0:00 1:00 S
|
||||
Rule Turkey 1970 1972 - Oct Sun>=2 0:00 0 -
|
||||
Rule Turkey 1973 only - Jun 3 1:00 1:00 S
|
||||
Rule Turkey 1973 only - Nov 4 3:00 0 -
|
||||
Rule Turkey 1973 1976 - Oct Sun>=31 2:00 0 -
|
||||
Rule Turkey 1974 only - Mar 31 2:00 1:00 S
|
||||
Rule Turkey 1974 only - Nov 3 5:00 0 -
|
||||
Rule Turkey 1975 only - Mar 30 0:00 1:00 S
|
||||
Rule Turkey 1975 1976 - Oct lastSun 0:00 0 -
|
||||
Rule Turkey 1976 only - Jun 1 0:00 1:00 S
|
||||
Rule Turkey 1977 1978 - Apr Sun>=1 0:00 1:00 S
|
||||
Rule Turkey 1977 only - Oct 16 0:00 0 -
|
||||
Rule Turkey 1979 1980 - Apr Sun>=1 3:00 1:00 S
|
||||
Rule Turkey 1979 1982 - Oct Mon>=11 0:00 0 -
|
||||
Rule Turkey 1981 1982 - Mar lastSun 3:00 1:00 S
|
||||
Rule Turkey 1983 only - Jul 31 0:00 1:00 S
|
||||
Rule Turkey 1983 only - Oct 2 0:00 0 -
|
||||
Rule Turkey 1985 only - Apr 20 0:00 1:00 S
|
||||
Rule Turkey 1985 only - Sep 28 0:00 0 -
|
||||
Rule Turkey 1975 only - Mar 22 2:00 1:00 S
|
||||
Rule Turkey 1976 only - Mar 21 2:00 1:00 S
|
||||
Rule Turkey 1977 1978 - Apr Sun>=1 2:00 1:00 S
|
||||
Rule Turkey 1977 1978 - Oct Sun>=15 2:00 0 -
|
||||
Rule Turkey 1978 only - Jun 29 0:00 0 -
|
||||
Rule Turkey 1983 only - Jul 31 2:00 1:00 S
|
||||
Rule Turkey 1983 only - Oct 2 2:00 0 -
|
||||
Rule Turkey 1985 only - Apr 20 1:00s 1:00 S
|
||||
Rule Turkey 1985 only - Sep 28 1:00s 0 -
|
||||
Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S
|
||||
Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 -
|
||||
Rule Turkey 1994 only - Mar 20 1:00s 1:00 S
|
||||
@ -3795,8 +3873,8 @@ Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 -
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone Europe/Istanbul 1:55:52 - LMT 1880
|
||||
1:56:56 - IMT 1910 Oct # Istanbul Mean Time?
|
||||
2:00 Turkey EE%sT 1978 Oct 15
|
||||
3:00 Turkey +03/+04 1985 Apr 20
|
||||
2:00 Turkey EE%sT 1978 Jun 29
|
||||
3:00 Turkey +03/+04 1984 Nov 1 2:00
|
||||
2:00 Turkey EE%sT 2007
|
||||
2:00 EU EE%sT 2011 Mar 27 1:00u
|
||||
2:00 - EET 2011 Mar 28 1:00u
|
||||
|
@ -204,10 +204,10 @@
|
||||
# current -- the update time stamp, the data and the name of the file
|
||||
# will not change.
|
||||
#
|
||||
# Updated through IERS Bulletin C57
|
||||
# File expires on: 28 December 2019
|
||||
# Updated through IERS Bulletin C58
|
||||
# File expires on: 28 June 2020
|
||||
#
|
||||
#@ 3786480000
|
||||
#@ 3802291200
|
||||
#
|
||||
2272060800 10 # 1 Jan 1972
|
||||
2287785600 11 # 1 Jul 1972
|
||||
@ -252,4 +252,4 @@
|
||||
# the hash line is also ignored in the
|
||||
# computation.
|
||||
#
|
||||
#h 83c68138 d3650221 07dbbbcd 11fcc859 ced1106a
|
||||
#h f28827d2 f263b6c3 ec0f19eb a3e0dbf0 97f3fa30
|
||||
|
@ -3,36 +3,39 @@
|
||||
# This file is in the public domain.
|
||||
|
||||
# This file is generated automatically from the data in the public-domain
|
||||
# leap-seconds.list file, which can be copied from
|
||||
# NIST format leap-seconds.list file, which can be copied from
|
||||
# <ftp://ftp.nist.gov/pub/time/leap-seconds.list>
|
||||
# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>
|
||||
# or <ftp://tycho.usno.navy.mil/pub/ntp/leap-seconds.list>.
|
||||
# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>.
|
||||
# For more about leap-seconds.list, please see
|
||||
# The NTP Timescale and Leap Seconds
|
||||
# <https://www.eecis.udel.edu/~mills/leap.html>.
|
||||
|
||||
# The International Earth Rotation and Reference Systems Service
|
||||
# The rules for leap seconds are specified in Annex 1 (Time scales) of:
|
||||
# Standard-frequency and time-signal emissions.
|
||||
# International Telecommunication Union - Radiocommunication Sector
|
||||
# (ITU-R) Recommendation TF.460-6 (02/2002)
|
||||
# <https://www.itu.int/rec/R-REC-TF.460-6-200202-I/>.
|
||||
# The International Earth Rotation and Reference Systems Service (IERS)
|
||||
# periodically uses leap seconds to keep UTC to within 0.9 s of UT1
|
||||
# (which measures the true angular orientation of the earth in space)
|
||||
# (a proxy for Earth's angle in space as measured by astronomers)
|
||||
# and publishes leap second data in a copyrighted file
|
||||
# <https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat>.
|
||||
# See: Levine J. Coordinated Universal Time and the leap second.
|
||||
# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995
|
||||
# <https://ieeexplore.ieee.org/document/7909995>.
|
||||
|
||||
# There were no leap seconds before 1972, because the official mechanism
|
||||
# accounting for the discrepancy between atomic time and the earth's rotation
|
||||
# did not exist. The first ("1 Jan 1972") data line in leap-seconds.list
|
||||
# There were no leap seconds before 1972, as no official mechanism
|
||||
# accounted for the discrepancy between atomic time (TAI) and the earth's
|
||||
# rotation. The first ("1 Jan 1972") data line in leap-seconds.list
|
||||
# does not denote a leap second; it denotes the start of the current definition
|
||||
# of UTC.
|
||||
|
||||
# The correction (+ or -) is made at the given time, so lines
|
||||
# will typically look like:
|
||||
# Leap YEAR MON DAY 23:59:60 + R/S
|
||||
# or
|
||||
# Leap YEAR MON DAY 23:59:59 - R/S
|
||||
|
||||
# If the leap second is Rolling (R) the given time is local time (unused here).
|
||||
# All leap-seconds are Stationary (S) at the given UTC time.
|
||||
# The correction (+ or -) is made at the given time, so in the unlikely
|
||||
# event of a negative leap second, a line would look like this:
|
||||
# Leap YEAR MON DAY 23:59:59 - S
|
||||
# Typical lines look like this:
|
||||
# Leap YEAR MON DAY 23:59:60 + S
|
||||
Leap 1972 Jun 30 23:59:60 + S
|
||||
Leap 1972 Dec 31 23:59:60 + S
|
||||
Leap 1973 Dec 31 23:59:60 + S
|
||||
@ -62,8 +65,8 @@ Leap 2015 Jun 30 23:59:60 + S
|
||||
Leap 2016 Dec 31 23:59:60 + S
|
||||
|
||||
# POSIX timestamps for the data in this file:
|
||||
#updated 1467936000
|
||||
#expires 1577491200
|
||||
#updated 1467936000 (2016-07-08 00:00:00 UTC)
|
||||
#expires 1593302400 (2020-06-28 00:00:00 UTC)
|
||||
|
||||
# Updated through IERS Bulletin C57
|
||||
# File expires on: 28 December 2019
|
||||
# Updated through IERS Bulletin C58
|
||||
# File expires on: 28 June 2020
|
||||
|
@ -1,43 +1,59 @@
|
||||
# Generate the 'leapseconds' file from 'leap-seconds.list'.
|
||||
# Generate zic format 'leapseconds' from NIST format 'leap-seconds.list'.
|
||||
|
||||
# This file is in the public domain.
|
||||
|
||||
# This program uses awk arithmetic. POSIX requires awk to support
|
||||
# exact integer arithmetic only through 10**10, which means for NTP
|
||||
# timestamps this program works only to the year 2216, which is the
|
||||
# year 1900 plus 10**10 seconds. However, in practice
|
||||
# POSIX-conforming awk implementations invariably use IEEE-754 double
|
||||
# and so support exact integers through 2**53. By the year 2216,
|
||||
# POSIX will almost surely require at least 2**53 for awk, so for NTP
|
||||
# timestamps this program should be good until the year 285,428,681
|
||||
# (the year 1900 plus 2**53 seconds). By then leap seconds will be
|
||||
# long obsolete, as the Earth will likely slow down so much that
|
||||
# there will be more than 25 hours per day and so some other scheme
|
||||
# will be needed.
|
||||
|
||||
BEGIN {
|
||||
print "# Allowance for leap seconds added to each time zone file."
|
||||
print ""
|
||||
print "# This file is in the public domain."
|
||||
print ""
|
||||
print "# This file is generated automatically from the data in the public-domain"
|
||||
print "# leap-seconds.list file, which can be copied from"
|
||||
print "# NIST format leap-seconds.list file, which can be copied from"
|
||||
print "# <ftp://ftp.nist.gov/pub/time/leap-seconds.list>"
|
||||
print "# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>"
|
||||
print "# or <ftp://tycho.usno.navy.mil/pub/ntp/leap-seconds.list>."
|
||||
print "# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>."
|
||||
print "# For more about leap-seconds.list, please see"
|
||||
print "# The NTP Timescale and Leap Seconds"
|
||||
print "# <https://www.eecis.udel.edu/~mills/leap.html>."
|
||||
print ""
|
||||
print "# The International Earth Rotation and Reference Systems Service"
|
||||
print "# The rules for leap seconds are specified in Annex 1 (Time scales) of:"
|
||||
print "# Standard-frequency and time-signal emissions."
|
||||
print "# International Telecommunication Union - Radiocommunication Sector"
|
||||
print "# (ITU-R) Recommendation TF.460-6 (02/2002)"
|
||||
print "# <https://www.itu.int/rec/R-REC-TF.460-6-200202-I/>."
|
||||
print "# The International Earth Rotation and Reference Systems Service (IERS)"
|
||||
print "# periodically uses leap seconds to keep UTC to within 0.9 s of UT1"
|
||||
print "# (which measures the true angular orientation of the earth in space)"
|
||||
print "# (a proxy for Earth's angle in space as measured by astronomers)"
|
||||
print "# and publishes leap second data in a copyrighted file"
|
||||
print "# <https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat>."
|
||||
print "# See: Levine J. Coordinated Universal Time and the leap second."
|
||||
print "# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995"
|
||||
print "# <https://ieeexplore.ieee.org/document/7909995>."
|
||||
print ""
|
||||
print "# There were no leap seconds before 1972, because the official mechanism"
|
||||
print "# accounting for the discrepancy between atomic time and the earth's rotation"
|
||||
print "# did not exist. The first (\"1 Jan 1972\") data line in leap-seconds.list"
|
||||
print "# There were no leap seconds before 1972, as no official mechanism"
|
||||
print "# accounted for the discrepancy between atomic time (TAI) and the earth's"
|
||||
print "# rotation. The first (\"1 Jan 1972\") data line in leap-seconds.list"
|
||||
print "# does not denote a leap second; it denotes the start of the current definition"
|
||||
print"# of UTC."
|
||||
print "# of UTC."
|
||||
print ""
|
||||
print "# The correction (+ or -) is made at the given time, so lines"
|
||||
print "# will typically look like:"
|
||||
print "# Leap YEAR MON DAY 23:59:60 + R/S"
|
||||
print "# or"
|
||||
print "# Leap YEAR MON DAY 23:59:59 - R/S"
|
||||
print ""
|
||||
print "# If the leap second is Rolling (R) the given time is local time (unused here)."
|
||||
print "# All leap-seconds are Stationary (S) at the given UTC time."
|
||||
print "# The correction (+ or -) is made at the given time, so in the unlikely"
|
||||
print "# event of a negative leap second, a line would look like this:"
|
||||
print "# Leap YEAR MON DAY 23:59:59 - S"
|
||||
print "# Typical lines look like this:"
|
||||
print "# Leap YEAR MON DAY 23:59:60 + S"
|
||||
|
||||
monthabbr[ 1] = "Jan"
|
||||
monthabbr[ 2] = "Feb"
|
||||
@ -51,45 +67,34 @@ BEGIN {
|
||||
monthabbr[10] = "Oct"
|
||||
monthabbr[11] = "Nov"
|
||||
monthabbr[12] = "Dec"
|
||||
for (i in monthabbr) {
|
||||
monthnum[monthabbr[i]] = i
|
||||
monthlen[i] = 31
|
||||
}
|
||||
monthlen[2] = 28
|
||||
monthlen[4] = monthlen[6] = monthlen[9] = monthlen[11] = 30
|
||||
|
||||
# Strip trailing CR, in case the input has CRLF form a la NIST.
|
||||
RS = "\r?\n"
|
||||
|
||||
sstamp_init()
|
||||
}
|
||||
|
||||
/^#\tUpdated through/ || /^#\tFile expires on:/ {
|
||||
/^#[ \t]*[Uu]pdated through/ || /^#[ \t]*[Ff]ile expires on/ {
|
||||
last_lines = last_lines $0 "\n"
|
||||
}
|
||||
|
||||
/^#[$][ \t]/ { updated = $2 }
|
||||
/^#[@][ \t]/ { expires = $2 }
|
||||
|
||||
/^#/ { next }
|
||||
/^[ \t]*#/ { next }
|
||||
|
||||
{
|
||||
NTP_timestamp = $1
|
||||
TAI_minus_UTC = $2
|
||||
hash_mark = $3
|
||||
one = $4
|
||||
month = $5
|
||||
year = $6
|
||||
if (old_TAI_minus_UTC) {
|
||||
if (old_TAI_minus_UTC < TAI_minus_UTC) {
|
||||
sign = "23:59:60\t+"
|
||||
} else {
|
||||
sign = "23:59:59\t-"
|
||||
}
|
||||
m = monthnum[month] - 1
|
||||
if (m == 0) {
|
||||
year--;
|
||||
m = 12
|
||||
}
|
||||
month = monthabbr[m]
|
||||
day = monthlen[m]
|
||||
day += m == 2 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
||||
printf "Leap\t%s\t%s\t%s\t%s\tS\n", year, month, day, sign
|
||||
sstamp_to_ymdhMs(NTP_timestamp - 1, ss_NTP)
|
||||
printf "Leap\t%d\t%s\t%d\t%s\tS\n", \
|
||||
ss_year, monthabbr[ss_month], ss_mday, sign
|
||||
}
|
||||
old_TAI_minus_UTC = TAI_minus_UTC
|
||||
}
|
||||
@ -102,7 +107,117 @@ END {
|
||||
|
||||
print ""
|
||||
print "# POSIX timestamps for the data in this file:"
|
||||
printf "#updated %s\n", updated - epoch_minus_NTP
|
||||
printf "#expires %s\n", expires - epoch_minus_NTP
|
||||
sstamp_to_ymdhMs(updated, ss_NTP)
|
||||
printf "#updated %d (%.4d-%.2d-%.2d %.2d:%.2d:%.2d UTC)\n", \
|
||||
updated - epoch_minus_NTP, \
|
||||
ss_year, ss_month, ss_mday, ss_hour, ss_min, ss_sec
|
||||
sstamp_to_ymdhMs(expires, ss_NTP)
|
||||
printf "#expires %d (%.4d-%.2d-%.2d %.2d:%.2d:%.2d UTC)\n", \
|
||||
expires - epoch_minus_NTP, \
|
||||
ss_year, ss_month, ss_mday, ss_hour, ss_min, ss_sec
|
||||
|
||||
printf "\n%s", last_lines
|
||||
}
|
||||
|
||||
# sstamp_to_ymdhMs - convert seconds timestamp to date and time
|
||||
#
|
||||
# Call as:
|
||||
#
|
||||
# sstamp_to_ymdhMs(sstamp, epoch_days)
|
||||
#
|
||||
# where:
|
||||
#
|
||||
# sstamp - is the seconds timestamp.
|
||||
# epoch_days - is the timestamp epoch in Gregorian days since 1600-03-01.
|
||||
# ss_NTP is appropriate for an NTP sstamp.
|
||||
#
|
||||
# Both arguments should be nonnegative integers.
|
||||
# On return, the following variables are set based on sstamp:
|
||||
#
|
||||
# ss_year - Gregorian calendar year
|
||||
# ss_month - month of the year (1-January to 12-December)
|
||||
# ss_mday - day of the month (1-31)
|
||||
# ss_hour - hour (0-23)
|
||||
# ss_min - minute (0-59)
|
||||
# ss_sec - second (0-59)
|
||||
# ss_wday - day of week (0-Sunday to 6-Saturday)
|
||||
#
|
||||
# The function sstamp_init should be called prior to using sstamp_to_ymdhMs.
|
||||
|
||||
function sstamp_init()
|
||||
{
|
||||
# Days in month N, where March is month 0 and January month 10.
|
||||
ss_mon_days[ 0] = 31
|
||||
ss_mon_days[ 1] = 30
|
||||
ss_mon_days[ 2] = 31
|
||||
ss_mon_days[ 3] = 30
|
||||
ss_mon_days[ 4] = 31
|
||||
ss_mon_days[ 5] = 31
|
||||
ss_mon_days[ 6] = 30
|
||||
ss_mon_days[ 7] = 31
|
||||
ss_mon_days[ 8] = 30
|
||||
ss_mon_days[ 9] = 31
|
||||
ss_mon_days[10] = 31
|
||||
|
||||
# Counts of days in a Gregorian year, quad-year, century, and quad-century.
|
||||
ss_year_days = 365
|
||||
ss_quadyear_days = ss_year_days * 4 + 1
|
||||
ss_century_days = ss_quadyear_days * 25 - 1
|
||||
ss_quadcentury_days = ss_century_days * 4 + 1
|
||||
|
||||
# Standard day epochs, suitable for epoch_days.
|
||||
# ss_MJD = 94493
|
||||
# ss_POSIX = 135080
|
||||
ss_NTP = 109513
|
||||
}
|
||||
|
||||
function sstamp_to_ymdhMs(sstamp, epoch_days, \
|
||||
quadcentury, century, quadyear, year, month, day)
|
||||
{
|
||||
ss_hour = int(sstamp / 3600) % 24
|
||||
ss_min = int(sstamp / 60) % 60
|
||||
ss_sec = sstamp % 60
|
||||
|
||||
# Start with a count of days since 1600-03-01 Gregorian.
|
||||
day = epoch_days + int(sstamp / (24 * 60 * 60))
|
||||
|
||||
# Compute a year-month-day date with days of the month numbered
|
||||
# 0-30, months (March-February) numbered 0-11, and years that start
|
||||
# start March 1 and end after the last day of February. A quad-year
|
||||
# starts on March 1 of a year evenly divisible by 4 and ends after
|
||||
# the last day of February 4 years later. A century starts on and
|
||||
# ends before March 1 in years evenly divisible by 100.
|
||||
# A quad-century starts on and ends before March 1 in years divisible
|
||||
# by 400. While the number of days in a quad-century is a constant,
|
||||
# the number of days in each other time period can vary by 1.
|
||||
# Any variation is in the last day of the time period (there might
|
||||
# or might not be a February 29) where it is easy to deal with.
|
||||
|
||||
quadcentury = int(day / ss_quadcentury_days)
|
||||
day -= quadcentury * ss_quadcentury_days
|
||||
ss_wday = (day + 3) % 7
|
||||
century = int(day / ss_century_days)
|
||||
century -= century == 4
|
||||
day -= century * ss_century_days
|
||||
quadyear = int(day / ss_quadyear_days)
|
||||
day -= quadyear * ss_quadyear_days
|
||||
year = int(day / ss_year_days)
|
||||
year -= year == 4
|
||||
day -= year * ss_year_days
|
||||
for (month = 0; month < 11; month++) {
|
||||
if (day < ss_mon_days[month])
|
||||
break
|
||||
day -= ss_mon_days[month]
|
||||
}
|
||||
|
||||
# Convert the date to a conventional day of month (1-31),
|
||||
# month (1-12, January-December) and Gregorian year.
|
||||
ss_mday = day + 1
|
||||
if (month <= 9) {
|
||||
ss_month = month + 3
|
||||
} else {
|
||||
ss_month = month - 9
|
||||
year++
|
||||
}
|
||||
ss_year = 1600 + quadcentury * 400 + century * 100 + quadyear * 4 + year
|
||||
}
|
||||
|
@ -406,6 +406,31 @@ Zone America/New_York -4:56:02 - LMT 1883 Nov 18 12:03:58
|
||||
# From Paul Eggert (2015-12-25):
|
||||
# Assume this practice predates 1970, so Fort Pierre can use America/Chicago.
|
||||
|
||||
# From Paul Eggert (2015-04-06):
|
||||
# In 1950s Nashville a public clock had dueling faces, one for conservatives
|
||||
# and the other for liberals; the two sides didn't agree about the time of day.
|
||||
# I haven't found a photo of this clock, nor have I tracked down the TIME
|
||||
# magazine report cited below, but here's the story as told by the late
|
||||
# American journalist John Seigenthaler, who was there:
|
||||
#
|
||||
# "The two [newspaper] owners held strongly contrasting political and
|
||||
# ideological views. Evans was a New South liberal, Stahlman an Old South
|
||||
# conservative, and their two papers frequently clashed editorially, often on
|
||||
# the same day.... In the 1950s as the state legislature was grappling with
|
||||
# the question of whether to approve daylight saving time for the entire state,
|
||||
# TIME magazine reported:
|
||||
#
|
||||
# "'The Nashville Banner and The Nashville Tennessean rarely agree on anything
|
||||
# but the time of day - and last week they couldn't agree on that.'
|
||||
#
|
||||
# "It was all too true. The clock on the front of the building had two faces -
|
||||
# The Tennessean side of the building facing west, the other, east. When it
|
||||
# was high noon Banner time, it was 11 a.m. Tennessean time."
|
||||
#
|
||||
# Seigenthaler J. For 100 years, Tennessean had it covered.
|
||||
# The Tennessean 2007-05-11, republished 2015-04-06.
|
||||
# https://www.tennessean.com/story/insider/extras/2015/04/06/archives-seigenthaler-for-100-years-the-tennessean-had-it-covered/25348545/
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
|
||||
Rule Chicago 1920 only - Jun 13 2:00 1:00 D
|
||||
Rule Chicago 1920 1921 - Oct lastSun 2:00 0 S
|
||||
@ -945,21 +970,21 @@ Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53
|
||||
-5:00 US E%sT
|
||||
#
|
||||
# Perry County, Indiana, switched from eastern to central time in April 2006.
|
||||
# From Alois Triendl (2019-07-09):
|
||||
# The Indianapolis News, Friday 27 October 1967 states that Perry County
|
||||
# returned to CST. It went again to EST on 27 April 1969, as documented by the
|
||||
# Indianapolis star of Saturday 26 April.
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
|
||||
Rule Perry 1946 only - Apr lastSun 2:00 1:00 D
|
||||
Rule Perry 1946 only - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1953 1954 - Apr lastSun 2:00 1:00 D
|
||||
Rule Perry 1953 1959 - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1955 only - May 1 0:00 1:00 D
|
||||
Rule Perry 1955 1960 - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D
|
||||
Rule Perry 1960 only - Oct lastSun 2:00 0 S
|
||||
Rule Perry 1961 only - Sep lastSun 2:00 0 S
|
||||
Rule Perry 1962 1963 - Oct lastSun 2:00 0 S
|
||||
Rule Perry 1961 1963 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57
|
||||
-6:00 US C%sT 1946
|
||||
-6:00 Perry C%sT 1964 Apr 26 2:00
|
||||
-5:00 - EST 1969
|
||||
-5:00 - EST 1967 Oct 29 2:00
|
||||
-6:00 US C%sT 1969 Apr 27 2:00
|
||||
-5:00 US E%sT 1971
|
||||
-5:00 - EST 2006 Apr 2 2:00
|
||||
-6:00 US C%sT
|
||||
@ -1035,16 +1060,27 @@ Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44
|
||||
# clear how this matched civil time in Louisville, so for now continue
|
||||
# to assume Louisville switched at noon new local time, like New York.
|
||||
#
|
||||
# From Michael Deckers (2019-08-06):
|
||||
# From the contemporary source given by Alois Treindl,
|
||||
# the switch in Louisville on 1946-04-28 was on 00:01
|
||||
# From Paul Eggert (2019-08-26):
|
||||
# That source was the Louisville Courier-Journal, 1946-04-27, p 4.
|
||||
# Shanks gives 02:00 for all 20th-century transition times in Louisville.
|
||||
# Evidently this is wrong for spring 1946. Although also likely wrong
|
||||
# for other dates, we have no data.
|
||||
#
|
||||
# Part of Kentucky left its clocks alone in 1974.
|
||||
# This also includes Clark, Floyd, and Harrison counties in Indiana.
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
|
||||
Rule Louisville 1921 only - May 1 2:00 1:00 D
|
||||
Rule Louisville 1921 only - Sep 1 2:00 0 S
|
||||
Rule Louisville 1941 1961 - Apr lastSun 2:00 1:00 D
|
||||
Rule Louisville 1941 only - Apr lastSun 2:00 1:00 D
|
||||
Rule Louisville 1941 only - Sep lastSun 2:00 0 S
|
||||
Rule Louisville 1946 only - Apr lastSun 0:01 1:00 D
|
||||
Rule Louisville 1946 only - Jun 2 2:00 0 S
|
||||
Rule Louisville 1950 1961 - Apr lastSun 2:00 1:00 D
|
||||
Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S
|
||||
Rule Louisville 1956 1960 - Oct lastSun 2:00 0 S
|
||||
Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58
|
||||
-6:00 US C%sT 1921
|
||||
@ -1134,18 +1170,19 @@ Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36
|
||||
# one hour in 1914." This change is not in Shanks. We have no more
|
||||
# info, so omit this for now.
|
||||
#
|
||||
# From Paul Eggert (2017-07-26):
|
||||
# Although Shanks says Detroit observed DST in 1967 from 06-14 00:01
|
||||
# until 10-29 00:01, I now see multiple reports that this is incorrect.
|
||||
# For example, according to a 50-year anniversary report about the 1967
|
||||
# Detroit riots and a major-league doubleheader on 1967-07-23, "By the time
|
||||
# the last fly ball of the doubleheader settled into the glove of leftfielder
|
||||
# Lenny Green, it was after 7 p.m. Detroit did not observe daylight saving
|
||||
# time, so light was already starting to fail. Twilight was made even deeper
|
||||
# by billowing columns of smoke that ascended in an unbroken wall north of the
|
||||
# ballpark." See: Dow B. Detroit '67: As violence unfolded, Tigers played two
|
||||
# at home vs. Yankees. Detroit Free Press 2017-07-23.
|
||||
# https://www.freep.com/story/sports/mlb/tigers/2017/07/23/detroit-tigers-1967-riot-new-york-yankees/499951001/
|
||||
# From Paul Eggert (2019-07-06):
|
||||
# Due to a complicated set of legal maneuvers, in 1967 Michigan did
|
||||
# not start daylight saving time when the rest of the US did.
|
||||
# Instead, it began DST on Jun 14 at 00:01. This was big news:
|
||||
# the Detroit Free Press reported it at the top of Page 1 on
|
||||
# 1967-06-14, in an article "State Adjusting to Switch to Fast Time"
|
||||
# by Gary Blonston, above an article about Thurgood Marshall's
|
||||
# confirmation to the US Supreme Court. Although Shanks says Detroit
|
||||
# observed DST until 1967-10-29 00:01, that time of day seems to be
|
||||
# incorrect, as the Free Press later said DST ended in Michigan at the
|
||||
# same time as the rest of the US. Also, although Shanks reports no DST in
|
||||
# Detroit in 1968, it did observe DST that year; in the November 1968
|
||||
# election Michigan voters narrowly repealed DST, effective 1969.
|
||||
#
|
||||
# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
|
||||
@ -1156,7 +1193,9 @@ Zone America/Detroit -5:32:11 - LMT 1905
|
||||
-6:00 - CST 1915 May 15 2:00
|
||||
-5:00 - EST 1942
|
||||
-5:00 US E%sT 1946
|
||||
-5:00 Detroit E%sT 1973
|
||||
-5:00 Detroit E%sT 1967 Jun 14 0:01
|
||||
-5:00 US E%sT 1969
|
||||
-5:00 - EST 1973
|
||||
-5:00 US E%sT 1975
|
||||
-5:00 - EST 1975 Apr 27 2:00
|
||||
-5:00 US E%sT
|
||||
@ -1205,6 +1244,12 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
|
||||
#
|
||||
# Other sources occasionally used include:
|
||||
#
|
||||
# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
|
||||
# <https://www.jstor.org/stable/1774359>.
|
||||
#
|
||||
# Pearce C. The Great Daylight Saving Time Controversy.
|
||||
# Australian Ebook Publisher. 2017. ISBN 978-1-925516-96-8.
|
||||
#
|
||||
# Edward W. Whitman, World Time Differences,
|
||||
# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
|
||||
# which I found in the UCLA library.
|
||||
@ -1213,9 +1258,6 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00
|
||||
# <http://cs.ucla.edu/~eggert/The-Waste-of-Daylight-19th.pdf>
|
||||
# [PDF] (1914-03)
|
||||
#
|
||||
# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94
|
||||
# <https://www.jstor.org/stable/1774359>.
|
||||
#
|
||||
# See the 'europe' file for Greenland.
|
||||
|
||||
# Canada
|
||||
@ -1857,9 +1899,8 @@ Zone America/Winnipeg -6:28:36 - LMT 1887 Jul 16
|
||||
# Willett (1914-03) notes that DST "has been in operation ... in the
|
||||
# City of Moose Jaw, Saskatchewan, for one year."
|
||||
|
||||
# From Paul Eggert (2019-04-26):
|
||||
# Chris Pearce's book "The Great Daylight Saving Time Controversy" (2017)
|
||||
# says that Regina observed DST in 1914-1917. No dates and times,
|
||||
# From Paul Eggert (2019-07-25):
|
||||
# Pearce's book says Regina observed DST in 1914-1917. No dates and times,
|
||||
# unfortunately. It also says that in 1914 Saskatoon observed DST
|
||||
# from 1 June to 6 July, and that DST was also tried out in Davidson,
|
||||
# Melfort, and Prince Albert.
|
||||
@ -1939,6 +1980,19 @@ Zone America/Swift_Current -7:11:20 - LMT 1905 Sep
|
||||
|
||||
# Alberta
|
||||
|
||||
# From Alois Triendl (2019-07-19):
|
||||
# There was no DST in Alberta in 1967... Calgary Herald, 29 April 1967.
|
||||
# 1969, no DST, from Edmonton Journal 18 April 1969
|
||||
#
|
||||
# From Paul Eggert (2019-07-25):
|
||||
# Pearce's book says that Alberta's 1948 Daylight Saving Act required
|
||||
# Mountain Standard Time without DST, and that "anyone who broke that law
|
||||
# could be fined up to $25 and costs". There seems to be no record of
|
||||
# anybody paying the fine. The law was not changed until an August 1971
|
||||
# plebiscite reinstituted DST in 1972. This story is also mentioned in:
|
||||
# Boyer JP. Forcing Choice: The Risky Reward of Referendums. Dundum. 2017.
|
||||
# ISBN 978-1459739123.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Edm 1918 1919 - Apr Sun>=8 2:00 1:00 D
|
||||
Rule Edm 1918 only - Oct 27 2:00 0 S
|
||||
@ -1951,10 +2005,6 @@ Rule Edm 1945 only - Aug 14 23:00u 1:00 P # Peace
|
||||
Rule Edm 1945 only - Sep lastSun 2:00 0 S
|
||||
Rule Edm 1947 only - Apr lastSun 2:00 1:00 D
|
||||
Rule Edm 1947 only - Sep lastSun 2:00 0 S
|
||||
Rule Edm 1967 only - Apr lastSun 2:00 1:00 D
|
||||
Rule Edm 1967 only - Oct lastSun 2:00 0 S
|
||||
Rule Edm 1969 only - Apr lastSun 2:00 1:00 D
|
||||
Rule Edm 1969 only - Oct lastSun 2:00 0 S
|
||||
Rule Edm 1972 1986 - Apr lastSun 2:00 1:00 D
|
||||
Rule Edm 1972 2006 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
@ -2037,8 +2087,20 @@ Zone America/Edmonton -7:33:52 - LMT 1906 Sep
|
||||
# been on MST (-0700) like Dawson Creek since it advanced its clocks on
|
||||
# 2015-03-08.
|
||||
#
|
||||
# From Paul Eggert (2015-09-23):
|
||||
# From Paul Eggert (2019-07-25):
|
||||
# Shanks says Fort Nelson did not observe DST in 1946, unlike Vancouver.
|
||||
# Alois Triendl confirmed this on 07-22, citing the 1946-04-27 Vancouver Daily
|
||||
# Province. He also cited the 1946-09-28 Victoria Daily Times, which said
|
||||
# that Vancouver, Victoria, etc. "change at midnight Saturday"; for now,
|
||||
# guess they meant 02:00 Sunday since 02:00 was common practice in Vancouver.
|
||||
#
|
||||
# Early Vancouver, Volume Four, by Major J.S. Matthews, V.D., 2011 edition
|
||||
# says that a 1922 plebiscite adopted DST, but a 1923 plebiscite rejected it.
|
||||
# http://former.vancouver.ca/ctyclerk/archives/digitized/EarlyVan/SearchEarlyVan/Vol4pdf/MatthewsEarlyVancouverVol4_DaylightSavings.pdf
|
||||
# A catalog entry for a newspaper clipping seems to indicate that Vancouver
|
||||
# observed DST in 1941 from 07-07 through 09-27; see
|
||||
# https://searcharchives.vancouver.ca/daylight-saving-1918-starts-again-july-7-1941-start-d-s-sept-27-end-of-d-s-1941
|
||||
# We have no further details, so omit them for now.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Vanc 1918 only - Apr 14 2:00 1:00 D
|
||||
@ -2047,7 +2109,7 @@ Rule Vanc 1942 only - Feb 9 2:00 1:00 W # War
|
||||
Rule Vanc 1945 only - Aug 14 23:00u 1:00 P # Peace
|
||||
Rule Vanc 1945 only - Sep 30 2:00 0 S
|
||||
Rule Vanc 1946 1986 - Apr lastSun 2:00 1:00 D
|
||||
Rule Vanc 1946 only - Oct 13 2:00 0 S
|
||||
Rule Vanc 1946 only - Sep 29 2:00 0 S
|
||||
Rule Vanc 1947 1961 - Sep lastSun 2:00 0 S
|
||||
Rule Vanc 1962 2006 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME STDOFF RULES FORMAT [UNTIL]
|
||||
|
@ -1230,14 +1230,8 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
|
||||
# From Juan Correa (2016-12-04):
|
||||
# Magallanes region ... will keep DST (UTC -3) all year round....
|
||||
# http://www.soychile.cl/Santiago/Sociedad/2016/12/04/433428/Bachelet-firmo-el-decreto-para-establecer-un-horario-unico-para-la-Region-de-Magallanes.aspx
|
||||
#
|
||||
# From Deborah Goldsmith (2017-01-19):
|
||||
# http://www.diariooficial.interior.gob.cl/publicaciones/2017/01/17/41660/01/1169626.pdf
|
||||
# From Paul Eggert (2017-01-19):
|
||||
# The above says the Magallanes change expires 2019-05-11 at 24:00,
|
||||
# so in theory, they will revert to -04/-03 after that, which means
|
||||
# they will switch from -03 to -04 one hour after Santiago does that day.
|
||||
# For now, assume that they will not revert.
|
||||
|
||||
# From Juan Correa (2018-08-13):
|
||||
# As of moments ago, the Ministry of Energy in Chile has announced the new
|
||||
@ -1258,6 +1252,11 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
|
||||
# So we extend the new rules on Saturdays at 24:00 mainland time indefinitely.
|
||||
# From Juan Correa (2019-02-04):
|
||||
# http://www.diariooficial.interior.gob.cl/publicaciones/2018/11/23/42212/01/1498738.pdf
|
||||
# From Paul Eggert (2019-09-01):
|
||||
# The above says the Magallanes exception expires 2022-04-02 at 24:00,
|
||||
# so in theory, they will revert to -04/-03 after that.
|
||||
# For now, assume that they will not revert,
|
||||
# since they have extended the expiration date once already.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Chile 1927 1931 - Sep 1 0:00 1:00 -
|
||||
|
@ -21,6 +21,7 @@
|
||||
database</a></li>
|
||||
<li><a href="#functions">Time and date functions</a></li>
|
||||
<li><a href="#stability">Interface stability</a></li>
|
||||
<li><a href="#leapsec">Leap seconds</a></li>
|
||||
<li><a href="#calendar">Calendrical issues</a></li>
|
||||
<li><a href="#planets">Time and time zones on other planets</a></li>
|
||||
</ul>
|
||||
@ -98,8 +99,9 @@ A <code><abbr>tz</abbr></code> timezone corresponds to a ruleset that can
|
||||
have more than two changes per year, these changes need not merely
|
||||
flip back and forth between two alternatives, and the rules themselves
|
||||
can change at times.
|
||||
Whether and when a timezone changes its
|
||||
clock, and even the timezone's notional base offset from UTC, are variable.
|
||||
Whether and when a timezone changes its clock,
|
||||
and even the timezone's notional base offset from <abbr>UTC</abbr>,
|
||||
are variable.
|
||||
It does not always make sense to talk about a timezone's
|
||||
"base offset", which is not necessarily a single number.
|
||||
</p>
|
||||
@ -428,7 +430,7 @@ in decreasing order of importance:
|
||||
EET/EEST Eastern European,
|
||||
GST/GDT Guam,
|
||||
HST/HDT/HWT/HPT Hawaii,
|
||||
HKT/HKST Hong Kong,
|
||||
HKT/HKST/HKWT Hong Kong,
|
||||
IST India,
|
||||
IST/GMT Irish,
|
||||
IST/IDT/IDDT Israel,
|
||||
@ -972,7 +974,8 @@ an older <code>zic</code>.
|
||||
that do not fit into the POSIX model.
|
||||
</li>
|
||||
<li>
|
||||
POSIX requires that systems ignore leap seconds.
|
||||
POSIX requires that <code>time_t</code> clock counts exclude leap
|
||||
seconds.
|
||||
</li>
|
||||
<li>
|
||||
The <code><abbr>tz</abbr></code> code attempts to support all the
|
||||
@ -1072,7 +1075,8 @@ an older <code>zic</code>.
|
||||
where <code>time_t</code> is signed.
|
||||
</li>
|
||||
<li>
|
||||
These functions can account for leap seconds, thanks to Bradley White.
|
||||
These functions can account for leap seconds;
|
||||
see <a href="#leapsec">Leap seconds</a> below.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -1248,6 +1252,69 @@ between now and the future time.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="leapsec">Leap seconds</h2>
|
||||
<p>
|
||||
The <code><abbr>tz</abbr></code> code and data can account for leap seconds,
|
||||
thanks to code contributed by Bradley White.
|
||||
However, the leap second support of this package is rarely used directly
|
||||
because POSIX requires leap seconds to be excluded and many
|
||||
software packages would mishandle leap seconds if they were present.
|
||||
Instead, leap seconds are more commonly handled by occasionally adjusting
|
||||
the operating system kernel clock as described in
|
||||
<a href="tz-link.html#precision">Precision timekeeping</a>,
|
||||
and this package by default installs a <samp>leapseconds</samp> file
|
||||
commonly used by
|
||||
<a href="http://www.ntp.org"><abbr title="Network Time Protocol">NTP</abbr></a>
|
||||
software that adjusts the kernel clock.
|
||||
However, kernel-clock twiddling approximates UTC only roughly,
|
||||
and systems needing more-precise UTC can use this package's leap
|
||||
second support directly.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The directly-supported mechanism assumes that <code>time_t</code>
|
||||
counts of seconds since the POSIX epoch normally include leap seconds,
|
||||
as opposed to POSIX <code>time_t</code> counts which exclude leap seconds.
|
||||
This modified timescale is converted to <abbr>UTC</abbr>
|
||||
at the same point that time zone and DST adjustments are applied –
|
||||
namely, at calls to <code>localtime</code> and analogous functions –
|
||||
and the process is driven by leap second information
|
||||
stored in alternate versions of the <abbr>TZif</abbr> files.
|
||||
Because a leap second adjustment may be needed even
|
||||
if no time zone correction is desired,
|
||||
calls to <code>gmtime</code>-like functions
|
||||
also need to consult a <abbr>TZif</abbr> file,
|
||||
conventionally named <samp><abbr>GMT</abbr></samp>,
|
||||
to see whether leap second corrections are needed.
|
||||
To convert an application's <code>time_t</code> timestamps to or from
|
||||
POSIX <code>time_t</code> timestamps (for use when, say,
|
||||
embedding or interpreting timestamps in portable
|
||||
<a href="https://en.wikipedia.org/wiki/Tar_(computing)"><code>tar</code></a>
|
||||
files),
|
||||
the application can call the utility functions
|
||||
<code>time2posix</code> and <code>posix2time</code>
|
||||
included with this package.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the POSIX-compatible <abbr>TZif</abbr> file set is installed
|
||||
in a directory whose basename is <samp>zoneinfo</samp>, the
|
||||
leap-second-aware file set is by default installed in a separate
|
||||
directory <samp>zoneinfo-leaps</samp>.
|
||||
Although each process can have its own time zone by setting
|
||||
its <code>TZ</code> environment variable, there is no support for some
|
||||
processes being leap-second aware while other processes are
|
||||
POSIX-compatible; the leap-second choice is system-wide.
|
||||
So if you configure your kernel to count leap seconds, you should also
|
||||
discard <samp>zoneinfo</samp> and rename <samp>zoneinfo-leaps</samp>
|
||||
to <samp>zoneinfo</samp>.
|
||||
Alternatively, you can install just one set of <abbr>TZif</abbr> files
|
||||
in the first place; see the <code>REDO</code> variable in this package's
|
||||
<a href="https://en.wikipedia.org/wiki/Makefile">makefile</a>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="calendar">Calendrical issues</h2>
|
||||
<p>
|
||||
|
@ -1 +1 @@
|
||||
2019b
|
||||
2019c
|
||||
|
@ -7,6 +7,101 @@
|
||||
https://github.com/openssl/openssl/commits/ and pick the appropriate
|
||||
release branch.
|
||||
|
||||
Changes between 1.1.1c and 1.1.1d [10 Sep 2019]
|
||||
|
||||
*) Fixed a fork protection issue. OpenSSL 1.1.1 introduced a rewritten random
|
||||
number generator (RNG). This was intended to include protection in the
|
||||
event of a fork() system call in order to ensure that the parent and child
|
||||
processes did not share the same RNG state. However this protection was not
|
||||
being used in the default case.
|
||||
|
||||
A partial mitigation for this issue is that the output from a high
|
||||
precision timer is mixed into the RNG state so the likelihood of a parent
|
||||
and child process sharing state is significantly reduced.
|
||||
|
||||
If an application already calls OPENSSL_init_crypto() explicitly using
|
||||
OPENSSL_INIT_ATFORK then this problem does not occur at all.
|
||||
(CVE-2019-1549)
|
||||
[Matthias St. Pierre]
|
||||
|
||||
*) For built-in EC curves, ensure an EC_GROUP built from the curve name is
|
||||
used even when parsing explicit parameters, when loading a serialized key
|
||||
or calling `EC_GROUP_new_from_ecpkparameters()`/
|
||||
`EC_GROUP_new_from_ecparameters()`.
|
||||
This prevents bypass of security hardening and performance gains,
|
||||
especially for curves with specialized EC_METHODs.
|
||||
By default, if a key encoded with explicit parameters is loaded and later
|
||||
serialized, the output is still encoded with explicit parameters, even if
|
||||
internally a "named" EC_GROUP is used for computation.
|
||||
[Nicola Tuveri]
|
||||
|
||||
*) Compute ECC cofactors if not provided during EC_GROUP construction. Before
|
||||
this change, EC_GROUP_set_generator would accept order and/or cofactor as
|
||||
NULL. After this change, only the cofactor parameter can be NULL. It also
|
||||
does some minimal sanity checks on the passed order.
|
||||
(CVE-2019-1547)
|
||||
[Billy Bob Brumley]
|
||||
|
||||
*) Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey.
|
||||
An attack is simple, if the first CMS_recipientInfo is valid but the
|
||||
second CMS_recipientInfo is chosen ciphertext. If the second
|
||||
recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct
|
||||
encryption key will be replaced by garbage, and the message cannot be
|
||||
decoded, but if the RSA decryption fails, the correct encryption key is
|
||||
used and the recipient will not notice the attack.
|
||||
As a work around for this potential attack the length of the decrypted
|
||||
key must be equal to the cipher default key length, in case the
|
||||
certifiate is not given and all recipientInfo are tried out.
|
||||
The old behaviour can be re-enabled in the CMS code by setting the
|
||||
CMS_DEBUG_DECRYPT flag.
|
||||
(CVE-2019-1563)
|
||||
[Bernd Edlinger]
|
||||
|
||||
*) Early start up entropy quality from the DEVRANDOM seed source has been
|
||||
improved for older Linux systems. The RAND subsystem will wait for
|
||||
/dev/random to be producing output before seeding from /dev/urandom.
|
||||
The seeded state is stored for future library initialisations using
|
||||
a system global shared memory segment. The shared memory identifier
|
||||
can be configured by defining OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID to
|
||||
the desired value. The default identifier is 114.
|
||||
[Paul Dale]
|
||||
|
||||
*) Correct the extended master secret constant on EBCDIC systems. Without this
|
||||
fix TLS connections between an EBCDIC system and a non-EBCDIC system that
|
||||
negotiate EMS will fail. Unfortunately this also means that TLS connections
|
||||
between EBCDIC systems with this fix, and EBCDIC systems without this
|
||||
fix will fail if they negotiate EMS.
|
||||
[Matt Caswell]
|
||||
|
||||
*) Use Windows installation paths in the mingw builds
|
||||
|
||||
Mingw isn't a POSIX environment per se, which means that Windows
|
||||
paths should be used for installation.
|
||||
(CVE-2019-1552)
|
||||
[Richard Levitte]
|
||||
|
||||
*) Changed DH_check to accept parameters with order q and 2q subgroups.
|
||||
With order 2q subgroups the bit 0 of the private key is not secret
|
||||
but DH_generate_key works around that by clearing bit 0 of the
|
||||
private key for those. This avoids leaking bit 0 of the private key.
|
||||
[Bernd Edlinger]
|
||||
|
||||
*) Significantly reduce secure memory usage by the randomness pools.
|
||||
[Paul Dale]
|
||||
|
||||
*) Revert the DEVRANDOM_WAIT feature for Linux systems
|
||||
|
||||
The DEVRANDOM_WAIT feature added a select() call to wait for the
|
||||
/dev/random device to become readable before reading from the
|
||||
/dev/urandom device.
|
||||
|
||||
It turned out that this change had negative side effects on
|
||||
performance which were not acceptable. After some discussion it
|
||||
was decided to revert this feature and leave it up to the OS
|
||||
resp. the platform maintainer to ensure a proper initialization
|
||||
during early boot time.
|
||||
[Matthias St. Pierre]
|
||||
|
||||
Changes between 1.1.1b and 1.1.1c [28 May 2019]
|
||||
|
||||
*) Add build tests for C++. These are generated files that only do one
|
||||
@ -75,6 +170,16 @@
|
||||
(CVE-2019-1543)
|
||||
[Matt Caswell]
|
||||
|
||||
*) Add DEVRANDOM_WAIT feature for Linux systems
|
||||
|
||||
On older Linux systems where the getrandom() system call is not available,
|
||||
OpenSSL normally uses the /dev/urandom device for seeding its CSPRNG.
|
||||
Contrary to getrandom(), the /dev/urandom device will not block during
|
||||
early boot when the kernel CSPRNG has not been seeded yet.
|
||||
|
||||
To mitigate this known weakness, use select() to wait for /dev/random to
|
||||
become readable before reading from /dev/urandom.
|
||||
|
||||
*) Ensure that SM2 only uses SM3 as digest algorithm
|
||||
[Paul Yang]
|
||||
|
||||
@ -322,7 +427,7 @@
|
||||
SSL_set_ciphersuites()
|
||||
[Matt Caswell]
|
||||
|
||||
*) Memory allocation failures consistenly add an error to the error
|
||||
*) Memory allocation failures consistently add an error to the error
|
||||
stack.
|
||||
[Rich Salz]
|
||||
|
||||
@ -6860,7 +6965,7 @@
|
||||
reason texts, thereby removing some of the footprint that may not
|
||||
be interesting if those errors aren't displayed anyway.
|
||||
|
||||
NOTE: it's still possible for any application or module to have it's
|
||||
NOTE: it's still possible for any application or module to have its
|
||||
own set of error texts inserted. The routines are there, just not
|
||||
used by default when no-err is given.
|
||||
[Richard Levitte]
|
||||
@ -8826,7 +8931,7 @@ des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
|
||||
Changes between 0.9.6g and 0.9.6h [5 Dec 2002]
|
||||
|
||||
*) New function OPENSSL_cleanse(), which is used to cleanse a section of
|
||||
memory from it's contents. This is done with a counter that will
|
||||
memory from its contents. This is done with a counter that will
|
||||
place alternating values in each byte. This can be used to solve
|
||||
two issues: 1) the removal of calls to memset() by highly optimizing
|
||||
compilers, and 2) cleansing with other values than 0, since those can
|
||||
|
@ -87,9 +87,6 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lx
|
||||
# linked openssl executable has rather debugging value than
|
||||
# production quality.
|
||||
#
|
||||
# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
|
||||
# provided to stack calls. Generates unique stack functions for
|
||||
# each possible stack type.
|
||||
# BN_LLONG use the type 'long long' in crypto/bn/bn.h
|
||||
# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
|
||||
# Following are set automatically by this script
|
||||
@ -145,13 +142,13 @@ my @gcc_devteam_warn = qw(
|
||||
# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
|
||||
# -Wextended-offsetof -- no, needed in CMS ASN1 code
|
||||
my @clang_devteam_warn = qw(
|
||||
-Wno-unknown-warning-option
|
||||
-Wswitch-default
|
||||
-Wno-parentheses-equality
|
||||
-Wno-language-extension-token
|
||||
-Wno-extended-offsetof
|
||||
-Wconditional-uninitialized
|
||||
-Wincompatible-pointer-types-discards-qualifiers
|
||||
-Wno-unknown-warning-option
|
||||
-Wmissing-variable-declarations
|
||||
);
|
||||
|
||||
|
@ -98,6 +98,9 @@
|
||||
$ nmake test
|
||||
$ nmake install
|
||||
|
||||
Note that in order to perform the install step above you need to have
|
||||
appropriate permissions to write to the installation directory.
|
||||
|
||||
If any of these steps fails, see section Installation in Detail below.
|
||||
|
||||
This will build and install OpenSSL in the default location, which is:
|
||||
@ -107,6 +110,12 @@
|
||||
OpenSSL version number with underscores instead of periods.
|
||||
Windows: C:\Program Files\OpenSSL or C:\Program Files (x86)\OpenSSL
|
||||
|
||||
The installation directory should be appropriately protected to ensure
|
||||
unprivileged users cannot make changes to OpenSSL binaries or files, or install
|
||||
engines. If you already have a pre-installed version of OpenSSL as part of
|
||||
your Operating System it is recommended that you do not overwrite the system
|
||||
version and instead install to somewhere else.
|
||||
|
||||
If you want to install it anywhere else, run config like this:
|
||||
|
||||
On Unix:
|
||||
@ -135,7 +144,10 @@
|
||||
Don't build with support for deprecated APIs below the
|
||||
specified version number. For example "--api=1.1.0" will
|
||||
remove support for all APIS that were deprecated in OpenSSL
|
||||
version 1.1.0 or below.
|
||||
version 1.1.0 or below. This is a rather specialized option
|
||||
for developers. If you just intend to remove all deprecated
|
||||
APIs entirely (up to the current version), it is easier
|
||||
to add the 'no-deprecated' option instead (see below).
|
||||
|
||||
--cross-compile-prefix=PREFIX
|
||||
The PREFIX to include in front of commands for your
|
||||
@ -229,7 +241,7 @@
|
||||
source exists.
|
||||
getrandom: Use the L<getrandom(2)> or equivalent system
|
||||
call.
|
||||
devrandom: Use the the first device from the DEVRANDOM list
|
||||
devrandom: Use the first device from the DEVRANDOM list
|
||||
which can be opened to read random bytes. The
|
||||
DEVRANDOM preprocessor constant expands to
|
||||
"/dev/urandom","/dev/random","/dev/srandom" on
|
||||
@ -908,8 +920,11 @@
|
||||
$ mms install ! OpenVMS
|
||||
$ nmake install # Windows
|
||||
|
||||
This will install all the software components in this directory
|
||||
tree under PREFIX (the directory given with --prefix or its
|
||||
Note that in order to perform the install step above you need to have
|
||||
appropriate permissions to write to the installation directory.
|
||||
|
||||
The above commands will install all the software components in this
|
||||
directory tree under PREFIX (the directory given with --prefix or its
|
||||
default):
|
||||
|
||||
Unix:
|
||||
@ -965,6 +980,12 @@
|
||||
for private key files.
|
||||
misc Various scripts.
|
||||
|
||||
The installation directory should be appropriately protected to ensure
|
||||
unprivileged users cannot make changes to OpenSSL binaries or files, or
|
||||
install engines. If you already have a pre-installed version of OpenSSL as
|
||||
part of your Operating System it is recommended that you do not overwrite
|
||||
the system version and instead install to somewhere else.
|
||||
|
||||
Package builders who want to configure the library for standard
|
||||
locations, but have the package installed somewhere else so that
|
||||
it can easily be packaged, can use
|
||||
|
@ -5,6 +5,23 @@
|
||||
This file gives a brief overview of the major changes between each OpenSSL
|
||||
release. For more details please read the CHANGES file.
|
||||
|
||||
Major changes between OpenSSL 1.1.1c and OpenSSL 1.1.1d [10 Sep 2019]
|
||||
|
||||
o Fixed a fork protection issue (CVE-2019-1549)
|
||||
o Fixed a padding oracle in PKCS7_dataDecode and CMS_decrypt_set1_pkey
|
||||
(CVE-2019-1563)
|
||||
o For built-in EC curves, ensure an EC_GROUP built from the curve name is
|
||||
used even when parsing explicit parameters
|
||||
o Compute ECC cofactors if not provided during EC_GROUP construction
|
||||
(CVE-2019-1547)
|
||||
o Early start up entropy quality from the DEVRANDOM seed source has been
|
||||
improved for older Linux systems
|
||||
o Correct the extended master secret constant on EBCDIC systems
|
||||
o Use Windows installation paths in the mingw builds (CVE-2019-1552)
|
||||
o Changed DH_check to accept parameters with order q and 2q subgroups
|
||||
o Significantly reduce secure memory usage by the randomness pools
|
||||
o Revert the DEVRANDOM_WAIT feature for Linux systems
|
||||
|
||||
Major changes between OpenSSL 1.1.1b and OpenSSL 1.1.1c [28 May 2019]
|
||||
|
||||
o Prevent over long nonces in ChaCha20-Poly1305 (CVE-2019-1543)
|
||||
@ -601,7 +618,7 @@
|
||||
|
||||
Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]:
|
||||
|
||||
o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
|
||||
o Give EVP_MAX_MD_SIZE its old value, except for a FIPS build.
|
||||
|
||||
Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h [11 Oct 2005]:
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
OpenSSL 1.1.1c 28 May 2019
|
||||
OpenSSL 1.1.1d 10 Sep 2019
|
||||
|
||||
Copyright (c) 1998-2019 The OpenSSL Project
|
||||
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
|
||||
|
@ -40,7 +40,6 @@
|
||||
#endif
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "s_apps.h"
|
||||
#include "apps.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -48,6 +47,14 @@ static int WIN32_rename(const char *from, const char *to);
|
||||
# define rename(from,to) WIN32_rename((from),(to))
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
|
||||
# include <conio.h>
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
|
||||
# define _kbhit kbhit
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
unsigned long flag;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -444,11 +444,9 @@ void destroy_ui_method(void);
|
||||
const UI_METHOD *get_ui_method(void);
|
||||
|
||||
int chopup_args(ARGS *arg, char *buf);
|
||||
# ifdef HEADER_X509_H
|
||||
int dump_cert_text(BIO *out, X509 *x);
|
||||
void print_name(BIO *out, const char *title, X509_NAME *nm,
|
||||
unsigned long lflags);
|
||||
# endif
|
||||
void print_bignum_var(BIO *, const BIGNUM *, const char*,
|
||||
int, unsigned char *);
|
||||
void print_array(BIO *, const char *, int, const unsigned char *);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -722,7 +722,7 @@ end_of_options:
|
||||
|
||||
/*****************************************************************/
|
||||
if (req || gencrl) {
|
||||
if (spkac_file != NULL) {
|
||||
if (spkac_file != NULL && outfile != NULL) {
|
||||
output_der = 1;
|
||||
batch = 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -421,7 +421,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
while (BIO_pending(bp) || !BIO_eof(bp)) {
|
||||
i = BIO_read(bp, (char *)buf, BUFSIZE);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Read Error in %s\n", file);
|
||||
|
@ -586,7 +586,7 @@ int enc_main(int argc, char **argv)
|
||||
if (benc != NULL)
|
||||
wbio = BIO_push(benc, wbio);
|
||||
|
||||
for (;;) {
|
||||
while (BIO_pending(rbio) || !BIO_eof(rbio)) {
|
||||
inl = BIO_read(rbio, (char *)buff, bsize);
|
||||
if (inl <= 0)
|
||||
break;
|
||||
|
@ -1416,9 +1416,11 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
|
||||
*q = '\0';
|
||||
|
||||
/*
|
||||
* Skip "GET / HTTP..." requests often used by load-balancers
|
||||
* Skip "GET / HTTP..." requests often used by load-balancers. Note:
|
||||
* 'p' was incremented above to point to the first byte *after* the
|
||||
* leading slash, so with 'GET / ' it is now an empty string.
|
||||
*/
|
||||
if (p[1] == '\0')
|
||||
if (p[0] == '\0')
|
||||
goto out;
|
||||
|
||||
len = urldecode(p);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -22,7 +22,6 @@
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
#include <openssl/err.h>
|
||||
#include "s_apps.h"
|
||||
/* Needed to get the other O_xxx flags. */
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
# include <unixio.h>
|
||||
|
@ -838,7 +838,7 @@ static int alg_print(const X509_ALGOR *alg)
|
||||
goto done;
|
||||
}
|
||||
BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, "
|
||||
"Block size(r): %ld, Paralelizm(p): %ld",
|
||||
"Block size(r): %ld, Parallelism(p): %ld",
|
||||
ASN1_STRING_length(kdf->salt),
|
||||
ASN1_INTEGER_get(kdf->costParameter),
|
||||
ASN1_INTEGER_get(kdf->blockSize),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -881,9 +881,19 @@ int req_main(int argc, char **argv)
|
||||
|
||||
if (text) {
|
||||
if (x509)
|
||||
X509_print_ex(out, x509ss, get_nameopt(), reqflag);
|
||||
ret = X509_print_ex(out, x509ss, get_nameopt(), reqflag);
|
||||
else
|
||||
X509_REQ_print_ex(out, req, get_nameopt(), reqflag);
|
||||
ret = X509_REQ_print_ex(out, req, get_nameopt(), reqflag);
|
||||
|
||||
if (ret == 0) {
|
||||
if (x509)
|
||||
BIO_printf(bio_err, "Error printing certificate\n");
|
||||
else
|
||||
BIO_printf(bio_err, "Error printing certificate request\n");
|
||||
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (subject) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -9,13 +9,7 @@
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
|
||||
# include <conio.h>
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
|
||||
# define _kbhit kbhit
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#define PORT "4433"
|
||||
#define PROTOCOL "tcp"
|
||||
@ -24,17 +18,15 @@ typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
|
||||
int do_server(int *accept_sock, const char *host, const char *port,
|
||||
int family, int type, int protocol, do_server_cb cb,
|
||||
unsigned char *context, int naccept, BIO *bio_s_out);
|
||||
#ifdef HEADER_X509_H
|
||||
|
||||
int verify_callback(int ok, X509_STORE_CTX *ctx);
|
||||
#endif
|
||||
#ifdef HEADER_SSL_H
|
||||
|
||||
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
|
||||
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
STACK_OF(X509) *chain, int build_chain);
|
||||
int ssl_print_sigalgs(BIO *out, SSL *s);
|
||||
int ssl_print_point_formats(BIO *out, SSL *s);
|
||||
int ssl_print_groups(BIO *out, SSL *s, int noshared);
|
||||
#endif
|
||||
int ssl_print_tmp_key(BIO *out, SSL *s);
|
||||
int init_client(int *sock, const char *host, const char *port,
|
||||
const char *bindhost, const char *bindport,
|
||||
@ -44,13 +36,11 @@ int should_retry(int i);
|
||||
long bio_dump_callback(BIO *bio, int cmd, const char *argp,
|
||||
int argi, long argl, long ret);
|
||||
|
||||
#ifdef HEADER_SSL_H
|
||||
void apps_ssl_info_callback(const SSL *s, int where, int ret);
|
||||
void msg_cb(int write_p, int version, int content_type, const void *buf,
|
||||
size_t len, SSL *ssl, void *arg);
|
||||
void tlsext_cb(SSL *s, int client_server, int type, const unsigned char *data,
|
||||
int len, void *arg);
|
||||
#endif
|
||||
|
||||
int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
|
||||
unsigned int *cookie_len);
|
||||
@ -75,7 +65,6 @@ int args_excert(int option, SSL_EXCERT **pexc);
|
||||
int load_excert(SSL_EXCERT **pexc);
|
||||
void print_verify_detail(SSL *s, BIO *bio);
|
||||
void print_ssl_summary(SSL *s);
|
||||
#ifdef HEADER_SSL_H
|
||||
int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx);
|
||||
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls,
|
||||
int crl_download);
|
||||
@ -86,4 +75,3 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
|
||||
void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
|
||||
int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
|
||||
void print_ca_names(BIO *bio, SSL *s);
|
||||
#endif
|
||||
|
@ -1525,7 +1525,8 @@ void print_ca_names(BIO *bio, SSL *s)
|
||||
int i;
|
||||
|
||||
if (sk == NULL || sk_X509_NAME_num(sk) == 0) {
|
||||
BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
|
||||
if (!SSL_is_server(s))
|
||||
BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2345,7 +2345,7 @@ int s_client_main(int argc, char **argv)
|
||||
(void)BIO_flush(fbio);
|
||||
/*
|
||||
* The first line is the HTTP response. According to RFC 7230,
|
||||
* it's formated exactly like this:
|
||||
* it's formatted exactly like this:
|
||||
*
|
||||
* HTTP/d.d ddd Reason text\r\n
|
||||
*/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user