diff options
77 files changed, 4046 insertions, 2146 deletions
diff --git a/readline/CHANGELOG b/readline/CHANGELOG index 6794591..18265ab 100644 --- a/readline/CHANGELOG +++ b/readline/CHANGELOG @@ -1304,3 +1304,50 @@ configure.ac ---- configure.ac,Makefile.in,examples/Makefile.in - remove references to purify + + 11/21 + ----- +configure.ac,config.h.in + - fnmatch: check for libc function, define HAVE_FNMATCH if found. Now + used by vi-mode history search functions + + 7/12 + ---- +Makefile.in,examples/Makefile.in + - add support for building with address sanitizer, using new target + `asan' + + 4/23/2018 + --------- +configure.ac + - TERMCAP_PKG_CONFIG_LIB: new variable, defined from TERMCAP_LIB, + defaults to termcap + +readline.pc.in + - change Requires.private to use TERMCAP_PKG_CONFIG_LIB instead of + hardcoded `tinfo'. Report and fix from Thomas Petazzoni + <thomas.petazzoni@bootlin.com> + + 5/4 + --- +Makefile.in + - new targets to install and uninstall the `readline.pc' pkgconfig + file + - install-{static,shared}: add install-pc to the list of prereqs + - uninstall{,-shared}: add uninstall-pc to list of prereqs. Change + from Thomas Petazzoni <thomas.petazzoni@bootlin.com> + +configure.ac,Makefile.in + - add new configure option to optionally disable installing the + source code examples. From Thomas Petazzoni <thomas.petazzoni@bootlin.com> + + 5/23 + ---- +Makefile.in + - install-pc: make sure we install readline.pc into an existing + pkgconfig directory. Report from ilove zfs <ilovezfs@icloud.com> + + 5/24 + ---- +Makefile.in + - installdirs: create $(pkgconfigdir) if it doesn't exist diff --git a/readline/CHANGES b/readline/CHANGES index b5e16b7..09eab6e 100644 --- a/readline/CHANGES +++ b/readline/CHANGES @@ -1,3 +1,145 @@ +This document details the changes between this version, readline-8.0, and the +previous version, readline-7.0. + +1. Changes to Readline + +a. Added a guard to prevent nested macros from causing an infinite expansion + loop. + +b. Instead of allocating enough history list entries to hold the maximum list + size, cap the number allocated initially. + +c. Added a strategy to avoid allocating huge amounts of memory if a block of + history entries without timestamps occurs after a block with timestamps. + +d. Added support for keyboard timeouts when an ESC character is the last + character in a macro. + +e. There are several performance improvements when in a UTF-8 locale. + +f. Readline does a better job of preserving the original set of blocked + signals when using pselect() to wait for input. + +g. Fixed a bug that caused multibyte characters in macros to be mishandled. + +h. Fixed several bugs in the code that calculates line breaks when expanding + prompts that span several lines, contain multibyte characters, and contain + invisible character seqeuences. + +i. Fixed several bugs in cursor positioning when displaying lines with prompts + containing invisible characters and multibyte characters. + +j. When performing case-insensitive completion, Readline no longer sorts the + list of matches unless directed to do so. + +k. Fixed a problem with key sequences ending with a backslash. + +l. Fixed out-of-bounds and free memory read errors found via fuzzing. + +m. Fixed several cases where the mark was set to an invalid value. + +n. Fixed a problem with the case-changing operators in the case where the + lower and upper case versions of a character do not have the same number + of bytes. + +o. Handle incremental and non-incremental search character reads returning EOF. + +p. Handle the case where a failing readline command at the end of a multi-key + sequence could be misinterpreted. + +q. The history library now prints a meaningful error message if the history + file isn't a regular file. + +r. Fixed a problem with vi-mode redo (`.') on a command when trying to replace + a multibyte character. + +s. The key binding code now attempts to remove a keymap if a key unbinding + leaves it empty. + +t. Fixed a line-wrapping issue that caused problems for some terminal + emulators. + +u. If there is a key bound to the tty's VDISCARD special character, readline + disables VDISCARD while it is active. + +v. Fixed a problem with exiting bracketed paste mode on terminals that assume + the bracketed paste mode character sequence contains visible characters. + +w. Fixed a bug that could cause a key binding command to refer to an + uninitialized variable. + +x. Added more UTF-8-specific versions of multibyte functions, and optimized + existing functions if the current locale uses UTF-8 encoding. + +y. Fixed a problem with bracketed-paste inserting more than one character and + interacting with other readline functions. + +z. Fixed a bug that caused the history library to attempt to append a history + line to a non-existent history entry. + +aa. If using bracketed paste mode, output a newline after the \r that is the + last character of the mode disable string to avoid overwriting output. + +bb. Fixes to the vi-mode `b', `B', `w', `W', `e', and `E' commands to better + handle multibyte characters. + +cc. Fixed a redisplay problem that caused an extra newline to be generated on + accept-line when the line length is exactly the screenwidth. + +dd. Fixed a bug with adding multibyte characters to an incremental search + string. + +ee. Fixed a bug with redoing text insertions in vi mode. + +ff. Fixed a bug with pasting text into an incremental search string if bracketed + paste mode is enabled. ESC cannot be one of the incremental search + terminator characters for this to work. + +gg. Fixed a bug with anchored search patterns when performing searches in vi + mode. + +2. New Features in Readline + +a. Non-incremental vi-mode search (`N', `n') can search for a shell pattern, as + Posix specifies (uses fnmatch(3) if available). + +b. There are new `next-screen-line' and `previous-screen-line' bindable + commands, which move the cursor to the same column in the next, or previous, + physical line, respectively. + +c. There are default key bindings for control-arrow-key key combinations. + +d. A negative argument (-N) to `quoted-insert' means to insert the next N + characters using quoted-insert. + +e. New public function: rl_check_signals(), which allows applications to + respond to signals that readline catches while waiting for input using + a custom read function. + +f. There is new support for conditionally testing the readline version in an + inputrc file, with a full set of arithmetic comparison operators available. + +g. There is a simple variable comparison facility available for use within an + inputrc file. Allowable operators are equality and inequality; string + variables may be compared to a value; boolean variables must be compared to + either `on' or `off'; variable names are separated from the operator by + whitespace. + +h. The history expansion library now understands command and process + substitution and extended globbing and allows them to appear anywhere in a + word. + +i. The history library has a new variable that allows applications to set the + initial quoting state, so quoting state can be inherited from a previous + line. + +j. Readline now allows application-defined keymap names; there is a new public + function, rl_set_keymap_name(), to do that. + +k. The "Insert" keypad key, if available, now puts readline into overwrite + mode. + +------------------------------------------------------------------------------- This document details the changes between this version, readline-7.0, and the previous version, readline-6.3. diff --git a/readline/ChangeLog.gdb b/readline/ChangeLog.gdb index 6937880..982ef7b 100644 --- a/readline/ChangeLog.gdb +++ b/readline/ChangeLog.gdb @@ -1,5 +1,9 @@ 2019-08-12 Tom Tromey <tom@tromey.com> + * Imported readline 8.0. + +2019-08-12 Tom Tromey <tom@tromey.com> + * Makefile.in (xfree.o): Don't depend on readline.h. * xfree.c (xfree): Remove gdb workaround. * xmalloc.h (xfree): Remove #define. diff --git a/readline/INSTALL b/readline/INSTALL index e1a92d3..afb4d53 100644 --- a/readline/INSTALL +++ b/readline/INSTALL @@ -1,7 +1,7 @@ Basic Installation ================== -These are installation instructions for Readline-7.0. +These are installation instructions for Readline-8.0. The simplest way to compile readline is: diff --git a/readline/MANIFEST b/readline/MANIFEST index bfd0547..ad49d66 100644 --- a/readline/MANIFEST +++ b/readline/MANIFEST @@ -118,6 +118,7 @@ examples/rl-fgets.c f examples/rlbasic.c f examples/rlcat.c f examples/rlevent.c f +examples/rlkeymaps.c f examples/rltest.c f examples/rl-callbacktest.c f examples/rl.c f diff --git a/readline/Makefile.in b/readline/Makefile.in index 1adfc28..bcbd18b 100644 --- a/readline/Makefile.in +++ b/readline/Makefile.in @@ -1,6 +1,6 @@ ## -*- text -*- ## # Master Makefile for the GNU readline library. -# Copyright (C) 1994-2009 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -59,6 +59,7 @@ mandir = @mandir@ includedir = @includedir@ datadir = @datadir@ localedir = @localedir@ +pkgconfigdir = ${libdir}/pkgconfig infodir = @infodir@ @@ -85,7 +86,7 @@ TERMCAP_LIB = @TERMCAP_LIB@ # For libraries which include headers from other libraries. INCLUDES = -I. -I$(srcdir) -XCCFLAGS = $(DEFS) $(LOCAL_DEFS) $(INCLUDES) $(CPPFLAGS) +XCCFLAGS = $(ASAN_CFLAGS) $(DEFS) $(LOCAL_DEFS) $(INCLUDES) $(CPPFLAGS) CCFLAGS = $(XCCFLAGS) $(LOCAL_CFLAGS) $(CFLAGS) # could add -Werror here @@ -94,6 +95,11 @@ GCC_LINT_FLAGS = -ansi -Wall -Wshadow -Wpointer-arith -Wcast-qual \ -Wmissing-prototypes -Wno-implicit -pedantic GCC_LINT_CFLAGS = $(XCCFLAGS) $(GCC_LINT_FLAGS) @CFLAGS@ @LOCAL_CFLAGS@ +ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer +ASAN_XLDFLAGS = -fsanitize=address + +install_examples = @EXAMPLES_INSTALL_TARGET@ + .c.o: ${RM} $@ $(CC) -c $(CCFLAGS) $< @@ -160,6 +166,9 @@ all: $(TARGETS) everything: all examples +asan: + ${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' everything + static: $(STATIC_LIBS) libreadline.a: $(OBJECTS) @@ -242,7 +251,16 @@ uninstall-headers: maybe-uninstall-headers: uninstall-headers -install-static: installdirs $(STATIC_LIBS) install-headers install-doc install-examples +install-pc: installdirs + -$(INSTALL_DATA) $(BUILD_DIR)/readline.pc $(DESTDIR)$(pkgconfigdir)/readline.pc + +uninstall-pc: + -test -n "$(pkgconfigdir)" && cd $(DESTDIR)$(pkgconfigdir) && \ + ${RM} readline.pc + +maybe-uninstall-pc: uninstall-pc + +install-static: installdirs $(STATIC_LIBS) install-headers install-doc ${install_examples} install-pc -$(MV) $(DESTDIR)$(libdir)/libreadline.a $(DESTDIR)$(libdir)/libreadline.old $(INSTALL_DATA) libreadline.a $(DESTDIR)$(libdir)/libreadline.a -test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libreadline.a @@ -253,17 +271,18 @@ install-static: installdirs $(STATIC_LIBS) install-headers install-doc install-e installdirs: $(srcdir)/support/mkinstalldirs -$(SHELL) $(srcdir)/support/mkinstalldirs $(DESTDIR)$(includedir) \ $(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \ - $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) $(DESTDIR)$(docdir) + $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) $(DESTDIR)$(docdir) \ + $(DESTDIR)$(pkgconfigdir) -uninstall: uninstall-headers uninstall-doc uninstall-examples +uninstall: uninstall-headers uninstall-doc uninstall-examples uninstall-pc -test -n "$(DESTDIR)$(libdir)" && cd $(DESTDIR)$(libdir) && \ ${RM} libreadline.a libreadline.old libhistory.a libhistory.old $(SHARED_LIBS) -( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall ) -install-shared: installdirs install-headers shared install-doc +install-shared: installdirs install-headers shared install-doc install-pc ( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install ) -uninstall-shared: maybe-uninstall-headers +uninstall-shared: maybe-uninstall-headers maybe-uninstall-pc -( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall ) install-examples: installdirs install-headers diff --git a/readline/NEWS b/readline/NEWS index cf7107e..42be21e 100644 --- a/readline/NEWS +++ b/readline/NEWS @@ -1,3 +1,48 @@ +This is a terse description of the new features added to readline-8.0 since +the release of readline-7.0. + +New Features in Readline + +a. Non-incremental vi-mode search (`N', `n') can search for a shell pattern, as + Posix specifies (uses fnmatch(3) if available). + +b. There are new `next-screen-line' and `previous-screen-line' bindable + commands, which move the cursor to the same column in the next, or previous, + physical line, respectively. + +c. There are default key bindings for control-arrow-key key combinations. + +d. A negative argument (-N) to `quoted-insert' means to insert the next N + characters using quoted-insert. + +e. New public function: rl_check_signals(), which allows applications to + respond to signals that readline catches while waiting for input using + a custom read function. + +f. There is new support for conditionally testing the readline version in an + inputrc file, with a full set of arithmetic comparison operators available. + +g. There is a simple variable comparison facility available for use within an + inputrc file. Allowable operators are equality and inequality; string + variables may be compared to a value; boolean variables must be compared to + either `on' or `off'; variable names are separated from the operator by + whitespace. + +h. The history expansion library now understands command and process + substitution and extended globbing and allows them to appear anywhere in a + word. + +i. The history library has a new variable that allows applications to set the + initial quoting state, so quoting state can be inherited from a previous + line. + +j. Readline now allows application-defined keymap names; there is a new public + function, rl_set_keymap_name(), to do that. + +k. The "Insert" keypad key, if available, now puts readline into overwrite + mode. + +------------------------------------------------------------------------------- This is a terse description of the new features added to readline-7.0 since the release of readline-6.3. @@ -46,6 +91,34 @@ k. If readline reads a history file that begins with `#' (or the value of l. Readline now throws an error if it parses a key binding without a terminating `:' or whitespace. +m. The default binding for ^W in vi mode now uses word boundaries specified + by Posix (vi-unix-word-rubout is bindable command name). + +n. rl_clear_visible_line: new application-callable function; clears all + screen lines occupied by the current visible readline line. + +o. rl_tty_set_echoing: application-callable function that controls whether + or not readline thinks it is echoing terminal output. + +p. Handle >| and strings of digits preceding and following redirection + specifications as single tokens when tokenizing the line for history + expansion. + +q. Fixed a bug with displaying completions when the prefix display length + is greater than the length of the completions to be displayed. + +r. The :p history modifier now applies to the entire line, so any expansion + specifying :p causes the line to be printed instead of expanded. + +s. New application-callable function: rl_pending_signal(): returns the signal + number of any signal readline has caught but not yet handled. + +t. New application-settable variable: rl_persistent_signal_handlers: if set + to a non-zero value, readline will enable the readline-6.2 signal handler + behavior in callback mode: handlers are installed when + rl_callback_handler_install is called and removed removed when a complete + line has been read. + ------------------------------------------------------------------------------- This is a terse description of the new features added to readline-6.3 since the release of readline-6.2. diff --git a/readline/README b/readline/README index 6a9c2b9..4fb0804 100644 --- a/readline/README +++ b/readline/README @@ -1,7 +1,7 @@ Introduction ============ -This is the Gnu Readline library, version 7.0. +This is the Gnu Readline library, version 8.0. The Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in. Both diff --git a/readline/aclocal.m4 b/readline/aclocal.m4 index d3bac07..1413267 100644 --- a/readline/aclocal.m4 +++ b/readline/aclocal.m4 @@ -1,4 +1,4 @@ -dnl +nl dnl Bash specific tests dnl dnl Some derived from PDKSH 5.1.3 autoconf tests @@ -962,7 +962,8 @@ AC_CACHE_VAL(bash_cv_termcap_lib, [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, [AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses, [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, - bash_cv_termcap_lib=gnutermcap)])])])])]) + [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, + bash_cv_termcap_lib=gnutermcap)])])])])])]) if test "X$_bash_needmsg" = "Xyes"; then AC_MSG_CHECKING(which library has the termcap functions) fi @@ -1307,7 +1308,7 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers, typedef RETSIGTYPE sigfunc(); -int nsigint; +volatile int nsigint; #ifdef HAVE_POSIX_SIGNALS sigfunc * @@ -1357,7 +1358,7 @@ AC_DEFUN(BASH_SYS_JOB_CONTROL_MISSING, [AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) AC_MSG_CHECKING(for presence of necessary job control definitions) AC_CACHE_VAL(bash_cv_job_control_missing, -[AC_TRY_RUN([ +[AC_TRY_COMPILE([ #include <sys/types.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> @@ -1367,42 +1368,38 @@ AC_CACHE_VAL(bash_cv_job_control_missing, #endif #include <signal.h> -/* Add more tests in here as appropriate. */ -main() -{ +/* add more tests in here as appropriate */ + /* signal type */ #if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS) -exit(1); +#error #endif /* signals and tty control. */ #if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT) -exit (1); +#error #endif /* process control */ #if !defined (WNOHANG) || !defined (WUNTRACED) -exit(1); +#error #endif /* Posix systems have tcgetpgrp and waitpid. */ #if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP) -exit(1); +#error #endif #if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID) -exit(1); +#error #endif /* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */ #if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3) -exit(1); +#error #endif -exit(0); -}], bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing, - [AC_MSG_WARN(cannot check job control if cross-compiling -- defaulting to missing) - bash_cv_job_control_missing=missing] +], , bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing )]) AC_MSG_RESULT($bash_cv_job_control_missing) if test $bash_cv_job_control_missing = missing; then @@ -1585,9 +1582,7 @@ fi AC_DEFUN(BASH_CHECK_DEV_STDIN, [AC_MSG_CHECKING(whether /dev/stdin stdout stderr are available) AC_CACHE_VAL(bash_cv_dev_stdin, -[if test -d /dev/fd && (exec test -r /dev/stdin < /dev/null) ; then - bash_cv_dev_stdin=present - elif test -d /proc/self/fd && (exec test -r /dev/stdin < /dev/null) ; then +[if (exec test -r /dev/stdin < /dev/null) ; then bash_cv_dev_stdin=present else bash_cv_dev_stdin=absent @@ -1798,6 +1793,8 @@ if test "$am_cv_func_iconv" = yes; then LIBS="$OLDLIBS" fi +AC_CHECK_SIZEOF(wchar_t, 4) + ]) dnl need: prefix exec_prefix libdir includedir CC TERMCAP_LIB @@ -1856,7 +1853,7 @@ main() ], ac_cv_rl_version=`cat conftest.rlv`, ac_cv_rl_version='0.0', -ac_cv_rl_version='6.3')]) +ac_cv_rl_version='8.0')]) CFLAGS="$_save_CFLAGS" LDFLAGS="$_save_LDFLAGS" @@ -4195,3 +4192,71 @@ fi AC_MSG_RESULT($bash_cv_wexitstatus_offset) AC_DEFINE_UNQUOTED([WEXITSTATUS_OFFSET], [$bash_cv_wexitstatus_offset], [Offset of exit status in wait status word]) ]) + +AC_DEFUN([BASH_FUNC_SBRK], +[ + AC_CHECK_FUNCS_ONCE([sbrk]) + if test X$ac_cv_func_sbrk = Xyes; then + AC_CACHE_CHECK([for working sbrk], [bash_cv_func_sbrk], + [AC_TRY_RUN([ +#include <stdlib.h> +#include <unistd.h> + +int +main(int c, char **v) +{ + void *x; + + x = sbrk (4096); + exit ((x == (void *)-1) ? 1 : 0); +} +], bash_cv_func_sbrk=yes, bash_cv_func_snprintf=sbrk, + [AC_MSG_WARN([cannot check working sbrk if cross-compiling]) + bash_cv_func_sbrk=yes] +)]) + if test $bash_cv_func_sbrk = no; then + ac_cv_func_sbrk=no + fi + fi + if test $ac_cv_func_sbrk = no; then + AC_DEFINE(HAVE_SBRK, 0, + [Define if you have a working sbrk function.]) + fi +]) + +AC_DEFUN(BASH_FUNC_FNMATCH_EQUIV_FALLBACK, +[AC_MSG_CHECKING(whether fnmatch can be used to check bracket equivalence classes) +AC_CACHE_VAL(bash_cv_fnmatch_equiv_fallback, +[AC_TRY_RUN([ +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <fnmatch.h> +#include <locale.h> + +char *pattern = "[[=a=]]"; + +/* char *string = "ä"; */ +unsigned char string[4] = { '\xc3', '\xa4', '\0' }; + +int +main (int c, char **v) +{ + setlocale (LC_ALL, "de_DE.UTF-8"); + if (fnmatch (pattern, (const char *)string, 0) != FNM_NOMATCH) + exit (0); + exit (1); +} + +], bash_cv_fnmatch_equiv_fallback=yes, bash_cv_fnmatch_equiv_fallback=no, + [AC_MSG_WARN(cannot check fnmatch if cross compiling -- defaulting to no) + bash_cv_fnmatch_equiv_fallback=no] +)]) +AC_MSG_RESULT($bash_cv_fnmatch_equiv_fallback) +if test "$bash_cv_fnmatch_equiv_fallback" = "yes" ; then + bash_cv_fnmatch_equiv_value=1 +else + bash_cv_fnmatch_equiv_value=0 +fi +AC_DEFINE_UNQUOTED([FNMATCH_EQUIV_FALLBACK], [$bash_cv_fnmatch_equiv_value], [Whether fnmatch can be used for bracket equivalence classes]) +]) diff --git a/readline/bind.c b/readline/bind.c index f1098c4..57ae10f 100644 --- a/readline/bind.c +++ b/readline/bind.c @@ -1,6 +1,6 @@ /* bind.c -- key binding and startup file support for the readline library. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -80,6 +80,8 @@ static void _rl_init_file_error (const char *, ...) __attribute__((__format__ ( static void _rl_init_file_error (); #endif +static rl_command_func_t *_rl_function_of_keyseq_internal PARAMS((const char *, size_t, Keymap, int *)); + static char *_rl_read_file PARAMS((char *, size_t *)); static int _rl_read_init_file PARAMS((const char *, int)); static int glean_key_from_name PARAMS((char *)); @@ -87,14 +89,30 @@ static int glean_key_from_name PARAMS((char *)); static int find_boolean_var PARAMS((const char *)); static int find_string_var PARAMS((const char *)); +static const char *boolean_varname PARAMS((int)); +static const char *string_varname PARAMS((int)); + static char *_rl_get_string_variable_value PARAMS((const char *)); static int substring_member_of_array PARAMS((const char *, const char * const *)); +static int _rl_get_keymap_by_name PARAMS((const char *)); +static int _rl_get_keymap_by_map PARAMS((Keymap)); + static int currently_reading_init_file; /* used only in this file */ static int _rl_prefer_visible_bell = 1; +#define OP_EQ 1 +#define OP_NE 2 +#define OP_GT 3 +#define OP_GE 4 +#define OP_LT 5 +#define OP_LE 6 + +#define OPSTART(c) ((c) == '=' || (c) == '!' || (c) == '<' || (c) == '>') +#define CMPSTART(c) ((c) == '=' || (c) == '!') + /* **************************************************************** */ /* */ /* Binding keys */ @@ -105,10 +123,7 @@ static int _rl_prefer_visible_bell = 1; Add NAME to the list of named functions. Make FUNCTION be the function that gets called. If KEY is not -1, then bind it. */ int -rl_add_defun (name, function, key) - const char *name; - rl_command_func_t *function; - int key; +rl_add_defun (const char *name, rl_command_func_t *function, int key) { if (key != -1) rl_bind_key (key, function); @@ -118,9 +133,7 @@ rl_add_defun (name, function, key) /* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ int -rl_bind_key (key, function) - int key; - rl_command_func_t *function; +rl_bind_key (int key, rl_command_func_t *function) { char keyseq[3]; int l; @@ -168,10 +181,7 @@ rl_bind_key (key, function) /* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid KEY. */ int -rl_bind_key_in_map (key, function, map) - int key; - rl_command_func_t *function; - Keymap map; +rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map) { int result; Keymap oldmap; @@ -184,57 +194,44 @@ rl_bind_key_in_map (key, function, map) } /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right - now, this is always used to attempt to bind the arrow keys, hence the - check for rl_vi_movement_mode. */ + now, this is always used to attempt to bind the arrow keys. */ int -rl_bind_key_if_unbound_in_map (key, default_func, kmap) - int key; - rl_command_func_t *default_func; - Keymap kmap; +rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *default_func, Keymap kmap) { - char keyseq[2]; + char *keyseq; - keyseq[0] = (unsigned char)key; - keyseq[1] = '\0'; + keyseq = rl_untranslate_keyseq ((unsigned char)key); return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)); } int -rl_bind_key_if_unbound (key, default_func) - int key; - rl_command_func_t *default_func; +rl_bind_key_if_unbound (int key, rl_command_func_t *default_func) { - char keyseq[2]; + char *keyseq; - keyseq[0] = (unsigned char)key; - keyseq[1] = '\0'; + keyseq = rl_untranslate_keyseq ((unsigned char)key); return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); } /* Make KEY do nothing in the currently selected keymap. - Returns non-zero in case of error. */ + Returns non-zero in case of error. This is not the same as self-insert; + this makes it a dead key. */ int -rl_unbind_key (key) - int key; +rl_unbind_key (int key) { return (rl_bind_key (key, (rl_command_func_t *)NULL)); } -/* Make KEY do nothing in MAP. - Returns non-zero in case of error. */ +/* Make KEY do nothing in MAP. Returns non-zero in case of error. */ int -rl_unbind_key_in_map (key, map) - int key; - Keymap map; +rl_unbind_key_in_map (int key, Keymap map) { return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map)); } /* Unbind all keys bound to FUNCTION in MAP. */ int -rl_unbind_function_in_map (func, map) - rl_command_func_t *func; - Keymap map; +rl_unbind_function_in_map (rl_command_func_t *func, Keymap map) { register int i, rval; @@ -249,10 +246,9 @@ rl_unbind_function_in_map (func, map) return rval; } +/* Unbind all keys bound to COMMAND, which is a bindable command name, in MAP */ int -rl_unbind_command_in_map (command, map) - const char *command; - Keymap map; +rl_unbind_command_in_map (const char *command, Keymap map) { rl_command_func_t *func; @@ -266,9 +262,7 @@ rl_unbind_command_in_map (command, map) FUNCTION, starting in the current keymap. This makes new keymaps as necessary. */ int -rl_bind_keyseq (keyseq, function) - const char *keyseq; - rl_command_func_t *function; +rl_bind_keyseq (const char *keyseq, rl_command_func_t *function) { return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap)); } @@ -277,20 +271,14 @@ rl_bind_keyseq (keyseq, function) FUNCTION. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ int -rl_bind_keyseq_in_map (keyseq, function, map) - const char *keyseq; - rl_command_func_t *function; - Keymap map; +rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map) { return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); } /* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */ int -rl_set_key (keyseq, function, map) - const char *keyseq; - rl_command_func_t *function; - Keymap map; +rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map) { return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); } @@ -299,16 +287,24 @@ rl_set_key (keyseq, function, map) now, this is always used to attempt to bind the arrow keys, hence the check for rl_vi_movement_mode. */ int -rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap) - const char *keyseq; - rl_command_func_t *default_func; - Keymap kmap; +rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *default_func, Keymap kmap) { rl_command_func_t *func; + char *keys; + int keys_len; if (keyseq) { - func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL); + /* Handle key sequences that require translations and `raw' ones that + don't. This might be a problem with backslashes. */ + keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); + if (rl_translate_keyseq (keyseq, keys, &keys_len)) + { + xfree (keys); + return -1; + } + func = rl_function_of_keyseq_len (keys, keys_len, kmap, (int *)NULL); + xfree (keys); #if defined (VI_MODE) if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) #else @@ -322,9 +318,7 @@ rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap) } int -rl_bind_keyseq_if_unbound (keyseq, default_func) - const char *keyseq; - rl_command_func_t *default_func; +rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *default_func) { return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); } @@ -333,9 +327,7 @@ rl_bind_keyseq_if_unbound (keyseq, default_func) the string of characters MACRO. This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ int -rl_macro_bind (keyseq, macro, map) - const char *keyseq, *macro; - Keymap map; +rl_macro_bind (const char *keyseq, const char *macro, Keymap map) { char *macro_keys; int macro_keys_len; @@ -357,16 +349,13 @@ rl_macro_bind (keyseq, macro, map) a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps as necessary. The initial place to do bindings is in MAP. */ int -rl_generic_bind (type, keyseq, data, map) - int type; - const char *keyseq; - char *data; - Keymap map; +rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) { char *keys; - int keys_len; + int keys_len, prevkey; register int i; KEYMAP_ENTRY k; + Keymap prevmap; k.function = 0; @@ -389,12 +378,18 @@ rl_generic_bind (type, keyseq, data, map) return -1; } + prevmap = map; + prevkey = keys[0]; + /* Bind keys, making new keymaps as necessary. */ for (i = 0; i < keys_len; i++) { unsigned char uc = keys[i]; int ic; + if (i > 0) + prevkey = ic; + ic = uc; if (ic < 0 || ic >= KEYMAP_SIZE) { @@ -406,7 +401,10 @@ rl_generic_bind (type, keyseq, data, map) { ic = UNMETA (ic); if (map[ESC].type == ISKMAP) - map = FUNCTION_TO_KEYMAP (map, ESC); + { + prevmap = map; + map = FUNCTION_TO_KEYMAP (map, ESC); + } } if ((i + 1) < keys_len) @@ -425,6 +423,7 @@ rl_generic_bind (type, keyseq, data, map) map[ic].type = ISKMAP; map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); } + prevmap = map; map = FUNCTION_TO_KEYMAP (map, ic); /* The dispatch code will return this function if no matching key sequence is found in the keymap. This (with a little @@ -444,6 +443,7 @@ rl_generic_bind (type, keyseq, data, map) xfree ((char *)map[ic].function); else if (map[ic].type == ISKMAP) { + prevmap = map; map = FUNCTION_TO_KEYMAP (map, ic); ic = ANYOTHERKEY; /* If we're trying to override a keymap with a null function @@ -460,7 +460,28 @@ rl_generic_bind (type, keyseq, data, map) } rl_binding_keymap = map; + } + + /* If we unbound a key (type == ISFUNC, data == 0), and the prev keymap + points to the keymap where we unbound the key (sanity check), and the + current binding keymap is empty (rl_empty_keymap() returns non-zero), + and the binding keymap has ANYOTHERKEY set with type == ISFUNC + (overridden function), delete the now-empty keymap, take the previously- + overridden function and remove the override. */ + /* Right now, this only works one level back. */ + if (type == ISFUNC && data == 0 && + prevmap[prevkey].type == ISKMAP && + (FUNCTION_TO_KEYMAP(prevmap, prevkey) == rl_binding_keymap) && + rl_binding_keymap[ANYOTHERKEY].type == ISFUNC && + rl_empty_keymap (rl_binding_keymap)) + { + prevmap[prevkey].type = rl_binding_keymap[ANYOTHERKEY].type; + prevmap[prevkey].function = rl_binding_keymap[ANYOTHERKEY].function; + rl_discard_keymap (rl_binding_keymap); + rl_binding_keymap = prevmap; + } + xfree (keys); return 0; } @@ -469,10 +490,7 @@ rl_generic_bind (type, keyseq, data, map) an array of characters. LEN gets the final length of ARRAY. Return non-zero if there was an error parsing SEQ. */ int -rl_translate_keyseq (seq, array, len) - const char *seq; - char *array; - int *len; +rl_translate_keyseq (const char *seq, char *array, int *len) { register int i, c, l, temp; @@ -483,7 +501,10 @@ rl_translate_keyseq (seq, array, len) c = seq[++i]; if (c == 0) - break; + { + array[l++] = '\\'; /* preserve trailing backslash */ + break; + } /* Handle \C- and \M- prefixes. */ if ((c == 'C' || c == 'M') && seq[i + 1] == '-') @@ -494,8 +515,6 @@ rl_translate_keyseq (seq, array, len) array[l++] = ESC; /* ESC is meta-prefix */ i += 5; array[l++] = CTRL (_rl_to_upper (seq[i])); - if (seq[i] == '\0') - i--; } else if (c == 'M') { @@ -524,6 +543,8 @@ rl_translate_keyseq (seq, array, len) /* Special hack for C-?... */ array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); } + if (seq[i] == '\0') + break; continue; } @@ -596,8 +617,7 @@ rl_translate_keyseq (seq, array, len) } static int -_rl_isescape (c) - int c; +_rl_isescape (int c) { switch (c) { @@ -613,8 +633,7 @@ _rl_isescape (c) } static int -_rl_escchar (c) - int c; +_rl_escchar (int c) { switch (c) { @@ -630,8 +649,7 @@ _rl_escchar (c) } char * -rl_untranslate_keyseq (seq) - int seq; +rl_untranslate_keyseq (int seq) { static char kseq[16]; int i, c; @@ -681,9 +699,7 @@ rl_untranslate_keyseq (seq) } char * -_rl_untranslate_macro_value (seq, use_escapes) - char *seq; - int use_escapes; +_rl_untranslate_macro_value (char *seq, int use_escapes) { char *ret, *r, *s; int c; @@ -742,8 +758,7 @@ _rl_untranslate_macro_value (seq, use_escapes) If STRING doesn't have a matching function, then a NULL pointer is returned. */ rl_command_func_t * -rl_named_function (string) - const char *string; +rl_named_function (const char *string) { register int i; @@ -760,18 +775,15 @@ rl_named_function (string) used. TYPE, if non-NULL, is a pointer to an int which will receive the type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), or ISMACR (macro). */ -rl_command_func_t * -rl_function_of_keyseq (keyseq, map, type) - const char *keyseq; - Keymap map; - int *type; +static rl_command_func_t * +_rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int *type) { register int i; if (map == 0) map = _rl_keymap; - for (i = 0; keyseq && keyseq[i]; i++) + for (i = 0; keyseq && i < len; i++) { unsigned char ic = keyseq[i]; @@ -823,6 +835,18 @@ rl_function_of_keyseq (keyseq, map, type) return ((rl_command_func_t *) NULL); } +rl_command_func_t * +rl_function_of_keyseq (const char *keyseq, Keymap map, int *type) +{ + return _rl_function_of_keyseq_internal (keyseq, strlen (keyseq), map, type); +} + +rl_command_func_t * +rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type) +{ + return _rl_function_of_keyseq_internal (keyseq, len, map, type); +} + /* The last key bindings file read. */ static char *last_readline_init_file = (char *)NULL; @@ -835,17 +859,20 @@ static int current_readline_init_lineno; The size of the buffer is returned in *SIZEP. Returns NULL if any errors were encountered. */ static char * -_rl_read_file (filename, sizep) - char *filename; - size_t *sizep; +_rl_read_file (char *filename, size_t *sizep) { struct stat finfo; size_t file_size; char *buffer; int i, file; - if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) - return ((char *)NULL); + file = -1; + if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0)) + { + if (file >= 0) + close (file); + return ((char *)NULL); + } file_size = (size_t)finfo.st_size; @@ -882,8 +909,7 @@ _rl_read_file (filename, sizep) /* Re-read the current keybindings file. */ int -rl_re_read_init_file (count, ignore) - int count, ignore; +rl_re_read_init_file (int count, int ignore) { int r; r = rl_read_init_file ((const char *)NULL); @@ -900,8 +926,7 @@ rl_re_read_init_file (count, ignore) If the file existed and could be opened and read, 0 is returned, otherwise errno is returned. */ int -rl_read_init_file (filename) - const char *filename; +rl_read_init_file (const char *filename) { /* Default the filename. */ if (filename == 0) @@ -926,9 +951,7 @@ rl_read_init_file (filename) } static int -_rl_read_init_file (filename, include_level) - const char *filename; - int include_level; +_rl_read_init_file (const char *filename, int include_level) { register int i; char *buffer, *openname, *line, *end; @@ -1027,6 +1050,62 @@ _rl_init_file_error (va_alist) /* **************************************************************** */ /* */ +/* Parser Helper Functions */ +/* */ +/* **************************************************************** */ + +static int +parse_comparison_op (s, indp) + const char *s; + int *indp; +{ + int i, peekc, op; + + if (OPSTART (s[*indp]) == 0) + return -1; + i = *indp; + peekc = s[i] ? s[i+1] : 0; + op = -1; + + if (s[i] == '=') + { + op = OP_EQ; + if (peekc == '=') + i++; + i++; + } + else if (s[i] == '!' && peekc == '=') + { + op = OP_NE; + i += 2; + } + else if (s[i] == '<' && peekc == '=') + { + op = OP_LE; + i += 2; + } + else if (s[i] == '>' && peekc == '=') + { + op = OP_GE; + i += 2; + } + else if (s[i] == '<') + { + op = OP_LT; + i += 1; + } + else if (s[i] == '>') + { + op = OP_GT; + i += 1; + } + + *indp = i; + return op; +} + +/* **************************************************************** */ +/* */ /* Parser Directives */ /* */ /* **************************************************************** */ @@ -1055,10 +1134,11 @@ static int if_stack_size; /* Push _rl_parsing_conditionalized_out, and set parser state based on ARGS. */ static int -parser_if (args) - char *args; +parser_if (char *args) { - register int i; + int i, llen, boolvar, strvar; + + boolvar = strvar = -1; /* Push parser state. */ if (if_stack_depth + 1 >= if_stack_size) @@ -1075,6 +1155,8 @@ parser_if (args) if (_rl_parsing_conditionalized_out) return 0; + llen = strlen (args); + /* Isolate first argument. */ for (i = 0; args[i] && !whitespace (args[i]); i++); @@ -1117,10 +1199,138 @@ parser_if (args) _rl_parsing_conditionalized_out = mode != rl_editing_mode; } #endif /* VI_MODE */ + else if (_rl_strnicmp (args, "version", 7) == 0) + { + int rlversion, versionarg, op, previ, major, minor; + + _rl_parsing_conditionalized_out = 1; + rlversion = RL_VERSION_MAJOR*10 + RL_VERSION_MINOR; + /* if "version" is separated from the operator by whitespace, or the + operand is separated from the operator by whitespace, restore it. + We're more liberal with allowed whitespace for this variable. */ + if (i > 0 && i <= llen && args[i-1] == '\0') + args[i-1] = ' '; + args[llen] = '\0'; /* just in case */ + for (i = 7; whitespace (args[i]); i++) + ; + if (OPSTART(args[i]) == 0) + { + _rl_init_file_error ("comparison operator expected, found `%s'", args[i] ? args + i : "end-of-line"); + return 0; + } + previ = i; + op = parse_comparison_op (args, &i); + if (op <= 0) + { + _rl_init_file_error ("comparison operator expected, found `%s'", args+previ); + return 0; + } + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] == 0 || _rl_digit_p (args[i]) == 0) + { + _rl_init_file_error ("numeric argument expected, found `%s'", args+i); + return 0; + } + major = minor = 0; + previ = i; + for ( ; args[i] && _rl_digit_p (args[i]); i++) + major = major*10 + _rl_digit_value (args[i]); + if (args[i] == '.') + { + if (args[i + 1] && _rl_digit_p (args [i + 1]) == 0) + { + _rl_init_file_error ("numeric argument expected, found `%s'", args+previ); + return 0; + } + for (++i; args[i] && _rl_digit_p (args[i]); i++) + minor = minor*10 + _rl_digit_value (args[i]); + } + /* optional - check for trailing garbage on the line, allow whitespace + and a trailing comment */ + previ = i; + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] && args[i] != '#') + { + _rl_init_file_error ("trailing garbage on line: `%s'", args+previ); + return 0; + } + versionarg = major*10 + minor; + + switch (op) + { + case OP_EQ: + _rl_parsing_conditionalized_out = rlversion == versionarg; + break; + case OP_NE: + _rl_parsing_conditionalized_out = rlversion != versionarg; + break; + case OP_GT: + _rl_parsing_conditionalized_out = rlversion > versionarg; + break; + case OP_GE: + _rl_parsing_conditionalized_out = rlversion >= versionarg; + break; + case OP_LT: + _rl_parsing_conditionalized_out = rlversion < versionarg; + break; + case OP_LE: + _rl_parsing_conditionalized_out = rlversion <= versionarg; + break; + } + } /* Check to see if the first word in ARGS is the same as the value stored in rl_readline_name. */ else if (_rl_stricmp (args, rl_readline_name) == 0) _rl_parsing_conditionalized_out = 0; + else if ((boolvar = find_boolean_var (args)) >= 0 || (strvar = find_string_var (args)) >= 0) + { + int op, previ; + size_t vlen; + const char *vname; + char *valuearg, *vval, prevc; + + _rl_parsing_conditionalized_out = 1; + vname = (boolvar >= 0) ? boolean_varname (boolvar) : string_varname (strvar); + vlen = strlen (vname); + if (i > 0 && i <= llen && args[i-1] == '\0') + args[i-1] = ' '; + args[llen] = '\0'; /* just in case */ + for (i = vlen; whitespace (args[i]); i++) + ; + if (CMPSTART(args[i]) == 0) + { + _rl_init_file_error ("equality comparison operator expected, found `%s'", args[i] ? args + i : "end-of-line"); + return 0; + } + previ = i; + op = parse_comparison_op (args, &i); + if (op != OP_EQ && op != OP_NE) + { + _rl_init_file_error ("equality comparison operator expected, found `%s'", args+previ); + return 0; + } + for ( ; args[i] && whitespace (args[i]); i++) + ; + if (args[i] == 0) + { + _rl_init_file_error ("argument expected, found `%s'", args+i); + return 0; + } + previ = i; + valuearg = args + i; + for ( ; args[i] && whitespace (args[i]) == 0; i++) + ; + prevc = args[i]; + args[i] = '\0'; /* null-terminate valuearg */ + vval = rl_variable_value (vname); + if (op == OP_EQ) + _rl_parsing_conditionalized_out = _rl_stricmp (vval, valuearg) != 0; + else if (op == OP_NE) + _rl_parsing_conditionalized_out = _rl_stricmp (vval, valuearg) == 0; + args[i] = prevc; + } else _rl_parsing_conditionalized_out = 1; return 0; @@ -1128,8 +1338,7 @@ parser_if (args) /* Invert the current parser state if there is anything on the stack. */ static int -parser_else (args) - char *args; +parser_else (char *args) { register int i; @@ -1159,8 +1368,7 @@ parser_else (args) /* Terminate a conditional, popping the value of _rl_parsing_conditionalized_out from the stack. */ static int -parser_endif (args) - char *args; +parser_endif (char *args) { if (if_stack_depth) _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; @@ -1170,8 +1378,7 @@ parser_endif (args) } static int -parser_include (args) - char *args; +parser_include (char *args) { const char *old_init_file; char *e; @@ -1211,8 +1418,7 @@ static const struct { /* Handle a parser directive. STATEMENT is the line of the directive without any leading `$'. */ static int -handle_parser_directive (statement) - char *statement; +handle_parser_directive (char *statement) { register int i; char *directive, *args; @@ -1249,9 +1455,7 @@ handle_parser_directive (statement) /* Start at STRING[START] and look for DELIM. Return I where STRING[I] == DELIM or STRING[I] == 0. DELIM is usually a double quote. */ static int -_rl_skip_to_delim (string, start, delim) - char *string; - int start, delim; +_rl_skip_to_delim (char *string, int start, int delim) { int i, c, passc; @@ -1283,8 +1487,7 @@ _rl_skip_to_delim (string, start, delim) a variable binding command looks like: set variable value. A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ int -rl_parse_and_bind (string) - char *string; +rl_parse_and_bind (char *string) { char *funname, *kname; register int c, i; @@ -1328,6 +1531,12 @@ rl_parse_and_bind (string) /* Advance to the colon (:) or whitespace which separates the two objects. */ for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); + if (i == 0) + { + _rl_init_file_error ("`%s': invalid key binding: missing key sequence", string); + return 1; + } + equivalency = (c == ':' && string[i + 1] == '='); foundsep = c != 0; @@ -1406,6 +1615,11 @@ remove_trailing: i = _rl_skip_to_delim (string, i+1, *funname); if (string[i]) i++; + else + { + _rl_init_file_error ("`%s': missing closing quote for macro", funname); + return 1; + } } /* Advance to the end of the string. */ @@ -1583,8 +1797,7 @@ static const struct { }; static int -find_boolean_var (name) - const char *name; +find_boolean_var (const char *name) { register int i; @@ -1594,12 +1807,17 @@ find_boolean_var (name) return -1; } +static const char * +boolean_varname (int i) +{ + return ((i >= 0) ? boolean_varlist[i].name : (char *)NULL); +} + /* Hooks for handling special boolean variables, where a function needs to be called or another variable needs to be changed when they're changed. */ static void -hack_special_boolean_var (i) - int i; +hack_special_boolean_var (int i) { const char *name; @@ -1668,8 +1886,7 @@ static const struct { }; static int -find_string_var (name) - const char *name; +find_string_var (const char *name) { register int i; @@ -1679,12 +1896,17 @@ find_string_var (name) return -1; } +static const char * +string_varname (int i) +{ + return ((i >= 0) ? string_varlist[i].name : (char *)NULL); +} + /* A boolean value that can appear in a `set variable' command is true if the value is null or empty, `on' (case-insensitive), or "1". Any other values result in 0 (false). */ static int -bool_to_int (value) - const char *value; +bool_to_int (const char *value) { return (value == 0 || *value == '\0' || (_rl_stricmp (value, "on") == 0) || @@ -1692,8 +1914,7 @@ bool_to_int (value) } char * -rl_variable_value (name) - const char *name; +rl_variable_value (const char *name) { register int i; @@ -1711,8 +1932,7 @@ rl_variable_value (name) } int -rl_variable_bind (name, value) - const char *name, *value; +rl_variable_bind (const char *name, const char *value) { register int i; int v; @@ -1743,8 +1963,7 @@ rl_variable_bind (name, value) } static int -sv_editmode (value) - const char *value; +sv_editmode (const char *value) { if (_rl_strnicmp (value, "vi", 2) == 0) { @@ -1764,8 +1983,7 @@ sv_editmode (value) } static int -sv_combegin (value) - const char *value; +sv_combegin (const char *value) { if (value && *value) { @@ -1777,8 +1995,7 @@ sv_combegin (value) } static int -sv_dispprefix (value) - const char *value; +sv_dispprefix (const char *value) { int nval = 0; @@ -1793,8 +2010,7 @@ sv_dispprefix (value) } static int -sv_compquery (value) - const char *value; +sv_compquery (const char *value) { int nval = 100; @@ -1809,8 +2025,7 @@ sv_compquery (value) } static int -sv_compwidth (value) - const char *value; +sv_compwidth (const char *value) { int nval = -1; @@ -1822,8 +2037,7 @@ sv_compwidth (value) } static int -sv_histsize (value) - const char *value; +sv_histsize (const char *value) { int nval; @@ -1842,8 +2056,7 @@ sv_histsize (value) } static int -sv_keymap (value) - const char *value; +sv_keymap (const char *value) { Keymap kmap; @@ -1857,8 +2070,7 @@ sv_keymap (value) } static int -sv_seqtimeout (value) - const char *value; +sv_seqtimeout (const char *value) { int nval; @@ -1874,8 +2086,7 @@ sv_seqtimeout (value) } static int -sv_bell_style (value) - const char *value; +sv_bell_style (const char *value) { if (value == 0 || *value == '\0') _rl_bell_preference = AUDIBLE_BELL; @@ -1891,8 +2102,7 @@ sv_bell_style (value) } static int -sv_isrchterm (value) - const char *value; +sv_isrchterm (const char *value) { int beg, end, delim; char *v; @@ -1929,8 +2139,7 @@ sv_isrchterm (value) extern char *_rl_emacs_mode_str; static int -sv_emacs_modestr (value) - const char *value; +sv_emacs_modestr (const char *value) { if (value && *value) { @@ -1958,8 +2167,7 @@ sv_emacs_modestr (value) } static int -sv_viins_modestr (value) - const char *value; +sv_viins_modestr (const char *value) { if (value && *value) { @@ -1987,8 +2195,7 @@ sv_viins_modestr (value) } static int -sv_vicmd_modestr (value) - const char *value; +sv_vicmd_modestr (const char *value) { if (value && *value) { @@ -2039,8 +2246,7 @@ static const assoc_list name_key_alist[] = { }; static int -glean_key_from_name (name) - char *name; +glean_key_from_name (char *name) { register int i; @@ -2052,10 +2258,12 @@ glean_key_from_name (name) } /* Auxiliary functions to manage keymaps. */ -static const struct { - const char * const name; +struct name_and_keymap { + char *name; Keymap map; -} keymap_names[] = { +}; + +static struct name_and_keymap builtin_keymap_names[] = { { "emacs", emacs_standard_keymap }, { "emacs-standard", emacs_standard_keymap }, { "emacs-meta", emacs_meta_keymap }, @@ -2069,45 +2277,116 @@ static const struct { { (char *)0x0, (Keymap)0x0 } }; -Keymap -rl_get_keymap_by_name (name) - const char *name; +/* -1 for NULL entry */ +#define NUM_BUILTIN_KEYMAPS (sizeof (builtin_keymap_names) / sizeof (builtin_keymap_names[0]) - 1) + +static struct name_and_keymap *keymap_names = builtin_keymap_names; + +static int +_rl_get_keymap_by_name (const char *name) { register int i; for (i = 0; keymap_names[i].name; i++) if (_rl_stricmp (name, keymap_names[i].name) == 0) - return (keymap_names[i].map); - return ((Keymap) NULL); + return (i); + return -1; } -char * -rl_get_keymap_name (map) - Keymap map; +Keymap +rl_get_keymap_by_name (const char *name) +{ + int i; + + i = _rl_get_keymap_by_name (name); + return ((i >= 0) ? keymap_names[i].map : (Keymap) NULL); +} + +static int +_rl_get_keymap_by_map (Keymap map) { register int i; + for (i = 0; keymap_names[i].name; i++) if (map == keymap_names[i].map) - return ((char *)keymap_names[i].name); - return ((char *)NULL); + return (i); + return -1; } - + +char * +rl_get_keymap_name (Keymap map) +{ + int i; + + i = _rl_get_keymap_by_map (map); + return ((i >= 0) ? keymap_names[i].name : (char *)NULL); +} + +int +rl_set_keymap_name (const char *name, Keymap map) +{ + int i, ni, mi; + + /* First check whether or not we're trying to rename a builtin keymap */ + mi = _rl_get_keymap_by_map (map); + if (mi >= 0 && mi < NUM_BUILTIN_KEYMAPS) + return -1; + + /* Then reject attempts to set one of the builtin names to a new map */ + ni = _rl_get_keymap_by_name (name); + if (ni >= 0 && ni < NUM_BUILTIN_KEYMAPS) + return -1; + + /* Renaming a keymap we already added */ + if (mi >= 0) /* XXX - could be >= NUM_BUILTIN_KEYMAPS */ + { + xfree (keymap_names[mi].name); + keymap_names[mi].name = savestring (name); + return mi; + } + + /* Associating new keymap with existing name */ + if (ni >= 0) + { + keymap_names[ni].map = map; + return ni; + } + + for (i = 0; keymap_names[i].name; i++) + ; + + if (keymap_names == builtin_keymap_names) + { + keymap_names = xmalloc ((i + 2) * sizeof (struct name_and_keymap)); + memcpy (keymap_names, builtin_keymap_names, i * sizeof (struct name_and_keymap)); + } + else + keymap_names = xrealloc (keymap_names, (i + 2) * sizeof (struct name_and_keymap)); + + keymap_names[i].name = savestring (name); + keymap_names[i].map = map; + + keymap_names[i+1].name = NULL; + keymap_names[i+1].map = NULL; + + return i; +} + void -rl_set_keymap (map) - Keymap map; +rl_set_keymap (Keymap map) { if (map) _rl_keymap = map; } Keymap -rl_get_keymap () +rl_get_keymap (void) { return (_rl_keymap); } void -rl_set_keymap_from_edit_mode () +rl_set_keymap_from_edit_mode (void) { if (rl_editing_mode == emacs_mode) _rl_keymap = emacs_standard_keymap; @@ -2118,7 +2397,7 @@ rl_set_keymap_from_edit_mode () } char * -rl_get_keymap_name_from_edit_mode () +rl_get_keymap_name_from_edit_mode (void) { if (rl_editing_mode == emacs_mode) return "emacs"; @@ -2143,7 +2422,7 @@ rl_get_keymap_name_from_edit_mode () /* Print the names of functions known to Readline. */ void -rl_list_funmap_names () +rl_list_funmap_names (void) { register int i; const char **funmap_names; @@ -2160,8 +2439,7 @@ rl_list_funmap_names () } static char * -_rl_get_keyname (key) - int key; +_rl_get_keyname (int key) { char *keyname; int i, c; @@ -2236,9 +2514,7 @@ _rl_get_keyname (key) /* Return a NULL terminated array of strings which represent the key sequences that are used to invoke FUNCTION in MAP. */ char ** -rl_invoking_keyseqs_in_map (function, map) - rl_command_func_t *function; - Keymap map; +rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map) { register int key; char **result; @@ -2345,8 +2621,7 @@ rl_invoking_keyseqs_in_map (function, map) /* Return a NULL terminated array of strings which represent the key sequences that can be used to invoke FUNCTION using the current keymap. */ char ** -rl_invoking_keyseqs (function) - rl_command_func_t *function; +rl_invoking_keyseqs (rl_command_func_t *function) { return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); } @@ -2355,8 +2630,7 @@ rl_invoking_keyseqs (function) PRINT_READABLY is non-zero, then print the output in such a way that it can be read back in. */ void -rl_function_dumper (print_readably) - int print_readably; +rl_function_dumper (int print_readably) { register int i; const char **names; @@ -2427,8 +2701,7 @@ rl_function_dumper (print_readably) rl_outstream. If an explicit argument is given, then print the output in such a way that it can be read back in. */ int -rl_dump_functions (count, key) - int count, key; +rl_dump_functions (int count, int key) { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); @@ -2438,10 +2711,7 @@ rl_dump_functions (count, key) } static void -_rl_macro_dumper_internal (print_readably, map, prefix) - int print_readably; - Keymap map; - char *prefix; +_rl_macro_dumper_internal (int print_readably, Keymap map, char *prefix) { register int key; char *keyname, *out; @@ -2500,15 +2770,13 @@ _rl_macro_dumper_internal (print_readably, map, prefix) } void -rl_macro_dumper (print_readably) - int print_readably; +rl_macro_dumper (int print_readably) { _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); } int -rl_dump_macros (count, key) - int count, key; +rl_dump_macros (int count, int key) { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); @@ -2518,8 +2786,7 @@ rl_dump_macros (count, key) } static char * -_rl_get_string_variable_value (name) - const char *name; +_rl_get_string_variable_value (const char *name) { static char numbuf[32]; char *ret; @@ -2599,8 +2866,7 @@ _rl_get_string_variable_value (name) } void -rl_variable_dumper (print_readably) - int print_readably; +rl_variable_dumper (int print_readably) { int i; char *v; @@ -2631,8 +2897,7 @@ rl_variable_dumper (print_readably) rl_outstream. If an explicit argument is given, then print the output in such a way that it can be read back in. */ int -rl_dump_variables (count, key) - int count, key; +rl_dump_variables (int count, int key) { if (rl_dispatching) fprintf (rl_outstream, "\r\n"); @@ -2643,9 +2908,7 @@ rl_dump_variables (count, key) /* Return non-zero if any members of ARRAY are a substring in STRING. */ static int -substring_member_of_array (string, array) - const char *string; - const char * const *array; +substring_member_of_array (const char *string, const char * const *array) { while (*array) { diff --git a/readline/callback.c b/readline/callback.c index cc3ce11..a466cf9 100644 --- a/readline/callback.c +++ b/readline/callback.c @@ -1,6 +1,6 @@ /* callback.c -- functions to use readline as an X `callback' mechanism. */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -60,7 +60,7 @@ int rl_persistent_signal_handlers = 0; /* **************************************************************** */ /* */ -/* Callback Readline Functions */ +/* Callback Readline Functions */ /* */ /* **************************************************************** */ @@ -80,7 +80,7 @@ static int in_handler; /* terminal_prepped and signals set? */ /* Make sure the terminal is set up, initialize readline, and prompt. */ static void -_rl_callback_newline () +_rl_callback_newline (void) { rl_initialize (); @@ -103,9 +103,7 @@ _rl_callback_newline () /* Install a readline handler, set up the terminal, and issue the prompt. */ void -rl_callback_handler_install (prompt, linefunc) - const char *prompt; - rl_vcpfunc_t *linefunc; +rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc) { rl_set_prompt (prompt); RL_SETSTATE (RL_STATE_CALLBACK); @@ -126,7 +124,7 @@ rl_callback_handler_install (prompt, linefunc) /* Read one character, and dispatch to the handler if it ends the line. */ void -rl_callback_read_char () +rl_callback_read_char (void) { char *line; int eof, jcode; @@ -299,7 +297,7 @@ rl_callback_read_char () /* Remove the handler, and make sure the terminal is in its normal state. */ void -rl_callback_handler_remove () +rl_callback_handler_remove (void) { rl_linefunc = NULL; RL_UNSETSTATE (RL_STATE_CALLBACK); @@ -316,8 +314,7 @@ rl_callback_handler_remove () } _rl_callback_generic_arg * -_rl_callback_data_alloc (count) - int count; +_rl_callback_data_alloc (int count) { _rl_callback_generic_arg *arg; @@ -330,15 +327,14 @@ _rl_callback_data_alloc (count) } void -_rl_callback_data_dispose (arg) - _rl_callback_generic_arg *arg; +_rl_callback_data_dispose (_rl_callback_generic_arg *arg) { xfree (arg); } /* Make sure that this agrees with cases in rl_callback_read_char */ void -rl_callback_sigcleanup () +rl_callback_sigcleanup (void) { if (RL_ISSTATE (RL_STATE_CALLBACK) == 0) return; diff --git a/readline/colors.c b/readline/colors.c index 7859f5d..53758e0 100644 --- a/readline/colors.c +++ b/readline/colors.c @@ -2,7 +2,7 @@ Modified by Chet Ramey for Readline. - Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015 + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -37,6 +37,10 @@ #include "posixstat.h" // stat related macros (S_ISREG, ...) #include <fcntl.h> // S_ISUID +#ifndef S_ISDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + // strlen() #if defined (HAVE_STRING_H) # include <string.h> @@ -66,7 +70,8 @@ COLOR_EXT_TYPE *_rl_color_ext_list = 0; /* Output a color indicator (which may contain nulls). */ void -_rl_put_indicator (const struct bin_str *ind) { +_rl_put_indicator (const struct bin_str *ind) +{ fwrite (ind->string, ind->len, 1, rl_outstream); } @@ -183,11 +188,17 @@ _rl_print_color_indicator (const char *f) { colored_filetype = C_FILE; +#if defined (S_ISUID) if ((mode & S_ISUID) != 0 && is_colored (C_SETUID)) colored_filetype = C_SETUID; - else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) + else +#endif +#if defined (S_ISGID) + if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) colored_filetype = C_SETGID; - else if (is_colored (C_CAP) && 0) //f->has_capability) + else +#endif + if (is_colored (C_CAP) && 0) //f->has_capability) colored_filetype = C_CAP; else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC)) colored_filetype = C_EXEC; @@ -211,12 +222,16 @@ _rl_print_color_indicator (const char *f) colored_filetype = C_STICKY; #endif } +#if defined (S_ISLNK) else if (S_ISLNK (mode)) colored_filetype = C_LINK; +#endif else if (S_ISFIFO (mode)) colored_filetype = C_FIFO; +#if defined (S_ISSOCK) else if (S_ISSOCK (mode)) colored_filetype = C_SOCK; +#endif else if (S_ISBLK (mode)) colored_filetype = C_BLK; else if (S_ISCHR (mode)) diff --git a/readline/compat.c b/readline/compat.c index 2af5120..3ade362 100644 --- a/readline/compat.c +++ b/readline/compat.c @@ -1,6 +1,6 @@ /* compat.c -- backwards compatibility functions. */ -/* Copyright (C) 2000-2009 Free Software Foundation, Inc. +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -46,68 +46,61 @@ extern char *rl_filename_completion_function PARAMS((const char *, int)); /* Provide backwards-compatible entry points for old function names. */ void -free_undo_list () +free_undo_list (void) { rl_free_undo_list (); } int -maybe_replace_line () +maybe_replace_line (void) { return rl_maybe_replace_line (); } int -maybe_save_line () +maybe_save_line (void) { return rl_maybe_save_line (); } int -maybe_unsave_line () +maybe_unsave_line (void) { return rl_maybe_unsave_line (); } int -ding () +ding (void) { return rl_ding (); } int -crlf () +crlf (void) { return rl_crlf (); } int -alphabetic (c) - int c; +alphabetic (int c) { return rl_alphabetic (c); } char ** -completion_matches (s, f) - const char *s; - rl_compentry_func_t *f; +completion_matches (const char *s, rl_compentry_func_t *f) { return rl_completion_matches (s, f); } char * -username_completion_function (s, i) - const char *s; - int i; +username_completion_function (const char *s, int i) { return rl_username_completion_function (s, i); } char * -filename_completion_function (s, i) - const char *s; - int i; +filename_completion_function (const char *s, int i) { return rl_filename_completion_function (s, i); } diff --git a/readline/complete.c b/readline/complete.c index 0a81129..adce0d6 100644 --- a/readline/complete.c +++ b/readline/complete.c @@ -1,6 +1,6 @@ /* complete.c -- filename completion for readline. */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -198,15 +198,6 @@ int _rl_completion_prefix_display_length = 0; matches. If < 0 or > _rl_screenwidth, it is ignored. */ int _rl_completion_columns = -1; -/* Global variables available to applications using readline. */ - -#if defined (VISIBLE_STATS) -/* Non-zero means add an additional character to each filename displayed - during listing completion iff rl_filename_completion_desired which helps - to indicate the type of file being listed. */ -int rl_visible_stats = 0; -#endif /* VISIBLE_STATS */ - #if defined (COLOR_SUPPORT) /* Non-zero means to use colors to indicate file type when listing possible completions. The colors used are taken from $LS_COLORS, if set. */ @@ -227,6 +218,15 @@ int _rl_skip_completed_text = 0; cycle of possible completions instead of the last. */ int _rl_menu_complete_prefix_first = 0; +/* Global variables available to applications using readline. */ + +#if defined (VISIBLE_STATS) +/* Non-zero means add an additional character to each filename displayed + during listing completion iff rl_filename_completion_desired which helps + to indicate the type of file being listed. */ +int rl_visible_stats = 0; +#endif /* VISIBLE_STATS */ + /* If non-zero, then this is the address of a function to call when completing on a directory name. The function is called with the address of a string (the current directory name) as an arg. */ @@ -422,8 +422,7 @@ static int _rl_complete_display_matches_interrupt = 0; that does the initial simple matching selection algorithm (see rl_completion_matches ()). The default is to do filename completion. */ int -rl_complete (ignore, invoking_key) - int ignore, invoking_key; +rl_complete (int ignore, int invoking_key) { rl_completion_invoking_key = invoking_key; @@ -441,16 +440,14 @@ rl_complete (ignore, invoking_key) /* List the possible completions. See description of rl_complete (). */ int -rl_possible_completions (ignore, invoking_key) - int ignore, invoking_key; +rl_possible_completions (int ignore, int invoking_key) { rl_completion_invoking_key = invoking_key; return (rl_complete_internal ('?')); } int -rl_insert_completions (ignore, invoking_key) - int ignore, invoking_key; +rl_insert_completions (int ignore, int invoking_key) { rl_completion_invoking_key = invoking_key; return (rl_complete_internal ('*')); @@ -462,8 +459,7 @@ rl_insert_completions (ignore, invoking_key) an application-specific completion function to honor the show-all-if-ambiguous readline variable. */ int -rl_completion_mode (cfunc) - rl_command_func_t *cfunc; +rl_completion_mode (rl_command_func_t *cfunc) { if (rl_last_func == cfunc && !completion_changed_buffer) return '?'; @@ -483,16 +479,14 @@ rl_completion_mode (cfunc) /* Reset readline state on a signal or other event. */ void -_rl_reset_completion_state () +_rl_reset_completion_state (void) { rl_completion_found_quote = 0; rl_completion_quote_character = 0; } static void -_rl_complete_sigcleanup (sig, ptr) - int sig; - void *ptr; +_rl_complete_sigcleanup (int sig, void *ptr) { if (sig == SIGINT) /* XXX - for now */ { @@ -504,8 +498,7 @@ _rl_complete_sigcleanup (sig, ptr) /* Set default values for readline word completion. These are the variables that application completion functions can change or inspect. */ static void -set_completion_defaults (what_to_do) - int what_to_do; +set_completion_defaults (int what_to_do) { /* Only the completion entry function can change these. */ rl_filename_completion_desired = 0; @@ -523,8 +516,7 @@ set_completion_defaults (what_to_do) /* The user must press "y" or "n". Non-zero return means "y" pressed. */ static int -get_y_or_n (for_pager) - int for_pager; +get_y_or_n (int for_pager) { int c; @@ -557,8 +549,7 @@ get_y_or_n (for_pager) } static int -_rl_internal_pager (lines) - int lines; +_rl_internal_pager (int lines) { int i; @@ -575,8 +566,7 @@ _rl_internal_pager (lines) } static int -path_isdir (filename) - const char *filename; +path_isdir (const char *filename) { struct stat finfo; @@ -593,8 +583,7 @@ path_isdir (filename) `%' for character special devices `#' for block special devices */ static int -stat_char (filename) - char *filename; +stat_char (char *filename) { struct stat finfo; int character, r; @@ -625,7 +614,10 @@ stat_char (filename) #endif if (r == -1) - return (0); + { + xfree (f); + return (0); + } character = 0; if (S_ISDIR (finfo.st_mode)) @@ -675,29 +667,28 @@ stat_char (filename) #if defined (COLOR_SUPPORT) static int -colored_stat_start (filename) - const char *filename; +colored_stat_start (const char *filename) { _rl_set_normal_color (); return (_rl_print_color_indicator (filename)); } static void -colored_stat_end () +colored_stat_end (void) { _rl_prep_non_filename_text (); _rl_put_indicator (&_rl_color_indicator[C_CLR_TO_EOL]); } static int -colored_prefix_start () +colored_prefix_start (void) { _rl_set_normal_color (); return (_rl_print_prefix_color ()); } static void -colored_prefix_end () +colored_prefix_end (void) { colored_stat_end (); /* for now */ } @@ -712,8 +703,7 @@ colored_prefix_end () for the previous slash and return the portion following that. If there's no previous slash, we just return what we were passed. */ static char * -printable_part (pathname) - char *pathname; +printable_part (char *pathname) { char *temp, *x; @@ -747,8 +737,7 @@ printable_part (pathname) /* Compute width of STRING when displayed on screen by print_filename */ static int -fnwidth (string) - const char *string; +fnwidth (const char *string) { int width, pos; #if defined (HANDLE_MULTIBYTE) @@ -800,10 +789,7 @@ fnwidth (string) #define ELLIPSIS_LEN 3 static int -fnprint (to_print, prefix_bytes, real_pathname) - const char *to_print; - int prefix_bytes; - const char *real_pathname; +fnprint (const char *to_print, int prefix_bytes, const char *real_pathname) { int printed_len, w; const char *s; @@ -818,6 +804,8 @@ fnprint (to_print, prefix_bytes, real_pathname) print_len = strlen (to_print); end = to_print + print_len + 1; memset (&ps, 0, sizeof (mbstate_t)); +#else + print_len = strlen (to_print); #endif printed_len = common_prefix_len = 0; @@ -929,9 +917,7 @@ fnprint (to_print, prefix_bytes, real_pathname) filenames. Return the number of characters we output. */ static int -print_filename (to_print, full_pathname, prefix_bytes) - char *to_print, *full_pathname; - int prefix_bytes; +print_filename (char *to_print, char *full_pathname, int prefix_bytes) { int printed_len, extension_char, slen, tlen; char *s, c, *new_full_pathname, *dn; @@ -988,7 +974,6 @@ print_filename (to_print, full_pathname, prefix_bytes) slen--; else new_full_pathname[slen] = '/'; - new_full_pathname[slen] = '/'; strcpy (new_full_pathname + slen + 1, to_print); #if defined (VISIBLE_STATS) @@ -1049,10 +1034,7 @@ print_filename (to_print, full_pathname, prefix_bytes) } static char * -rl_quote_filename (s, rtype, qcp) - char *s; - int rtype; - char *qcp; +rl_quote_filename (char *s, int rtype, char *qcp) { char *r; @@ -1080,8 +1062,7 @@ rl_quote_filename (s, rtype, qcp) the value of the delimiter character that caused a word break. */ char -_rl_find_completion_word (fp, dp) - int *fp, *dp; +_rl_find_completion_word (int *fp, int *dp) { int scan, end, found_quote, delimiter, pass_next, isbrk; char quote_char, *brkchars; @@ -1213,11 +1194,7 @@ _rl_find_completion_word (fp, dp) } static char ** -gen_completion_matches (text, start, end, our_func, found_quote, quote_char) - char *text; - int start, end; - rl_compentry_func_t *our_func; - int found_quote, quote_char; +gen_completion_matches (char *text, int start, int end, rl_compentry_func_t *our_func, int found_quote, int quote_char) { char **matches; @@ -1261,8 +1238,7 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) /* Filter out duplicates in MATCHES. This frees up the strings in MATCHES. */ static char ** -remove_duplicate_matches (matches) - char **matches; +remove_duplicate_matches (char **matches) { char *lowest_common; int i, j, newlen; @@ -1322,10 +1298,7 @@ remove_duplicate_matches (matches) /* Find the common prefix of the list of matches, and put it into matches[0]. */ static int -compute_lcd_of_matches (match_list, matches, text) - char **match_list; - int matches; - const char *text; +compute_lcd_of_matches (char **match_list, int matches, const char *text) { register int i, c1, c2, si; int low; /* Count of max-matched characters. */ @@ -1451,7 +1424,8 @@ compute_lcd_of_matches (match_list, matches, text) } /* sort the list to get consistent answers. */ - qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); + if (rl_sort_completion_matches) + qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); si = strlen (text); lx = (si <= low) ? si : low; /* check shorter of text and matches */ @@ -1481,9 +1455,7 @@ compute_lcd_of_matches (match_list, matches, text) } static int -postprocess_matches (matchesp, matching_filenames) - char ***matchesp; - int matching_filenames; +postprocess_matches (char ***matchesp, int matching_filenames) { char *t, **matches, **temp_matches; int nmatch, i; @@ -1537,7 +1509,7 @@ postprocess_matches (matchesp, matching_filenames) } static int -complete_get_screenwidth () +complete_get_screenwidth (void) { int cols; char *envcols; @@ -1558,9 +1530,7 @@ complete_get_screenwidth () of strings, in argv format, LEN is the number of strings in MATCHES, and MAX is the length of the longest string in MATCHES. */ void -rl_display_match_list (matches, len, max) - char **matches; - int len, max; +rl_display_match_list (char **matches, int len, int max) { int count, limit, printed_len, lines, cols; int i, j, k, l, common_length, sind; @@ -1717,8 +1687,7 @@ rl_display_match_list (matches, len, max) and ask the user if he wants to see the list if there are more matches than RL_COMPLETION_QUERY_ITEMS. */ static void -display_matches (matches) - char **matches; +display_matches (char **matches) { int len, max, i; char *temp; @@ -1784,11 +1753,9 @@ display_matches (matches) rl_display_fixed = 1; } +/* qc == pointer to quoting character, if any */ static char * -make_quoted_replacement (match, mtype, qc) - char *match; - int mtype; - char *qc; /* Pointer to quoting character, if any */ +make_quoted_replacement (char *match, int mtype, char *qc) { int should_quote, do_replace; char *replacement; @@ -1830,10 +1797,7 @@ make_quoted_replacement (match, mtype, qc) } static void -insert_match (match, start, mtype, qc) - char *match; - int start, mtype; - char *qc; +insert_match (char *match, int start, int mtype, char *qc) { char *replacement, *r; char oqc; @@ -1890,9 +1854,7 @@ insert_match (match, start, mtype, qc) value of _rl_complete_mark_symlink_dirs, but may be modified by an application's completion function). */ static int -append_to_match (text, delimiter, quote_char, nontrivial_match) - char *text; - int delimiter, quote_char, nontrivial_match; +append_to_match (char *text, int delimiter, int quote_char, int nontrivial_match) { char temp_string[4], *filename, *fn; int temp_string_index, s; @@ -1959,10 +1921,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) } static void -insert_all_matches (matches, point, qc) - char **matches; - int point; - char *qc; +insert_all_matches (char **matches, int point, char *qc) { int i; char *rp; @@ -1998,8 +1957,7 @@ insert_all_matches (matches, point, qc) } void -_rl_free_match_list (matches) - char **matches; +_rl_free_match_list (char **matches) { register int i; @@ -2021,17 +1979,14 @@ _rl_free_match_list (matches) `@' means to do standard completion, and list all possible completions if there is more than one and partial completion is not possible. */ int -rl_complete_internal (what_to_do) - int what_to_do; +rl_complete_internal (int what_to_do) { char **matches; rl_compentry_func_t *our_func; int start, end, delimiter, found_quote, i, nontrivial_lcd; char *text, *saved_line_buffer; char quote_char; -#if 1 int tlen, mlen; -#endif RL_SETSTATE(RL_STATE_COMPLETING); @@ -2206,9 +2161,7 @@ rl_complete_internal (what_to_do) when there are no more matches. */ char ** -rl_completion_matches (text, entry_function) - const char *text; - rl_compentry_func_t *entry_function; +rl_completion_matches (const char *text, rl_compentry_func_t *entry_function) { register int i; @@ -2276,9 +2229,7 @@ rl_completion_matches (text, entry_function) TEXT contains a partial username preceded by a random character (usually `~'). */ char * -rl_username_completion_function (text, state) - const char *text; - int state; +rl_username_completion_function (const char *text, int state) { #if defined (__WIN32__) || defined (__OPENNT) return (char *)NULL; @@ -2340,11 +2291,7 @@ rl_username_completion_function (text, state) _rl_completion_case_map is set, make `-' and `_' equivalent. CONVFN is the possibly-converted directory entry; FILENAME is what the user typed. */ static int -complete_fncmp (convfn, convlen, filename, filename_len) - const char *convfn; - int convlen; - const char *filename; - int filename_len; +complete_fncmp (const char *convfn, int convlen, const char *filename, int filename_len) { register char *s1, *s2; int d, len; @@ -2472,9 +2419,7 @@ complete_fncmp (convfn, convlen, filename, filename_len) because of all the pathnames that must be followed when looking up the completion for a command. */ char * -rl_filename_completion_function (text, state) - const char *text; - int state; +rl_filename_completion_function (const char *text, int state) { static DIR *directory = (DIR *)NULL; static char *filename = (char *)NULL; @@ -2702,8 +2647,7 @@ rl_filename_completion_function (text, state) hit the end of the match list, we restore the original unmatched text, ring the bell, and reset the counter to zero. */ int -rl_old_menu_complete (count, invoking_key) - int count, invoking_key; +rl_old_menu_complete (int count, int invoking_key) { rl_compentry_func_t *our_func; int matching_filenames, found_quote; @@ -2824,9 +2768,17 @@ rl_old_menu_complete (count, invoking_key) return (0); } +/* The current version of menu completion. + The differences between this function and the original are: + +1. It honors the maximum number of completions variable (completion-query-items) +2. It appends to the word as usual if there is only one match +3. It displays the common prefix if there is one, and makes it the first menu + choice if the menu-complete-display-prefix option is enabled +*/ + int -rl_menu_complete (count, ignore) - int count, ignore; +rl_menu_complete (int count, int ignore) { rl_compentry_func_t *our_func; int matching_filenames, found_quote; @@ -2998,8 +2950,7 @@ rl_menu_complete (count, ignore) } int -rl_backward_menu_complete (count, key) - int count, key; +rl_backward_menu_complete (int count, int key) { /* Positive arguments to backward-menu-complete translate into negative arguments for menu-complete, and vice versa. */ diff --git a/readline/config.h.in b/readline/config.h.in index d03ebe0..6de47b5 100644 --- a/readline/config.h.in +++ b/readline/config.h.in @@ -46,6 +46,9 @@ /* Define if you have the fcntl function. */ #undef HAVE_FCNTL +/* Define if you have the fnmatch function. */ +#undef HAVE_FNMATCH + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT diff --git a/readline/configure b/readline/configure index 3054c47..0e2d333 100755 --- a/readline/configure +++ b/readline/configure @@ -1,7 +1,7 @@ #! /bin/sh -# From configure.ac for Readline 7.0, version 2.81. +# From configure.ac for Readline 8.0, version 2.85. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for readline 7.0. +# Generated by GNU Autoconf 2.69 for readline 8.0. # # Report bugs to <bug-readline@gnu.org>. # @@ -581,8 +581,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='readline' PACKAGE_TARNAME='readline' -PACKAGE_VERSION='7.0' -PACKAGE_STRING='readline 7.0' +PACKAGE_VERSION='8.0' +PACKAGE_STRING='readline 8.0' PACKAGE_BUGREPORT='bug-readline@gnu.org' PACKAGE_URL='' @@ -624,6 +624,7 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +TERMCAP_PKG_CONFIG_LIB TERMCAP_LIB LIBVERSION ARFLAGS @@ -631,6 +632,7 @@ LOCAL_DEFS LOCAL_LDFLAGS LOCAL_CFLAGS BUILD_DIR +EXAMPLES_INSTALL_TARGET SHARED_INSTALL_TARGET STATIC_INSTALL_TARGET SHARED_TARGET @@ -723,6 +725,7 @@ enable_option_checking with_curses enable_multibyte enable_static +enable_install_examples enable_largefile ' ac_precious_vars='build_alias @@ -1274,7 +1277,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures readline 7.0 to adapt to many kinds of systems. +\`configure' configures readline 8.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1339,7 +1342,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of readline 7.0:";; + short | recursive ) echo "Configuration of readline 8.0:";; esac cat <<\_ACEOF @@ -1349,6 +1352,8 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-multibyte enable multibyte characters if OS supports them --enable-static build static libraries [[default=YES]] + --disable-install-examples + don't install examples [[default=install]] --disable-largefile omit support for large files Optional Packages: @@ -1433,7 +1438,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -readline configure 7.0 +readline configure 8.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1898,11 +1903,194 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by readline $as_me 7.0, which was +It was created by readline $as_me 8.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2289,7 +2477,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers config.h" -LIBVERSION=7.0 +LIBVERSION=8.0 # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || @@ -2380,6 +2568,7 @@ fi opt_multibyte=yes opt_static_libs=yes opt_shared_libs=no +opt_install_examples=no # Check whether --enable-multibyte was given. if test "${enable_multibyte+set}" = set; then : @@ -2391,6 +2580,11 @@ if test "${enable_static+set}" = set; then : enableval=$enable_static; opt_static_libs=$enableval fi +# Check whether --enable-install-examples was given. +if test "${enable_install_examples+set}" = set; then : + enableval=$enable_install_examples; opt_install_examples=$enableval +fi + if test $opt_multibyte = no; then $as_echo "#define NO_MULTIBYTE_SUPPORT 1" >>confdefs.h @@ -4586,7 +4780,7 @@ _ACEOF fi done -for ac_func in memmove pselect putenv select setenv setlocale \ +for ac_func in fnmatch memmove pselect putenv select setenv setlocale \ strcasecmp strpbrk tcgetattr vsnprintf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -5125,7 +5319,7 @@ else typedef RETSIGTYPE sigfunc(); -int nsigint; +volatile int nsigint; #ifdef HAVE_POSIX_SIGNALS sigfunc * @@ -6057,6 +6251,45 @@ $as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : bash_cv_termcap_lib=libncurses else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncursesw" >&5 +$as_echo_n "checking for tgetent in -lncursesw... " >&6; } +if ${ac_cv_lib_ncursesw_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncursesw_tgetent=yes +else + ac_cv_lib_ncursesw_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_tgetent" >&5 +$as_echo "$ac_cv_lib_ncursesw_tgetent" >&6; } +if test "x$ac_cv_lib_ncursesw_tgetent" = xyes; then : + bash_cv_termcap_lib=libncursesw +else bash_cv_termcap_lib=gnutermcap fi @@ -6070,6 +6303,8 @@ fi fi +fi + if test "X$_bash_needmsg" = "Xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking which library has the termcap functions" >&5 $as_echo_n "checking which library has the termcap functions... " >&6; } @@ -6120,6 +6355,14 @@ done fi +case "$TERMCAP_LIB" in +-ltinfo) TERMCAP_PKG_CONFIG_LIB=tinfo ;; +-lcurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; +-lncurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; +-ltermcap) TERMCAP_PKG_CONFIG_LIB=termcap ;; +*) TERMCAP_PKG_CONFIG_LIB=termcap ;; +esac + for ac_header in wctype.h do : @@ -6517,6 +6760,40 @@ done LIBS="$OLDLIBS" fi +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5 +$as_echo_n "checking size of wchar_t... " >&6; } +if ${ac_cv_sizeof_wchar_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_wchar_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (wchar_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_wchar_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5 +$as_echo "$ac_cv_sizeof_wchar_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t +_ACEOF + + + case "$host_cpu" in @@ -6589,6 +6866,11 @@ fi +if test "$opt_install_examples" = "yes"; then + EXAMPLES_INSTALL_TARGET=install-examples +fi + + case "$build_os" in msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file *) BUILD_DIR=`pwd` ;; @@ -6616,6 +6898,7 @@ esac + ac_config_files="$ac_config_files Makefile doc/Makefile examples/Makefile shlib/Makefile readline.pc" ac_config_commands="$ac_config_commands default" @@ -7126,7 +7409,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by readline $as_me 7.0, which was +This file was extended by readline $as_me 8.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7192,7 +7475,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -readline config.status 7.0 +readline config.status 8.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/readline/configure.ac b/readline/configure.ac index f482579..e338343 100644 --- a/readline/configure.ac +++ b/readline/configure.ac @@ -5,7 +5,7 @@ dnl report bugs to chet@po.cwru.edu dnl dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 1987-2016 Free Software Foundation, Inc. +# Copyright (C) 1987-2018 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -20,11 +20,11 @@ dnl Process this file with autoconf to produce a configure script. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -AC_REVISION([for Readline 7.0, version 2.81]) +AC_REVISION([for Readline 8.0, version 2.85]) m4_include([../config/override.m4]) -AC_INIT(readline, 7.0, bug-readline@gnu.org) +AC_INIT(readline, 8.0, bug-readline@gnu.org) dnl make sure we are using a recent autoconf version AC_PREREQ(2.50) @@ -36,7 +36,7 @@ AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..) AC_CONFIG_HEADERS(config.h) dnl update the value of RL_READLINE_VERSION in readline.h when this changes -LIBVERSION=7.0 +LIBVERSION=8.0 AC_CANONICAL_HOST AC_CANONICAL_BUILD @@ -55,10 +55,12 @@ dnl option parsing for optional features opt_multibyte=yes opt_static_libs=yes opt_shared_libs=no +opt_install_examples=no AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval) dnl AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval) AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval) +AC_ARG_ENABLE(install-examples, AC_HELP_STRING([--disable-install-examples], [don't install examples [[default=install]]]), opt_install_examples=$enableval) if test $opt_multibyte = no; then AC_DEFINE(NO_MULTIBYTE_SUPPORT) @@ -136,7 +138,7 @@ AC_HEADER_STAT AC_HEADER_DIRENT AC_CHECK_FUNCS(fcntl kill lstat readlink) -AC_CHECK_FUNCS(memmove pselect putenv select setenv setlocale \ +AC_CHECK_FUNCS(fnmatch memmove pselect putenv select setenv setlocale \ strcasecmp strpbrk tcgetattr vsnprintf) AC_CHECK_FUNCS(isascii isxdigit) AC_CHECK_FUNCS(getpwent getpwnam getpwuid) @@ -200,6 +202,14 @@ if test "$TERMCAP_LIB" = "-lncurses"; then AC_CHECK_HEADERS(ncurses/termcap.h) fi +case "$TERMCAP_LIB" in +-ltinfo) TERMCAP_PKG_CONFIG_LIB=tinfo ;; +-lcurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; +-lncurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; +-ltermcap) TERMCAP_PKG_CONFIG_LIB=termcap ;; +*) TERMCAP_PKG_CONFIG_LIB=termcap ;; +esac + BASH_CHECK_MULTIBYTE case "$host_cpu" in @@ -270,6 +280,11 @@ AC_SUBST(SHARED_TARGET) AC_SUBST(STATIC_INSTALL_TARGET) AC_SUBST(SHARED_INSTALL_TARGET) +if test "$opt_install_examples" = "yes"; then + EXAMPLES_INSTALL_TARGET=install-examples +fi +AC_SUBST(EXAMPLES_INSTALL_TARGET) + case "$build_os" in msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file *) BUILD_DIR=`pwd` ;; @@ -296,6 +311,7 @@ AC_SUBST(host_os) AC_SUBST(LIBVERSION) AC_SUBST(TERMCAP_LIB) +AC_SUBST(TERMCAP_PKG_CONFIG_LIB) AC_OUTPUT([Makefile doc/Makefile examples/Makefile shlib/Makefile readline.pc], [ diff --git a/readline/display.c b/readline/display.c index cfe8164..b39f282 100644 --- a/readline/display.c +++ b/readline/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -124,7 +124,6 @@ static int _rl_col_width PARAMS((const char *, int, int, int)); #define PROMPT_ENDING_INDEX \ ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1) - /* **************************************************************** */ /* */ /* Display stuff */ @@ -159,9 +158,6 @@ rl_voidfunc_t *rl_redisplay_function = rl_redisplay; /* What YOU turn on when you have handled all redisplay yourself. */ int rl_display_fixed = 0; -int _rl_suppress_redisplay = 0; -int _rl_want_redisplay = 0; - /* The stuff that gets printed out before the actual text of the line. This is usually pointing to rl_prompt. */ char *rl_display_prompt = (char *)NULL; @@ -178,6 +174,10 @@ int _rl_vi_cmd_modestr_len; /* Pseudo-global variables declared here. */ +/* Hints for other parts of readline to give to the display engine. */ +int _rl_suppress_redisplay = 0; +int _rl_want_redisplay = 0; + /* The visible cursor position. If you print some text, adjust this. */ /* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale supporting multibyte characters, and an absolute cursor position when @@ -186,14 +186,24 @@ int _rl_vi_cmd_modestr_len; int _rl_last_c_pos = 0; int _rl_last_v_pos = 0; +/* Number of physical lines consumed by the current line buffer currently + on screen minus 1. */ +int _rl_vis_botlin = 0; + +/* This is a hint update_line gives to rl_redisplay that it has adjusted the + value of _rl_last_c_pos *and* taken the presence of any invisible chars in + the prompt into account. rl_redisplay notes this and does not do the + adjustment itself. */ static int cpos_adjusted; + +/* The index into the line buffer corresponding to the cursor position */ static int cpos_buffer_position; + +/* A flag to note when we're displaying the first line of the prompt */ static int displaying_prompt_first_line; +/* The number of multibyte characters in the prompt, if any */ static int prompt_multibyte_chars; -/* Number of lines currently on screen minus 1. */ -int _rl_vis_botlin = 0; - static int _rl_inv_botlin = 0; /* Variables used only in this file. */ @@ -216,7 +226,11 @@ static int line_size = 1024; static char *local_prompt, *local_prompt_prefix; static int local_prompt_len; -static int prompt_visible_length, prompt_prefix_length; +static int prompt_prefix_length; +/* Number of chars in the buffer that contribute to visible chars on the screen. + This might be different from the number of physical chars in the presence + of multibyte characters */ +static int prompt_visible_length; /* The number of invisible characters in the line currently being displayed on the screen. */ @@ -242,16 +256,26 @@ static int prompt_last_screen_line; static int prompt_physical_chars; +/* An array of indexes into the prompt string where we will break physical + screen lines. It's easier to compute in expand_prompt and use later in + rl_redisplay instead of having rl_redisplay try to guess about invisible + characters in the prompt or use heuristics about where they are. */ +static int *local_prompt_newlines; + /* set to a non-zero value by rl_redisplay if we are marking modified history lines and the current line is so marked. */ static int modmark; +static int line_totbytes; + /* Variables to save and restore prompt and display information. */ /* These are getting numerous enough that it's time to create a struct. */ static char *saved_local_prompt; static char *saved_local_prefix; +static int *saved_local_prompt_newlines; + static int saved_last_invisible; static int saved_visible_length; static int saved_prefix_length; @@ -262,8 +286,7 @@ static int saved_physical_chars; /* Return a string indicating the editing mode, for use in the prompt. */ static char * -prompt_modestr (lenp) - int *lenp; +prompt_modestr (int *lenp) { if (rl_editing_mode == emacs_mode) { @@ -291,7 +314,8 @@ prompt_modestr (lenp) index of the last invisible character in the returned string. NIFLP, if non-zero, is a place to store the number of invisible characters in the first prompt line. The previous are used as byte counts -- indexes - into a character buffer. */ + into a character buffer. *VLP gets the number of physical characters in + the expanded prompt (visible length) */ /* Current implementation: \001 (^A) start non-visible characters @@ -304,15 +328,16 @@ prompt_modestr (lenp) PMT_MULTILINE caller indicates that this is part of a multiline prompt */ +/* This approximates the number of lines the prompt will take when displayed */ +#define APPROX_DIV(n, d) (((n) < (d)) ? 1 : ((n) / (d)) + 1) + static char * -expand_prompt (pmt, flags, lp, lip, niflp, vlp) - char *pmt; - int flags; - int *lp, *lip, *niflp, *vlp; +expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) { char *r, *ret, *p, *igstart, *nprompt, *ms; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; - int mlen; + int mlen, newlines, newlines_guess, bound; + int mb_cur_max; /* We only expand the mode string for the last line of a multiline prompt (a prompt with embedded newlines). */ @@ -327,29 +352,54 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) else nprompt = pmt; - /* Short-circuit if we can. */ - if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0) + mb_cur_max = MB_CUR_MAX; + + if (_rl_screenwidth == 0) + _rl_get_screen_size (0, 0); /* avoid division by zero */ + + /* Short-circuit if we can. We can do this if we are treating the prompt as + a sequence of bytes and there are no invisible characters in the prompt + to deal with. Since we populate local_prompt_newlines, we have to run + through the rest of the function if this prompt looks like it's going to + be longer than one screen line. */ + if ((mb_cur_max <= 1 || rl_byte_oriented) && strchr (nprompt, RL_PROMPT_START_IGNORE) == 0) { - r = (nprompt == pmt) ? savestring (pmt) : nprompt; + l = strlen (nprompt); + if (l < (_rl_screenwidth > 0 ? _rl_screenwidth : 80)) + { + r = (nprompt == pmt) ? savestring (pmt) : nprompt; + if (lp) + *lp = l; + if (lip) + *lip = 0; + if (niflp) + *niflp = 0; + if (vlp) + *vlp = l; + + local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * 2); + local_prompt_newlines[0] = 0; + local_prompt_newlines[1] = -1; - if (lp) - *lp = strlen (r); - if (lip) - *lip = 0; - if (niflp) - *niflp = 0; - if (vlp) - *vlp = lp ? *lp : strlen (r); - return r; + return r; + } } l = strlen (nprompt); /* XXX */ r = ret = (char *)xmalloc (l + 1); + /* Guess at how many screen lines the prompt will take to size the array that + keeps track of where the line wraps happen */ + newlines_guess = (_rl_screenwidth > 0) ? APPROX_DIV(l, _rl_screenwidth) : APPROX_DIV(l, 80); + local_prompt_newlines = (int *) xrealloc (local_prompt_newlines, sizeof (int) * (newlines_guess + 1)); + local_prompt_newlines[newlines = 0] = 0; + for (rl = 1; rl <= newlines_guess; rl++) + local_prompt_newlines[rl] = -1; + rl = physchars = 0; /* mode string now part of nprompt */ - invfl = 0; /* invisible chars in first line of prompt */ - invflset = 0; /* we only want to set invfl once */ - igstart = 0; + invfl = 0; /* invisible chars in first line of prompt */ + invflset = 0; /* we only want to set invfl once */ + igstart = 0; /* we're not ignoring any characters yet */ for (ignoring = last = ninvis = 0, p = nprompt; p && *p; p++) { @@ -371,7 +421,7 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) else { #if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + if (mb_cur_max > 1 && rl_byte_oriented == 0) { pind = p - nprompt; ind = _rl_find_next_mbchar (nprompt, pind, 1, MB_FIND_NONZERO); @@ -405,11 +455,29 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) ninvis++; /* invisible chars byte counter */ } - if (invflset == 0 && rl >= _rl_screenwidth) + if (invflset == 0 && physchars >= _rl_screenwidth) { invfl = ninvis; invflset = 1; } + + if (physchars >= (bound = (newlines + 1) * _rl_screenwidth) && local_prompt_newlines[newlines+1] == -1) + { + int new; + if (physchars > bound) /* should rarely happen */ + { +#if defined (HANDLE_MULTIBYTE) + *r = '\0'; /* need null-termination for strlen */ + if (mb_cur_max > 1 && rl_byte_oriented == 0) + new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY); + else +#endif + new = r - ret - (physchars - bound); /* XXX */ + } + else + new = r - ret; + local_prompt_newlines[++newlines] = new; + } } } @@ -435,8 +503,7 @@ expand_prompt (pmt, flags, lp, lip, niflp, vlp) /* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from PMT and return the rest of PMT. */ char * -_rl_strip_prompt (pmt) - char *pmt; +_rl_strip_prompt (char *pmt) { char *ret; @@ -445,7 +512,7 @@ _rl_strip_prompt (pmt) } void -_rl_reset_prompt () +_rl_reset_prompt (void) { rl_visible_prompt_length = rl_expand_prompt (rl_prompt); } @@ -461,15 +528,20 @@ _rl_reset_prompt () * prompt_visible_length = number of visible characters in local_prompt * prompt_prefix_length = number of visible characters in local_prompt_prefix * + * It also tries to keep track of the number of invisible characters in the + * prompt string, and where they are. + * * This function is called once per call to readline(). It may also be * called arbitrarily to expand the primary prompt. * * The return value is the number of visible characters on the last line - * of the (possibly multi-line) prompt. + * of the (possibly multi-line) prompt. In this case, multi-line means + * there are embedded newlines in the prompt string itself, not that the + * number of physical characters exceeds the screen width and the prompt + * wraps. */ int -rl_expand_prompt (prompt) - char *prompt; +rl_expand_prompt (char *prompt) { char *p, *t; int c; @@ -527,8 +599,7 @@ rl_expand_prompt (prompt) increased. If the lines have already been allocated, this ensures that they can hold at least MINSIZE characters. */ static void -init_line_structures (minsize) - int minsize; +init_line_structures (int minsize) { register int n; @@ -578,9 +649,9 @@ init_line_structures (minsize) line_structures_initialized = 1; } -/* Basic redisplay algorithm. */ +/* Basic redisplay algorithm. See comments inline. */ void -rl_redisplay () +rl_redisplay (void) { register int in, out, c, linenum, cursor_linenum; register char *line; @@ -643,6 +714,10 @@ rl_redisplay () one passed to readline()), use the values we have already expanded. If not, use what's already in rl_display_prompt. WRAP_OFFSET is the number of non-visible characters in the prompt string. */ + /* This is where we output the characters in the prompt before the last + newline, if any. If there aren't any embedded newlines, we don't + write anything. Copy the last line of the prompt string into the line in + any case */ if (rl_display_prompt == rl_prompt || local_prompt) { if (local_prompt_prefix && forced_display) @@ -697,6 +772,7 @@ rl_redisplay () wrap_offset = prompt_invis_chars_first_line = 0; } +#if defined (HANDLE_MULTIBYTE) #define CHECK_INV_LBREAKS() \ do { \ if (newlines >= (inv_lbsize - 2)) \ @@ -704,7 +780,22 @@ rl_redisplay () inv_lbsize *= 2; \ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ } \ + if (newlines >= (line_state_invisible->wbsize - 2)) \ + { \ + line_state_invisible->wbsize *= 2; \ + line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ + } \ } while (0) +#else +#define CHECK_INV_LBREAKS() \ + do { \ + if (newlines >= (inv_lbsize - 2)) \ + { \ + inv_lbsize *= 2; \ + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + } while (0) +#endif /* !HANDLE_MULTIBYTE */ #if defined (HANDLE_MULTIBYTE) #define CHECK_LPOS() \ @@ -718,7 +809,7 @@ rl_redisplay () inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ } \ inv_lbreaks[++newlines] = out; \ - if (newlines >= (line_state_invisible->wbsize - 1)) \ + if (newlines >= (line_state_invisible->wbsize - 2)) \ { \ line_state_invisible->wbsize *= 2; \ line_state_invisible->wrapped_line = (int *)xrealloc (line_state_invisible->wrapped_line, line_state_invisible->wbsize * sizeof(int)); \ @@ -747,7 +838,10 @@ rl_redisplay () /* inv_lbreaks[i] is where line i starts in the buffer. */ inv_lbreaks[newlines = 0] = 0; /* lpos is a physical cursor position, so it needs to be adjusted by the - number of invisible characters in the prompt, per line */ + number of invisible characters in the prompt, per line. We compute + the line breaks in the prompt string in expand_prompt, taking invisible + characters into account, and if lpos exceeds the screen width, we copy + the data in the loop below. */ lpos = prompt_physical_chars + modmark; #if defined (HANDLE_MULTIBYTE) @@ -757,92 +851,38 @@ rl_redisplay () /* prompt_invis_chars_first_line is the number of invisible characters in the first physical line of the prompt. - wrap_offset - prompt_invis_chars_first_line is the number of invis - chars on the second (or, more generally, last) line. */ + wrap_offset - prompt_invis_chars_first_line is usually the number of + invis chars on the second (or, more generally, last) line. */ /* This is zero-based, used to set the newlines */ prompt_lines_estimate = lpos / _rl_screenwidth; /* what if lpos is already >= _rl_screenwidth before we start drawing the contents of the command line? */ - while (lpos >= _rl_screenwidth) - { - int z, p; - int nocorrect, wadjust; - - nocorrect = 0; - /* Adjust depending on the invisible characters in the line. We use a - heuristic based on experience: invisible characters nearly always - appear in the first and last lines of the prompt */ - wadjust = (newlines == 0) - ? prompt_invis_chars_first_line - : ((newlines == prompt_lines_estimate) - ? (wrap_offset - prompt_invis_chars_first_line) - : 0); - - /* fix from Darin Johnson <darin@acuson.com> for prompt string with - invisible characters that is longer than the screen width. The - prompt_invis_chars_first_line variable could be made into an array - saying how many invisible characters there are per line, but that's - probably too much work for the benefit gained. How many people have - prompts that exceed two physical lines? - Additional logic fix from Edward Catmur <ed@catmur.co.uk> */ -#if defined (HANDLE_MULTIBYTE) - if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) - { - nocorrect = 1; - n0 = num; - temp = local_prompt_len; - while (num < temp) - { - /* This has to take invisible characters in the prompt into - account. */ - z = _rl_col_width (local_prompt, n0, num, 1) - wadjust; - if (z > _rl_screenwidth) - { - num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); - break; - } - else if (z == _rl_screenwidth) - { - /* If we are in the middle or at the end of a multibyte - character, we want to move to the start, then find out - where it ends so we know where to insert the newline. - If this isn't a multibyte character, its the same as num++ */ - p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY); - num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY); - break; - } - num++; - } - temp = num; - } - else -#endif /* !HANDLE_MULTIBYTE */ - temp = ((newlines + 1) * _rl_screenwidth); + if (lpos >= _rl_screenwidth) + { + temp = 0; - /* Now account for invisible characters in the current line. */ - /* XXX - this assumes that the invisible characters may be split, but only - between the first and the last lines. */ - if (nocorrect == 0) - temp += wadjust; + /* first copy the linebreaks array we computed in expand_prompt */ + while (local_prompt_newlines[newlines+1] != -1) + { + temp = local_prompt_newlines[newlines+1]; + inv_lbreaks[++newlines] = temp; + } - inv_lbreaks[++newlines] = temp; -#if defined (HANDLE_MULTIBYTE) - /* lpos is a physical cursor position, so it needs to take the invisible - characters into account. */ + /* Now set lpos from the last newline */ if (mb_cur_max > 1 && rl_byte_oriented == 0 && prompt_multibyte_chars > 0) - lpos -= _rl_col_width (local_prompt, n0, num, 1) - wadjust; + lpos = _rl_col_width (local_prompt, temp, local_prompt_len, 1) - (wrap_offset - prompt_invis_chars_first_line); else -#endif - lpos -= _rl_screenwidth; /* all physical cursor positions */ + lpos -= (_rl_screenwidth * newlines); } prompt_last_screen_line = newlines; /* Draw the rest of the line (after the prompt) into invisible_line, keeping - track of where the cursor is (cpos_buffer_position), the number of the line containing - the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin). + track of where the cursor is (cpos_buffer_position), the number of the + line containing the cursor (lb_linenum), the last line number (lb_botlin + and inv_botlin). It maintains an array of line breaks for display (inv_lbreaks). This handles expanding tabs for display and displaying meta characters. */ lb_linenum = 0; @@ -851,8 +891,13 @@ rl_redisplay () if (mb_cur_max > 1 && rl_byte_oriented == 0) { memset (&ps, 0, sizeof (mbstate_t)); - /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ - wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[0])) + { + wc = (wchar_t)rl_line_buffer[0]; + wc_bytes = 1; + } + else + wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps); } else wc_bytes = 1; @@ -914,6 +959,9 @@ rl_redisplay () temp = _rl_screenwidth - lpos; CHECK_INV_LBREAKS (); inv_lbreaks[++newlines] = out + temp; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif lpos = 4 - temp; } else @@ -944,6 +992,9 @@ rl_redisplay () temp2 = _rl_screenwidth - lpos; CHECK_INV_LBREAKS (); inv_lbreaks[++newlines] = out + temp2; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif lpos = temp - temp2; while (out < newout) line[out++] = ' '; @@ -961,6 +1012,9 @@ rl_redisplay () line[out++] = '\0'; /* XXX - sentinel */ CHECK_INV_LBREAKS (); inv_lbreaks[++newlines] = out; +#if defined (HANDLE_MULTIBYTE) + line_state_invisible->wrapped_line[newlines] = _rl_wrapped_multicolumn; +#endif lpos = 0; } else if (CTRL_CHAR (c) || c == RUBOUT) @@ -1012,15 +1066,21 @@ rl_redisplay () if (mb_cur_max > 1 && rl_byte_oriented == 0) { in += wc_bytes; - /* XXX - what if wc_bytes ends up <= 0? check for MB_INVALIDCH */ - wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(rl_line_buffer[in])) + { + wc = (wchar_t)rl_line_buffer[in]; + wc_bytes = 1; + memset (&ps, 0, sizeof (mbstate_t)); /* re-init state */ + } + else + wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps); } else in++; #endif - } line[out] = '\0'; + line_totbytes = out; if (cpos_buffer_position < 0) { cpos_buffer_position = out; @@ -1030,6 +1090,10 @@ rl_redisplay () inv_botlin = lb_botlin = _rl_inv_botlin = newlines; CHECK_INV_LBREAKS (); inv_lbreaks[newlines+1] = out; +#if defined (HANDLE_MULTIBYTE) + /* This should be 0 anyway */ + line_state_invisible->wrapped_line[newlines+1] = _rl_wrapped_multicolumn; +#endif cursor_linenum = lb_linenum; /* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed. @@ -1097,8 +1161,8 @@ rl_redisplay () /* update_line potentially changes _rl_last_c_pos, but doesn't take invisible characters into account, since _rl_last_c_pos - is an absolute cursor position in a multibyte locale. See - if compensating here is the right thing, or if we have to + is an absolute cursor position in a multibyte locale. We + choose to (mostly) compensate for that here, rather than change update_line itself. There are several cases in which update_line adjusts _rl_last_c_pos itself (so it can pass _rl_move_cursor_relative accurate values); it communicates @@ -1109,11 +1173,16 @@ rl_redisplay () wrap_offset. */ if (linenum == 0 && (mb_cur_max > 1 && rl_byte_oriented == 0) && OLD_CPOS_IN_PROMPT()) _rl_last_c_pos -= prompt_invis_chars_first_line; /* XXX - was wrap_offset */ - else if (linenum == prompt_last_screen_line && prompt_physical_chars > _rl_screenwidth && + else if (cpos_adjusted == 0 && + linenum == prompt_last_screen_line && + prompt_physical_chars > _rl_screenwidth && (mb_cur_max > 1 && rl_byte_oriented == 0) && - cpos_adjusted == 0 && _rl_last_c_pos != o_cpos && - _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) + _rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line)) /* XXX - rethink this last one */ + /* This assumes that all the invisible characters are split + between the first and last lines of the prompt, if the + prompt consumes more than two lines. It's usually right */ + /* XXX - not sure this is ever executed */ _rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line); /* If this is the line with the prompt, we might need to @@ -1183,6 +1252,9 @@ rl_redisplay () _rl_last_c_pos += wrap_offset; } + /* Now we move the cursor to where it needs to be. First, make + sure we are on the correct line (cursor_linenum). */ + /* We have to reprint the prompt if it contains invisible characters, since it's not generally OK to just reprint the characters from the current cursor position. But we @@ -1224,9 +1296,10 @@ rl_redisplay () position that doesn't take invisible characters in the prompt into account. We use a fudge factor to compensate. */ - /* Since _rl_backspace() doesn't know about invisible characters in the - prompt, and there's no good way to tell it, we compensate for - those characters here and call _rl_backspace() directly. */ + /* Since _rl_backspace() doesn't know about invisible characters in + the prompt, and there's no good way to tell it, we compensate for + those characters here and call _rl_backspace() directly if + necessary */ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { /* TX == new physical cursor position in multibyte locale. */ @@ -1251,7 +1324,7 @@ rl_redisplay () _rl_move_cursor_relative (nleft, &invisible_line[pos]); } } - else /* Do horizontal scrolling. */ + else /* Do horizontal scrolling. Much simpler */ { #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) int lmargin, ndisp, nleft, phys_c_pos, t; @@ -1311,7 +1384,7 @@ rl_redisplay () right edge of the screen. If LMARGIN is 0, we need to take the wrap offset into account. */ t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth; - if (t < out) + if (t > 0 && t < out) line[t - 1] = '>'; if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin) @@ -1389,9 +1462,7 @@ new: eddie> Oh, my little buggy says to me, as lurgid as Could be made even smarter, but this works well enough */ static void -update_line (old, new, current_line, omax, nmax, inv_botlin) - register char *old, *new; - int current_line, omax, nmax, inv_botlin; +update_line (char *old, char *new, int current_line, int omax, int nmax, int inv_botlin) { register char *ofd, *ols, *oe, *nfd, *nls, *ne; int temp, lendiff, wsatend, od, nd, twidth, o_cpos; @@ -1416,52 +1487,145 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode && _rl_last_v_pos == current_line - 1) { + /* We're going to wrap around by writing the first character of NEW to + the screen and dealing with changes to what's visible by modifying + OLD to match it. Complicated by the presence of multi-width + characters at the end of the line or beginning of the new one. */ + /* old is always somewhere in visible_line; new is always somewhere in + invisible_line. These should always be null-terminated. */ #if defined (HANDLE_MULTIBYTE) if (mb_cur_max > 1 && rl_byte_oriented == 0) { wchar_t wc; mbstate_t ps; - int tempwidth, bytes; + int oldwidth, newwidth; + int oldbytes, newbytes; size_t ret; /* This fixes only double-column characters, but if the wrapped character consumes more than three columns, spaces will be inserted in the string buffer. */ - if (current_line < line_state_visible->wbsize && line_state_visible->wrapped_line[current_line] > 0) - _rl_clear_to_eol (line_state_visible->wrapped_line[current_line]); + /* XXX remember that we are working on the invisible line right now; + we don't swap visible and invisible until just before rl_redisplay + returns */ + /* This will remove the extra placeholder space we added with + _rl_wrapped_multicolumn */ + if (current_line < line_state_invisible->wbsize && line_state_invisible->wrapped_line[current_line] > 0) + _rl_clear_to_eol (line_state_invisible->wrapped_line[current_line]); + + /* 1. how many screen positions does first char in old consume? */ + memset (&ps, 0, sizeof (mbstate_t)); + ret = mbrtowc (&wc, old, mb_cur_max, &ps); + oldbytes = ret; + if (MB_INVALIDCH (ret)) + { + oldwidth = 1; + oldbytes = 1; + } + else if (MB_NULLWCH (ret)) + oldwidth = 0; + else + oldwidth = WCWIDTH (wc); + if (oldwidth < 0) + oldwidth = 1; + /* 2. how many screen positions does the first char in new consume? */ memset (&ps, 0, sizeof (mbstate_t)); ret = mbrtowc (&wc, new, mb_cur_max, &ps); + newbytes = ret; if (MB_INVALIDCH (ret)) { - tempwidth = 1; - ret = 1; + newwidth = 1; + newbytes = 1; } else if (MB_NULLWCH (ret)) - tempwidth = 0; + newwidth = 0; else - tempwidth = WCWIDTH (wc); + newwidth = WCWIDTH (wc); + if (newwidth < 0) + newwidth = 1; + + /* 3. if the new width is less than the old width, we need to keep + going in new until we have consumed at least that many screen + positions, and figure out how many bytes that will take */ + while (newbytes < nmax && newwidth < oldwidth) + { + int t; - if (tempwidth > 0) + ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps); + if (MB_INVALIDCH (ret)) + { + newwidth += 1; + newbytes += 1; + } + else if (MB_NULLWCH (ret)) + break; + else + { + t = WCWIDTH (wc); + newwidth += (t >= 0) ? t : 1; + newbytes += ret; + } + } + /* 4. If the new width is more than the old width, keep going in old + until we have consumed exactly that many screen positions, and + figure out how many bytes that will take. This is an optimization */ + while (oldbytes < omax && oldwidth < newwidth) { - int count, i; - bytes = ret; - for (count = 0; count < bytes; count++) - putc (new[count], rl_outstream); - _rl_last_c_pos = tempwidth; + int t; + + ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps); + if (MB_INVALIDCH (ret)) + { + oldwidth += 1; + oldbytes += 1; + } + else if (MB_NULLWCH (ret)) + break; + else + { + t = WCWIDTH (wc); + oldwidth += (t >= 0) ? t : 1; + oldbytes += ret; + } + } + /* 5. write the first newbytes of new, which takes newwidth. This is + where the screen wrapping takes place, and we are now writing + characters onto the new line. We need to fix up old so it + accurately reflects what is on the screen after the + _rl_output_some_chars below. */ + if (newwidth > 0) + { + int count, i, j; + char *optr; + + _rl_output_some_chars (new, newbytes); + _rl_last_c_pos = newwidth; _rl_last_v_pos++; - memset (&ps, 0, sizeof (mbstate_t)); - ret = mbrtowc (&wc, old, mb_cur_max, &ps); - if (ret != 0 && bytes != 0) + + /* 5a. If the number of screen positions doesn't match, punt + and do a dumb update. */ + if (newwidth != oldwidth) { - if (MB_INVALIDCH (ret)) - ret = 1; - memmove (old+bytes, old+ret, strlen (old+ret)); - memcpy (old, new, bytes); + ne = new + nmax; + nd = newbytes; + nfd = new + nd; + goto dumb_update; + } + if (oldbytes != 0 && newbytes != 0) + { + /* We have written as many bytes from new as we need to + consume the first character of old. Fix up `old' so it + reflects the new screen contents. We use +1 in the + memmove call to copy the trailing NUL. */ + memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1); + memcpy (old, new, newbytes); + j = newbytes - oldbytes; + + omax += j; /* Fix up indices if we copy data from one line to another */ - omax += bytes - ret; for (i = current_line+1; i <= inv_botlin+1; i++) - vis_lbreaks[i] += bytes - ret; + vis_lbreaks[i] += j; } } else @@ -1487,7 +1651,6 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) } } - /* Find first difference. */ #if defined (HANDLE_MULTIBYTE) if (mb_cur_max > 1 && rl_byte_oriented == 0) @@ -1506,6 +1669,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) memset (&ps_new, 0, sizeof(mbstate_t)); memset (&ps_old, 0, sizeof(mbstate_t)); + /* Are the old and new lines the same? */ if (omax == nmax && STREQN (new, old, omax)) { old_offset = omax; @@ -1515,6 +1679,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) } else { + /* Go through the line from the beginning and find the first + difference. */ new_offset = old_offset = 0; for (ofd = old, nfd = new; (ofd - old < omax) && *ofd && @@ -1570,6 +1736,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) wsatend = 1; /* flag for trailing whitespace */ #if defined (HANDLE_MULTIBYTE) + /* Find the last character that is the same between the two lines. This + bounds the region that needs to change. */ if (mb_cur_max > 1 && rl_byte_oriented == 0) { ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY); @@ -1729,12 +1897,29 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) nd = lendiff; /* Do a dumb update and return */ +dumb_update: temp = ne - nfd; if (temp > 0) { _rl_output_some_chars (nfd, temp); if (mb_cur_max > 1 && rl_byte_oriented == 0) - _rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1); + { + _rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1); + /* Need to adjust here based on wrap_offset. Guess that if + this is the line containing the last line of the prompt + we need to adjust by + wrap_offset-prompt_invis_chars_first_line + on the assumption that this is the number of invisible + characters in the last line of the prompt. */ + if (wrap_offset > prompt_invis_chars_first_line && + current_line == prompt_last_screen_line && + prompt_physical_chars > _rl_screenwidth && + _rl_horizontal_scroll_mode == 0) + { + _rl_last_c_pos -= wrap_offset - prompt_invis_chars_first_line; + cpos_adjusted = 1; + } + } else _rl_last_c_pos += temp; } @@ -1809,6 +1994,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) { /* Non-zero if we're increasing the number of lines. */ int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; + /* If col_lendiff is > 0, implying that the new string takes up more screen real estate than the old, but lendiff is < 0, meaning that it takes fewer bytes, we need to just output the characters starting @@ -1824,7 +2010,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) cpos_adjusted to let the caller know. */ if (current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) { - _rl_last_c_pos -= wrap_offset; + _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */ cpos_adjusted = 1; } return; @@ -1877,7 +2063,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) and set cpos_adjusted to let the caller know. */ if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) { - _rl_last_c_pos -= wrap_offset; + _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */ cpos_adjusted = 1; } return; @@ -1890,7 +2076,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) and set cpos_adjusted to let the caller know. */ if ((mb_cur_max > 1 && rl_byte_oriented == 0) && current_line == 0 && displaying_prompt_first_line && wrap_offset && ((nfd - new) <= prompt_last_invisible)) { - _rl_last_c_pos -= wrap_offset; + _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */ cpos_adjusted = 1; } } @@ -1957,12 +2143,26 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) _rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1); if (current_line == 0 && wrap_offset && displaying_prompt_first_line && - _rl_last_c_pos > wrap_offset && + _rl_last_c_pos >= wrap_offset && /* XXX was > */ ((nfd - new) <= prompt_last_invisible)) { - _rl_last_c_pos -= wrap_offset; + _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */ cpos_adjusted = 1; } + +#if 1 +#ifdef HANDLE_MULTIBYTE + /* If we write a non-space into the last screen column, + remove the note that we added a space to compensate for + a multibyte double-width character that didn't fit, since + it's only valid for what was previously there. */ + /* XXX - watch this */ + if (_rl_last_c_pos == _rl_screenwidth && + line_state_invisible->wrapped_line[current_line+1] && + nfd[bytes_to_insert-1] != ' ') + line_state_invisible->wrapped_line[current_line+1] = 0; +#endif +#endif } else _rl_last_c_pos += bytes_to_insert; @@ -1994,7 +2194,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) _rl_last_c_pos > wrap_offset && ((nfd - new) <= prompt_last_invisible)) { - _rl_last_c_pos -= wrap_offset; + _rl_last_c_pos -= wrap_offset; /* XXX - prompt_invis_chars_first_line? */ cpos_adjusted = 1; } } @@ -2024,7 +2224,7 @@ clear_rest_of_line: /* Tell the update routines that we have moved onto a new (empty) line. */ int -rl_on_new_line () +rl_on_new_line (void) { if (visible_line) visible_line[0] = '\0'; @@ -2040,7 +2240,7 @@ rl_on_new_line () /* Clear all screen lines occupied by the current readline line buffer (visible line) */ int -rl_clear_visible_line () +rl_clear_visible_line (void) { int curr_line; @@ -2068,9 +2268,10 @@ rl_clear_visible_line () /* Tell the update routines that we have moved onto a new line with the prompt already displayed. Code originally from the version of readline distributed with CLISP. rl_expand_prompt must have already been called - (explicitly or implicitly). This still doesn't work exactly right. */ + (explicitly or implicitly). This still doesn't work exactly right; it + should use expand_prompt() */ int -rl_on_new_line_with_prompt () +rl_on_new_line_with_prompt (void) { int prompt_size, i, l, real_screenwidth, newlines; char *prompt_last_line, *lprompt; @@ -2126,7 +2327,7 @@ rl_on_new_line_with_prompt () /* Actually update the display, period. */ int -rl_forced_update_display () +rl_forced_update_display (void) { register char *temp; @@ -2144,7 +2345,7 @@ rl_forced_update_display () /* Redraw only the last line of a multi-line prompt. */ void -rl_redraw_prompt_last_line () +rl_redraw_prompt_last_line (void) { char *t; @@ -2162,9 +2363,7 @@ rl_redraw_prompt_last_line () the movement is being done. DATA is always the visible line or the invisible line */ void -_rl_move_cursor_relative (new, data) - int new; - const char *data; +_rl_move_cursor_relative (int new, const char *data) { register int i; int woff; /* number of invisible chars on current line */ @@ -2321,8 +2520,7 @@ _rl_move_cursor_relative (new, data) /* PWP: move the cursor up or down. */ void -_rl_move_vert (to) - int to; +_rl_move_vert (int to) { register int delta, i; @@ -2362,8 +2560,7 @@ _rl_move_vert (to) /* Physically print C on rl_outstream. This is for functions which know how to optimize the display. Return the number of characters output. */ int -rl_show_char (c) - int c; +rl_show_char (int c) { int n = 1; if (META_CHAR (c) && (_rl_output_meta_chars == 0)) @@ -2390,8 +2587,7 @@ rl_show_char (c) } int -rl_character_len (c, pos) - register int c, pos; +rl_character_len (int c, int pos) { unsigned char uc; @@ -2526,7 +2722,7 @@ rl_message (format, arg1, arg2) /* How to clear things from the "echo-area". */ int -rl_clear_message () +rl_clear_message (void) { rl_display_prompt = rl_prompt; if (msg_saved_prompt) @@ -2539,7 +2735,7 @@ rl_clear_message () } int -rl_reset_line_state () +rl_reset_line_state (void) { rl_on_new_line (); @@ -2548,8 +2744,12 @@ rl_reset_line_state () return 0; } +/* Save all of the variables associated with the prompt and its display. Most + of the complexity is dealing with the invisible characters in the prompt + string and where they are. There are enough of these that I should consider + a struct. */ void -rl_save_prompt () +rl_save_prompt (void) { saved_local_prompt = local_prompt; saved_local_prefix = local_prompt_prefix; @@ -2559,22 +2759,28 @@ rl_save_prompt () saved_visible_length = prompt_visible_length; saved_invis_chars_first_line = prompt_invis_chars_first_line; saved_physical_chars = prompt_physical_chars; + saved_local_prompt_newlines = local_prompt_newlines; local_prompt = local_prompt_prefix = (char *)0; local_prompt_len = 0; + local_prompt_newlines = (int *)0; + prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0; prompt_invis_chars_first_line = prompt_physical_chars = 0; } void -rl_restore_prompt () +rl_restore_prompt (void) { FREE (local_prompt); FREE (local_prompt_prefix); + FREE (local_prompt_newlines); local_prompt = saved_local_prompt; local_prompt_prefix = saved_local_prefix; local_prompt_len = saved_local_length; + local_prompt_newlines = saved_local_prompt_newlines; + prompt_prefix_length = saved_prefix_length; prompt_last_invisible = saved_last_invisible; prompt_visible_length = saved_visible_length; @@ -2586,11 +2792,11 @@ rl_restore_prompt () saved_local_length = 0; saved_last_invisible = saved_visible_length = saved_prefix_length = 0; saved_invis_chars_first_line = saved_physical_chars = 0; + saved_local_prompt_newlines = 0; } char * -_rl_make_prompt_for_search (pchar) - int pchar; +_rl_make_prompt_for_search (int pchar) { int len; char *pmt, *p; @@ -2628,8 +2834,7 @@ _rl_make_prompt_for_search (pchar) /* Quick redisplay hack when erasing characters at the end of the line. */ void -_rl_erase_at_end_of_line (l) - int l; +_rl_erase_at_end_of_line (int l) { register int i; @@ -2643,10 +2848,10 @@ _rl_erase_at_end_of_line (l) } /* Clear to the end of the line. COUNT is the minimum - number of character spaces to clear, */ + number of character spaces to clear, but we use a terminal escape + sequence if available. */ void -_rl_clear_to_eol (count) - int count; +_rl_clear_to_eol (int count) { #ifndef __MSDOS__ if (_rl_term_clreol) @@ -2660,36 +2865,33 @@ _rl_clear_to_eol (count) /* Clear to the end of the line using spaces. COUNT is the minimum number of character spaces to clear, */ static void -space_to_eol (count) - int count; +space_to_eol (int count) { register int i; for (i = 0; i < count; i++) - putc (' ', rl_outstream); + putc (' ', rl_outstream); _rl_last_c_pos += count; } void -_rl_clear_screen () +_rl_clear_screen (void) { -#ifndef __DJGPP__ +#if defined (__DJGPP__) + ScreenClear (); + ScreenSetCursor (0, 0); +#else if (_rl_term_clrpag) tputs (_rl_term_clrpag, 1, _rl_output_character_function); else rl_crlf (); -#else - ScreenClear (); - ScreenSetCursor (0, 0); #endif /* __DJGPP__ */ } /* Insert COUNT characters from STRING to the output stream at column COL. */ static void -insert_some_chars (string, count, col) - char *string; - int count, col; +insert_some_chars (char *string, int count, int col) { open_some_spaces (col); _rl_output_some_chars (string, count); @@ -2699,8 +2901,7 @@ insert_some_chars (string, count, col) ncurses documentation and use either im/ei with explicit spaces, or IC/ic by itself. We assume there will either be ei or we don't need to use it. */ static void -open_some_spaces (col) - int col; +open_some_spaces (int col) { #if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION)) char *buffer; @@ -2736,8 +2937,7 @@ open_some_spaces (col) /* Delete COUNT characters from the display line. */ static void -delete_chars (count) - int count; +delete_chars (int count) { if (count > _rl_screenwidth) /* XXX */ return; @@ -2759,9 +2959,9 @@ delete_chars (count) } void -_rl_update_final () +_rl_update_final (void) { - int full_lines; + int full_lines, woff, botline_length; full_lines = 0; /* If the cursor is the only thing on an otherwise-blank last line, @@ -2773,26 +2973,34 @@ _rl_update_final () full_lines = 1; } _rl_move_vert (_rl_vis_botlin); + woff = W_OFFSET(_rl_vis_botlin, wrap_offset); + botline_length = VIS_LLEN(_rl_vis_botlin) - woff; /* If we've wrapped lines, remove the final xterm line-wrap flag. */ - if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth)) + if (full_lines && _rl_term_autowrap && botline_length == _rl_screenwidth) { char *last_line; - last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; + /* LAST_LINE includes invisible characters, so if you want to get the + last character of the first line, you have to take WOFF into account. + This needs to be done for both calls to _rl_move_cursor_relative, + which takes a buffer position as the first argument, and any direct + subscripts of LAST_LINE. */ + last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */ cpos_buffer_position = -1; /* don't know where we are in buffer */ - _rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */ + _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line); /* XXX */ _rl_clear_to_eol (0); - putc (last_line[_rl_screenwidth - 1], rl_outstream); + putc (last_line[_rl_screenwidth - 1 + woff], rl_outstream); } _rl_vis_botlin = 0; - rl_crlf (); + if (botline_length > 0 || _rl_last_c_pos > 0) + rl_crlf (); fflush (rl_outstream); rl_display_fixed++; } /* Move to the start of the current line. */ static void -cr () +cr (void) { if (_rl_term_cr) { @@ -2809,8 +3017,7 @@ cr () terminal escape sequences. Called with the cursor at column 0 of the line to draw the prompt on. */ static void -redraw_prompt (t) - char *t; +redraw_prompt (char *t) { char *oldp; @@ -2834,7 +3041,7 @@ redraw_prompt (t) /* Redisplay the current line after a SIGWINCH is received. */ void -_rl_redisplay_after_sigwinch () +_rl_redisplay_after_sigwinch (void) { char *t; @@ -2879,7 +3086,7 @@ _rl_redisplay_after_sigwinch () } void -_rl_clean_up_for_exit () +_rl_clean_up_for_exit (void) { if (_rl_echoing_p) { @@ -2892,7 +3099,7 @@ _rl_clean_up_for_exit () } void -_rl_erase_entire_line () +_rl_erase_entire_line (void) { cr (); _rl_clear_to_eol (0); @@ -2901,7 +3108,7 @@ _rl_erase_entire_line () } void -_rl_ttyflush () +_rl_ttyflush (void) { fflush (rl_outstream); } @@ -2909,7 +3116,7 @@ _rl_ttyflush () /* return the `current display line' of the cursor -- the number of lines to move up to get to the first screen line of the current readline line. */ int -_rl_current_display_line () +_rl_current_display_line (void) { int ret, nleft; @@ -2933,9 +3140,7 @@ _rl_current_display_line () In the case of multibyte characters with stateful encoding, we have to scan from the beginning of the string to take the state into account. */ static int -_rl_col_width (str, start, end, flags) - const char *str; - int start, end, flags; +_rl_col_width (const char *str, int start, int end, int flags) { wchar_t wc; mbstate_t ps; @@ -2968,7 +3173,13 @@ _rl_col_width (str, start, end, flags) while (point < start) { - tmp = mbrlen (str + point, max, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) + { + memset (&ps, 0, sizeof (mbstate_t)); + tmp = 1; + } + else + tmp = mbrlen (str + point, max, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* In this case, the bytes are invalid or too short to compose a @@ -2997,7 +3208,13 @@ _rl_col_width (str, start, end, flags) while (point < end) { - tmp = mbrtowc (&wc, str + point, max, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(str[point])) + { + tmp = 1; + wc = (wchar_t) str[point]; + } + else + tmp = mbrtowc (&wc, str + point, max, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* In this case, the bytes are invalid or too short to compose a diff --git a/readline/doc/history.3 b/readline/doc/history.3 index 7ddc26a..8de64f6 100644 --- a/readline/doc/history.3 +++ b/readline/doc/history.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Sun May 24 18:01:17 EDT 2015 +.\" Last Change: Sun Oct 8 11:43:43 EDT 2017 .\" -.TH HISTORY 3 "2015 May 24" "GNU History 6.3" +.TH HISTORY 3 "2017 October 8" "GNU History 6.3" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -40,8 +40,8 @@ .SH NAME history \- GNU History Library .SH COPYRIGHT -.if t The GNU History Library is Copyright \(co 1989-2014 by the Free Software Foundation, Inc. -.if n The GNU History Library is Copyright (C) 1989-2014 by the Free Software Foundation, Inc. +.if t The GNU History Library is Copyright \(co 1989-2017 by the Free Software Foundation, Inc. +.if n The GNU History Library is Copyright (C) 1989-2017 by the Free Software Foundation, Inc. .SH DESCRIPTION Many programs read input from the user a line at a time. The GNU History library is able to keep track of those lines, associate arbitrary @@ -356,6 +356,9 @@ parameters managing the list itself. .Fn1 void add_history "const char *string" Place \fIstring\fP at the end of the history list. The associated data field (if any) is set to \fBNULL\fP. +If the maximum number of history entries has been set using +\fBstifle_history()\fP, and the new number of history entries would exceed +that maximum, the oldest history entry is removed. .Fn1 void add_history_time "const char *string" Change the time stamp associated with the most recent history entry to @@ -382,6 +385,7 @@ Clear the history list by deleting all the entries. .Fn1 void stifle_history "int max" Stifle the history list, remembering only the last \fImax\fP entries. +The history list will contain only \fImax\fP entries at a time. .Fn1 int unstifle_history "void" Stop stifling the history. This returns the previously-set @@ -411,10 +415,11 @@ Return the history entry at the current position, as determined by pointer. .Fn1 "HIST_ENTRY *" history_get "int offset" -Return the history entry at position \fIoffset\fP, starting from -\fBhistory_base\fP. -If there is no entry there, or if \fIoffset\fP -is greater than the history length, return a \fBNULL\fP pointer. +Return the history entry at position \fIoffset\fP. +The range of valid values of \fIoffset\fP starts at \fBhistory_base\fP +and ends at \fBhistory_length\fP \- 1. +If there is no entry there, or if \fIoffset\fP is outside the valid +range, return a \fBNULL\fP pointer. .Fn1 "time_t" history_get_time "HIST_ENTRY *" Return the time stamp associated with the history entry passed as the argument. diff --git a/readline/doc/hstech.texi b/readline/doc/hstech.texi index bba7b59..dbc21c1 100644 --- a/readline/doc/hstech.texi +++ b/readline/doc/hstech.texi @@ -166,6 +166,9 @@ parameters managing the list itself. @deftypefun void add_history (const char *string) Place @var{string} at the end of the history list. The associated data field (if any) is set to @code{NULL}. +If the maximum number of history entries has been set using +@code{stifle_history()}, and the new number of history entries would exceed +that maximum, the oldest history entry is removed. @end deftypefun @deftypefun void add_history_time (const char *string) @@ -198,6 +201,7 @@ Clear the history list by deleting all the entries. @deftypefun void stifle_history (int max) Stifle the history list, remembering only the last @var{max} entries. +The history list will contain only @var{max} entries at a time. @end deftypefun @deftypefun int unstifle_history (void) @@ -234,10 +238,12 @@ pointer. @end deftypefun @deftypefun {HIST_ENTRY *} history_get (int offset) -Return the history entry at position @var{offset}, starting from -@code{history_base} (@pxref{History Variables}). -If there is no entry there, or if @var{offset} -is greater than the history length, return a @code{NULL} pointer. +Return the history entry at position @var{offset}. +The range of valid +values of @var{offset} starts at @code{history_base} and ends at +@var{history_length} - 1 (@pxref{History Variables}). +If there is no entry there, or if @var{offset} is outside the valid +range, return a @code{NULL} pointer. @end deftypefun @deftypefun time_t history_get_time (HIST_ENTRY *entry) @@ -397,7 +403,7 @@ to the ``normal'' terminating characters. Return an array of tokens parsed out of @var{string}, much as the shell might. The tokens are split on the characters in the @var{history_word_delimiters} variable, -and shell quoting conventions are obeyed. +and shell quoting conventions are obeyed as described below. @end deftypefun @deftypefun {char *} history_arg_extract (int first, int last, const char *string) @@ -470,8 +476,24 @@ carriage return, and @samp{=}. @end deftypevar @deftypevar int history_quotes_inhibit_expansion -If non-zero, double-quoted words are not scanned for the history expansion -character or the history comment character. The default value is 0. +If non-zero, the history expansion code implements shell-like quoting: +single-quoted words are not scanned for the history expansion +character or the history comment character, and double-quoted words may +have history expansion performed, since single quotes are not special +within double quotes. +The default value is 0. +@end deftypevar + +@deftypevar int history_quoting_state +An application may set this variable to indicate that the current line +being expanded is subject to existing quoting. If set to @samp{'}, the +history expansion function will assume that the line is single-quoted and +inhibit expansion until it reads an unquoted closing single quote; if set +to @samp{"}, history expansion will assume the line is double quoted until +it reads an unquoted closing double quote. If set to zero, the default, +the history expansion function will assume the line is not quoted and +treat quote characters within the line as described above. +This is only effective if @var{history_quotes_inhibit_expansion} is set. @end deftypevar @deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function diff --git a/readline/doc/hsuser.texi b/readline/doc/hsuser.texi index 311933a..e92c794 100644 --- a/readline/doc/hsuser.texi +++ b/readline/doc/hsuser.texi @@ -1,7 +1,7 @@ @ignore This file documents the user interface to the GNU History library. -Copyright (C) 1988--2016 Free Software Foundation, Inc. +Copyright (C) 1988--2018 Free Software Foundation, Inc. Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual @@ -126,7 +126,7 @@ The @code{lithist} shell option causes the shell to save the command with embedded newlines instead of semicolons. The @code{shopt} builtin is used to set these options. -@xref{Bash Builtins}, for a description of @code{shopt}. +@xref{The Shopt Builtin}, for a description of @code{shopt}. @node Bash History Builtins @section Bash History Builtins @@ -151,8 +151,8 @@ Both @var{first} and @var{last} may be specified as a string (to locate the most recent command beginning with that string) or as a number (an index into the history list, where a negative number is used as an offset from the -current command number). If @var{last} is not specified it is set to -@var{first}. If @var{first} is not specified it is set to the previous +current command number). If @var{last} is not specified, it is set to +@var{first}. If @var{first} is not specified, it is set to the previous command for editing and @minus{}16 for listing. If the @option{-l} flag is given, the commands are listed on standard output. The @option{-n} flag suppresses the command numbers when listing. The @option{-r} flag @@ -178,6 +178,7 @@ and typing @samp{r} re-executes the last command (@pxref{Aliases}). history [@var{n}] history -c history -d @var{offset} +history -d @var{start}-@var{end} history [-anrw] [@var{filename}] history -ps @var{arg} @end example @@ -200,8 +201,17 @@ with the other options to replace the history list completely. @item -d @var{offset} Delete the history entry at position @var{offset}. -@var{offset} should be specified as it appears when the history is -displayed. +If @var{offset} is positive, it should be specified as it appears when +the history is displayed. +If @var{offset} is negative, it is interpreted as relative to one greater +than the last history position, so negative indices count back from the +end of the history, and an index of @samp{-1} refers to the current +@code{history -d} command. + +@item -d @var{start}-@var{end} +Delete the history entries between positions @var{start} and @var{end}, +inclusive. Positive and negative values for @var{start} and @var{end} +are interpreted as described above. @item -a Append the new history lines to the history file. @@ -253,7 +263,9 @@ fix errors in previous commands quickly. @ifset BashFeatures History expansion is performed immediately after a complete line -is read, before the shell breaks it into words. +is read, before the shell breaks it into words, and is performed +on each line individually. Bash attempts to inform the history +expansion functions about quoting still in effect from previous lines. @end ifset History expansion takes place in two parts. The first is to determine @@ -267,16 +279,26 @@ that Bash does, so that several words surrounded by quotes are considered one word. History expansions are introduced by the appearance of the history expansion character, which is @samp{!} by default. + +History expansion implements shell-like quoting conventions: +a backslash can be used to remove the special handling for the next character; +single quotes enclose verbatim sequences of characters, and can be used to +inhibit history expansion; +and characters enclosed within double quotes may be subject to history +expansion, since backslash can escape the history expansion character, +but single quotes may not, since they are not treated specially within +double quotes. + @ifset BashFeatures -Only @samp{\} and @samp{'} may be used to escape the history expansion -character, but the history expansion character is +When using the shell, only @samp{\} and @samp{'} may be used to escape the +history expansion character, but the history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string. @end ifset @ifset BashFeatures Several shell options settable with the @code{shopt} -builtin (@pxref{Bash Builtins}) may be used to tailor +builtin (@pxref{The Shopt Builtin}) may be used to tailor the behavior of history expansion. If the @code{histverify} shell option is enabled, and Readline is being used, history substitutions are not immediately passed to diff --git a/readline/doc/readline.3 b/readline/doc/readline.3 index b57f00b..be89c2d 100644 --- a/readline/doc/readline.3 +++ b/readline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Sun Feb 28 15:42:34 EST 2016 +.\" Last Change: Thu Dec 28 14:49:51 EST 2017 .\" -.TH READLINE 3 "2016 February 28" "GNU Readline 7.0" +.TH READLINE 3 "2017 December 28" "GNU Readline 7.0" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -378,13 +378,13 @@ in emacs mode and to .B # in vi command mode. .TP -.B completion\-display\-width (-1) +.B completion\-display\-width (\-1) The number of screen columns used to display possible matches when performing completion. The value is ignored if it is less than 0 or greater than the terminal screen width. A value of 0 will cause matches to be displayed one per line. -The default value is -1. +The default value is \-1. .TP .B completion\-ignore\-case (Off) If set to \fBOn\fP, readline performs filename matching and completion @@ -438,6 +438,16 @@ can be set to either or .BR vi . .TP +.B emacs\-mode\-string (@) +If the \fIshow\-mode\-in\-prompt\fP variable is enabled, +this string is displayed immediately before the last line of the primary +prompt when emacs editing mode is active. The value is expanded like a +key binding, so the standard set of meta- and control prefixes and +backslash escape sequences is available. +Use the \e1 and \e2 escapes to begin and end sequences of +non-printing characters, which can be used to embed a terminal control +sequence into the mode string. +.TP .B enable\-bracketed\-paste (Off) When set to \fBOn\fP, readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a @@ -506,15 +516,6 @@ The value of .B editing\-mode also affects the default keymap. .TP -.B emacs\-mode\-string (@) -This string is displayed immediately before the last line of the primary -prompt when emacs editing mode is active. The value is expanded like a -key binding, so the standard set of meta- and control prefixes and -backslash escape sequences is available. -Use the \e1 and \e2 escapes to begin and end sequences of -non-printing characters, which can be used to embed a terminal control -sequence into the mode string. -.TP .B keyseq\-timeout (500) Specifies the duration \fIreadline\fP will wait for a character when reading an ambiguous key sequence (one that can form a complete key sequence using @@ -592,9 +593,9 @@ a common prefix) cause the matches to be listed immediately instead of ringing the bell. .TP .B show\-mode\-in\-prompt (Off) -If set to \fBOn\fP, add a character to the beginning of the prompt +If set to \fBOn\fP, add a string to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion. -The mode strings are user-settable. +The mode strings are user-settable (e.g., \fIemacs\-mode\-string\fP). .TP .B skip\-completed\-text (Off) If set to \fBOn\fP, this alters the default completion behavior when @@ -605,7 +606,8 @@ after point in the word being completed, so portions of the word following the cursor are not duplicated. .TP .B vi\-cmd\-mode\-string ((cmd)) -This string is displayed immediately before the last line of the primary +If the \fIshow\-mode\-in\-prompt\fP variable is enabled, +this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in command mode. The value is expanded like a key binding, so the standard set of meta- and control prefixes and @@ -615,7 +617,8 @@ non-printing characters, which can be used to embed a terminal control sequence into the mode string. .TP .B vi\-ins\-mode\-string ((ins)) -This string is displayed immediately before the last line of the primary +If the \fIshow\-mode\-in\-prompt\fP variable is enabled, +this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in insertion mode. The value is expanded like a key binding, so the standard set of meta- and control prefixes and @@ -640,8 +643,9 @@ The .B $if construct allows bindings to be made based on the editing mode, the terminal being used, or the application using -readline. The text of the test extends to the end of the line; -no characters are required to isolate it. +readline. The text of the test, after any comparison operator, +extends to the end of the line; +unless otherwise noted, no characters are required to isolate it. .RS .IP \fBmode\fP The \fBmode=\fP form of the \fB$if\fP directive is used to test @@ -663,6 +667,26 @@ to match both and .IR sun\-cmd , for instance. +.IP \fBversion\fP +The \fBversion\fP test may be used to perform comparisons against +specific readline versions. +The \fBversion\fP expands to the current readline version. +The set of comparison operators includes +.BR = , +(and +.BR == ), +.BR != , +.BR <= , +.BR >= , +.BR < , +and +.BR > . +The version number supplied on the right side of the operator consists +of a major version number, an optional decimal point, and an optional +minor version (e.g., \fB7.1\fP). If the minor version is omitted, it +is assumed to be \fB0\fP. +The operator may be separated from the string \fBversion\fP +and from the version number argument by whitespace. .IP \fBapplication\fP The \fBapplication\fP construct is used to include application-specific settings. Each program using the readline @@ -680,6 +704,15 @@ key sequence that quotes the current or previous word in \fBbash\fP: \fB$endif\fP .fi .RE +.IP \fIvariable\fP +The \fIvariable\fP construct provides simple equality tests for readline +variables and values. +The permitted comparison operators are \fI=\fP, \fI==\fP, and \fI!=\fP. +The variable name must be separated from the comparison operator by +whitespace; the operator may be separated from the value on the right hand +side by whitespace. +Both string and boolean variables may be tested. Boolean variables must be +tested against the values \fIon\fP and \fIoff\fP. .RE .IP \fB$endif\fP This command, as seen in the previous example, terminates an @@ -771,6 +804,19 @@ alphanumeric characters (letters and digits). Move back to the start of the current or previous word. Words are composed of alphanumeric characters (letters and digits). .TP +.B previous\-screen\-line +Attempt to move point to the same physical screen column on the previous +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if point is not +greater than the length of the prompt plus the screen width. +.TP +.B next\-screen\-line +Attempt to move point to the same physical screen column on the next +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if the length +of the current Readline line is not greater than the length of the prompt +plus the screen width. +.TP .B clear\-screen (C\-l) Clear the screen leaving the current line at the top of the screen. With an argument, refresh the current line without clearing the @@ -1103,6 +1149,7 @@ and store the definition. .B call\-last\-kbd\-macro (C\-x e) Re-execute the last keyboard macro defined, by making the characters in the macro appear as if typed at the keyboard. +.TP .B print\-last\-kbd\-macro () Print the last keyboard macro defined in a format suitable for the \fIinputrc\fP file. @@ -1120,9 +1167,10 @@ Abort the current editing command and ring the terminal's bell (subject to the setting of .BR bell\-style ). .TP -.B do\-uppercase\-version (M\-a, M\-b, M\-\fIx\fP, ...) -If the metafied character \fIx\fP is lowercase, run the command -that is bound to the corresponding uppercase character. +.B do\-lowercase\-version (M\-A, M\-B, M\-\fIx\fP, ...) +If the metafied character \fIx\fP is uppercase, run the command +that is bound to the corresponding metafied lowercase character. +The behavior is undefined if \fIx\fP is already lowercase. .TP .B prefix\-meta (ESC) Metafy the next character typed. diff --git a/readline/doc/rltech.texi b/readline/doc/rltech.texi index b8ce90f..28a02d9 100644 --- a/readline/doc/rltech.texi +++ b/readline/doc/rltech.texi @@ -90,6 +90,12 @@ If @code{readline} encounters an @code{EOF} while reading the line, and the line is empty at that point, then @code{(char *)NULL} is returned. Otherwise, the line is ended just as if a newline had been typed. +Readline performs some expansion on the @var{prompt} before it is +displayed on the screen. See the description of @code{rl_expand_prompt} +(@pxref{Redisplay}) for additional details, especially if @var{prompt} +will contain characters that do not consume physical screen space when +displayed. + If you want the user to be able to get at the line later, (with @key{C-p} for example), you must call @code{add_history()} to save the line away in a @dfn{history} list of such lines. @@ -688,6 +694,11 @@ Free all storage associated with @var{keymap}. This calls @code{rl_discard_keymap} to free subordindate keymaps and macros. @end deftypefun +@deftypefun int rl_empty_keymap (Keymap keymap) +Return non-zero if there are no keys bound to functions in @var{keymap}; +zero if there are any keys bound. +@end deftypefun + Readline has several internal keymaps. These functions allow you to change which keymap is active. @@ -709,6 +720,24 @@ Return the name matching @var{keymap}. @var{name} is one which would be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). @end deftypefun +@deftypefun int rl_set_keymap_name (const char *name, Keymap keymap) +Set the name of @var{keymap}. This name will then be "registered" and +available for use in a @code{set keymap} inputrc directive +@pxref{Readline Init File}). +The @var{name} may not be one of Readline's builtin keymap names; +you may not add a different name for one of Readline's builtin keymaps. +You may replace the name associated with a given keymap by calling this +function more than once with the same @var{keymap} argument. +You may associate a registered @var{name} with a new keymap by calling this +function more than once with the same @var{name} argument. +There is no way to remove a named keymap once the name has been +registered. +Readline will make a copy of @var{name}. +The return value is greater than zero unless @var{name} is one of +Readline's builtin keymap names or @var{keymap} is one of Readline's +builtin keymaps. +@end deftypefun + @node Binding Keys @subsection Binding Keys @@ -835,6 +864,16 @@ Return the function invoked by @var{keyseq} in keymap @var{map}. If @var{map} is @code{NULL}, the current keymap is used. If @var{type} is not @code{NULL}, the type of the object is returned in the @code{int} variable it points to (one of @code{ISFUNC}, @code{ISKMAP}, or @code{ISMACR}). +It takes a "translated" key sequence and should not be used if the key sequence +can include NUL. +@end deftypefun + +@deftypefun {rl_command_func_t *} rl_function_of_keyseq_len (const char *keyseq, size_t len, Keymap map, int *type) +Return the function invoked by @var{keyseq} of length @var{len} +in keymap @var{map}. Equivalent to @code{rl_function_of_keyseq} with the +addition of the @var{len} parameter. +It takes a "translated" key sequence and should be used if the key sequence +can include NUL. @end deftypefun @deftypefun {char **} rl_invoking_keyseqs (rl_command_func_t *function) @@ -1679,6 +1718,19 @@ handlers, depending on the values of @code{rl_catch_signals} and @code{rl_catch_sigwinch}. @end deftypefun +If an application wants to force Readline to handle any signals that +have arrived while it has been executing, @code{rl_check_signals()} +will call Readline's internal signal handler if there are any pending +signals. This is primarily intended for those applications that use +a custom @code{rl_getc_function} (@pxref{Readline Variables}) and wish +to handle signals received while waiting for input. + +@deftypefun void rl_check_signals (void) +If there are any pending signals, call Readline's internal signal handling +functions to process them. @code{rl_pending_signal()} can be used independently +to determine whether or not there are any pending signals. +@end deftypefun + If an application does not wish Readline to catch @code{SIGWINCH}, it may call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force Readline to update its idea of the terminal size when a @code{SIGWINCH} @@ -2094,6 +2146,8 @@ character (@samp{\0}) prevents anything being appended automatically. This can be changed in application-specific completion functions to provide the ``most sensible word separator character'' according to an application-specific command line syntax specification. +It is set to the default before any application-specific completion function +is called, and may only be changed within such a function. @end deftypevar @deftypevar int rl_completion_suppress_append diff --git a/readline/doc/rluser.texi b/readline/doc/rluser.texi index 4c094c8..a59bd14 100644 --- a/readline/doc/rluser.texi +++ b/readline/doc/rluser.texi @@ -475,6 +475,7 @@ The default value is @samp{off}. If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when performing case-insensitive filename matching and completion. +The default value is @samp{off}. @item completion-prefix-display-length @vindex completion-prefix-display-length @@ -524,7 +525,8 @@ set to either @samp{emacs} or @samp{vi}. @item emacs-mode-string @vindex emacs-mode-string -This string is displayed immediately before the last line of the primary +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary prompt when emacs editing mode is active. The value is expanded like a key binding, so the standard set of meta- and control prefixes and backslash escape sequences is available. @@ -604,7 +606,7 @@ If this variable has not been given a value, the characters @key{ESC} and @item keymap @vindex keymap Sets Readline's idea of the current keymap for key binding commands. -Acceptable @code{keymap} names are +Built-in @code{keymap} names are @code{emacs}, @code{emacs-standard}, @code{emacs-meta}, @@ -615,6 +617,7 @@ Acceptable @code{keymap} names are @code{vi-insert}. @code{vi} is equivalent to @code{vi-command} (@code{vi-move} is also a synonym); @code{emacs} is equivalent to @code{emacs-standard}. +Applications may add additional names. The default value is @code{emacs}. The value of the @code{editing-mode} variable also affects the default keymap. @@ -714,9 +717,9 @@ The default value is @samp{off}. @item show-mode-in-prompt @vindex show-mode-in-prompt -If set to @samp{on}, add a character to the beginning of the prompt +If set to @samp{on}, add a string to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion. -The mode strings are user-settable. +The mode strings are user-settable (e.g., @var{emacs-mode-string}). The default value is @samp{off}. @item skip-completed-text @@ -735,7 +738,8 @@ The default value is @samp{off}. @item vi-cmd-mode-string @vindex vi-cmd-mode-string -This string is displayed immediately before the last line of the primary +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in command mode. The value is expanded like a key binding, so the standard set of meta- and control prefixes and @@ -747,7 +751,8 @@ The default is @samp{(cmd)}. @item vi-ins-mode-string @vindex vi-ins-mode-string -This string is displayed immediately before the last line of the primary +If the @var{show-mode-in-prompt} variable is enabled, +this string is displayed immediately before the last line of the primary prompt when vi editing mode is active and in insertion mode. The value is expanded like a key binding, so the standard set of meta- and control prefixes and @@ -799,7 +804,7 @@ Meta-Rubout: backward-kill-word Control-o: "> output" @end example -In the above example, @kbd{C-u} is bound to the function +In the example above, @kbd{C-u} is bound to the function @code{universal-argument}, @kbd{M-DEL} is bound to the function @code{backward-kill-word}, and @kbd{C-o} is bound to run the macro @@ -914,8 +919,9 @@ of tests. There are four parser directives used. @item $if The @code{$if} construct allows bindings to be made based on the editing mode, the terminal being used, or the application using -Readline. The text of the test extends to the end of the line; -no characters are required to isolate it. +Readline. The text of the test, after any comparison operator, +extends to the end of the line; +unless otherwise noted, no characters are required to isolate it. @table @code @item mode @@ -935,6 +941,27 @@ the portion of the terminal name before the first @samp{-}. This allows @code{sun} to match both @code{sun} and @code{sun-cmd}, for instance. +@item version +The @code{version} test may be used to perform comparisons against +specific Readline versions. +The @code{version} expands to the current Readline version. +The set of comparison operators includes +@samp{=} (and @samp{==}), @samp{!=}, @samp{<=}, @samp{>=}, @samp{<}, +and @samp{>}. +The version number supplied on the right side of the operator consists +of a major version number, an optional decimal point, and an optional +minor version (e.g., @samp{7.1}). If the minor version is omitted, it +is assumed to be @samp{0}. +The operator may be separated from the string @code{version} and +from the version number argument by whitespace. +The following example sets a variable if the Readline version being used +is 7.0 or newer: +@example +$if version >= 7.0 +set show-mode-in-prompt on +$endif +@end example + @item application The @var{application} construct is used to include application-specific settings. Each program using the Readline @@ -949,6 +976,23 @@ $if Bash "\C-xq": "\eb\"\ef\"" $endif @end example + +@item variable +The @var{variable} construct provides simple equality tests for Readline +variables and values. +The permitted comparison operators are @samp{=}, @samp{==}, and @samp{!=}. +The variable name must be separated from the comparison operator by +whitespace; the operator may be separated from the value on the right hand +side by whitespace. +Both string and boolean variables may be tested. Boolean variables must be +tested against the values @var{on} and @var{off}. +The following example is equivalent to the @code{mode=emacs} test described +above: +@example +$if editing-mode == emacs +set show-mode-in-prompt on +$endif +@end example @end table @item $endif @@ -1138,6 +1182,19 @@ Move back to the start of the current or previous word. Words are delimited by non-quoted shell metacharacters. @end ifset +@item previous-screen-line () +Attempt to move point to the same physical screen column on the previous +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if point is not +greater than the length of the prompt plus the screen width. + +@item next-screen-line () +Attempt to move point to the same physical screen column on the next +physical screen line. This will not have the desired effect if the current +Readline line does not take up more than one physical line or if the length +of the current Readline line is not greater than the length of the prompt +plus the screen width. + @item clear-screen (C-l) Clear the screen and redraw the current line, leaving the current line at the top of the screen. @@ -1216,14 +1273,14 @@ The search string must match at the beginning of a history line. This is a non-incremental search. By default, this command is unbound. -@item history-substr-search-forward () +@item history-substring-search-forward () Search forward through the history for the string of characters between the start of the current line and the point. The search string may match anywhere in a history line. This is a non-incremental search. By default, this command is unbound. -@item history-substr-search-backward () +@item history-substring-search-backward () Search backward through the history for the string of characters between the start of the current line and the point. The search string may match anywhere in a history line. @@ -1297,7 +1354,7 @@ This function is intended to be bound to the "bracketed paste" escape sequence sent by some terminals, and such a binding is assigned by default. It allows Readline to insert the pasted text as a single unit without treating each character as if it had been read from the keyboard. The characters -are inserted as if each one was bound to @code{self-insert}) instead of +are inserted as if each one was bound to @code{self-insert} instead of executing any editing commands. @item transpose-chars (C-t) @@ -1590,9 +1647,10 @@ Abort the current editing command and ring the terminal's bell (subject to the setting of @code{bell-style}). -@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{}) -If the metafied character @var{x} is lowercase, run the command -that is bound to the corresponding uppercase character. +@item do-lowercase-version (M-A, M-B, M-@var{x}, @dots{}) +If the metafied character @var{x} is upper case, run the command +that is bound to the corresponding metafied lower case character. +The behavior is undefined if @var{x} is already lower case. @item prefix-meta (@key{ESC}) Metafy the next character typed. This is for keyboards @@ -1718,10 +1776,11 @@ A synonym for @code{yank-last-arg}. @item operate-and-get-next (C-o) Accept the current line for execution and fetch the next line -relative to the current line from the history for editing. Any -argument is ignored. +relative to the current line from the history for editing. +A numeric argument, if supplied, specifies the history entry to use instead +of the current line. -@item edit-and-execute-command (C-xC-e) +@item edit-and-execute-command (C-x C-e) Invoke an editor on the current command line, and execute the result as shell commands. Bash attempts to invoke @@ -1792,6 +1851,9 @@ If no compspec is found for the full pathname, an attempt is made to find a compspec for the portion following the final slash. If those searches do not result in a compspec, any compspec defined with the @option{-D} option to @code{complete} is used as the default. +If there is no default compspec, Bash attempts alias expansion +on the command word as a final resort, and attempts to find a compspec +for the command word from any successful expansion Once a compspec has been found, it is used to generate the list of matching words. @@ -1816,7 +1878,9 @@ Next, the string specified as the argument to the @option{-W} option is considered. The string is first split using the characters in the @env{IFS} special variable as delimiters. -Shell quoting is honored. +Shell quoting is honored within the string, in order to provide a +mechanism for the words to contain shell metacharacters or characters +in the value of @env{IFS}. Each word is then expanded using brace expansion, tilde expansion, parameter and variable expansion, command substitution, and arithmetic expansion, @@ -1960,10 +2024,10 @@ matches were generated. @item complete @btindex complete @example -@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DE] [-A @var{action}] [-G @var{globpat}] [-W @var{wordlist}] -[-F @var{function}] [-C @var{command}] [-X @var{filterpat}] +@code{complete [-abcdefgjksuv] [-o @var{comp-option}] [-DEI] [-A @var{action}] [-G @var{globpat}] +[-W @var{wordlist}] [-F @var{function}] [-C @var{command}] [-X @var{filterpat}] [-P @var{prefix}] [-S @var{suffix}] @var{name} [@var{name} @dots{}]} -@code{complete -pr [-DE] [@var{name} @dots{}]} +@code{complete -pr [-DEI] [@var{name} @dots{}]} @end example Specify how arguments to each @var{name} should be completed. @@ -1973,16 +2037,24 @@ reused as input. The @option{-r} option removes a completion specification for each @var{name}, or, if no @var{name}s are supplied, all completion specifications. -The @option{-D} option indicates that the remaining options and actions should +The @option{-D} option indicates that other supplied options and actions should apply to the ``default'' command completion; that is, completion attempted on a command for which no completion has previously been defined. -The @option{-E} option indicates that the remaining options and actions should +The @option{-E} option indicates that other supplied options and actions should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The @option{-I} option indicates that other supplied options and actions should +apply to completion on the inital non-assignment word on the line, or after a +command delimiter such as @samp{;} or @samp{|}, which is usually command +name completion. +If multiple options are supplied, the @option{-D} option takes precedence +over @option{-E}, and both take precedence over @option{-I}. +If any of @option{-D}, @option{-E}, or @option{-I} are supplied, any other +@var{name} arguments are ignored; these completions only apply to the case +specified by the option. The process of applying these completion specifications when word completion -is attempted is described above (@pxref{Programmable Completion}). The -@option{-D} option takes precedence over @option{-E}. +is attempted is described above (@pxref{Programmable Completion}). Other options, if specified, have the following meanings. The arguments to the @option{-G}, @option{-W}, and @option{-X} options @@ -2012,7 +2084,7 @@ Perform directory name completion if the compspec generates no matches. @item filenames Tell Readline that the compspec generates filenames, so it can perform any -filename-specific processing (like adding a slash to directory names +filename-specific processing (like adding a slash to directory names, quoting special characters, or suppressing trailing spaces). This option is intended to be used with shell functions specified with @option{-F}. @@ -2167,7 +2239,7 @@ an error occurs adding a completion specification. @item compopt @btindex compopt @example -@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}] +@code{compopt} [-o @var{option}] [-DEI] [+o @var{option}] [@var{name}] @end example Modify completion options for each @var{name} according to the @var{option}s, or for the currently-executing completion if no @var{name}s @@ -2176,14 +2248,19 @@ If no @var{option}s are given, display the completion options for each @var{name} or the current completion. The possible values of @var{option} are those valid for the @code{complete} builtin described above. -The @option{-D} option indicates that the remaining options should +The @option{-D} option indicates that other supplied options should apply to the ``default'' command completion; that is, completion attempted on a command for which no completion has previously been defined. -The @option{-E} option indicates that the remaining options should +The @option{-E} option indicates that other supplied options should apply to ``empty'' command completion; that is, completion attempted on a blank line. +The @option{-I} option indicates that other supplied options should +apply to completion on the inital non-assignment word on the line, or after a +command delimiter such as @samp{;} or @samp{|}, which is usually command +name completion. -The @option{-D} option takes precedence over @option{-E}. +If multiple options are supplied, the @option{-D} option takes precedence +over @option{-E}, and both take precedence over @option{-I} The return value is true unless an invalid option is supplied, an attempt is made to modify the options for a @var{name} for which no completion @@ -2200,7 +2277,7 @@ a shell function and bind it to a particular command using @code{complete -F}. The following function provides completions for the @code{cd} builtin. It is a reasonably good example of what shell functions must do when -used for completion. This function uses the word passsed as @code{$2} +used for completion. This function uses the word passed as @code{$2} to determine the directory name to complete. You can also use the @code{COMP_WORDS} array variable; the current word is indexed by the @code{COMP_CWORD} variable. @@ -2230,7 +2307,7 @@ _comp_cd() local cur _skipdot _cdpath local i j k - # Tilde expansion, with side effect of expanding tilde to full pathname + # Tilde expansion, which also expands tilde to full pathname case "$2" in \~*) eval cur="$2" ;; *) cur=$2 ;; diff --git a/readline/doc/version.texi b/readline/doc/version.texi index 9dc2998..576c35c 100644 --- a/readline/doc/version.texi +++ b/readline/doc/version.texi @@ -1,10 +1,10 @@ @ignore -Copyright (C) 1988-2016 Free Software Foundation, Inc. +Copyright (C) 1988-2018 Free Software Foundation, Inc. @end ignore -@set EDITION 7.0 -@set VERSION 7.0 -@set UPDATED 16 July 2016 -@set UPDATED-MONTH July 2016 +@set EDITION 8.0 +@set VERSION 8.0 +@set UPDATED 30 November 2018 +@set UPDATED-MONTH November 2018 -@set LASTCHANGE Sat Jul 16 13:43:15 EDT 2016 +@set LASTCHANGE Fri Nov 30 22:50:53 EST 2018 diff --git a/readline/emacs_keymap.c b/readline/emacs_keymap.c index cb6e140..b5e53f4 100644 --- a/readline/emacs_keymap.c +++ b/readline/emacs_keymap.c @@ -1,6 +1,6 @@ /* emacs_keymap.c -- the keymap for emacs_mode in readline (). */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. diff --git a/readline/examples/Makefile.in b/readline/examples/Makefile.in index 5094c6c..4a7c39e 100644 --- a/readline/examples/Makefile.in +++ b/readline/examples/Makefile.in @@ -53,8 +53,12 @@ CPPFLAGS = @CPPFLAGS@ INCLUDES = -I$(srcdir) -I$(top_srcdir) -I.. -CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -LDFLAGS = -g -L.. @LDFLAGS@ +CCFLAGS = $(ASAN_CFLAGS) $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES) $(CPPFLAGS) \ + $(CFLAGS) +LDFLAGS = -g -L.. @LDFLAGS@ $(ASAN_LDFLAGS) + +ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer +ASAN_XLDFLAGS = -fsanitize=address READLINE_LIB = ../libreadline.a HISTORY_LIB = ../libhistory.a @@ -67,15 +71,18 @@ TERMCAP_LIB = @TERMCAP_LIB@ SOURCES = excallback.c fileman.c histexamp.c manexamp.c rl-fgets.c rl.c \ rlbasic.c rlcat.c rlevent.c rlptytest.c rltest.c rlversion.c \ - rl-callbacktest.c hist_erasedups.c hist_purgecmd.c + rltest2.c rl-callbacktest.c hist_erasedups.c hist_purgecmd.c \ + rlkeymaps.c EXECUTABLES = fileman$(EXEEXT) rltest$(EXEEXT) rl$(EXEEXT) rlcat$(EXEEXT) \ rlevent$(EXEEXT) rlversion$(EXEEXT) histexamp$(EXEEXT) \ rl-callbacktest$(EXEEXT) rlbasic$(EXEEXT) \ - hist_erasedups$(EXEEXT) hist_purgecmd$(EXEEXT) + hist_erasedups$(EXEEXT) hist_purgecmd$(EXEEXT) \ + rlkeymaps$(EXEEXT) OBJECTS = fileman.o rltest.o rl.o rlevent.o rlcat.o rlversion.o histexamp.o \ - rl-callbacktest.o rlbasic.o hist_erasedups.o hist_purgecmd.o + rltest2.o rl-callbacktest.o rlbasic.o hist_erasedups.o hist_purgecmd.o \ + rlkeymaps.o OTHEREXE = rlptytest$(EXEEXT) OTHEROBJ = rlptytest.o @@ -83,6 +90,9 @@ OTHEROBJ = rlptytest.o all: $(EXECUTABLES) everything: all +asan: + ${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' all + check: rlversion$(EXEEXT) @echo Readline version: `rlversion$(EXEEXT)` @@ -113,12 +123,18 @@ rlcat$(EXEEXT): rlcat.o $(READLINE_LIB) rlevent$(EXEEXT): rlevent.o $(READLINE_LIB) $(CC) $(LDFLAGS) -o $@ rlevent.o $(READLINE_LIB) $(TERMCAP_LIB) +rlkeymaps$(EXEEXT): rlkeymaps.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rlkeymaps.o $(READLINE_LIB) $(TERMCAP_LIB) + fileman$(EXEEXT): fileman.o $(READLINE_LIB) $(CC) $(LDFLAGS) -o $@ fileman.o $(READLINE_LIB) $(TERMCAP_LIB) rltest$(EXEEXT): rltest.o $(READLINE_LIB) $(CC) $(LDFLAGS) -o $@ rltest.o $(READLINE_LIB) $(TERMCAP_LIB) +rltest2$(EXEEXT): rltest2.o $(READLINE_LIB) + $(CC) $(LDFLAGS) -o $@ rltest2.o $(READLINE_LIB) $(TERMCAP_LIB) + rl-callbacktest$(EXEEXT): rl-callbacktest.o $(READLINE_LIB) $(CC) $(LDFLAGS) -o $@ rl-callbacktest.o $(READLINE_LIB) $(TERMCAP_LIB) @@ -146,18 +162,21 @@ distclean maintainer-clean: clean fileman.o: fileman.c rltest.o: rltest.c +rltest2.o: rltest2.c rl.o: rl.c rlversion.o: rlversion.c histexamp.o: histexamp.c hist_erasedups.o: hist_erasedups.c hist_purgecmd.o: hist_purgecmd.c rlbasic.o: rlbasic.c +rlkeymaps.o: rlkeymaps.c rlcat.o: rlcat.c rlptytest.o: rlptytest.c rl-callbacktest.o: rl-callbacktest.c fileman.o: $(top_srcdir)/readline.h rltest.o: $(top_srcdir)/readline.h +rltest2.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h rl.o: $(top_srcdir)/readline.h rlversion.o: $(top_srcdir)/readline.h histexamp.o: $(top_srcdir)/history.h diff --git a/readline/examples/hist_erasedups.c b/readline/examples/hist_erasedups.c index 2ecee89..f820eba 100644 --- a/readline/examples/hist_erasedups.c +++ b/readline/examples/hist_erasedups.c @@ -38,6 +38,8 @@ #define STREQN(a, b, n) ((n == 0) ? (1) \ : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)) +int hist_erasedups (void); + static void usage() { diff --git a/readline/examples/hist_purgecmd.c b/readline/examples/hist_purgecmd.c index d836d14..7992d81 100644 --- a/readline/examples/hist_purgecmd.c +++ b/readline/examples/hist_purgecmd.c @@ -43,6 +43,8 @@ #define PURGE_REGEXP 0x01 +int hist_purgecmd (char *, int); + static void usage() { diff --git a/readline/examples/histexamp.c b/readline/examples/histexamp.c index 3b43674..309d769 100644 --- a/readline/examples/histexamp.c +++ b/readline/examples/histexamp.c @@ -27,8 +27,11 @@ # include <readline/history.h> #endif +#include <unistd.h> +#include <stdlib.h> #include <string.h> +int main (argc, argv) int argc; char **argv; diff --git a/readline/examples/rlcat.c b/readline/examples/rlcat.c index fa9e06f..b494241 100644 --- a/readline/examples/rlcat.c +++ b/readline/examples/rlcat.c @@ -137,7 +137,7 @@ fcopy(fp) if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0) { x = rl_untranslate_keyseq (c); - if (fputs (x, stdout) != 0) + if (fputs (x, stdout) == EOF) return 1; } else if (putchar (c) == EOF) diff --git a/readline/examples/rlevent.c b/readline/examples/rlevent.c index 77f1887..8143cb0 100644 --- a/readline/examples/rlevent.c +++ b/readline/examples/rlevent.c @@ -28,6 +28,13 @@ # include <config.h> #endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#else +extern int getopt(); +extern int sleep(); +#endif + #include <stdio.h> #include <sys/types.h> diff --git a/readline/examples/rlkeymaps.c b/readline/examples/rlkeymaps.c new file mode 100644 index 0000000..fef77b3 --- /dev/null +++ b/readline/examples/rlkeymaps.c @@ -0,0 +1,61 @@ +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include <readline/readline.h> +# include <readline/history.h> +#endif + +int +main (int c, char **v) +{ + Keymap nmap, emacsmap, newemacs; + int r, errs; + + errs = 0; + nmap = rl_make_keymap (); + + r = rl_set_keymap_name ("emacs", nmap); + if (r >= 0) + { + fprintf (stderr, "rlkeymaps: error: able to rename `emacs' keymap\n"); + errs++; + } + + emacsmap = rl_get_keymap_by_name ("emacs"); + r = rl_set_keymap_name ("newemacs", emacsmap); + if (r >= 0) + { + fprintf (stderr, "rlkeymaps: error: able to set new name for emacs keymap\n"); + errs++; + } + + r = rl_set_keymap_name ("newemacs", nmap); + if (r < 0) + { + fprintf (stderr, "rlkeymaps: error: newemacs: could not set keymap name\n"); + errs++; + } + + newemacs = rl_copy_keymap (emacsmap); + r = rl_set_keymap_name ("newemacs", newemacs); + if (r < 0) + { + fprintf (stderr, "rlkeymaps: error: newemacs: could not set `newemacs' keymap to new map\n"); + errs++; + } + + r = rl_set_keymap_name ("emacscopy", newemacs); + if (r < 0) + { + fprintf (stderr, "rlkeymaps: error: emacscopy: could not rename created keymap\n"); + errs++; + } + + exit (errs); +} diff --git a/readline/examples/rltest.c b/readline/examples/rltest.c index 78e2608..65abe87 100644 --- a/readline/examples/rltest.c +++ b/readline/examples/rltest.c @@ -46,6 +46,7 @@ extern void exit(); extern HIST_ENTRY **history_list (); +int main () { char *temp, *prompt; diff --git a/readline/funmap.c b/readline/funmap.c index 34b1d6b..aaf144d 100644 --- a/readline/funmap.c +++ b/readline/funmap.c @@ -1,6 +1,6 @@ /* funmap.c -- attach names to functions. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -110,6 +110,7 @@ static const FUNMAP default_funmap[] = { { "menu-complete", rl_menu_complete }, { "menu-complete-backward", rl_backward_menu_complete }, { "next-history", rl_get_next_history }, + { "next-screen-line", rl_next_screen_line }, { "non-incremental-forward-search-history", rl_noninc_forward_search }, { "non-incremental-reverse-search-history", rl_noninc_reverse_search }, { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, @@ -121,6 +122,7 @@ static const FUNMAP default_funmap[] = { #endif { "possible-completions", rl_possible_completions }, { "previous-history", rl_get_previous_history }, + { "previous-screen-line", rl_previous_screen_line }, { "print-last-kbd-macro", rl_print_last_kbd_macro }, { "quoted-insert", rl_quoted_insert }, { "re-read-init-file", rl_re_read_init_file }, @@ -204,9 +206,7 @@ static const FUNMAP default_funmap[] = { }; int -rl_add_funmap_entry (name, function) - const char *name; - rl_command_func_t *function; +rl_add_funmap_entry (const char *name, rl_command_func_t *function) { if (funmap_entry + 2 >= funmap_size) { @@ -226,7 +226,7 @@ static int funmap_initialized; /* Make the funmap contain all of the default entries. */ void -rl_initialize_funmap () +rl_initialize_funmap (void) { register int i; @@ -244,7 +244,7 @@ rl_initialize_funmap () is sorted. The array itself is allocated, but not the strings inside. You should free () the array when you done, but not the pointers. */ const char ** -rl_funmap_names () +rl_funmap_names (void) { const char **result; int result_size, result_index; diff --git a/readline/histexpand.c b/readline/histexpand.c index b84a6b8..adcf5dc 100644 --- a/readline/histexpand.c +++ b/readline/histexpand.c @@ -1,6 +1,6 @@ /* histexpand.c -- history expansion. */ -/* Copyright (C) 1989-2015 Free Software Foundation, Inc. +/* Copyright (C) 1989-2018 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -55,6 +55,8 @@ #define slashify_in_quotes "\\`\"$" +#define fielddelim(c) (whitespace(c) || (c) == '\n') + typedef int _hist_search_func_t PARAMS((const char *, int)); static char error_pointer; @@ -107,6 +109,8 @@ char *history_word_delimiters = HISTORY_WORD_DELIMITERS; particular history expansion should be performed. */ rl_linebuf_func_t *history_inhibit_expansion_function; +int history_quoting_state = 0; + /* **************************************************************** */ /* */ /* History Expansion */ @@ -132,10 +136,7 @@ static char *search_match; So you might call this function like: line = get_history_event ("!echo:p", &index, 0); */ char * -get_history_event (string, caller_index, delimiting_quote) - const char *string; - int *caller_index; - int delimiting_quote; +get_history_event (const char *string, int *caller_index, int delimiting_quote) { register int i; register char c; @@ -316,9 +317,7 @@ get_history_event (string, caller_index, delimiting_quote) to the closing single quote. FLAGS currently used to allow backslash to escape a single quote (e.g., for bash $'...'). */ static void -hist_string_extract_single_quoted (string, sindex, flags) - char *string; - int *sindex, flags; +hist_string_extract_single_quoted (char *string, int *sindex, int flags) { register int i; @@ -332,8 +331,7 @@ hist_string_extract_single_quoted (string, sindex, flags) } static char * -quote_breaks (s) - char *s; +quote_breaks (char *s) { register char *p, *r; char *ret; @@ -374,9 +372,7 @@ quote_breaks (s) } static char * -hist_error(s, start, current, errtype) - char *s; - int start, current, errtype; +hist_error(char *s, int start, int current, int errtype) { char *temp; const char *emsg; @@ -433,9 +429,7 @@ hist_error(s, start, current, errtype) subst_rhs is allowed to be set to the empty string. */ static char * -get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) - char *str; - int *iptr, delimiter, is_rhs, *lenptr; +get_subst_pattern (char *str, int *iptr, int delimiter, int is_rhs, int *lenptr) { register int si, i, j, k; char *s; @@ -490,7 +484,7 @@ get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr) } static void -postproc_subst_rhs () +postproc_subst_rhs (void) { char *new; int i, j, new_size; @@ -526,12 +520,9 @@ postproc_subst_rhs () if the `p' modifier was supplied and the caller should just print the returned string. Returns the new index into string in *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */ +/* need current line for !# */ static int -history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_line) - char *string; - int start, qc, *end_index_ptr; - char **ret_string; - char *current_line; /* for !# */ +history_expand_internal (char *string, int start, int qc, int *end_index_ptr, char **ret_string, char *current_line) { int i, n, starting_index; int substitute_globally, subst_bywords, want_quotes, print_only; @@ -780,7 +771,7 @@ history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_l the last time. */ if (subst_bywords && si > we) { - for (; temp[si] && whitespace (temp[si]); si++) + for (; temp[si] && fielddelim (temp[si]); si++) ; ws = si; we = history_tokenize_word (temp, si); @@ -908,9 +899,7 @@ history_expand_internal (string, start, qc, end_index_ptr, ret_string, current_l while (0) int -history_expand (hstring, output) - char *hstring; - char **output; +history_expand (char *hstring, char **output) { register int j; int i, r, l, passc, cc, modified, eindex, only_printing, dquote, squote, flag; @@ -976,7 +965,22 @@ history_expand (hstring, output) /* `!' followed by one of the characters in history_no_expand_chars is NOT an expansion. */ - for (i = dquote = squote = 0; string[i]; i++) + dquote = history_quoting_state == '"'; + squote = history_quoting_state == '\''; + + /* If the calling application tells us we are already reading a + single-quoted string, consume the rest of the string right now + and then go on. */ + i = 0; + if (squote && history_quotes_inhibit_expansion) + { + hist_string_extract_single_quoted (string, &i, 0); + squote = 0; + if (string[i]) + i++; + } + + for ( ; string[i]; i++) { #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) @@ -1064,7 +1068,29 @@ history_expand (hstring, output) } /* Extract and perform the substitution. */ - for (passc = dquote = squote = i = j = 0; i < l; i++) + dquote = history_quoting_state == '"'; + squote = history_quoting_state == '\''; + + /* If the calling application tells us we are already reading a + single-quoted string, consume the rest of the string right now + and then go on. */ + i = j = 0; + if (squote && history_quotes_inhibit_expansion) + { + int c; + + hist_string_extract_single_quoted (string, &i, 0); + squote = 0; + for (c = 0; c < i; c++) + ADD_CHAR (string[c]); + if (string[i]) + { + ADD_CHAR (string[i]); + i++; + } + } + + for (passc = 0; i < l; i++) { int qc, tchar = string[i]; @@ -1249,9 +1275,7 @@ history_expand (hstring, output) CALLER_INDEX is the offset in SPEC to start looking; it is updated to point to just after the last character parsed. */ static char * -get_history_word_specifier (spec, from, caller_index) - char *spec, *from; - int *caller_index; +get_history_word_specifier (char *spec, char *from, int *caller_index) { register int i = *caller_index; int first, last; @@ -1357,9 +1381,7 @@ get_history_word_specifier (spec, from, caller_index) tokens, so that FIRST = -1 means the next to last token on the line). If LAST is `$' the last arg from STRING is used. */ char * -history_arg_extract (first, last, string) - int first, last; - const char *string; +history_arg_extract (int first, int last, const char *string) { register int i, len; char *result; @@ -1418,9 +1440,7 @@ history_arg_extract (first, last, string) } static int -history_tokenize_word (string, ind) - const char *string; - int ind; +history_tokenize_word (const char *string, int ind) { register int i, j; int delimiter, nestdelim, delimopen; @@ -1428,7 +1448,7 @@ history_tokenize_word (string, ind) i = ind; delimiter = nestdelim = 0; - if (member (string[i], "()\n")) + if (member (string[i], "()\n")) /* XXX - included \n, but why? been here forever */ { i++; return i; @@ -1450,11 +1470,11 @@ history_tokenize_word (string, ind) } } - if (member (string[i], "<>;&|$")) + if (member (string[i], "<>;&|")) { int peek = string[i + 1]; - if (peek == string[i] && peek != '$') + if (peek == string[i]) { if (peek == '<' && string[i + 2] == '-') i++; @@ -1477,9 +1497,8 @@ history_tokenize_word (string, ind) i += 2; return i; } - /* XXX - separated out for later -- bash-4.2 */ - else if ((peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */ - (peek == '(' && string[i] == '$')) /*)*/ + /* XXX - process substitution -- separated out for later -- bash-4.2 */ + else if (peek == '(' && (string[i] == '>' || string[i] == '<')) /*)*/ { i += 2; delimopen = '('; @@ -1487,34 +1506,9 @@ history_tokenize_word (string, ind) nestdelim = 1; goto get_word; } -#if 0 - else if (peek == '\'' && string[i] == '$') - { - i += 2; /* XXX */ - return i; - } -#endif - if (string[i] != '$') - { - i++; - return i; - } - } - - /* same code also used for $(...)/<(...)/>(...) above */ - if (member (string[i], "!@?+*")) - { - int peek = string[i + 1]; - - if (peek == '(') /*)*/ - { - /* Shell extended globbing patterns */ - i += 2; - delimopen = '('; - delimiter = ')'; /* XXX - not perfect */ - nestdelim = 1; - } + i++; + return i; } get_word: @@ -1559,6 +1553,16 @@ get_word: continue; } + /* Command and process substitution; shell extended globbing patterns */ + if (nestdelim == 0 && delimiter == 0 && member (string[i], "<>$!@?+*") && string[i+1] == '(') /*)*/ + { + i += 2; + delimopen = '('; + delimiter = ')'; + nestdelim = 1; + continue; + } + if (delimiter == 0 && (member (string[i], history_word_delimiters))) break; @@ -1570,9 +1574,7 @@ get_word: } static char * -history_substring (string, start, end) - const char *string; - int start, end; +history_substring (const char *string, int start, int end) { register int len; register char *result; @@ -1589,9 +1591,7 @@ history_substring (string, start, end) WIND. The position in the returned array of strings is returned in *INDP. */ static char ** -history_tokenize_internal (string, wind, indp) - const char *string; - int wind, *indp; +history_tokenize_internal (const char *string, int wind, int *indp) { char **result; register int i, start, result_index, size; @@ -1606,7 +1606,7 @@ history_tokenize_internal (string, wind, indp) for (i = result_index = size = 0, result = (char **)NULL; string[i]; ) { /* Skip leading whitespace. */ - for (; string[i] && whitespace (string[i]); i++) + for (; string[i] && fielddelim (string[i]); i++) ; if (string[i] == 0 || string[i] == history_comment_char) return (result); @@ -1644,17 +1644,14 @@ history_tokenize_internal (string, wind, indp) /* Return an array of tokens, much as the shell might. The tokens are parsed out of STRING. */ char ** -history_tokenize (string) - const char *string; +history_tokenize (const char *string) { return (history_tokenize_internal (string, -1, (int *)NULL)); } /* Free members of WORDS from START to an empty string */ static void -freewords (words, start) - char **words; - int start; +freewords (char **words, int start) { register int i; @@ -1666,9 +1663,7 @@ freewords (words, start) in the history line LINE. Used to save the word matched by the last history !?string? search. */ static char * -history_find_word (line, ind) - char *line; - int ind; +history_find_word (char *line, int ind) { char **words, *s; int i, wind; diff --git a/readline/histfile.c b/readline/histfile.c index 5b057cd..dc64bde 100644 --- a/readline/histfile.c +++ b/readline/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989-2016 Free Software Foundation, Inc. +/* Copyright (C) 1989-2018 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -143,8 +143,7 @@ static int histfile_restore PARAMS((const char *, const char *)); filename. This only matters when you don't specify the filename to read_history (), or write_history (). */ static char * -history_filename (filename) - const char *filename; +history_filename (const char *filename) { char *return_val; const char *home; @@ -179,8 +178,7 @@ history_filename (filename) } static char * -history_backupfile (filename) - const char *filename; +history_backupfile (const char *filename) { const char *fn; char *ret, linkbuf[PATH_MAX+1]; @@ -208,8 +206,7 @@ history_backupfile (filename) } static char * -history_tempfile (filename) - const char *filename; +history_tempfile (const char *filename) { const char *fn; char *ret, linkbuf[PATH_MAX+1]; @@ -251,8 +248,7 @@ history_tempfile (filename) If FILENAME is NULL, then read from ~/.history. Returns 0 if successful, or errno if not. */ int -read_history (filename) - const char *filename; +read_history (const char *filename) { return (read_history_range (filename, 0, -1)); } @@ -263,9 +259,7 @@ read_history (filename) until the end of the file. If FILENAME is NULL, then read from ~/.history. Returns 0 if successful, or errno if not. */ int -read_history_range (filename, from, to) - const char *filename; - int from, to; +read_history_range (const char *filename, int from, int to) { register char *line_start, *line_end, *p; char *input, *buffer, *bufend, *last_ts; @@ -289,6 +283,16 @@ read_history_range (filename, from, to) if ((file < 0) || (fstat (file, &finfo) == -1)) goto error_and_exit; + if (S_ISREG (finfo.st_mode) == 0) + { +#ifdef EFTYPE + errno = EFTYPE; +#else + errno = EINVAL; +#endif + goto error_and_exit; + } + file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ @@ -298,6 +302,12 @@ read_history_range (filename, from, to) goto error_and_exit; } + if (file_size == 0) + { + free (input); + return 0; /* don't waste time if we don't have to */ + } + #ifdef HISTORY_USE_MMAP /* We map read/write and private so we can change newlines to NULs without affecting the underlying object. */ @@ -344,6 +354,7 @@ read_history_range (filename, from, to) /* Start at beginning of file, work to end. */ bufend = buffer + chars_read; + *bufend = '\0'; /* null-terminate buffer for timestamp checks */ current_line = 0; /* Heuristic: the history comment character rarely changes, so assume we @@ -385,7 +396,7 @@ read_history_range (filename, from, to) { if (HIST_TIMESTAMP_START(line_start) == 0) { - if (last_ts == NULL && history_multiline_entries) + if (last_ts == NULL && history_length > 0 && history_multiline_entries) _hs_append_history_line (history_length - 1, line_start); else add_history (line_start); @@ -427,9 +438,7 @@ read_history_range (filename, from, to) /* Save FILENAME to BACK, handling case where FILENAME is a symlink (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ static int -histfile_backup (filename, back) - const char *filename; - const char *back; +histfile_backup (const char *filename, const char *back) { #if defined (HAVE_READLINK) char linkbuf[PATH_MAX+1]; @@ -448,9 +457,7 @@ histfile_backup (filename, back) /* Restore ORIG from BACKUP handling case where ORIG is a symlink (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ static int -histfile_restore (backup, orig) - const char *backup; - const char *orig; +histfile_restore (const char *backup, const char *orig) { #if defined (HAVE_READLINK) char linkbuf[PATH_MAX+1]; @@ -470,9 +477,7 @@ histfile_restore (backup, orig) If FNAME is NULL, then use ~/.history. Writes a new file and renames it to the original name. Returns 0 on success, errno on failure. */ int -history_truncate_file (fname, lines) - const char *fname; - int lines; +history_truncate_file (const char *fname, int lines) { char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */ int file, chars_read, rv, orig_lines, exists, r; @@ -606,12 +611,14 @@ history_truncate_file (fname, lines) history_lines_written_to_file = 0; } +#if defined (HAVE_CHOWN) /* Make sure the new filename is owned by the same user as the old. If one user is running this, it's a no-op. If the shell is running after sudo with a shared history file, we don't want to leave the history file owned by root. */ if (rv == 0 && exists) r = chown (filename, finfo.st_uid, finfo.st_gid); +#endif xfree (filename); FREE (tempname); @@ -623,9 +630,7 @@ history_truncate_file (fname, lines) from the history list to FILENAME. OVERWRITE is non-zero if you wish to replace FILENAME with the entries. */ static int -history_do_write (filename, nelements, overwrite) - const char *filename; - int nelements, overwrite; +history_do_write (const char *filename, int nelements, int overwrite) { register int i; char *output, *tempname, *histname; @@ -753,12 +758,14 @@ mmap_error: history_lines_written_to_file = 0; } +#if defined (HAVE_CHOWN) /* Make sure the new filename is owned by the same user as the old. If one user is running this, it's a no-op. If the shell is running after sudo with a shared history file, we don't want to leave the history file owned by root. */ if (rv == 0 && exists) mode = chown (histname, finfo.st_uid, finfo.st_gid); +#endif FREE (histname); FREE (tempname); @@ -769,9 +776,7 @@ mmap_error: /* Append NELEMENT entries to FILENAME. The entries appended are from the end of the list minus NELEMENTs up to the end of the list. */ int -append_history (nelements, filename) - int nelements; - const char *filename; +append_history (int nelements, const char *filename) { return (history_do_write (filename, nelements, HISTORY_APPEND)); } @@ -780,8 +785,7 @@ append_history (nelements, filename) then write the history list to ~/.history. Values returned are as in read_history ().*/ int -write_history (filename) - const char *filename; +write_history (const char *filename) { return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); } diff --git a/readline/histlib.h b/readline/histlib.h index 28cad14..9627b24 100644 --- a/readline/histlib.h +++ b/readline/histlib.h @@ -51,9 +51,9 @@ #endif #ifndef member -# ifndef strchr +# if !defined (strchr) && !defined (__STDC__) extern char *strchr (); -# endif +# endif /* !strchr && !__STDC__ */ #define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) #endif @@ -69,11 +69,17 @@ extern char *strchr (); #define NO_PREV_SUBST 4 /* Possible definitions for history starting point specification. */ -#define ANCHORED_SEARCH 1 -#define NON_ANCHORED_SEARCH 0 +#define NON_ANCHORED_SEARCH 0 +#define ANCHORED_SEARCH 0x01 +#define PATTERN_SEARCH 0x02 /* Possible definitions for what style of writing the history file we want. */ #define HISTORY_APPEND 0 #define HISTORY_OVERWRITE 1 +/* internal extern function declarations used by other parts of the library */ + +/* histsearch.c */ +extern int _hs_history_patsearch PARAMS((const char *, int, int)); + #endif /* !_HISTLIB_H_ */ diff --git a/readline/history.c b/readline/history.c index 129c57a..67158b1 100644 --- a/readline/history.c +++ b/readline/history.c @@ -1,6 +1,6 @@ /* history.c -- standalone history library */ -/* Copyright (C) 1989-2015 Free Software Foundation, Inc. +/* Copyright (C) 1989-2017 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -97,7 +97,7 @@ int history_base = 1; /* Return the current HISTORY_STATE of the history. */ HISTORY_STATE * -history_get_history_state () +history_get_history_state (void) { HISTORY_STATE *state; @@ -115,8 +115,7 @@ history_get_history_state () /* Set the state of the current history array to STATE. */ void -history_set_history_state (state) - HISTORY_STATE *state; +history_set_history_state (HISTORY_STATE *state) { the_history = state->entries; history_offset = state->offset; @@ -129,7 +128,7 @@ history_set_history_state (state) /* Begin a session in which the history functions might be used. This initializes interactive variables. */ void -using_history () +using_history (void) { history_offset = history_length; } @@ -138,7 +137,7 @@ using_history () This just adds up the lengths of the_history->lines and the associated timestamps. */ int -history_total_bytes () +history_total_bytes (void) { register int i, result; @@ -151,7 +150,7 @@ history_total_bytes () /* Returns the magic number which says what history element we are looking at now. In this implementation, it returns history_offset. */ int -where_history () +where_history (void) { return (history_offset); } @@ -159,8 +158,7 @@ where_history () /* Make the current history item be the one at POS, an absolute index. Returns zero if POS is out of range, else non-zero. */ int -history_set_pos (pos) - int pos; +history_set_pos (int pos) { if (pos > history_length || pos < 0 || !the_history) return (0); @@ -172,7 +170,7 @@ history_set_pos (pos) is the actual array of data, and could be bashed or made corrupt easily. The array is terminated with a NULL pointer. */ HIST_ENTRY ** -history_list () +history_list (void) { return (the_history); } @@ -180,7 +178,7 @@ history_list () /* Return the history entry at the current position, as determined by history_offset. If there is no entry there, return a NULL pointer. */ HIST_ENTRY * -current_history () +current_history (void) { return ((history_offset == history_length) || the_history == 0) ? (HIST_ENTRY *)NULL @@ -191,7 +189,7 @@ current_history () a pointer to that entry. If there is no previous entry then return a NULL pointer. */ HIST_ENTRY * -previous_history () +previous_history (void) { return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL; } @@ -200,7 +198,7 @@ previous_history () a pointer to that entry. If there is no next entry then return a NULL pointer. */ HIST_ENTRY * -next_history () +next_history (void) { return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset]; } @@ -208,8 +206,7 @@ next_history () /* Return the history entry which is logically at OFFSET in the history array. OFFSET is relative to history_base. */ HIST_ENTRY * -history_get (offset) - int offset; +history_get (int offset) { int local_index; @@ -220,9 +217,7 @@ history_get (offset) } HIST_ENTRY * -alloc_history_entry (string, ts) - char *string; - char *ts; +alloc_history_entry (char *string, char *ts) { HIST_ENTRY *temp; @@ -236,8 +231,7 @@ alloc_history_entry (string, ts) } time_t -history_get_time (hist) - HIST_ENTRY *hist; +history_get_time (HIST_ENTRY *hist) { char *ts; time_t t; @@ -255,7 +249,7 @@ history_get_time (hist) } static char * -hist_inittime () +hist_inittime (void) { time_t t; char ts[64], *ret; @@ -275,8 +269,7 @@ hist_inittime () /* Place STRING at the end of the history list. The data field is set to NULL. */ void -add_history (string) - const char *string; +add_history (const char *string) { HIST_ENTRY *temp; int new_length; @@ -335,8 +328,7 @@ add_history (string) /* Change the time stamp of the most recent history entry to STRING. */ void -add_history_time (string) - const char *string; +add_history_time (const char *string) { HIST_ENTRY *hs; @@ -350,8 +342,7 @@ add_history_time (string) /* Free HIST and return the data so the calling application can free it if necessary and desired. */ histdata_t -free_history_entry (hist) - HIST_ENTRY *hist; +free_history_entry (HIST_ENTRY *hist) { histdata_t x; @@ -365,8 +356,7 @@ free_history_entry (hist) } HIST_ENTRY * -copy_history_entry (hist) - HIST_ENTRY *hist; +copy_history_entry (HIST_ENTRY *hist) { HIST_ENTRY *ret; char *ts; @@ -388,10 +378,7 @@ copy_history_entry (hist) the old entry so you can dispose of the data. In the case of an invalid WHICH, a NULL pointer is returned. */ HIST_ENTRY * -replace_history_entry (which, line, data) - int which; - const char *line; - histdata_t data; +replace_history_entry (int which, const char *line, histdata_t data) { HIST_ENTRY *temp, *old_value; @@ -413,17 +400,26 @@ replace_history_entry (which, line, data) end of the current line first. This can be used to construct multi-line history entries while reading lines from the history file. */ void -_hs_append_history_line (which, line) - int which; - const char *line; +_hs_append_history_line (int which, const char *line) { HIST_ENTRY *hent; - size_t newlen, curlen; + size_t newlen, curlen, minlen; char *newline; hent = the_history[which]; curlen = strlen (hent->line); - newlen = curlen + strlen (line) + 2; + minlen = curlen + strlen (line) + 2; /* min space needed */ + if (curlen > 256) /* XXX - for now */ + { + newlen = 512; /* now realloc in powers of 2 */ + /* we recalcluate every time; the operations are cheap */ + while (newlen < minlen) + newlen <<= 1; + } + else + newlen = minlen; + /* Assume that realloc returns the same pointer and doesn't try a new + alloc/copy if the new size is the same as the one last passed. */ newline = realloc (hent->line, newlen); if (newline) { @@ -440,9 +436,7 @@ _hs_append_history_line (which, line) WHICH >= 0 means to replace that particular history entry's data, as long as it matches OLD. */ void -_hs_replace_history_data (which, old, new) - int which; - histdata_t *old, *new; +_hs_replace_history_data (int which, histdata_t *old, histdata_t *new) { HIST_ENTRY *entry; register int i, last; @@ -482,29 +476,76 @@ _hs_replace_history_data (which, old, new) element is returned to you so you can free the line, data, and containing structure. */ HIST_ENTRY * -remove_history (which) - int which; +remove_history (int which) { HIST_ENTRY *return_value; register int i; +#if 1 + int nentries; + HIST_ENTRY **start, **end; +#endif if (which < 0 || which >= history_length || history_length == 0 || the_history == 0) return ((HIST_ENTRY *)NULL); return_value = the_history[which]; +#if 1 + /* Copy the rest of the entries, moving down one slot. Copy includes + trailing NULL. */ + nentries = history_length - which; + start = the_history + which; + end = start + 1; + memmove (start, end, nentries * sizeof (HIST_ENTRY *)); +#else for (i = which; i < history_length; i++) the_history[i] = the_history[i + 1]; +#endif history_length--; return (return_value); } +HIST_ENTRY ** +remove_history_range (int first, int last) +{ + HIST_ENTRY **return_value; + register int i; + int nentries; + HIST_ENTRY **start, **end; + + if (the_history == 0 || history_length == 0) + return ((HIST_ENTRY **)NULL); + if (first < 0 || first >= history_length || last < 0 || last >= history_length) + return ((HIST_ENTRY **)NULL); + if (first > last) + return (HIST_ENTRY **)NULL; + + nentries = last - first + 1; + return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *)); + if (return_value == 0) + return return_value; + + /* Return all the deleted entries in a list */ + for (i = first ; i <= last; i++) + return_value[i - first] = the_history[i]; + return_value[i - first] = (HIST_ENTRY *)NULL; + + /* Copy the rest of the entries, moving down NENTRIES slots. Copy includes + trailing NULL. */ + start = the_history + first; + end = the_history + last + 1; + memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *)); + + history_length -= nentries; + + return (return_value); +} + /* Stifle the history list, remembering only MAX number of lines. */ void -stifle_history (max) - int max; +stifle_history (int max) { register int i, j; @@ -532,7 +573,7 @@ stifle_history (max) number of history entries. The value is positive if the history was stifled, negative if it wasn't. */ int -unstifle_history () +unstifle_history (void) { if (history_stifled) { @@ -544,13 +585,13 @@ unstifle_history () } int -history_is_stifled () +history_is_stifled (void) { return (history_stifled); } void -clear_history () +clear_history (void) { register int i; @@ -562,4 +603,5 @@ clear_history () } history_offset = history_length = 0; + history_base = 1; /* reset history base to default */ } diff --git a/readline/history.h b/readline/history.h index 8ce7c80..cc3de29 100644 --- a/readline/history.h +++ b/readline/history.h @@ -86,11 +86,13 @@ extern void add_history PARAMS((const char *)); STRING. */ extern void add_history_time PARAMS((const char *)); -/* A reasonably useless function, only here for completeness. WHICH - is the magic number that tells us which element to delete. The - elements are numbered from 0. */ +/* Remove an entry from the history list. WHICH is the magic number that + tells us which element to delete. The elements are numbered from 0. */ extern HIST_ENTRY *remove_history PARAMS((int)); +/* Remove a set of entries from the history list: FIRST to LAST, inclusive */ +extern HIST_ENTRY **remove_history_range PARAMS((int, int)); + /* Allocate a history entry consisting of STRING and TIMESTAMP and return a pointer to it. */ extern HIST_ENTRY *alloc_history_entry PARAMS((char *, char *)); @@ -259,7 +261,9 @@ extern char *history_word_delimiters; extern char history_comment_char; extern char *history_no_expand_chars; extern char *history_search_delimiter_chars; + extern int history_quotes_inhibit_expansion; +extern int history_quoting_state; extern int history_write_timestamps; diff --git a/readline/histsearch.c b/readline/histsearch.c index 1ad55d2..7a426c9 100644 --- a/readline/histsearch.c +++ b/readline/histsearch.c @@ -1,6 +1,6 @@ /* histsearch.c -- searching the history list. */ -/* Copyright (C) 1989, 1992-2009 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1992-2009,2017 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -39,8 +39,13 @@ # include <unistd.h> #endif +#if defined (HAVE_FNMATCH) +# include <fnmatch.h> +#endif + #include "history.h" #include "histlib.h" +#include "xmalloc.h" /* The list of alternate characters that can delimit a history search string. */ @@ -59,18 +64,22 @@ static int history_search_internal PARAMS((const char *, int, int)); returned. */ static int -history_search_internal (string, direction, anchored) - const char *string; - int direction, anchored; +history_search_internal (const char *string, int direction, int flags) { register int i, reverse; register char *line; register int line_index; - int string_len; + int string_len, anchored, patsearch; HIST_ENTRY **the_history; /* local */ i = history_offset; reverse = (direction < 0); + anchored = (flags & ANCHORED_SEARCH); +#if defined (HAVE_FNMATCH) + patsearch = (flags & PATTERN_SEARCH); +#else + patsearch = 0; +#endif /* Take care of trivial cases first. */ if (string == 0 || *string == '\0') @@ -98,7 +107,7 @@ history_search_internal (string, direction, anchored) line_index = strlen (line); /* If STRING is longer than line, no match. */ - if (string_len > line_index) + if (patsearch == 0 && (string_len > line_index)) { NEXT_LINE (); continue; @@ -107,6 +116,17 @@ history_search_internal (string, direction, anchored) /* Handle anchored searches first. */ if (anchored == ANCHORED_SEARCH) { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line, 0) == 0) + { + history_offset = i; + return (0); + } + } + else +#endif if (STREQN (string, line, string_len)) { history_offset = i; @@ -120,10 +140,21 @@ history_search_internal (string, direction, anchored) /* Do substring search. */ if (reverse) { - line_index -= string_len; + line_index -= (patsearch == 0) ? string_len : 1; while (line_index >= 0) { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line + line_index, 0) == 0) + { + history_offset = i; + return (line_index); + } + } + else +#endif if (STREQN (string, line + line_index, string_len)) { history_offset = i; @@ -141,6 +172,17 @@ history_search_internal (string, direction, anchored) while (line_index < limit) { +#if defined (HAVE_FNMATCH) + if (patsearch) + { + if (fnmatch (string, line + line_index, 0) == 0) + { + history_offset = i; + return (line_index); + } + } + else +#endif if (STREQN (string, line + line_index, string_len)) { history_offset = i; @@ -153,20 +195,73 @@ history_search_internal (string, direction, anchored) } } +int +_hs_history_patsearch (const char *string, int direction, int flags) +{ + char *pat; + size_t len, start; + int ret, unescaped_backslash; + +#if defined (HAVE_FNMATCH) + /* Assume that the string passed does not have a leading `^' and any + anchored search request is captured in FLAGS */ + len = strlen (string); + ret = len - 1; + /* fnmatch is required to reject a pattern that ends with an unescaped + backslash */ + if (unescaped_backslash = (string[ret] == '\\')) + { + while (ret > 0 && string[--ret] == '\\') + unescaped_backslash = 1 - unescaped_backslash; + } + if (unescaped_backslash) + return -1; + pat = (char *)xmalloc (len + 3); + /* If the search string is not anchored, we'll be calling fnmatch (assuming + we have it). Prefix a `*' to the front of the search string so we search + anywhere in the line. */ + if ((flags & ANCHORED_SEARCH) == 0 && string[0] != '*') + { + pat[0] = '*'; + start = 1; + len++; + } + else + { + start = 0; + } + + /* Attempt to reduce the number of searches by tacking a `*' onto the end + of a pattern that doesn't have one. Assume a pattern that ends in a + backslash contains an even number of trailing backslashes; we check + above */ + strcpy (pat + start, string); + if (pat[len - 1] != '*') + { + pat[len] = '*'; /* XXX */ + pat[len+1] = '\0'; + } +#else + pat = string; +#endif + + ret = history_search_internal (pat, direction, flags|PATTERN_SEARCH); + + if (pat != string) + free (pat); + return ret; +} + /* Do a non-anchored search for STRING through the history in DIRECTION. */ int -history_search (string, direction) - const char *string; - int direction; +history_search (const char *string, int direction) { return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); } /* Do an anchored search for string through the history in DIRECTION. */ int -history_search_prefix (string, direction) - const char *string; - int direction; +history_search_prefix (const char *string, int direction) { return (history_search_internal (string, direction, ANCHORED_SEARCH)); } @@ -175,9 +270,7 @@ history_search_prefix (string, direction) backwards. POS is an absolute index into the history list at which point to begin searching. */ int -history_search_pos (string, dir, pos) - const char *string; - int dir, pos; +history_search_pos (const char *string, int dir, int pos) { int ret, old; diff --git a/readline/input.c b/readline/input.c index 077d53c..95ace84 100644 --- a/readline/input.c +++ b/readline/input.c @@ -1,6 +1,6 @@ /* input.c -- character input functions for readline. */ -/* Copyright (C) 1994-2015 Free Software Foundation, Inc. +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -76,6 +76,10 @@ extern int errno; # define O_NDELAY O_NONBLOCK /* Posix style */ #endif +#if defined (HAVE_PSELECT) +extern sigset_t _rl_orig_sigset; +#endif + /* Non-null means it is a pointer to a function to run while waiting for character input. */ rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL; @@ -108,10 +112,10 @@ int w32_isatty (int fd) { if (_isatty(fd)) { - HANDLE h = (HANDLE) _get_osfhandle (fd); + HANDLE h; DWORD ignored; - if (h == INVALID_HANDLE_VALUE) + if ((h = (HANDLE) _get_osfhandle (fd)) == INVALID_HANDLE_VALUE) { errno = EBADF; return 0; @@ -139,13 +143,13 @@ static int ibuffer_len = sizeof (ibuffer) - 1; #define any_typein (push_index != pop_index) int -_rl_any_typein () +_rl_any_typein (void) { return any_typein; } int -_rl_pushed_input_available () +_rl_pushed_input_available (void) { return (push_index != pop_index); } @@ -153,7 +157,7 @@ _rl_pushed_input_available () /* Return the amount of space available in the buffer for stuffing characters. */ static int -ibuffer_space () +ibuffer_space (void) { if (pop_index > push_index) return (pop_index - push_index - 1); @@ -165,8 +169,7 @@ ibuffer_space () Return the key in KEY. Result is non-zero if there was a key, or 0 if there wasn't. */ static int -rl_get_char (key) - int *key; +rl_get_char (int *key) { if (push_index == pop_index) return (0); @@ -186,8 +189,7 @@ rl_get_char (key) Returns non-zero if successful, zero if there is no space left in the buffer. */ int -_rl_unget_char (key) - int key; +_rl_unget_char (int key) { if (ibuffer_space ()) { @@ -204,7 +206,7 @@ _rl_unget_char (key) IBUFFER. Otherwise, just return. Returns number of characters read (0 if none available) and -1 on error (EIO). */ static int -rl_gather_tyi () +rl_gather_tyi (void) { int tty; register int tem, result; @@ -307,8 +309,7 @@ rl_gather_tyi () } int -rl_set_keyboard_input_timeout (u) - int u; +rl_set_keyboard_input_timeout (int u) { int o; @@ -325,7 +326,7 @@ rl_set_keyboard_input_timeout (u) the user, it should use _rl_input_queued(timeout_value_in_microseconds) instead. */ int -_rl_input_available () +_rl_input_available (void) { #if defined(HAVE_SELECT) fd_set readfds, exceptfds; @@ -367,8 +368,7 @@ _rl_input_available () } int -_rl_input_queued (t) - int t; +_rl_input_queued (int t) { int old_timeout, r; @@ -379,8 +379,7 @@ _rl_input_queued (t) } void -_rl_insert_typein (c) - int c; +_rl_insert_typein (int c) { int key, t, i; char *string; @@ -405,8 +404,7 @@ _rl_insert_typein (c) /* Add KEY to the buffer of characters to be read. Returns 1 if the character was stuffed correctly; 0 otherwise. */ int -rl_stuff_char (key) - int key; +rl_stuff_char (int key) { if (ibuffer_space () == 0) return 0; @@ -430,8 +428,7 @@ rl_stuff_char (key) /* Make C be the next command to be executed. */ int -rl_execute_next (c) - int c; +rl_execute_next (int c) { rl_pending_input = c; RL_SETSTATE (RL_STATE_INPUTPENDING); @@ -440,7 +437,7 @@ rl_execute_next (c) /* Clear any pending input pushed with rl_execute_next() */ int -rl_clear_pending_input () +rl_clear_pending_input (void) { rl_pending_input = 0; RL_UNSETSTATE (RL_STATE_INPUTPENDING); @@ -455,20 +452,20 @@ rl_clear_pending_input () /* Read a key, including pending input. */ int -rl_read_key () +rl_read_key (void) { int c, r; if (rl_pending_input) { - c = rl_pending_input; + c = rl_pending_input; /* XXX - cast to unsigned char if > 0? */ rl_clear_pending_input (); } else { /* If input is coming from a macro, then use that. */ if (c = _rl_next_macro_key ()) - return (c); + return ((unsigned char)c); /* If the user has an event function, then call it periodically. */ if (rl_event_hook) @@ -505,8 +502,7 @@ rl_read_key () } int -rl_getc (stream) - FILE *stream; +rl_getc (FILE *stream) { int result; unsigned char c; @@ -527,11 +523,15 @@ rl_getc (stream) #endif result = 0; #if defined (HAVE_PSELECT) - sigemptyset (&empty_set); - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set); FD_ZERO (&readfds); FD_SET (fileno (stream), &readfds); +# if defined (HANDLE_SIGNALS) + result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset); +# else + sigemptyset (&empty_set); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set); result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set); +# endif /* HANDLE_SIGNALS */ #endif if (result >= 0) result = read (fileno (stream), &c, sizeof (unsigned char)); @@ -618,9 +618,7 @@ handle_error: #if defined (HANDLE_MULTIBYTE) /* read multibyte char */ int -_rl_read_mbchar (mbchar, size) - char *mbchar; - int size; +_rl_read_mbchar (char *mbchar, int size) { int mb_len, c; size_t mbchar_bytes_length; @@ -669,12 +667,9 @@ _rl_read_mbchar (mbchar, size) may be FIRST. Used by the search functions, among others. Very similar to _rl_read_mbchar. */ int -_rl_read_mbstring (first, mb, mlen) - int first; - char *mb; - int mlen; +_rl_read_mbstring (int first, char *mb, int mlen) { - int i, c; + int i, c, n; mbstate_t ps; c = first; @@ -683,7 +678,8 @@ _rl_read_mbstring (first, mb, mlen) { mb[i] = (char)c; memset (&ps, 0, sizeof (mbstate_t)); - if (_rl_get_char_len (mb, &ps) == -2) + n = _rl_get_char_len (mb, &ps); + if (n == -2) { /* Read more for multibyte character */ RL_SETSTATE (RL_STATE_MOREINPUT); diff --git a/readline/isearch.c b/readline/isearch.c index 819fcbc..d6c5904 100644 --- a/readline/isearch.c +++ b/readline/isearch.c @@ -6,7 +6,7 @@ /* */ /* **************************************************************** */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -78,8 +78,7 @@ static int last_isearch_string_len; static char * const default_isearch_terminators = "\033\012"; _rl_search_cxt * -_rl_scxt_alloc (type, flags) - int type, flags; +_rl_scxt_alloc (int type, int flags) { _rl_search_cxt *cxt; @@ -120,9 +119,7 @@ _rl_scxt_alloc (type, flags) } void -_rl_scxt_dispose (cxt, flags) - _rl_search_cxt *cxt; - int flags; +_rl_scxt_dispose (_rl_search_cxt *cxt, int flags) { FREE (cxt->search_string); FREE (cxt->allocated_line); @@ -134,8 +131,7 @@ _rl_scxt_dispose (cxt, flags) /* Search backwards through the history looking for a string which is typed interactively. Start with the current line. */ int -rl_reverse_search_history (sign, key) - int sign, key; +rl_reverse_search_history (int sign, int key) { return (rl_search_history (-sign, key)); } @@ -143,8 +139,7 @@ rl_reverse_search_history (sign, key) /* Search forwards through the history looking for a string which is typed interactively. Start with the current line. */ int -rl_forward_search_history (sign, key) - int sign, key; +rl_forward_search_history (int sign, int key) { return (rl_search_history (sign, key)); } @@ -155,9 +150,7 @@ rl_forward_search_history (sign, key) WHERE is the history list number of the current line. If it is -1, then this line is the starting one. */ static void -rl_display_search (search_string, flags, where) - char *search_string; - int flags, where; +rl_display_search (char *search_string, int flags, int where) { char *message; int msglen, searchlen; @@ -206,8 +199,7 @@ rl_display_search (search_string, flags, where) } static _rl_search_cxt * -_rl_isearch_init (direction) - int direction; +_rl_isearch_init (int direction) { _rl_search_cxt *cxt; register int i; @@ -267,11 +259,10 @@ _rl_isearch_init (direction) } static void -_rl_isearch_fini (cxt) - _rl_search_cxt *cxt; +_rl_isearch_fini (_rl_search_cxt *cxt) { /* First put back the original state. */ - strcpy (rl_line_buffer, cxt->lines[cxt->save_line]); + rl_replace_line (cxt->lines[cxt->save_line], 0); rl_restore_prompt (); @@ -301,13 +292,13 @@ _rl_isearch_fini (cxt) rl_point = cxt->sline_index; /* Don't worry about where to put the mark here; rl_get_previous_history and rl_get_next_history take care of it. */ + _rl_fix_point (0); rl_clear_message (); } int -_rl_search_getchar (cxt) - _rl_search_cxt *cxt; +_rl_search_getchar (_rl_search_cxt *cxt) { int c; @@ -334,11 +325,12 @@ _rl_search_getchar (cxt) -1 if the caller should just free the context and return, 0 if we should break out of the loop, and 1 if we should continue to read characters. */ int -_rl_isearch_dispatch (cxt, c) - _rl_search_cxt *cxt; - int c; +_rl_isearch_dispatch (_rl_search_cxt *cxt, int c) { - int n, wstart, wlen, limit, cval; + int n, wstart, wlen, limit, cval, incr; + char *paste; + size_t pastelen; + int j; rl_command_func_t *f; f = (rl_command_func_t *)NULL; @@ -409,6 +401,8 @@ add_character: cxt->lastc = -5; else if (c == CTRL ('Y') || f == rl_yank) /* XXX */ cxt->lastc = -6; + else if (f == rl_bracketed_paste_begin) + cxt->lastc = -7; } /* If we changed the keymap earlier while translating a key sequence into @@ -527,7 +521,7 @@ add_character: } return (1); } - else if (cxt->sflags & SF_REVERSE) + else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0) cxt->sline_index--; else if (cxt->sline_index != cxt->sline_len) cxt->sline_index++; @@ -631,22 +625,44 @@ add_character: cxt->search_string[cxt->search_string_index] = '\0'; break; + case -7: /* bracketed paste */ + paste = _rl_bracketed_text (&pastelen); + if (paste == 0 || *paste == 0) + { + free (paste); + break; + } + if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size) + { + cxt->search_string_size += pastelen + 2; + cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); + } + strcpy (cxt->search_string + cxt->search_string_index, paste); + cxt->search_string_index += pastelen; + free (paste); + break; + /* Add character to search string and continue search. */ default: - if (cxt->search_string_index + 2 >= cxt->search_string_size) +#if defined (HANDLE_MULTIBYTE) + wlen = (cxt->mb[0] == 0 || cxt->mb[1] == 0) ? 1 : RL_STRLEN (cxt->mb); +#else + wlen = 1; +#endif + if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size) { - cxt->search_string_size += 128; + cxt->search_string_size += 128; /* 128 much greater than MB_CUR_MAX */ cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size); } #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - int j, l; + int j; if (cxt->mb[0] == 0 || cxt->mb[1] == 0) cxt->search_string[cxt->search_string_index++] = cxt->mb[0]; else - for (j = 0, l = RL_STRLEN (cxt->mb); j < l; ) + for (j = 0; j < wlen; ) cxt->search_string[cxt->search_string_index++] = cxt->mb[j++]; } else @@ -676,6 +692,12 @@ add_character: } else cxt->sline_index += cxt->direction; + + if (cxt->sline_index < 0) + { + cxt->sline_index = 0; + break; + } } if (cxt->sflags & SF_FOUND) break; @@ -703,7 +725,12 @@ add_character: (cxt->search_string_index > cxt->sline_len)); if (cxt->sflags & SF_FAILED) - break; + { + /* XXX - reset sline_index if < 0 */ + if (cxt->sline_index < 0) + cxt->sline_index = 0; + break; + } /* Now set up the line for searching... */ cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0; @@ -734,9 +761,7 @@ add_character: } int -_rl_isearch_cleanup (cxt, r) - _rl_search_cxt *cxt; - int r; +_rl_isearch_cleanup (_rl_search_cxt *cxt, int r) { if (r >= 0) _rl_isearch_fini (cxt); @@ -753,8 +778,7 @@ _rl_isearch_cleanup (cxt, r) DIRECTION is which direction to search; >= 0 means forward, < 0 means backwards. */ static int -rl_search_history (direction, invoking_key) - int direction, invoking_key; +rl_search_history (int direction, int invoking_key) { _rl_search_cxt *cxt; /* local for now, but saved globally */ int c, r; @@ -792,8 +816,7 @@ rl_search_history (direction, invoking_key) If _rl_isearch_dispatch finishes searching, this function is responsible for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */ int -_rl_isearch_callback (cxt) - _rl_search_cxt *cxt; +_rl_isearch_callback (_rl_search_cxt *cxt) { int c, r; diff --git a/readline/keymaps.c b/readline/keymaps.c index 58661e2..4ade30b 100644 --- a/readline/keymaps.c +++ b/readline/keymaps.c @@ -1,6 +1,6 @@ /* keymaps.c -- Functions and keymaps for the GNU Readline library. */ -/* Copyright (C) 1988,1989-2009 Free Software Foundation, Inc. +/* Copyright (C) 1988,1989-2009,2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -54,7 +54,7 @@ /* Return a new, empty keymap. Free it with free() when you are done. */ Keymap -rl_make_bare_keymap () +rl_make_bare_keymap (void) { register int i; Keymap keymap; @@ -77,11 +77,25 @@ rl_make_bare_keymap () return (keymap); } +/* A convenience function that returns 1 if there are no keys bound to + functions in KEYMAP */ +int +rl_empty_keymap (Keymap keymap) +{ + int i; + + for (i = 0; i < ANYOTHERKEY; i++) + { + if (keymap[i].type != ISFUNC || keymap[i].function) + return 0; + } + return 1; +} + /* Return a new keymap which is a copy of MAP. Just copies pointers, does not copy text of macros or descend into child keymaps. */ Keymap -rl_copy_keymap (map) - Keymap map; +rl_copy_keymap (Keymap map) { register int i; Keymap temp; @@ -99,7 +113,7 @@ rl_copy_keymap (map) the uppercase Meta characters bound to run their lowercase equivalents, and the Meta digits bound to produce numeric arguments. */ Keymap -rl_make_keymap () +rl_make_keymap (void) { register int i; Keymap newmap; @@ -125,8 +139,7 @@ rl_make_keymap () /* Free the storage associated with MAP. */ void -rl_discard_keymap (map) - Keymap map; +rl_discard_keymap (Keymap map) { int i; @@ -154,8 +167,7 @@ rl_discard_keymap (map) /* Convenience function that discards, then frees, MAP. */ void -rl_free_keymap (map) - Keymap map; +rl_free_keymap (Keymap map) { rl_discard_keymap (map); xfree ((char *)map); diff --git a/readline/keymaps.h b/readline/keymaps.h index af8d5d9..1fa853d 100644 --- a/readline/keymaps.h +++ b/readline/keymaps.h @@ -90,6 +90,9 @@ extern Keymap rl_get_keymap PARAMS((void)); /* Set the current keymap to MAP. */ extern void rl_set_keymap PARAMS((Keymap)); +/* Set the name of MAP to NAME */ +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + #ifdef __cplusplus } #endif diff --git a/readline/kill.c b/readline/kill.c index 696f193..cf8ca93 100644 --- a/readline/kill.c +++ b/readline/kill.c @@ -1,6 +1,6 @@ /* kill.c -- kill ring management. */ -/* Copyright (C) 1994-2015 Free Software Foundation, Inc. +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -78,8 +78,7 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int)); /* How to say that you only want to save a certain amount of kill material. */ int -rl_set_retained_kills (num) - int num; +rl_set_retained_kills (int num) { return 0; } @@ -89,9 +88,7 @@ rl_set_retained_kills (num) non-zero, and the last command was a kill, the text is appended to the current kill ring slot, otherwise prepended. */ static int -_rl_copy_to_kill_ring (text, append) - char *text; - int append; +_rl_copy_to_kill_ring (char *text, int append) { char *old, *new; int slot; @@ -122,7 +119,7 @@ _rl_copy_to_kill_ring (text, append) else { slot = rl_kill_ring_length += 1; - rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *)); + rl_kill_ring = (char **)xrealloc (rl_kill_ring, (slot + 1) * sizeof (char *)); } rl_kill_ring[--slot] = (char *)NULL; } @@ -131,7 +128,7 @@ _rl_copy_to_kill_ring (text, append) slot = rl_kill_ring_length - 1; /* If the last command was a kill, prepend or append. */ - if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) + if (_rl_last_command_was_kill && rl_kill_ring[slot] && rl_editing_mode != vi_mode) { old = rl_kill_ring[slot]; new = (char *)xmalloc (1 + strlen (old) + strlen (text)); @@ -163,8 +160,7 @@ _rl_copy_to_kill_ring (text, append) last command was not a kill command, then a new slot is made for this kill. */ int -rl_kill_text (from, to) - int from, to; +rl_kill_text (int from, int to) { char *text; @@ -198,8 +194,7 @@ rl_kill_text (from, to) /* Delete the word at point, saving the text in the kill ring. */ int -rl_kill_word (count, key) - int count, key; +rl_kill_word (int count, int key) { int orig_point; @@ -222,17 +217,16 @@ rl_kill_word (count, key) /* Rubout the word before point, placing it on the kill ring. */ int -rl_backward_kill_word (count, ignore) - int count, ignore; +rl_backward_kill_word (int count, int key) { int orig_point; if (count < 0) - return (rl_kill_word (-count, ignore)); + return (rl_kill_word (-count, key)); else { orig_point = rl_point; - rl_backward_word (count, ignore); + rl_backward_word (count, key); if (rl_point != orig_point) rl_kill_text (orig_point, rl_point); @@ -246,17 +240,16 @@ rl_backward_kill_word (count, ignore) /* Kill from here to the end of the line. If DIRECTION is negative, kill back to the line start instead. */ int -rl_kill_line (direction, ignore) - int direction, ignore; +rl_kill_line (int direction, int key) { int orig_point; if (direction < 0) - return (rl_backward_kill_line (1, ignore)); + return (rl_backward_kill_line (1, key)); else { orig_point = rl_point; - rl_end_of_line (1, ignore); + rl_end_of_line (1, key); if (orig_point != rl_point) rl_kill_text (orig_point, rl_point); rl_point = orig_point; @@ -269,13 +262,12 @@ rl_kill_line (direction, ignore) /* Kill backwards to the start of the line. If DIRECTION is negative, kill forwards to the line end instead. */ int -rl_backward_kill_line (direction, ignore) - int direction, ignore; +rl_backward_kill_line (int direction, int key) { int orig_point; if (direction < 0) - return (rl_kill_line (1, ignore)); + return (rl_kill_line (1, key)); else { if (rl_point == 0) @@ -283,7 +275,7 @@ rl_backward_kill_line (direction, ignore) else { orig_point = rl_point; - rl_beg_of_line (1, ignore); + rl_beg_of_line (1, key); if (rl_point != orig_point) rl_kill_text (orig_point, rl_point); if (rl_editing_mode == emacs_mode) @@ -295,8 +287,7 @@ rl_backward_kill_line (direction, ignore) /* Kill the whole line, no matter where point is. */ int -rl_kill_full_line (count, ignore) - int count, ignore; +rl_kill_full_line (int count, int key) { rl_begin_undo_group (); rl_point = 0; @@ -313,8 +304,7 @@ rl_kill_full_line (count, ignore) /* This does what C-w does in Unix. We can't prevent people from using behaviour that they expect. */ int -rl_unix_word_rubout (count, key) - int count, key; +rl_unix_word_rubout (int count, int key) { int orig_point; @@ -332,7 +322,7 @@ rl_unix_word_rubout (count, key) rl_point--; while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0)) - rl_point--; + rl_point--; /* XXX - multibyte? */ } rl_kill_text (orig_point, rl_point); @@ -346,8 +336,7 @@ rl_unix_word_rubout (count, key) /* This deletes one filename component in a Unix pathname. That is, it deletes backward to directory separator (`/') or whitespace. */ int -rl_unix_filename_rubout (count, key) - int count, key; +rl_unix_filename_rubout (int count, int key) { int orig_point, c; @@ -370,7 +359,7 @@ rl_unix_filename_rubout (count, key) while (rl_point && (whitespace (c) == 0) && c != '/') { - rl_point--; + rl_point--; /* XXX - multibyte? */ c = rl_line_buffer[rl_point - 1]; } } @@ -390,8 +379,7 @@ rl_unix_filename_rubout (count, key) into the line at all, and if you aren't, then you know what you are doing. */ int -rl_unix_line_discard (count, key) - int count, key; +rl_unix_line_discard (int count, int key) { if (rl_point == 0) rl_ding (); @@ -408,8 +396,7 @@ rl_unix_line_discard (count, key) /* Copy the text in the `region' to the kill ring. If DELETE is non-zero, delete the text from the line as well. */ static int -region_kill_internal (delete) - int delete; +region_kill_internal (int delete) { char *text; @@ -427,16 +414,14 @@ region_kill_internal (delete) /* Copy the text in the region to the kill ring. */ int -rl_copy_region_to_kill (count, ignore) - int count, ignore; +rl_copy_region_to_kill (int count, int key) { return (region_kill_internal (0)); } /* Kill the text between the point and mark. */ int -rl_kill_region (count, ignore) - int count, ignore; +rl_kill_region (int count, int key) { int r, npoint; @@ -450,8 +435,7 @@ rl_kill_region (count, ignore) /* Copy COUNT words to the kill ring. DIR says which direction we look to find the words. */ static int -_rl_copy_word_as_kill (count, dir) - int count, dir; +_rl_copy_word_as_kill (int count, int dir) { int om, op, r; @@ -479,8 +463,7 @@ _rl_copy_word_as_kill (count, dir) } int -rl_copy_forward_word (count, key) - int count, key; +rl_copy_forward_word (int count, int key) { if (count < 0) return (rl_copy_backward_word (-count, key)); @@ -489,8 +472,7 @@ rl_copy_forward_word (count, key) } int -rl_copy_backward_word (count, key) - int count, key; +rl_copy_backward_word (int count, int key) { if (count < 0) return (rl_copy_forward_word (-count, key)); @@ -500,8 +482,7 @@ rl_copy_backward_word (count, key) /* Yank back the last killed text. This ignores arguments. */ int -rl_yank (count, ignore) - int count, ignore; +rl_yank (int count, int key) { if (rl_kill_ring == 0) { @@ -519,8 +500,7 @@ rl_yank (count, ignore) delete that text from the line, rotate the index down, and yank back some other text. */ int -rl_yank_pop (count, key) - int count, key; +rl_yank_pop (int count, int key) { int l, n; @@ -552,8 +532,7 @@ rl_yank_pop (count, key) #if defined (VI_MODE) int -rl_vi_yank_pop (count, key) - int count, key; +rl_vi_yank_pop (int count, int key) { int l, n; @@ -587,8 +566,7 @@ rl_vi_yank_pop (count, key) /* Yank the COUNTh argument from the previous history line, skipping HISTORY_SKIP lines before looking for the `previous line'. */ static int -rl_yank_nth_arg_internal (count, ignore, history_skip) - int count, ignore, history_skip; +rl_yank_nth_arg_internal (int count, int key, int history_skip) { register HIST_ENTRY *entry; char *arg; @@ -629,7 +607,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip) inserts it right *after* rl_point. */ if (rl_editing_mode == vi_mode) { - rl_vi_append_mode (1, ignore); + rl_vi_append_mode (1, key); rl_insert_text (" "); } #endif /* VI_MODE */ @@ -643,18 +621,16 @@ rl_yank_nth_arg_internal (count, ignore, history_skip) /* Yank the COUNTth argument from the previous history line. */ int -rl_yank_nth_arg (count, ignore) - int count, ignore; +rl_yank_nth_arg (int count, int key) { - return (rl_yank_nth_arg_internal (count, ignore, 0)); + return (rl_yank_nth_arg_internal (count, key, 0)); } /* Yank the last argument from the previous history line. This `knows' how rl_yank_nth_arg treats a count of `$'. With an argument, this behaves the same as rl_yank_nth_arg. */ int -rl_yank_last_arg (count, key) - int count, key; +rl_yank_last_arg (int count, int key) { static int history_skip = 0; static int explicit_arg_p = 0; @@ -694,17 +670,16 @@ rl_yank_last_arg (count, key) `bracketed paste' sequence, read the rest of the pasted input until the closing sequence and insert the pasted text as a single unit without interpretation. */ -int -rl_bracketed_paste_begin (count, key) - int count, key; +char * +_rl_bracketed_text (size_t *lenp) { - int retval, c; + int c; size_t len, cap; char *buf; - retval = 1; len = 0; buf = xmalloc (cap = 64); + buf[0] = '\0'; RL_SETSTATE (RL_STATE_MOREINPUT); while ((c = rl_read_key ()) >= 0) @@ -733,20 +708,33 @@ rl_bracketed_paste_begin (count, key) if (len == cap) buf = xrealloc (buf, cap + 1); buf[len] = '\0'; - retval = rl_insert_text (buf); } + if (lenp) + *lenp = len; + return (buf); +} + +int +rl_bracketed_paste_begin (int count, int key) +{ + int retval, c; + size_t len, cap; + char *buf; + + buf = _rl_bracketed_text (&len); + retval = rl_insert_text (buf) == len ? 0 : 1; + xfree (buf); return (retval); } -/* A special paste command for Windows users.. */ +/* A special paste command for Windows users. */ #if defined (_WIN32) #include <windows.h> int -rl_paste_from_clipboard (count, key) - int count, key; +rl_paste_from_clipboard (int count, int key) { char *data, *ptr; int len; diff --git a/readline/macro.c b/readline/macro.c index c7017cc..92cc55c 100644 --- a/readline/macro.c +++ b/readline/macro.c @@ -1,6 +1,6 @@ /* macro.c -- keyboard macros for readline. */ -/* Copyright (C) 1994-2009 Free Software Foundation, Inc. +/* Copyright (C) 1994-2009,2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -49,6 +49,8 @@ #include "rlprivate.h" #include "xmalloc.h" +#define MAX_MACRO_LEVEL 16 + /* **************************************************************** */ /* */ /* Hacking Keyboard Macros */ @@ -83,13 +85,24 @@ struct saved_macro { /* The list of saved macros. */ static struct saved_macro *macro_list = (struct saved_macro *)NULL; +static int macro_level = 0; + /* Set up to read subsequent input from STRING. STRING is free ()'ed when we are done with it. */ void -_rl_with_macro_input (string) - char *string; +_rl_with_macro_input (char *string) { - _rl_push_executing_macro (); + if (macro_level > MAX_MACRO_LEVEL) + { + _rl_errmsg ("maximum macro execution nesting level exceeded"); + _rl_abort_internal (); + return; + } + +#if 0 + if (rl_executing_macro) /* XXX - later */ +#endif + _rl_push_executing_macro (); rl_executing_macro = string; executing_macro_index = 0; RL_SETSTATE(RL_STATE_MACROINPUT); @@ -98,7 +111,7 @@ _rl_with_macro_input (string) /* Return the next character available from a macro, or 0 if there are no macro characters. */ int -_rl_next_macro_key () +_rl_next_macro_key (void) { int c; @@ -117,12 +130,26 @@ _rl_next_macro_key () _rl_pop_executing_macro (); return c; #else + /* XXX - consider doing the same as the callback code, just not testing + whether we're running in callback mode */ return (rl_executing_macro[executing_macro_index++]); #endif } int -_rl_prev_macro_key () +_rl_peek_macro_key (void) +{ + if (rl_executing_macro == 0) + return (0); + if (rl_executing_macro[executing_macro_index] == 0 && (macro_list == 0 || macro_list->string == 0)) + return (0); + if (rl_executing_macro[executing_macro_index] == 0 && macro_list && macro_list->string) + return (macro_list->string[0]); + return (rl_executing_macro[executing_macro_index]); +} + +int +_rl_prev_macro_key (void) { if (rl_executing_macro == 0) return (0); @@ -136,7 +163,7 @@ _rl_prev_macro_key () /* Save the currently executing macro on a stack of saved macros. */ void -_rl_push_executing_macro () +_rl_push_executing_macro (void) { struct saved_macro *saver; @@ -146,12 +173,14 @@ _rl_push_executing_macro () saver->string = rl_executing_macro; macro_list = saver; + + macro_level++; } /* Discard the current macro, replacing it with the one on the top of the stack of saved macros. */ void -_rl_pop_executing_macro () +_rl_pop_executing_macro (void) { struct saved_macro *macro; @@ -168,14 +197,15 @@ _rl_pop_executing_macro () xfree (macro); } + macro_level--; + if (rl_executing_macro == 0) RL_UNSETSTATE(RL_STATE_MACROINPUT); } /* Add a character to the macro being built. */ void -_rl_add_macro_char (c) - int c; +_rl_add_macro_char (int c) { if (current_macro_index + 1 >= current_macro_size) { @@ -190,7 +220,7 @@ _rl_add_macro_char (c) } void -_rl_kill_kbd_macro () +_rl_kill_kbd_macro (void) { if (current_macro) { @@ -213,8 +243,7 @@ _rl_kill_kbd_macro () definition to the end of the existing macro, and start by re-executing the existing macro. */ int -rl_start_kbd_macro (ignore1, ignore2) - int ignore1, ignore2; +rl_start_kbd_macro (int ignore1, int ignore2) { if (RL_ISSTATE (RL_STATE_MACRODEF)) { @@ -238,8 +267,7 @@ rl_start_kbd_macro (ignore1, ignore2) A numeric argument says to execute the macro right now, that many times, counting the definition as the first time. */ int -rl_end_kbd_macro (count, ignore) - int count, ignore; +rl_end_kbd_macro (int count, int ignore) { if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) { @@ -258,8 +286,7 @@ rl_end_kbd_macro (count, ignore) /* Execute the most recently defined keyboard macro. COUNT says how many times to execute it. */ int -rl_call_last_kbd_macro (count, ignore) - int count, ignore; +rl_call_last_kbd_macro (int count, int ignore) { if (current_macro == 0) _rl_abort_internal (); @@ -277,8 +304,7 @@ rl_call_last_kbd_macro (count, ignore) } int -rl_print_last_kbd_macro (count, ignore) - int count, ignore; +rl_print_last_kbd_macro (int count, int ignore) { char *m; @@ -300,8 +326,7 @@ rl_print_last_kbd_macro (count, ignore) } void -rl_push_macro_input (macro) - char *macro; +rl_push_macro_input (char *macro) { _rl_with_macro_input (macro); } diff --git a/readline/mbutil.c b/readline/mbutil.c index 314a49b..1771635 100644 --- a/readline/mbutil.c +++ b/readline/mbutil.c @@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001-2015 Free Software Foundation, Inc. +/* Copyright (C) 2001-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -75,10 +75,59 @@ int _rl_utf8locale = 0; #if defined(HANDLE_MULTIBYTE) +/* **************************************************************** */ +/* */ +/* UTF-8 specific Character Utility Functions */ +/* */ +/* **************************************************************** */ + +/* Return the length in bytes of the possibly-multibyte character beginning + at S. Encoding is UTF-8. */ +static int +_rl_utf8_mblen (const char *s, size_t n) +{ + unsigned char c, c1; + + if (s == 0) + return (0); /* no shift states */ + if (n <= 0) + return (-1); + + c = (unsigned char)*s; + if (c < 0x80) + return (c != 0); + if (c >= 0xc2) + { + c1 = (unsigned char)s[1]; + if (c < 0xe0) + { + if (n >= 2 && (s[1] ^ 0x80) < 0x40) + return 2; + } + else if (c < 0xf0) + { + if (n >= 3 + && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || c1 >= 0xa0) + && (c != 0xed || c1 < 0xa0)) + return 3; + } + else if (c < 0xf8) + { + if (n >= 4 + && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || c1 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c1 < 0x90))) + return 4; + } + } + /* invalid or incomplete multibyte character */ + return -1; +} + static int -_rl_find_next_mbchar_internal (string, seed, count, find_non_zero) - char *string; - int seed, count, find_non_zero; +_rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero) { size_t tmp, len; mbstate_t ps; @@ -94,6 +143,11 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) return seed; point = seed + _rl_adjust_point (string, seed, &ps); + /* if _rl_adjust_point returns -1, the character or string is invalid. + treat as a byte. */ + if (point == seed - 1) /* invalid */ + return seed + 1; + /* if this is true, means that seed was not pointing to a byte indicating the beginning of a multibyte character. Correct the point and consume one char. */ @@ -105,7 +159,14 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) len = strlen (string + point); if (len == 0) break; - tmp = mbrtowc (&wc, string+point, len, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string+point, len, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* invalid bytes. assume a byte represents a character */ @@ -146,9 +207,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) } /*static*/ int -_rl_find_prev_mbchar_internal (string, seed, find_non_zero) - char *string; - int seed, find_non_zero; +_rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero) { mbstate_t ps; int prev, non_zero_prev, point, length; @@ -166,10 +225,17 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) prev = non_zero_prev = point = 0; while (point < seed) { - tmp = mbrtowc (&wc, string + point, length - point, &ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point])) + { + tmp = 1; + wc = (wchar_t) string[point]; + memset(&ps, 0, sizeof(mbstate_t)); + } + else + tmp = mbrtowc (&wc, string + point, length - point, &ps); if (MB_INVALIDCH ((size_t)tmp)) { - /* in this case, bytes are invalid or shorted to compose + /* in this case, bytes are invalid or too short to compose multibyte char, so assume that the first byte represents a single character anyway. */ tmp = 1; @@ -206,16 +272,23 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) if an invalid multibyte sequence was encountered. It returns (size_t)(-2) if it couldn't parse a complete multibyte character. */ int -_rl_get_char_len (src, ps) - char *src; - mbstate_t *ps; +_rl_get_char_len (char *src, mbstate_t *ps) { - size_t tmp; + size_t tmp, l; + int mb_cur_max; - tmp = mbrlen((const char *)src, (size_t)strlen (src), ps); + /* Look at no more than MB_CUR_MAX characters */ + l = (size_t)strlen (src); + if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src)) + tmp = (*src != 0) ? 1 : 0; + else + { + mb_cur_max = MB_CUR_MAX; + tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps); + } if (tmp == (size_t)(-2)) { - /* shorted to compose multibyte char */ + /* too short to compose multibyte char */ if (ps) memset (ps, 0, sizeof(mbstate_t)); return -2; @@ -237,13 +310,7 @@ _rl_get_char_len (src, ps) /* compare the specified two characters. If the characters matched, return 1. Otherwise return 0. */ int -_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) - char *buf1; - int pos1; - mbstate_t *ps1; - char *buf2; - int pos2; - mbstate_t *ps2; +_rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, mbstate_t *ps2) { int i, w1, w2; @@ -263,18 +330,16 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) /* adjust pointed byte and find mbstate of the point of string. adjusted point will be point <= adjusted_point, and returns differences of the byte(adjusted_point - point). - if point is invalied (point < 0 || more than string length), + if point is invalid (point < 0 || more than string length), it returns -1 */ int -_rl_adjust_point (string, point, ps) - char *string; - int point; - mbstate_t *ps; +_rl_adjust_point (char *string, int point, mbstate_t *ps) { - size_t tmp = 0; - int length; - int pos = 0; + size_t tmp; + int length, pos; + tmp = 0; + pos = 0; length = strlen(string); if (point < 0) return -1; @@ -283,10 +348,13 @@ _rl_adjust_point (string, point, ps) while (pos < point) { - tmp = mbrlen (string + pos, length - pos, ps); + if (_rl_utf8locale && UTF8_SINGLEBYTE(string[pos])) + tmp = 1; + else + tmp = mbrlen (string + pos, length - pos, ps); if (MB_INVALIDCH ((size_t)tmp)) { - /* in this case, bytes are invalid or shorted to compose + /* in this case, bytes are invalid or too short to compose multibyte char, so assume that the first byte represents a single character anyway. */ pos++; @@ -305,11 +373,7 @@ _rl_adjust_point (string, point, ps) } int -_rl_is_mbchar_matched (string, seed, end, mbchar, length) - char *string; - int seed, end; - char *mbchar; - int length; +_rl_is_mbchar_matched (char *string, int seed, int end, char *mbchar, int length) { int i; @@ -323,9 +387,7 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length) } wchar_t -_rl_char_value (buf, ind) - char *buf; - int ind; +_rl_char_value (char *buf, int ind) { size_t tmp; wchar_t wc; @@ -334,9 +396,13 @@ _rl_char_value (buf, ind) if (MB_LEN_MAX == 1 || rl_byte_oriented) return ((wchar_t) buf[ind]); + if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind])) + return ((wchar_t) buf[ind]); l = strlen (buf); if (ind >= l - 1) return ((wchar_t) buf[ind]); + if (l < ind) /* Sanity check */ + l = strlen (buf+ind); memset (&ps, 0, sizeof (mbstate_t)); tmp = mbrtowc (&wc, buf + ind, l - ind, &ps); if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) @@ -350,9 +416,7 @@ _rl_char_value (buf, ind) characters. */ #undef _rl_find_next_mbchar int -_rl_find_next_mbchar (string, seed, count, flags) - char *string; - int seed, count, flags; +_rl_find_next_mbchar (char *string, int seed, int count, int flags) { #if defined (HANDLE_MULTIBYTE) return _rl_find_next_mbchar_internal (string, seed, count, flags); @@ -366,9 +430,7 @@ _rl_find_next_mbchar (string, seed, count, flags) we look for non-zero-width multibyte characters. */ #undef _rl_find_prev_mbchar int -_rl_find_prev_mbchar (string, seed, flags) - char *string; - int seed, flags; +_rl_find_prev_mbchar (char *string, int seed, int flags) { #if defined (HANDLE_MULTIBYTE) return _rl_find_prev_mbchar_internal (string, seed, flags); diff --git a/readline/misc.c b/readline/misc.c index f7acdee..64b1457 100644 --- a/readline/misc.c +++ b/readline/misc.c @@ -1,6 +1,6 @@ /* misc.c -- miscellaneous bindable readline functions. */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -76,7 +76,7 @@ int _rl_history_saved_point = -1; /* **************************************************************** */ int -_rl_arg_overflow () +_rl_arg_overflow (void) { if (rl_numeric_arg > 1000000) { @@ -92,7 +92,7 @@ _rl_arg_overflow () } void -_rl_arg_init () +_rl_arg_init (void) { rl_save_prompt (); _rl_argcxt = 0; @@ -100,7 +100,7 @@ _rl_arg_init () } int -_rl_arg_getchar () +_rl_arg_getchar (void) { int c; @@ -116,9 +116,7 @@ _rl_arg_getchar () argument should be aborted, 0 if we should not read any more chars, and 1 if we should continue to read chars. */ int -_rl_arg_dispatch (cxt, c) - _rl_arg_cxt cxt; - int c; +_rl_arg_dispatch (_rl_arg_cxt cxt, int c) { int key, r; @@ -193,7 +191,7 @@ _rl_arg_dispatch (cxt, c) /* Handle C-u style numeric args, as well as M--, and M-digits. */ static int -rl_digit_loop () +rl_digit_loop (void) { int c, r; @@ -220,7 +218,7 @@ rl_digit_loop () /* Create a default argument. */ void -_rl_reset_argument () +_rl_reset_argument (void) { rl_numeric_arg = rl_arg_sign = 1; rl_explicit_arg = 0; @@ -229,8 +227,7 @@ _rl_reset_argument () /* Start a numeric argument with initial value KEY */ int -rl_digit_argument (ignore, key) - int ignore, key; +rl_digit_argument (int ignore, int key) { _rl_arg_init (); if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -250,8 +247,7 @@ rl_digit_argument (ignore, key) Read a key. If the key has nothing to do with arguments, then dispatch on it. If the key is the abort character then abort. */ int -rl_universal_argument (count, key) - int count, key; +rl_universal_argument (int count, int key) { _rl_arg_init (); rl_numeric_arg *= 4; @@ -260,8 +256,7 @@ rl_universal_argument (count, key) } int -_rl_arg_callback (cxt) - _rl_arg_cxt cxt; +_rl_arg_callback (_rl_arg_cxt cxt) { int c, r; @@ -280,12 +275,14 @@ _rl_arg_callback (cxt) } r = _rl_arg_dispatch (cxt, c); + if (r > 0) + rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg); return (r != 1); } /* What to do when you abort reading an argument. */ int -rl_discard_argument () +rl_discard_argument (void) { rl_ding (); rl_clear_message (); @@ -310,7 +307,7 @@ HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL; /* Set the history pointer back to the last entry in the history. */ void -_rl_start_using_history () +_rl_start_using_history (void) { using_history (); if (_rl_saved_line_for_history) @@ -321,8 +318,7 @@ _rl_start_using_history () /* Free the contents (and containing structure) of a HIST_ENTRY. */ void -_rl_free_history_entry (entry) - HIST_ENTRY *entry; +_rl_free_history_entry (HIST_ENTRY *entry) { if (entry == 0) return; @@ -335,7 +331,7 @@ _rl_free_history_entry (entry) /* Perhaps put back the current line if it has changed. */ int -rl_maybe_replace_line () +rl_maybe_replace_line (void) { HIST_ENTRY *temp; @@ -353,7 +349,7 @@ rl_maybe_replace_line () /* Restore the _rl_saved_line_for_history if there is one. */ int -rl_maybe_unsave_line () +rl_maybe_unsave_line (void) { if (_rl_saved_line_for_history) { @@ -372,7 +368,7 @@ rl_maybe_unsave_line () /* Save the current line in _rl_saved_line_for_history. */ int -rl_maybe_save_line () +rl_maybe_save_line (void) { if (_rl_saved_line_for_history == 0) { @@ -386,7 +382,7 @@ rl_maybe_save_line () } int -_rl_free_saved_history_line () +_rl_free_saved_history_line (void) { if (_rl_saved_line_for_history) { @@ -397,7 +393,7 @@ _rl_free_saved_history_line () } static void -_rl_history_set_point () +_rl_history_set_point (void) { rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1) ? _rl_history_saved_point @@ -415,9 +411,7 @@ _rl_history_set_point () } void -rl_replace_from_history (entry, flags) - HIST_ENTRY *entry; - int flags; /* currently unused */ +rl_replace_from_history (HIST_ENTRY *entry, int flags) { /* Can't call with `1' because rl_undo_list might point to an undo list from a history entry, just like we're setting up here. */ @@ -441,7 +435,7 @@ rl_replace_from_history (entry, flags) intended to be called while actively editing, and the current line is not assumed to have been added to the history list. */ void -_rl_revert_all_lines () +_rl_revert_all_lines (void) { int hpos; HIST_ENTRY *entry; @@ -490,7 +484,7 @@ _rl_revert_all_lines () to an UNDO_LIST * saved as some history entry's data member. This should not be called while editing is active. */ void -rl_clear_history () +rl_clear_history (void) { HIST_ENTRY **hlist, *hent; register int i; @@ -524,16 +518,14 @@ rl_clear_history () /* Meta-< goes to the start of the history. */ int -rl_beginning_of_history (count, key) - int count, key; +rl_beginning_of_history (int count, int key) { return (rl_get_previous_history (1 + where_history (), key)); } /* Meta-> goes to the end of the history. (The current line). */ int -rl_end_of_history (count, key) - int count, key; +rl_end_of_history (int count, int key) { rl_maybe_replace_line (); using_history (); @@ -543,8 +535,7 @@ rl_end_of_history (count, key) /* Move down to the next history line. */ int -rl_get_next_history (count, key) - int count, key; +rl_get_next_history (int count, int key) { HIST_ENTRY *temp; @@ -582,15 +573,14 @@ rl_get_next_history (count, key) /* Get the previous item out of our interactive history, making it the current line. If there is no previous history, just ding. */ int -rl_get_previous_history (count, key) - int count, key; +rl_get_previous_history (int count, int key) { HIST_ENTRY *old_temp, *temp; if (count < 0) return (rl_get_next_history (-count, key)); - if (count == 0) + if (count == 0 || history_list () == 0) return 0; /* either not saved by rl_newline or at end of line, so set appropriately. */ @@ -620,7 +610,10 @@ rl_get_previous_history (count, key) temp = old_temp; if (temp == 0) - rl_ding (); + { + rl_maybe_unsave_line (); + rl_ding (); + } else { rl_replace_from_history (temp, 0); @@ -637,8 +630,7 @@ rl_get_previous_history (count, key) /* **************************************************************** */ /* How to toggle back and forth between editing modes. */ int -rl_vi_editing_mode (count, key) - int count, key; +rl_vi_editing_mode (int count, int key) { #if defined (VI_MODE) _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ @@ -650,8 +642,7 @@ rl_vi_editing_mode (count, key) } int -rl_emacs_editing_mode (count, key) - int count, key; +rl_emacs_editing_mode (int count, int key) { rl_editing_mode = emacs_mode; _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */ @@ -665,8 +656,7 @@ rl_emacs_editing_mode (count, key) /* Function for the rest of the library to use to set insert/overwrite mode. */ void -_rl_set_insert_mode (im, force) - int im, force; +_rl_set_insert_mode (int im, int force) { #ifdef CURSOR_MODE _rl_set_cursor (im, force); @@ -678,8 +668,7 @@ _rl_set_insert_mode (im, force) /* Toggle overwrite mode. A positive explicit argument selects overwrite mode. A negative or zero explicit argument selects insert mode. */ int -rl_overwrite_mode (count, key) - int count, key; +rl_overwrite_mode (int count, int key) { if (rl_explicit_arg == 0) _rl_set_insert_mode (rl_insert_mode ^ 1, 0); diff --git a/readline/nls.c b/readline/nls.c index d3b3634..d2f67e0 100644 --- a/readline/nls.c +++ b/readline/nls.c @@ -1,6 +1,6 @@ /* nls.c -- skeletal internationalization code. */ -/* Copyright (C) 1996-2009 Free Software Foundation, Inc. +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -74,6 +74,7 @@ static char *legal_lang_values[] = "iso88599", "iso885910", "koi8r", + "utf8", 0 }; @@ -85,8 +86,7 @@ static char *find_codeset PARAMS((char *, size_t *)); static char *_rl_get_locale_var PARAMS((const char *)); static char * -_rl_get_locale_var (v) - const char *v; +_rl_get_locale_var (const char *v) { char *lspec; @@ -100,8 +100,7 @@ _rl_get_locale_var (v) } static int -utf8locale (lspec) - char *lspec; +utf8locale (char *lspec) { char *cp; size_t len; @@ -118,16 +117,12 @@ utf8locale (lspec) #endif } -/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value - to decide the defaults for 8-bit character input and output. Returns - 1 if we set eight-bit mode. */ -int -_rl_init_eightbit () +/* Query the right environment variables and call setlocale() to initialize + the C library locale settings. */ +char * +_rl_init_locale (void) { -/* If we have setlocale(3), just check the current LC_CTYPE category - value, and go into eight-bit mode if it's not C or POSIX. */ -#if defined (HAVE_SETLOCALE) - char *lspec, *t; + char *ret, *lspec; /* Set the LC_CTYPE locale category from environment variables. */ lspec = _rl_get_locale_var ("LC_CTYPE"); @@ -140,10 +135,25 @@ _rl_init_eightbit () lspec = setlocale (LC_CTYPE, (char *)NULL); if (lspec == 0) lspec = ""; - t = setlocale (LC_CTYPE, lspec); + ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */ + + _rl_utf8locale = (ret && *ret) ? utf8locale (ret) : 0; + + return ret; +} + +/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value + to decide the defaults for 8-bit character input and output. Returns + 1 if we set eight-bit mode. */ +int +_rl_init_eightbit (void) +{ +/* If we have setlocale(3), just check the current LC_CTYPE category + value, and go into eight-bit mode if it's not C or POSIX. */ +#if defined (HAVE_SETLOCALE) + char *lspec, *t; - if (t && *t) - _rl_utf8locale = utf8locale (t); + t = _rl_init_locale (); /* returns static pointer */ if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0)) { @@ -174,16 +184,17 @@ _rl_init_eightbit () _rl_output_meta_chars = 1; break; } + + _rl_utf8locale = *t ? STREQ (t, "utf8") : 0; + xfree (t); return (legal_lang_values[i] ? 1 : 0); - #endif /* !HAVE_SETLOCALE */ } #if !defined (HAVE_SETLOCALE) static char * -normalize_codeset (codeset) - char *codeset; +normalize_codeset (char *codeset) { size_t namelen, i; int len, all_digits; @@ -230,9 +241,7 @@ normalize_codeset (codeset) /* Isolate codeset portion of locale specification. */ static char * -find_codeset (name, lenp) - char *name; - size_t *lenp; +find_codeset (char *name, size_t *lenp) { char *cp, *language, *result; diff --git a/readline/parens.c b/readline/parens.c index ecc465c..af47977 100644 --- a/readline/parens.c +++ b/readline/parens.c @@ -1,6 +1,6 @@ /* parens.c -- implementation of matching parentheses feature. */ -/* Copyright (C) 1987, 1989, 1992-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987, 1989, 1992-2015, 2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -64,8 +64,7 @@ static int _paren_blink_usec = 500000; /* Change emacs_standard_keymap to have bindings for paren matching when ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */ void -_rl_enable_paren_matching (on_or_off) - int on_or_off; +_rl_enable_paren_matching (int on_or_off) { if (on_or_off) { @@ -98,8 +97,7 @@ _rl_enable_paren_matching (on_or_off) } int -rl_set_paren_blink_timeout (u) - int u; +rl_set_paren_blink_timeout (int u) { int o; @@ -110,8 +108,7 @@ rl_set_paren_blink_timeout (u) } int -rl_insert_close (count, invoking_key) - int count, invoking_key; +rl_insert_close (int count, int invoking_key) { if (rl_explicit_arg || !rl_blink_matching_paren) _rl_insert_char (count, invoking_key); @@ -148,9 +145,7 @@ rl_insert_close (count, invoking_key) } static int -find_matching_open (string, from, closer) - char *string; - int from, closer; +find_matching_open (char *string, int from, int closer) { register int i; int opener, level, delimiter; diff --git a/readline/parse-colors.c b/readline/parse-colors.c index 98b2e9d..05ec9bc 100644 --- a/readline/parse-colors.c +++ b/readline/parse-colors.c @@ -2,8 +2,8 @@ Modified by Chet Ramey for Readline. - Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation, - Inc. + Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2017 + Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -297,7 +297,7 @@ get_funky_string (char **dest, const char **src, bool equals_end, size_t *output } #endif /* COLOR_SUPPORT */ -void _rl_parse_colors() +void _rl_parse_colors(void) { #if defined (COLOR_SUPPORT) const char *p; /* Pointer to character being parsed */ diff --git a/readline/patchlevel b/readline/patchlevel index e0ba09d..d8c9df7 100644 --- a/readline/patchlevel +++ b/readline/patchlevel @@ -1,3 +1,3 @@ # Do not edit -- exists only for use by patch -5 +0 diff --git a/readline/readline.c b/readline/readline.c index a05b35e..678f989 100644 --- a/readline/readline.c +++ b/readline/readline.c @@ -1,7 +1,7 @@ /* readline.c -- a general facility for reading lines of input with emacs style editing and completion. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -214,6 +214,9 @@ int _rl_eof_char = CTRL ('D'); /* Non-zero makes this the next keystroke to read. */ int rl_pending_input = 0; +/* If non-zero when readline_internal returns, it means we found EOF */ +int _rl_eof_found = 0; + /* Pointer to a useful terminal name. */ const char *rl_terminal_name = (const char *)NULL; @@ -222,7 +225,7 @@ int _rl_horizontal_scroll_mode = 0; /* Non-zero means to display an asterisk at the starts of history lines which have been modified. */ -int _rl_mark_modified_lines = 0; +int _rl_mark_modified_lines = 0; /* The style of `bell' notification preferred. This can be set to NO_BELL, AUDIBLE_BELL, or VISIBLE_BELL. */ @@ -242,7 +245,7 @@ int rl_erase_empty_line = 0; /* Non-zero means to read only this many characters rather than up to a character bound to accept-line. */ -int rl_num_chars_to_read; +int rl_num_chars_to_read = 0; /* Line buffer and maintenance. */ char *rl_line_buffer = (char *)NULL; @@ -325,8 +328,7 @@ int _rl_meta_flag = 0; /* Forward declaration */ /* Set up the prompt and expand it. Called from readline() and rl_callback_handler_install (). */ int -rl_set_prompt (prompt) - const char *prompt; +rl_set_prompt (const char *prompt) { FREE (rl_prompt); rl_prompt = prompt ? savestring (prompt) : (char *)NULL; @@ -339,8 +341,7 @@ rl_set_prompt (prompt) /* Read a line of input. Prompt with PROMPT. An empty PROMPT means none. A return value of NULL means that EOF was encountered. */ char * -readline (prompt) - const char *prompt; +readline (const char *prompt) { char *value; #if 0 @@ -401,7 +402,7 @@ readline (prompt) #endif STATIC_CALLBACK void -readline_internal_setup () +readline_internal_setup (void) { char *nprompt; @@ -419,7 +420,10 @@ readline_internal_setup () #if defined (VI_MODE) if (rl_editing_mode == vi_mode) rl_vi_insertion_mode (1, 'i'); /* don't want to reset last */ + else #endif /* VI_MODE */ + if (_rl_show_mode_in_prompt) + _rl_reset_prompt (); /* If we're not echoing, we still want to at least print a prompt, because rl_redisplay will not do it for us. If the calling application has a @@ -450,8 +454,7 @@ readline_internal_setup () } STATIC_CALLBACK char * -readline_internal_teardown (eof) - int eof; +readline_internal_teardown (int eof) { char *temp; HIST_ENTRY *entry; @@ -493,7 +496,7 @@ readline_internal_teardown (eof) } void -_rl_internal_char_cleanup () +_rl_internal_char_cleanup (void) { #if defined (VI_MODE) /* In vi mode, when you exit insert mode, the cursor moves back @@ -524,13 +527,13 @@ _rl_internal_char_cleanup () STATIC_CALLBACK int #if defined (READLINE_CALLBACKS) -readline_internal_char () +readline_internal_char (void) #else -readline_internal_charloop () +readline_internal_charloop (void) #endif { static int lastc, eof_found; - int c, code, lk; + int c, code, lk, r; lastc = EOF; @@ -626,7 +629,7 @@ readline_internal_charloop () } lastc = c; - _rl_dispatch ((unsigned char)c, _rl_keymap); + r = _rl_dispatch ((unsigned char)c, _rl_keymap); RL_CHECK_SIGNALS (); /* If there was no change in _rl_last_command_was_kill, then no kill @@ -648,7 +651,7 @@ readline_internal_charloop () #if defined (READLINE_CALLBACKS) static int -readline_internal_charloop () +readline_internal_charloop (void) { int eof = 1; @@ -662,17 +665,15 @@ readline_internal_charloop () the global rl_outstream. If rl_prompt is non-null, then that is our prompt. */ static char * -readline_internal () +readline_internal (void) { - int eof; - readline_internal_setup (); - eof = readline_internal_charloop (); - return (readline_internal_teardown (eof)); + _rl_eof_found = readline_internal_charloop (); + return (readline_internal_teardown (_rl_eof_found)); } void -_rl_init_line_state () +_rl_init_line_state (void) { rl_point = rl_end = rl_mark = 0; the_line = rl_line_buffer; @@ -680,14 +681,14 @@ _rl_init_line_state () } void -_rl_set_the_line () +_rl_set_the_line (void) { the_line = rl_line_buffer; } #if defined (READLINE_CALLBACKS) _rl_keyseq_cxt * -_rl_keyseq_cxt_alloc () +_rl_keyseq_cxt_alloc (void) { _rl_keyseq_cxt *cxt; @@ -703,14 +704,13 @@ _rl_keyseq_cxt_alloc () } void -_rl_keyseq_cxt_dispose (cxt) - _rl_keyseq_cxt *cxt; +_rl_keyseq_cxt_dispose (_rl_keyseq_cxt *cxt) { xfree (cxt); } void -_rl_keyseq_chain_dispose () +_rl_keyseq_chain_dispose (void) { _rl_keyseq_cxt *cxt; @@ -724,8 +724,7 @@ _rl_keyseq_chain_dispose () #endif static int -_rl_subseq_getchar (key) - int key; +_rl_subseq_getchar (int key) { int k; @@ -742,8 +741,7 @@ _rl_subseq_getchar (key) #if defined (READLINE_CALLBACKS) int -_rl_dispatch_callback (cxt) - _rl_keyseq_cxt *cxt; +_rl_dispatch_callback (_rl_keyseq_cxt *cxt) { int nkey, r; @@ -794,19 +792,14 @@ _rl_dispatch_callback (cxt) If the associated command is really a keymap, then read another key, and dispatch into that map. */ int -_rl_dispatch (key, map) - register int key; - Keymap map; +_rl_dispatch (register int key, Keymap map) { _rl_dispatching_keymap = map; return _rl_dispatch_subseq (key, map, 0); } int -_rl_dispatch_subseq (key, map, got_subseq) - register int key; - Keymap map; - int got_subseq; +_rl_dispatch_subseq (register int key, Keymap map, int got_subseq) { int r, newkey; char *macro; @@ -920,6 +913,15 @@ _rl_dispatch_subseq (key, map, got_subseq) _rl_pushed_input_available () == 0 && _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0) return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); + /* This is a very specific test. It can possibly be generalized in + the future, but for now it handles a specific case of ESC being + the last character in a keyboard macro. */ + if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap && + (RL_ISSTATE (RL_STATE_INPUTPENDING) == 0) && + (RL_ISSTATE (RL_STATE_MACROINPUT) && _rl_peek_macro_key () == 0) && + _rl_pushed_input_available () == 0 && + _rl_input_queued ((_rl_keyseq_timeout > 0) ? _rl_keyseq_timeout*1000 : 0) == 0) + return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key))); #endif RESIZE_KEYSEQ_BUFFER (); @@ -1014,10 +1016,7 @@ _rl_dispatch_subseq (key, map, got_subseq) } static int -_rl_subseq_result (r, map, key, got_subseq) - int r; - Keymap map; - int key, got_subseq; +_rl_subseq_result (int r, Keymap map, int key, int got_subseq) { Keymap m; int type, nt; @@ -1091,11 +1090,11 @@ _rl_subseq_result (r, map, key, got_subseq) /* Initialize readline (and terminal if not already). */ int -rl_initialize () +rl_initialize (void) { /* If we have never been called before, initialize the terminal and data structures. */ - if (!rl_initialized) + if (rl_initialized == 0) { RL_SETSTATE(RL_STATE_INITIALIZING); readline_initialize_everything (); @@ -1103,6 +1102,8 @@ rl_initialize () rl_initialized++; RL_SETSTATE(RL_STATE_INITIALIZED); } + else + (void)_rl_init_locale (); /* check current locale */ /* Initialize the current line information. */ _rl_init_line_state (); @@ -1137,7 +1138,7 @@ rl_initialize () #if 0 #if defined (__EMX__) static void -_emx_build_environ () +_emx_build_environ (void) { TIB *tibp; PIB *pibp; @@ -1162,7 +1163,7 @@ _emx_build_environ () /* Initialize the entire state of the world. */ static void -readline_initialize_everything () +readline_initialize_everything (void) { #if 0 #if defined (__EMX__) @@ -1247,7 +1248,7 @@ readline_initialize_everything () input editing characters, then bind them to their readline equivalents, iff the characters are not bound to keymaps. */ static void -readline_default_bindings () +readline_default_bindings (void) { if (_rl_bind_stty_chars) rl_tty_set_default_bindings (_rl_keymap); @@ -1256,7 +1257,7 @@ readline_default_bindings () /* Reset the default bindings for the terminal special characters we're interested in back to rl_insert and read the new ones. */ static void -reset_default_bindings () +reset_default_bindings (void) { if (_rl_bind_stty_chars) { @@ -1267,8 +1268,7 @@ reset_default_bindings () /* Bind some common arrow key sequences in MAP. */ static void -bind_arrow_keys_internal (map) - Keymap map; +bind_arrow_keys_internal (Keymap map) { Keymap xkeymap; @@ -1296,6 +1296,15 @@ bind_arrow_keys_internal (map) rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line); rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line); + /* Key bindings for control-arrow keys */ + rl_bind_keyseq_if_unbound ("\033[1;5C", rl_forward_word); + rl_bind_keyseq_if_unbound ("\033[1;5D", rl_backward_word); + rl_bind_keyseq_if_unbound ("\033[3;5~", rl_kill_word); + + /* Key bindings for alt-arrow keys */ + rl_bind_keyseq_if_unbound ("\033[1;3C", rl_forward_word); + rl_bind_keyseq_if_unbound ("\033[1;3D", rl_backward_word); + #if defined (__MINGW32__) rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history); @@ -1324,7 +1333,7 @@ bind_arrow_keys_internal (map) the inputrc file a chance to bind them and create `real' keymaps for the arrow key prefix. */ static void -bind_arrow_keys () +bind_arrow_keys (void) { bind_arrow_keys_internal (emacs_standard_keymap); @@ -1339,7 +1348,7 @@ bind_arrow_keys () } static void -bind_bracketed_paste_prefix () +bind_bracketed_paste_prefix (void) { Keymap xkeymap; @@ -1361,8 +1370,7 @@ bind_bracketed_paste_prefix () /* **************************************************************** */ int -rl_save_state (sp) - struct readline_state *sp; +rl_save_state (struct readline_state *sp) { if (sp == 0) return -1; @@ -1402,8 +1410,7 @@ rl_save_state (sp) } int -rl_restore_state (sp) - struct readline_state *sp; +rl_restore_state (struct readline_state *sp) { if (sp == 0) return -1; diff --git a/readline/readline.h b/readline/readline.h index 924bbfb..da78271 100644 --- a/readline/readline.h +++ b/readline/readline.h @@ -39,8 +39,8 @@ extern "C" { #endif /* Hex-encoded Readline version number. */ -#define RL_READLINE_VERSION 0x0700 /* Readline 7.0 */ -#define RL_VERSION_MAJOR 7 +#define RL_READLINE_VERSION 0x0800 /* Readline 8.0 */ +#define RL_VERSION_MAJOR 8 #define RL_VERSION_MINOR 0 /* Readline data structures. */ @@ -98,6 +98,9 @@ extern int rl_clear_screen PARAMS((int, int)); extern int rl_skip_csi_sequence PARAMS((int, int)); extern int rl_arrow_keys PARAMS((int, int)); +extern int rl_previous_screen_line PARAMS((int, int)); +extern int rl_next_screen_line PARAMS((int, int)); + /* Bindable commands for inserting and deleting text. */ extern int rl_insert PARAMS((int, int)); extern int rl_quoted_insert PARAMS((int, int)); @@ -329,6 +332,7 @@ extern char *rl_untranslate_keyseq PARAMS((int)); extern rl_command_func_t *rl_named_function PARAMS((const char *)); extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *)); +extern rl_command_func_t *rl_function_of_keyseq_len PARAMS((const char *, size_t, Keymap, int *)); extern void rl_list_funmap_names PARAMS((void)); extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap)); @@ -343,6 +347,7 @@ extern int rl_parse_and_bind PARAMS((char *)); /* Functions for manipulating keymaps. */ extern Keymap rl_make_bare_keymap PARAMS((void)); +extern int rl_empty_keymap PARAMS((Keymap)); extern Keymap rl_copy_keymap PARAMS((Keymap)); extern Keymap rl_make_keymap PARAMS((void)); extern void rl_discard_keymap PARAMS((Keymap)); @@ -352,6 +357,9 @@ extern Keymap rl_get_keymap_by_name PARAMS((const char *)); extern char *rl_get_keymap_name PARAMS((Keymap)); extern void rl_set_keymap PARAMS((Keymap)); extern Keymap rl_get_keymap PARAMS((void)); + +extern int rl_set_keymap_name PARAMS((const char *, Keymap)); + /* Undocumented; used internally only. */ extern void rl_set_keymap_from_edit_mode PARAMS((void)); extern char *rl_get_keymap_name_from_edit_mode PARAMS((void)); @@ -413,6 +421,7 @@ extern void rl_deprep_terminal PARAMS((void)); extern void rl_tty_set_default_bindings PARAMS((Keymap)); extern void rl_tty_unset_default_bindings PARAMS((Keymap)); +extern int rl_tty_set_echoing PARAMS((int)); extern int rl_reset_terminal PARAMS((const char *)); extern void rl_resize_terminal PARAMS((void)); extern void rl_set_screen_size PARAMS((int, int)); @@ -443,6 +452,7 @@ extern void rl_reset_after_signal PARAMS((void)); extern void rl_free_line_state PARAMS((void)); extern int rl_pending_signal PARAMS((void)); +extern void rl_check_signals PARAMS((void)); extern void rl_echo_signal_char PARAMS((int)); diff --git a/readline/readline.pc.in b/readline/readline.pc.in index fbfca8a..a7f2cf3 100644 --- a/readline/readline.pc.in +++ b/readline/readline.pc.in @@ -7,6 +7,6 @@ Name: Readline Description: Gnu Readline library for command line editing URL: http://tiswww.cwru.edu/php/chet/readline/rltop.html Version: @LIBVERSION@ -Requires.private: tinfo +Requires.private: @TERMCAP_PKG_CONFIG_LIB@ Libs: -L${libdir} -lreadline Cflags: -I${includedir}/readline diff --git a/readline/rlconf.h b/readline/rlconf.h index 98c970a..b6d6a2f 100644 --- a/readline/rlconf.h +++ b/readline/rlconf.h @@ -42,7 +42,7 @@ /* The next-to-last-ditch effort file name for a user-specific init file. */ #define DEFAULT_INPUTRC "~/.inputrc" -/* The ultimate last-ditch filenname for an init file -- system-wide. */ +/* The ultimate last-ditch filename for an init file -- system-wide. */ #define SYS_INPUTRC "/etc/inputrc" /* If defined, expand tabs to spaces. */ diff --git a/readline/rlmbutil.h b/readline/rlmbutil.h index 4748a61..6fd03f6 100644 --- a/readline/rlmbutil.h +++ b/readline/rlmbutil.h @@ -172,6 +172,10 @@ _rl_wcwidth (wc) # define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0) #endif +#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0) +#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0) +#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80) + #else /* !HANDLE_MULTIBYTE */ #undef MB_LEN_MAX @@ -196,6 +200,12 @@ _rl_wcwidth (wc) #define MB_INVALIDCH(x) (0) #define MB_NULLWCH(x) (0) +#define UTF8_SINGLEBYTE(c) (1) + +#if !defined (HAVE_WCHAR_T) && !defined (wchar_t) +# define wchar_t int +#endif + #endif /* !HANDLE_MULTIBYTE */ extern int rl_byte_oriented; diff --git a/readline/rlprivate.h b/readline/rlprivate.h index fc3856a..e85e4d8 100644 --- a/readline/rlprivate.h +++ b/readline/rlprivate.h @@ -26,6 +26,7 @@ #include "rlconf.h" /* for VISIBLE_STATS */ #include "rlstdc.h" #include "posixjmp.h" /* defines procenv_t */ +#include "rlmbutil.h" /* for HANDLE_MULTIBYTE */ /************************************************************************* * * @@ -64,6 +65,7 @@ #define SF_FOUND 0x02 #define SF_FAILED 0x04 #define SF_CHGKMAP 0x08 +#define SF_PATTERN 0x10 /* unused so far */ typedef struct __rl_search_context { @@ -305,10 +307,13 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *)); #define BRACK_PASTE_SLEN 6 #define BRACK_PASTE_INIT "\033[?2004h" -#define BRACK_PASTE_FINI "\033[?2004l" +#define BRACK_PASTE_FINI "\033[?2004l\r" + +extern char *_rl_bracketed_text PARAMS((size_t *)); /* macro.c */ extern void _rl_with_macro_input PARAMS((char *)); +extern int _rl_peek_macro_key PARAMS((void)); extern int _rl_next_macro_key PARAMS((void)); extern int _rl_prev_macro_key PARAMS((void)); extern void _rl_push_executing_macro PARAMS((void)); @@ -330,6 +335,7 @@ extern void _rl_set_insert_mode PARAMS((int, int)); extern void _rl_revert_all_lines PARAMS((void)); /* nls.c */ +extern char *_rl_init_locale PARAMS((void)); extern int _rl_init_eightbit PARAMS((void)); /* parens.c */ @@ -378,6 +384,7 @@ extern void _rl_set_cursor PARAMS((int, int)); extern void _rl_fix_point PARAMS((int)); extern int _rl_replace_text PARAMS((const char *, int, int)); extern int _rl_forward_char_internal PARAMS((int)); +extern int _rl_backward_char_internal PARAMS((int)); extern int _rl_insert_char PARAMS((int, int)); extern int _rl_overwrite_char PARAMS((int, int)); extern int _rl_overwrite_rubout PARAMS((int, int)); @@ -507,6 +514,7 @@ extern FILE *_rl_in_stream; extern FILE *_rl_out_stream; extern int _rl_last_command_was_kill; extern int _rl_eof_char; +extern int _rl_eof_found; extern procenv_t _rl_top_level; extern _rl_keyseq_cxt *_rl_kscxt; extern int _rl_keyseq_timeout; @@ -534,6 +542,7 @@ extern int _rl_enable_keypad; extern int _rl_enable_meta; extern char *_rl_term_clreol; extern char *_rl_term_clrpag; +extern char *_rl_term_clrscroll; extern char *_rl_term_im; extern char *_rl_term_ic; extern char *_rl_term_ei; diff --git a/readline/rltty.c b/readline/rltty.c index b1c7929..d0cd572 100644 --- a/readline/rltty.c +++ b/readline/rltty.c @@ -1,7 +1,7 @@ /* rltty.c -- functions to prepare and restore the terminal for readline's use. */ -/* Copyright (C) 1992-2016 Free Software Foundation, Inc. +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -130,8 +130,7 @@ static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t *)); static void -save_tty_chars (tiop) - TIOTYPE *tiop; +save_tty_chars (TIOTYPE *tiop) { _rl_last_tty_chars = _rl_tty_chars; @@ -168,9 +167,7 @@ save_tty_chars (tiop) } static int -get_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +get_tty_settings (int tty, TIOTYPE *tiop) { set_winsize (tty); @@ -200,9 +197,7 @@ get_tty_settings (tty, tiop) } static int -set_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +set_tty_settings (int tty, TIOTYPE *tiop) { if (tiop->flags & SGTTY_SET) { @@ -239,9 +234,7 @@ set_tty_settings (tty, tiop) } static void -prepare_terminal_settings (meta_flag, oldtio, tiop) - int meta_flag; - TIOTYPE oldtio, *tiop; +prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop) { _rl_echoing_p = (oldtio.sgttyb.sg_flags & ECHO); _rl_echoctl = (oldtio.sgttyb.sg_flags & ECHOCTL); @@ -357,8 +350,7 @@ static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE)); #endif static void -save_tty_chars (tiop) - TIOTYPE *tiop; +save_tty_chars (TIOTYPE *tiop) { _rl_last_tty_chars = _rl_tty_chars; @@ -403,8 +395,7 @@ save_tty_chars (tiop) #if defined (_AIX) || defined (_AIX41) /* Currently this is only used on AIX */ static void -rltty_warning (msg) - char *msg; +rltty_warning (char *msg) { _rl_errmsg ("warning: %s", msg); } @@ -412,8 +403,7 @@ rltty_warning (msg) #if defined (_AIX) void -setopost(tp) -TIOTYPE *tp; +setopost (TIOTYPE *tp) { if ((tp->c_oflag & OPOST) == 0) { @@ -424,9 +414,7 @@ TIOTYPE *tp; #endif static int -_get_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +_get_tty_settings (int tty, TIOTYPE *tiop) { int ioctl_ret; @@ -457,9 +445,7 @@ _get_tty_settings (tty, tiop) } static int -get_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +get_tty_settings (int tty, TIOTYPE *tiop) { set_winsize (tty); @@ -475,9 +461,7 @@ get_tty_settings (tty, tiop) } static int -_set_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +_set_tty_settings (int tty, TIOTYPE *tiop) { while (SETATTR (tty, tiop) < 0) { @@ -489,9 +473,7 @@ _set_tty_settings (tty, tiop) } static int -set_tty_settings (tty, tiop) - int tty; - TIOTYPE *tiop; +set_tty_settings (int tty, TIOTYPE *tiop) { if (_set_tty_settings (tty, tiop) < 0) return -1; @@ -518,10 +500,11 @@ set_tty_settings (tty, tiop) } static void -prepare_terminal_settings (meta_flag, oldtio, tiop) - int meta_flag; - TIOTYPE oldtio, *tiop; +prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop) { + int sc; + Keymap kmap; + _rl_echoing_p = (oldtio.c_lflag & ECHO); #if defined (ECHOCTL) _rl_echoctl = (oldtio.c_lflag & ECHOCTL); @@ -578,6 +561,20 @@ prepare_terminal_settings (meta_flag, oldtio, tiop) tiop->c_cc[VDSUSP] = _POSIX_VDISABLE; #endif + /* Conditionally disable some other tty special characters if there is a + key binding for them in the current keymap. Readline ordinarily doesn't + bind these characters, but an application or user might. */ +#if defined (VI_MODE) + kmap = (rl_editing_mode == vi_mode) ? vi_insertion_keymap : _rl_keymap; +#else + kmap = _rl_keymap; +#endif +#if defined (VDISCARD) + sc = tiop->c_cc[VDISCARD]; + if (sc != _POSIX_VDISABLE && kmap[(unsigned char)sc].type == ISFUNC) + tiop->c_cc[VDISCARD] = _POSIX_VDISABLE; +#endif /* VDISCARD */ + #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */ } #endif /* !NEW_TTY_DRIVER */ @@ -585,21 +582,19 @@ prepare_terminal_settings (meta_flag, oldtio, tiop) /* Put the terminal in CBREAK mode so that we can detect key presses. */ #if defined (NO_TTY_DRIVER) void -rl_prep_terminal (meta_flag) - int meta_flag; +rl_prep_terminal (int meta_flag) { _rl_echoing_p = 1; } void -rl_deprep_terminal () +rl_deprep_terminal (void) { } #else /* ! NO_TTY_DRIVER */ void -rl_prep_terminal (meta_flag) - int meta_flag; +rl_prep_terminal (int meta_flag) { int tty, nprep; TIOTYPE tio; @@ -682,7 +677,7 @@ rl_prep_terminal (meta_flag) /* Restore the terminal's normal settings and modes. */ void -rl_deprep_terminal () +rl_deprep_terminal (void) { int tty; @@ -695,7 +690,11 @@ rl_deprep_terminal () tty = rl_instream ? fileno (rl_instream) : fileno (stdin); if (terminal_prepped & TPX_BRACKPASTE) - fprintf (rl_outstream, BRACK_PASTE_FINI); + { + fprintf (rl_outstream, BRACK_PASTE_FINI); + if (_rl_eof_found) + fprintf (rl_outstream, "\n"); + } if (_rl_enable_keypad) _rl_control_keypad (0); @@ -718,8 +717,7 @@ rl_deprep_terminal () /* Set readline's idea of whether or not it is echoing output to the terminal, returning the old value. */ int -rl_tty_set_echoing (u) - int u; +rl_tty_set_echoing (int u) { int o; @@ -735,8 +733,7 @@ rl_tty_set_echoing (u) /* **************************************************************** */ int -rl_restart_output (count, key) - int count, key; +rl_restart_output (int count, int key) { #if defined (__MINGW32__) return 0; @@ -773,8 +770,7 @@ rl_restart_output (count, key) } int -rl_stop_output (count, key) - int count, key; +rl_stop_output (int count, int key) { #if defined (__MINGW32__) return 0; @@ -822,11 +818,7 @@ rl_stop_output (count, key) #elif defined (NEW_TTY_DRIVER) static void -set_special_char (kmap, tiop, sc, func) - Keymap kmap; - TIOTYPE *tiop; - int sc; - rl_command_func_t *func; +set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func) { if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC) kmap[(unsigned char)sc].function = func; @@ -837,9 +829,7 @@ set_special_char (kmap, tiop, sc, func) kmap[(unsigned char)c].function = rl_insert; static void -_rl_bind_tty_special_chars (kmap, ttybuff) - Keymap kmap; - TIOTYPE ttybuff; +_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff) { if (ttybuff.flags & SGTTY_SET) { @@ -858,11 +848,7 @@ _rl_bind_tty_special_chars (kmap, ttybuff) #else /* !NEW_TTY_DRIVER */ static void -set_special_char (kmap, tiop, sc, func) - Keymap kmap; - TIOTYPE *tiop; - int sc; - rl_command_func_t *func; +set_special_char (Keymap kmap, TIOTYPE *tiop, int sc, rl_command_func_t *func) { unsigned char uc; @@ -877,9 +863,7 @@ set_special_char (kmap, tiop, sc, func) kmap[uc].function = rl_insert; static void -_rl_bind_tty_special_chars (kmap, ttybuff) - Keymap kmap; - TIOTYPE ttybuff; +_rl_bind_tty_special_chars (Keymap kmap, TIOTYPE ttybuff) { SET_SPECIAL (VERASE, rl_rubout); SET_SPECIAL (VKILL, rl_unix_line_discard); @@ -903,8 +887,7 @@ _rl_bind_tty_special_chars (kmap, ttybuff) /* Set the system's default editing characters to their readline equivalents in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */ void -rltty_set_default_bindings (kmap) - Keymap kmap; +rltty_set_default_bindings (Keymap kmap) { #if !defined (NO_TTY_DRIVER) TIOTYPE ttybuff; @@ -920,8 +903,7 @@ rltty_set_default_bindings (kmap) /* New public way to set the system default editing chars to their readline equivalents. */ void -rl_tty_set_default_bindings (kmap) - Keymap kmap; +rl_tty_set_default_bindings (Keymap kmap) { rltty_set_default_bindings (kmap); } @@ -931,8 +913,7 @@ rl_tty_set_default_bindings (kmap) chars with save_tty_chars(). This only works on POSIX termios or termio systems. */ void -rl_tty_unset_default_bindings (kmap) - Keymap kmap; +rl_tty_unset_default_bindings (Keymap kmap) { /* Don't bother before we've saved the tty special chars at least once. */ if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0) @@ -954,13 +935,13 @@ rl_tty_unset_default_bindings (kmap) #if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER) int -_rl_disable_tty_signals () +_rl_disable_tty_signals (void) { return 0; } int -_rl_restore_tty_signals () +_rl_restore_tty_signals (void) { return 0; } @@ -970,7 +951,7 @@ static TIOTYPE sigstty, nosigstty; static int tty_sigs_disabled = 0; int -_rl_disable_tty_signals () +_rl_disable_tty_signals (void) { if (tty_sigs_disabled) return 0; @@ -991,7 +972,7 @@ _rl_disable_tty_signals () } int -_rl_restore_tty_signals () +_rl_restore_tty_signals (void) { int r; diff --git a/readline/savestring.c b/readline/savestring.c index af98538..f4bb6aa 100644 --- a/readline/savestring.c +++ b/readline/savestring.c @@ -1,6 +1,6 @@ /* savestring.c - function version of savestring for backwards compatibility */ -/* Copyright (C) 1998,2003 Free Software Foundation, Inc. +/* Copyright (C) 1998,2003,2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -30,8 +30,7 @@ /* Backwards compatibility, now that savestring has been removed from all `public' readline header files. */ char * -savestring (s) - const char *s; +savestring (const char *s) { char *ret; diff --git a/readline/search.c b/readline/search.c index 45d95d2..c9c1f5d 100644 --- a/readline/search.c +++ b/readline/search.c @@ -1,6 +1,6 @@ /* search.c - code for non-incremental searching in emacs and vi modes. */ -/* Copyright (C) 1992-2015 Free Software Foundation, Inc. +/* Copyright (C) 1992-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -73,8 +73,8 @@ static char *history_search_string; static int history_string_size; static void make_history_line_current PARAMS((HIST_ENTRY *)); -static int noninc_search_from_pos PARAMS((char *, int, int)); -static int noninc_dosearch PARAMS((char *, int)); +static int noninc_search_from_pos PARAMS((char *, int, int, int, int *)); +static int noninc_dosearch PARAMS((char *, int, int)); static int noninc_search PARAMS((int, int)); static int rl_history_search_internal PARAMS((int, int)); static void rl_history_search_reinit PARAMS((int)); @@ -87,8 +87,7 @@ static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int)); current line. This doesn't do anything with rl_point; the caller must set it. */ static void -make_history_line_current (entry) - HIST_ENTRY *entry; +make_history_line_current (HIST_ENTRY *entry) { _rl_replace_text (entry->line, 0, rl_end); _rl_fix_point (1); @@ -112,11 +111,10 @@ make_history_line_current (entry) for STRING. DIR < 0 means to search backwards through the history list, DIR >= 0 means to search forward. */ static int -noninc_search_from_pos (string, pos, dir) - char *string; - int pos, dir; +noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp) { - int ret, old; + int ret, old, sflags; + char *s; if (pos < 0) return -1; @@ -126,12 +124,28 @@ noninc_search_from_pos (string, pos, dir) return -1; RL_SETSTATE(RL_STATE_SEARCH); - if (*string == '^') + /* These functions return the match offset in the line; history_offset gives + the matching line in the history list */ + if (flags & SF_PATTERN) + { + s = string; + sflags = 0; /* Non-anchored search */ + if (*s == '^') + { + sflags |= ANCHORED_SEARCH; + s++; + } + ret = _hs_history_patsearch (s, dir, sflags); + } + else if (*string == '^') ret = history_search_prefix (string + 1, dir); else ret = history_search (string, dir); RL_UNSETSTATE(RL_STATE_SEARCH); + if (ncp) + *ncp = ret; /* caller will catch -1 to indicate no-op */ + if (ret != -1) ret = where_history (); @@ -143,9 +157,7 @@ noninc_search_from_pos (string, pos, dir) search is backwards through previous entries, else through subsequent entries. Returns 1 if the search was successful, 0 otherwise. */ static int -noninc_dosearch (string, dir) - char *string; - int dir; +noninc_dosearch (char *string, int dir, int flags) { int oldpos, pos; HIST_ENTRY *entry; @@ -156,7 +168,7 @@ noninc_dosearch (string, dir) return 0; } - pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); + pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0); if (pos == -1) { /* Search failed, current history position unchanged. */ @@ -188,8 +200,7 @@ noninc_dosearch (string, dir) } static _rl_search_cxt * -_rl_nsearch_init (dir, pchar) - int dir, pchar; +_rl_nsearch_init (int dir, int pchar) { _rl_search_cxt *cxt; char *p; @@ -197,6 +208,10 @@ _rl_nsearch_init (dir, pchar) cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0); if (dir < 0) cxt->sflags |= SF_REVERSE; /* not strictly needed */ +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/')) + cxt->sflags |= SF_PATTERN; +#endif cxt->direction = dir; cxt->history_pos = cxt->save_line; @@ -224,9 +239,7 @@ _rl_nsearch_init (dir, pchar) } int -_rl_nsearch_cleanup (cxt, r) - _rl_search_cxt *cxt; - int r; +_rl_nsearch_cleanup (_rl_search_cxt *cxt, int r) { _rl_scxt_dispose (cxt, 0); _rl_nscxt = 0; @@ -237,8 +250,7 @@ _rl_nsearch_cleanup (cxt, r) } static void -_rl_nsearch_abort (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_abort (_rl_search_cxt *cxt) { rl_maybe_unsave_line (); rl_clear_message (); @@ -253,10 +265,11 @@ _rl_nsearch_abort (cxt) if the caller should abort the search, 0 if we should break out of the loop, and 1 if we should continue to read characters. */ static int -_rl_nsearch_dispatch (cxt, c) - _rl_search_cxt *cxt; - int c; +_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c) { + if (c < 0) + c = CTRL ('C'); + switch (c) { case CTRL('W'): @@ -306,8 +319,7 @@ _rl_nsearch_dispatch (cxt, c) using _rl_nsearch_cleanup (). Returns 1 if the search was successful, 0 otherwise. */ static int -_rl_nsearch_dosearch (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_dosearch (_rl_search_cxt *cxt) { rl_mark = cxt->save_mark; @@ -340,7 +352,7 @@ _rl_nsearch_dosearch (cxt) } rl_restore_prompt (); - return (noninc_dosearch (noninc_search_string, cxt->direction)); + return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN)); } /* Search non-interactively through the history list. DIR < 0 means to @@ -349,9 +361,7 @@ _rl_nsearch_dosearch (cxt) history list. PCHAR is the character to use for prompting when reading the search string; if not specified (0), it defaults to `:'. */ static int -noninc_search (dir, pchar) - int dir; - int pchar; +noninc_search (int dir, int pchar) { _rl_search_cxt *cxt; int c, r; @@ -367,6 +377,12 @@ noninc_search (dir, pchar) { c = _rl_search_getchar (cxt); + if (c < 0) + { + _rl_nsearch_abort (cxt); + return 1; + } + if (c == 0) break; @@ -384,8 +400,7 @@ noninc_search (dir, pchar) /* Search forward through the history list for a string. If the vi-mode code calls this, KEY will be `?'. */ int -rl_noninc_forward_search (count, key) - int count, key; +rl_noninc_forward_search (int count, int key) { return noninc_search (1, (key == '?') ? '?' : 0); } @@ -393,17 +408,16 @@ rl_noninc_forward_search (count, key) /* Reverse search the history list for a string. If the vi-mode code calls this, KEY will be `/'. */ int -rl_noninc_reverse_search (count, key) - int count, key; +rl_noninc_reverse_search (int count, int key) { return noninc_search (-1, (key == '/') ? '/' : 0); } /* Search forward through the history list for the last string searched - for. If there is no saved search string, abort. */ + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `N'. */ int -rl_noninc_forward_search_again (count, key) - int count, key; +rl_noninc_forward_search_again (int count, int key) { int r; @@ -412,15 +426,20 @@ rl_noninc_forward_search_again (count, key) rl_ding (); return (1); } - r = noninc_dosearch (noninc_search_string, 1); +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'N') + r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, 1, 0); return (r != 1); } /* Reverse search in the history list for the last string searched - for. If there is no saved search string, abort. */ + for. If there is no saved search string, abort. If the vi-mode code + calls this, KEY will be `n'. */ int -rl_noninc_reverse_search_again (count, key) - int count, key; +rl_noninc_reverse_search_again (int count, int key) { int r; @@ -429,18 +448,28 @@ rl_noninc_reverse_search_again (count, key) rl_ding (); return (1); } - r = noninc_dosearch (noninc_search_string, -1); +#if defined (VI_MODE) + if (VI_COMMAND_MODE() && key == 'n') + r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN); + else +#endif + r = noninc_dosearch (noninc_search_string, -1, 0); return (r != 1); } #if defined (READLINE_CALLBACKS) int -_rl_nsearch_callback (cxt) - _rl_search_cxt *cxt; +_rl_nsearch_callback (_rl_search_cxt *cxt) { int c, r; c = _rl_search_getchar (cxt); + if (c <= 0) + { + if (c < 0) + _rl_nsearch_abort (cxt); + return 1; + } r = _rl_nsearch_dispatch (cxt, c); if (r != 0) return 1; @@ -451,11 +480,10 @@ _rl_nsearch_callback (cxt) #endif static int -rl_history_search_internal (count, dir) - int count, dir; +rl_history_search_internal (int count, int dir) { HIST_ENTRY *temp; - int ret, oldpos; + int ret, oldpos, newcol; char *t; rl_maybe_save_line (); @@ -469,7 +497,7 @@ rl_history_search_internal (count, dir) while (count) { RL_CHECK_SIGNALS (); - ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol); if (ret == -1) break; @@ -512,12 +540,17 @@ rl_history_search_internal (count, dir) /* Copy the line we found into the current line buffer. */ make_history_line_current (temp); + /* decide where to put rl_point -- need to change this for pattern search */ if (rl_history_search_flags & ANCHORED_SEARCH) rl_point = rl_history_search_len; /* easy case */ else { - t = strstr (rl_line_buffer, history_search_string); +#if 0 + t = strstr (rl_line_buffer, history_search_string); /* XXX */ rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end; +#else + rl_point = (newcol >= 0) ? newcol : rl_end; +#endif } rl_mark = rl_end; @@ -525,8 +558,7 @@ rl_history_search_internal (count, dir) } static void -rl_history_search_reinit (flags) - int flags; +rl_history_search_reinit (int flags) { int sind; @@ -556,8 +588,7 @@ rl_history_search_reinit (flags) from the start of the line to rl_point. This is a non-incremental search. The search is anchored to the beginning of the history line. */ int -rl_history_search_forward (count, ignore) - int count, ignore; +rl_history_search_forward (int count, int ignore) { if (count == 0) return (0); @@ -575,8 +606,7 @@ rl_history_search_forward (count, ignore) from the start of the line to rl_point. This is a non-incremental search. */ int -rl_history_search_backward (count, ignore) - int count, ignore; +rl_history_search_backward (int count, int ignore) { if (count == 0) return (0); @@ -595,8 +625,7 @@ rl_history_search_backward (count, ignore) search. The search succeeds if the search string is present anywhere in the history line. */ int -rl_history_substr_search_forward (count, ignore) - int count, ignore; +rl_history_substr_search_forward (int count, int ignore) { if (count == 0) return (0); @@ -614,8 +643,7 @@ rl_history_substr_search_forward (count, ignore) from the start of the line to rl_point. This is a non-incremental search. */ int -rl_history_substr_search_backward (count, ignore) - int count, ignore; +rl_history_substr_search_backward (int count, int ignore) { if (count == 0) return (0); diff --git a/readline/shell.c b/readline/shell.c index 6947295..7fe2e97 100644 --- a/readline/shell.c +++ b/readline/shell.c @@ -1,7 +1,7 @@ /* shell.c -- readline utility functions that are normally provided by bash when readline is linked as part of the shell. */ -/* Copyright (C) 1997-2009 Free Software Foundation, Inc. +/* Copyright (C) 1997-2009,2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -92,8 +92,7 @@ extern struct passwd *getpwuid PARAMS((uid_t)); /* Does shell-like quoting using single quotes. */ char * -sh_single_quote (string) - char *string; +sh_single_quote (char *string) { register int c; char *result, *r, *s; @@ -127,8 +126,7 @@ static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1]; /* sizeof("LINES=") == static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1]; /* sizeof("COLUMNS=") == 8 */ void -sh_set_lines_and_columns (lines, cols) - int lines, cols; +sh_set_lines_and_columns (int lines, int cols) { #if defined (HAVE_SETENV) sprintf (setenv_buf, "%d", lines); @@ -148,14 +146,13 @@ sh_set_lines_and_columns (lines, cols) } char * -sh_get_env_value (varname) - const char *varname; +sh_get_env_value (const char *varname) { return ((char *)getenv (varname)); } char * -sh_get_home_dir () +sh_get_home_dir (void) { static char *home_dir = (char *)NULL; struct passwd *entry; @@ -188,8 +185,7 @@ sh_get_home_dir () #endif int -sh_unset_nodelay_mode (fd) - int fd; +sh_unset_nodelay_mode (int fd) { #if defined (HAVE_FCNTL) int flags, bflags; diff --git a/readline/signals.c b/readline/signals.c index 927f532..76c5c47 100644 --- a/readline/signals.c +++ b/readline/signals.c @@ -1,6 +1,6 @@ /* signals.c -- signal handling support for readline. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -113,6 +113,10 @@ int _rl_susp_char = 0; static int signals_set_flag; static int sigwinch_set_flag; +#if defined (HAVE_POSIX_SIGNALS) +sigset_t _rl_orig_sigset; +#endif /* !HAVE_POSIX_SIGNALS */ + /* **************************************************************** */ /* */ /* Signal Handling */ @@ -134,8 +138,7 @@ void *_rl_sigcleanarg; /* Called from RL_CHECK_SIGNALS() macro */ RETSIGTYPE -_rl_signal_handler (sig) - int sig; +_rl_signal_handler (int sig) { _rl_caught_signal = 0; /* XXX */ @@ -158,8 +161,7 @@ _rl_signal_handler (sig) } static RETSIGTYPE -rl_signal_handler (sig) - int sig; +rl_signal_handler (int sig) { if (_rl_interrupt_immediately) { @@ -173,8 +175,7 @@ rl_signal_handler (sig) } static RETSIGTYPE -_rl_handle_signal (sig) - int sig; +_rl_handle_signal (int sig) { #if defined (HAVE_POSIX_SIGNALS) sigset_t set; @@ -248,9 +249,11 @@ _rl_handle_signal (sig) rl_cleanup_after_signal (); #if defined (HAVE_POSIX_SIGNALS) +# if defined (SIGTSTP) /* Unblock SIGTTOU blocked above */ if (sig == SIGTTIN || sig == SIGTSTP) sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL); +# endif sigemptyset (&set); sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); @@ -289,8 +292,7 @@ _rl_handle_signal (sig) #if defined (SIGWINCH) static RETSIGTYPE -rl_sigwinch_handler (sig) - int sig; +rl_sigwinch_handler (int sig) { SigHandler *oh; @@ -321,9 +323,7 @@ rl_sigwinch_handler (sig) #if !defined (HAVE_POSIX_SIGNALS) static int -rl_sigaction (sig, nh, oh) - int sig; - sighandler_cxt *nh, *oh; +rl_sigaction (int sig, sighandler_cxt *nh, sighandler_cxt *oh) { oh->sa_handler = signal (sig, nh->sa_handler); return 0; @@ -334,10 +334,7 @@ rl_sigaction (sig, nh, oh) information in OHANDLER. Return the old signal handler, like signal(). */ static SigHandler * -rl_set_sighandler (sig, handler, ohandler) - int sig; - SigHandler *handler; - sighandler_cxt *ohandler; +rl_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) { sighandler_cxt old_handler; #if defined (HAVE_POSIX_SIGNALS) @@ -368,10 +365,7 @@ rl_set_sighandler (sig, handler, ohandler) /* Set disposition of SIG to HANDLER, returning old state in OHANDLER. Don't change disposition if OHANDLER indicates the signal was ignored. */ static void -rl_maybe_set_sighandler (sig, handler, ohandler) - int sig; - SigHandler *handler; - sighandler_cxt *ohandler; +rl_maybe_set_sighandler (int sig, SigHandler *handler, sighandler_cxt *ohandler) { sighandler_cxt dummy; SigHandler *oh; @@ -388,9 +382,7 @@ rl_maybe_set_sighandler (sig, handler, ohandler) disposition was changed using rl_maybe_set_sighandler or for which the SIG_IGN check was performed inline (e.g., SIGALRM below). */ static void -rl_maybe_restore_sighandler (sig, handler) - int sig; - sighandler_cxt *handler; +rl_maybe_restore_sighandler (int sig, sighandler_cxt *handler) { sighandler_cxt dummy; @@ -401,7 +393,7 @@ rl_maybe_restore_sighandler (sig, handler) } int -rl_set_signals () +rl_set_signals (void) { sighandler_cxt dummy; SigHandler *oh; @@ -442,8 +434,8 @@ rl_set_signals () if (rl_catch_signals && signals_set_flag == 0) { #if defined (HAVE_POSIX_SIGNALS) - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &bset, &oset); + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, &bset, &_rl_orig_sigset); #endif rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int); @@ -484,7 +476,14 @@ rl_set_signals () signals_set_flag = 1; #if defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); + sigprocmask (SIG_SETMASK, &_rl_orig_sigset, (sigset_t *)NULL); +#endif + } + else if (rl_catch_signals == 0) + { +#if defined (HAVE_POSIX_SIGNALS) + sigemptyset (&_rl_orig_sigset); + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &_rl_orig_sigset); #endif } @@ -500,14 +499,12 @@ rl_set_signals () } int -rl_clear_signals () +rl_clear_signals (void) { sighandler_cxt dummy; if (rl_catch_signals && signals_set_flag == 1) { - sigemptyset (&dummy.sa_mask); - /* Since rl_maybe_set_sighandler doesn't override a SIG_IGN handler, we should in theory not have to restore a handler where old_xxx.sa_handler == SIG_IGN. That's what rl_maybe_restore_sighandler @@ -555,7 +552,7 @@ rl_clear_signals () /* Clean up the terminal and readline state after catching a signal, before resending it to the calling application. */ void -rl_cleanup_after_signal () +rl_cleanup_after_signal (void) { _rl_clean_up_for_exit (); if (rl_deprep_term_function) @@ -566,7 +563,7 @@ rl_cleanup_after_signal () /* Reset the terminal and readline state after a signal handler returns. */ void -rl_reset_after_signal () +rl_reset_after_signal (void) { if (rl_prep_term_function) (*rl_prep_term_function) (_rl_meta_flag); @@ -578,7 +575,7 @@ rl_reset_after_signal () numeric arguments in process) after catching a signal, before calling rl_cleanup_after_signal(). */ void -rl_free_line_state () +rl_free_line_state (void) { register HIST_ENTRY *entry; @@ -594,10 +591,16 @@ rl_free_line_state () } int -rl_pending_signal () +rl_pending_signal (void) { return (_rl_caught_signal); } + +void +rl_check_signals (void) +{ + RL_CHECK_SIGNALS (); +} #endif /* HANDLE_SIGNALS */ /* **************************************************************** */ @@ -622,7 +625,7 @@ static int sigwinch_blocked; /* Cause SIGINT to not be delivered until the corresponding call to release_sigint(). */ void -_rl_block_sigint () +_rl_block_sigint (void) { if (sigint_blocked) return; @@ -632,7 +635,7 @@ _rl_block_sigint () /* Allow SIGINT to be delivered. */ void -_rl_release_sigint () +_rl_release_sigint (void) { if (sigint_blocked == 0) return; @@ -644,7 +647,7 @@ _rl_release_sigint () /* Cause SIGWINCH to not be delivered until the corresponding call to release_sigwinch(). */ void -_rl_block_sigwinch () +_rl_block_sigwinch (void) { if (sigwinch_blocked) return; @@ -673,7 +676,7 @@ _rl_block_sigwinch () /* Allow SIGWINCH to be delivered. */ void -_rl_release_sigwinch () +_rl_release_sigwinch (void) { if (sigwinch_blocked == 0) return; @@ -703,8 +706,7 @@ _rl_release_sigwinch () /* */ /* **************************************************************** */ void -rl_echo_signal_char (sig) - int sig; +rl_echo_signal_char (int sig) { char cstr[3]; int cslen, c; diff --git a/readline/support/config.guess b/readline/support/config.guess index 637da23..15c6cbf 100755 --- a/readline/support/config.guess +++ b/readline/support/config.guess @@ -247,7 +247,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` @@ -395,7 +395,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build @@ -877,7 +877,7 @@ EOF echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 @@ -945,11 +945,11 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -962,11 +962,11 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) set_cc_for_build @@ -1494,10 +1494,13 @@ EOF echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs exit ;; esac @@ -1624,12 +1627,13 @@ main () #endif #endif -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <<EOF - exit (1); -} +NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize +the system type. Please install a C compiler and try again. EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && diff --git a/readline/support/config.rpath b/readline/support/config.rpath index b6c4d8f..fc5913d 100755 --- a/readline/support/config.rpath +++ b/readline/support/config.rpath @@ -2,27 +2,13 @@ # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # -# Copyright 1996-2003 Free Software Foundation, Inc. +# Copyright 1996-2018 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM @@ -39,7 +25,7 @@ # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. -# All known linkers require a `.a' archive for static linking (except M$VC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so @@ -49,7 +35,19 @@ host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then @@ -59,7 +57,7 @@ else aix*) wl='-Wl,' ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' @@ -67,40 +65,83 @@ else irix5* | irix6* | nonstopux*) wl='-Wl,' ;; - newsos6) - ;; - linux*) - case $CC in - icc|ecc) + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) wl='-Wl,' ;; - ccc) + xl* | bgxl* | bgf* | mpixl*) wl='-Wl,' ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; esac ;; + newsos6) + ;; + *nto* | *qnx*) + ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; - sco3.2v5*) + rdos*) ;; solaris*) - wl='-Wl,' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac ;; sunos4*) wl='-Qoption ld ' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; uts4*) ;; esac fi -# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= @@ -108,7 +149,7 @@ hardcode_direct=no hardcode_minus_L=no case "$host_os" in - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. @@ -116,6 +157,10 @@ case "$host_os" in with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -123,32 +168,37 @@ esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in - aix3* | aix4* | aix5*) + aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac ;; beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' @@ -158,32 +208,57 @@ if test "$with_gnu_ld" = yes; then ld_shlibs=no fi ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; netbsd*) ;; - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; sunos4*) hardcode_direct=yes ;; *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac - if test "$ld_shlibs" = yes; then - # Unlike libtool, we use -rpath here, not --rpath, since the documented - # option of GNU ld is called -rpath, not --rpath. - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= fi else case "$host_os" in @@ -197,7 +272,7 @@ else hardcode_direct=unsupported fi ;; - aix4* | aix5*) + aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -207,13 +282,14 @@ else # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done + ;; esac fi hardcode_direct=yes @@ -225,7 +301,7 @@ else strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - hardcode_direct=yes + : else # We have old collect2 hardcode_direct=unsupported @@ -233,6 +309,7 @@ else hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi + ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. @@ -260,14 +337,18 @@ else fi ;; amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac ;; - bsdi4*) + bsdi[45]*) ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is @@ -276,25 +357,21 @@ else libext=lib ;; darwin* | rhapsody*) - if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then - hardcode_direct=no + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; - freebsd1*) - ld_shlibs=no - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) + freebsd2.[01]*) hardcode_direct=yes hardcode_minus_L=yes ;; - freebsd*) + freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; @@ -306,24 +383,25 @@ else # but as the default location of the library. hardcode_minus_L=yes ;; - hpux10* | hpux11*) + hpux10*) if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) hardcode_direct=no - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes ;; *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -345,19 +423,25 @@ else hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; + *nto* | *qnx*) + ;; openbsd*) - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac + ld_shlibs=no fi ;; os2*) @@ -377,8 +461,6 @@ else fi hardcode_libdir_separator=: ;; - sco3.2v5*) - ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; @@ -407,14 +489,11 @@ else ld_shlibs=yes fi ;; - sysv4.2uw2*) - hardcode_direct=yes - hardcode_minus_L=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - ;; - sysv5*) - hardcode_libdir_flag_spec= + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' @@ -426,35 +505,59 @@ else fi # Check dynamic linker characteristics -# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) + library_names_spec='$libname.a' ;; - aix4* | aix5*) + aix[4-9]*) + library_names_spec='$libname$shrext' ;; amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac ;; beos*) + library_names_spec='$libname$shrext' ;; - bsdi4*) + bsdi[45]*) + library_names_spec='$libname$shrext' ;; - cygwin* | mingw* | pw32*) + cygwin* | mingw* | pw32* | cegcc*) shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib + library_names_spec='$libname$shrext' ;; dgux*) + library_names_spec='$libname$shrext' ;; - freebsd1*) + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' ;; - freebsd*) + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' ;; gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) - case "$host_cpu" in + case $host_cpu in ia64*) shrext=.so ;; @@ -465,8 +568,13 @@ case "$host_os" in shrext=.sl ;; esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= @@ -483,42 +591,65 @@ case "$host_os" in ;; linux*oldld* | linux*aout* | linux*coff*) ;; - linux*) + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' ;; netbsd*) + library_names_spec='$libname$shrext' ;; newsos6) + library_names_spec='$libname$shrext' ;; - nto-qnx) + *nto* | *qnx*) + library_names_spec='$libname$shrext' ;; openbsd*) + library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll + library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' ;; - sco3.2v5*) + rdos*) ;; solaris*) + library_names_spec='$libname$shrext' ;; sunos4*) + library_names_spec='$libname$shrext$versuffix' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' ;; sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' ;; uts4*) + library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF # How to pass a linker flag through the compiler. wl="$escaped_wl" @@ -529,6 +660,12 @@ libext="$libext" # Shared library suffix (normally "so"). shlibext="$shlibext" +# Format of library name prefix. +libname_spec="$escaped_libname_spec" + +# Library names that the linker finds when passed -lNAME. +library_names_spec="$escaped_library_names_spec" + # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist. hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec" diff --git a/readline/support/shlib-install b/readline/support/shlib-install index cfec3bd..f4eea27 100755 --- a/readline/support/shlib-install +++ b/readline/support/shlib-install @@ -73,7 +73,7 @@ fi case "$host_os" in hpux*|darwin*|macosx*|linux*|solaris2*) if [ -z "$uninstall" ]; then - chmod 555 ${INSTALLDIR}/${LIBNAME} + chmod 755 ${INSTALLDIR}/${LIBNAME} fi ;; cygwin*|mingw*) IMPLIBNAME=`echo ${LIBNAME} \ diff --git a/readline/support/shobj-conf b/readline/support/shobj-conf index 1f64433..7920f1b 100755 --- a/readline/support/shobj-conf +++ b/readline/support/shobj-conf @@ -189,7 +189,7 @@ darwin*) darwin[1-7].*) SHOBJ_STATUS=unsupported SHOBJ_LDFLAGS='-dynamic' - SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' + SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -v' ;; # Darwin 8 == Mac OS X 10.4; Mac OS X 10.N == Darwin N+4 *) @@ -205,7 +205,7 @@ darwin*) ;; esac SHOBJ_LDFLAGS="-dynamiclib -dynamic -undefined dynamic_lookup ${SHOBJ_ARCHFLAGS}" - SHLIB_XLDFLAGS="-dynamiclib ${SHOBJ_ARCHFLAGS}"' -install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' + SHLIB_XLDFLAGS="-dynamiclib ${SHOBJ_ARCHFLAGS}"' -install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -v' ;; esac diff --git a/readline/terminal.c b/readline/terminal.c index ef2884e..e557389 100644 --- a/readline/terminal.c +++ b/readline/terminal.c @@ -1,6 +1,6 @@ /* terminal.c -- controlling the terminal with termcap. */ -/* Copyright (C) 1996-2015 Free Software Foundation, Inc. +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -112,6 +112,7 @@ char PC, *BC, *UP; /* Some strings to control terminal actions. These are output by tputs (). */ char *_rl_term_clreol; char *_rl_term_clrpag; +char *_rl_term_clrscroll; char *_rl_term_cr; char *_rl_term_backspace; char *_rl_term_goto; @@ -131,6 +132,7 @@ char *_rl_term_IC; char *_rl_term_dc; char *_rl_term_DC; +/* How to move forward a char, non-destructively */ char *_rl_term_forward_char; /* How to go up a line. */ @@ -188,8 +190,7 @@ int _rl_enable_meta = 1; #if defined (__EMX__) static void -_emx_get_screensize (swp, shp) - int *swp, *shp; +_emx_get_screensize (int *swp, int *shp) { int sz[2]; @@ -204,8 +205,7 @@ _emx_get_screensize (swp, shp) #if defined (__MINGW32__) static void -_win_get_screensize (swp, shp) - int *swp, *shp; +_win_get_screensize (int *swp, int *shp) { HANDLE hConOut; CONSOLE_SCREEN_BUFFER_INFO scr; @@ -227,8 +227,7 @@ _win_get_screensize (swp, shp) values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being non-null serve to check whether or not we have initialized termcap. */ void -_rl_get_screen_size (tty, ignore_env) - int tty, ignore_env; +_rl_get_screen_size (int tty, int ignore_env) { char *ss; #if defined (TIOCGWINSZ) @@ -318,8 +317,7 @@ _rl_get_screen_size (tty, ignore_env) } void -_rl_set_screen_size (rows, cols) - int rows, cols; +_rl_set_screen_size (int rows, int cols) { if (_rl_term_autowrap == -1) _rl_init_terminal_io (rl_terminal_name); @@ -338,15 +336,13 @@ _rl_set_screen_size (rows, cols) } void -rl_set_screen_size (rows, cols) - int rows, cols; +rl_set_screen_size (int rows, int cols) { _rl_set_screen_size (rows, cols); } void -rl_get_screen_size (rows, cols) - int *rows, *cols; +rl_get_screen_size (int *rows, int *cols) { if (rows) *rows = _rl_screenheight; @@ -355,19 +351,19 @@ rl_get_screen_size (rows, cols) } void -rl_reset_screen_size () +rl_reset_screen_size (void) { _rl_get_screen_size (fileno (rl_instream), 0); } void -_rl_sigwinch_resize_terminal () +_rl_sigwinch_resize_terminal (void) { _rl_get_screen_size (fileno (rl_instream), 1); } void -rl_resize_terminal () +rl_resize_terminal (void) { _rl_get_screen_size (fileno (rl_instream), 1); if (_rl_echoing_p) @@ -390,6 +386,7 @@ static const struct _tc_string tc_strings[] = { { "@7", &_rl_term_at7 }, { "DC", &_rl_term_DC }, + { "E3", &_rl_term_clrscroll }, { "IC", &_rl_term_IC }, { "ce", &_rl_term_clreol }, { "cl", &_rl_term_clrpag }, @@ -424,8 +421,7 @@ static const struct _tc_string tc_strings[] = /* Read the desired terminal capability strings into BP. The capabilities are described in the TC_STRINGS table. */ static void -get_term_capabilities (bp) - char **bp; +get_term_capabilities (char **bp) { #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ register int i; @@ -437,15 +433,14 @@ get_term_capabilities (bp) } int -_rl_init_terminal_io (terminal_name) - const char *terminal_name; +_rl_init_terminal_io (const char *terminal_name) { const char *term; char *buffer; int tty, tgetent_ret; term = terminal_name ? terminal_name : sh_get_env_value ("TERM"); - _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL; + _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL; tty = rl_instream ? fileno (rl_instream) : 0; if (term == 0) @@ -458,7 +453,7 @@ _rl_init_terminal_io (terminal_name) _rl_term_mm = _rl_term_mo = (char *)NULL; _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0; _rl_term_cr = "\r"; - _rl_term_clreol = _rl_term_clrpag = _rl_term_backspace = (char *)NULL; + _rl_term_backspace = (char *)NULL; _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL; _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL; _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL; @@ -584,8 +579,7 @@ _rl_init_terminal_io (terminal_name) /* Bind the arrow key sequences from the termcap description in MAP. */ static void -bind_termcap_arrow_keys (map) - Keymap map; +bind_termcap_arrow_keys (Keymap map) { Keymap xkeymap; @@ -601,13 +595,13 @@ bind_termcap_arrow_keys (map) rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete); + rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode); /* Insert */ _rl_keymap = xkeymap; } char * -rl_get_termcap (cap) - const char *cap; +rl_get_termcap (const char *cap) { register int i; @@ -624,8 +618,7 @@ rl_get_termcap (cap) /* Re-initialize the terminal considering that the TERM/TERMCAP variable has changed. */ int -rl_reset_terminal (terminal_name) - const char *terminal_name; +rl_reset_terminal (const char *terminal_name) { _rl_screenwidth = _rl_screenheight = 0; _rl_init_terminal_io (terminal_name); @@ -635,15 +628,13 @@ rl_reset_terminal (terminal_name) /* A function for the use of tputs () */ #ifdef _MINIX void -_rl_output_character_function (c) - int c; +_rl_output_character_function (int c) { putc (c, _rl_out_stream); } #else /* !_MINIX */ int -_rl_output_character_function (c) - int c; +_rl_output_character_function (int c) { return putc (c, _rl_out_stream); } @@ -651,17 +642,14 @@ _rl_output_character_function (c) /* Write COUNT characters from STRING to the output stream. */ void -_rl_output_some_chars (string, count) - const char *string; - int count; +_rl_output_some_chars (const char *string, int count) { fwrite (string, 1, count, _rl_out_stream); } /* Move the cursor back. */ int -_rl_backspace (count) - int count; +_rl_backspace (int count) { register int i; @@ -678,7 +666,7 @@ _rl_backspace (count) /* Move to the start of the next line. */ int -rl_crlf () +rl_crlf (void) { #if defined (NEW_TTY_DRIVER) || defined (__MINT__) if (_rl_term_cr) @@ -690,7 +678,7 @@ rl_crlf () /* Ring the terminal bell. */ int -rl_ding () +rl_ding (void) { if (_rl_echoing_p) { @@ -729,7 +717,7 @@ rl_ding () static int enabled_meta = 0; /* flag indicating we enabled meta mode */ void -_rl_enable_meta_key () +_rl_enable_meta_key (void) { #if !defined (__DJGPP__) if (term_has_meta && _rl_term_mm) @@ -741,7 +729,7 @@ _rl_enable_meta_key () } void -_rl_disable_meta_key () +_rl_disable_meta_key (void) { #if !defined (__DJGPP__) if (term_has_meta && _rl_term_mo && enabled_meta) @@ -753,8 +741,7 @@ _rl_disable_meta_key () } void -_rl_control_keypad (on) - int on; +_rl_control_keypad (int on) { #if !defined (__DJGPP__) if (on && _rl_term_ks) @@ -775,8 +762,7 @@ _rl_control_keypad (on) cursor. Overwrite mode gets a very visible cursor. Only does anything if we have both capabilities. */ void -_rl_set_cursor (im, force) - int im, force; +_rl_set_cursor (int im, int force) { #ifndef __MSDOS__ if (_rl_term_ve && _rl_term_vs) diff --git a/readline/text.c b/readline/text.c index c353252..cddaeeb 100644 --- a/readline/text.c +++ b/readline/text.c @@ -1,6 +1,6 @@ /* text.c -- text handling commands for readline. */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -83,8 +83,7 @@ int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */ way that you should do insertion. _rl_insert_char () calls this function. Returns the number of characters inserted. */ int -rl_insert_text (string) - const char *string; +rl_insert_text (const char *string) { register int i, l; @@ -121,8 +120,7 @@ rl_insert_text (string) /* Delete the string between FROM and TO. FROM is inclusive, TO is not. Returns the number of characters deleted. */ int -rl_delete_text (from, to) - int from, to; +rl_delete_text (int from, int to) { register char *text; register int diff, i; @@ -172,8 +170,7 @@ rl_delete_text (from, to) } while (0) void -_rl_fix_point (fix_mark_too) - int fix_mark_too; +_rl_fix_point (int fix_mark_too) { _RL_FIX_POINT (rl_point); if (fix_mark_too) @@ -185,9 +182,7 @@ _rl_fix_point (fix_mark_too) TEXT. The operation is undoable. To replace the entire line in an undoable mode, use _rl_replace_text(text, 0, rl_end); */ int -_rl_replace_text (text, start, end) - const char *text; - int start, end; +_rl_replace_text (const char *text, int start, int end) { int n; @@ -206,9 +201,7 @@ _rl_replace_text (text, start, end) /* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is non-zero, we free the current undo list. */ void -rl_replace_line (text, clear_undo) - const char *text; - int clear_undo; +rl_replace_line (const char *text, int clear_undo) { int len; @@ -259,8 +252,7 @@ rl_replace_line (text, clear_undo) /* Move forward COUNT bytes. */ int -rl_forward_byte (count, key) - int count, key; +rl_forward_byte (int count, int key) { if (count < 0) return (rl_backward_byte (-count, key)); @@ -292,8 +284,7 @@ rl_forward_byte (count, key) } int -_rl_forward_char_internal (count) - int count; +_rl_forward_char_internal (int count) { int point; @@ -306,21 +297,47 @@ _rl_forward_char_internal (count) #endif if (rl_end < 0) - rl_end = 0; + rl_end = 0; #else point = rl_point + count; +#endif + if (point > rl_end) point = rl_end; + return (point); +} + +int +_rl_backward_char_internal (int count) +{ + int point; + + point = rl_point; +#if defined (HANDLE_MULTIBYTE) + if (count > 0) + { + while (count > 0 && point > 0) + { + point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO); + count--; + } + if (count > 0) + return 0; /* XXX - rl_ding() here? */ + } +#else + if (count > 0) + point -= count; #endif + if (point < 0) + point = 0; return (point); } #if defined (HANDLE_MULTIBYTE) /* Move forward COUNT characters. */ int -rl_forward_char (count, key) - int count, key; +rl_forward_char (int count, int key) { int point; @@ -350,8 +367,7 @@ rl_forward_char (count, key) } #else /* !HANDLE_MULTIBYTE */ int -rl_forward_char (count, key) - int count, key; +rl_forward_char (int count, int key) { return (rl_forward_byte (count, key)); } @@ -359,16 +375,14 @@ rl_forward_char (count, key) /* Backwards compatibility. */ int -rl_forward (count, key) - int count, key; +rl_forward (int count, int key) { return (rl_forward_char (count, key)); } /* Move backward COUNT bytes. */ int -rl_backward_byte (count, key) - int count, key; +rl_backward_byte (int count, int key) { if (count < 0) return (rl_forward_byte (-count, key)); @@ -393,8 +407,7 @@ rl_backward_byte (count, key) #if defined (HANDLE_MULTIBYTE) /* Move backward COUNT characters. */ int -rl_backward_char (count, key) - int count, key; +rl_backward_char (int count, int key) { int point; @@ -426,8 +439,7 @@ rl_backward_char (count, key) } #else int -rl_backward_char (count, key) - int count, key; +rl_backward_char (int count, int key) { return (rl_backward_byte (count, key)); } @@ -435,16 +447,14 @@ rl_backward_char (count, key) /* Backwards compatibility. */ int -rl_backward (count, key) - int count, key; +rl_backward (int count, int key) { return (rl_backward_char (count, key)); } /* Move to the beginning of the line. */ int -rl_beg_of_line (count, key) - int count, key; +rl_beg_of_line (int count, int key) { rl_point = 0; return 0; @@ -452,8 +462,7 @@ rl_beg_of_line (count, key) /* Move to the end of the line. */ int -rl_end_of_line (count, key) - int count, key; +rl_end_of_line (int count, int key) { rl_point = rl_end; return 0; @@ -461,8 +470,7 @@ rl_end_of_line (count, key) /* Move forward a word. We do what Emacs does. Handles multibyte chars. */ int -rl_forward_word (count, key) - int count, key; +rl_forward_word (int count, int key) { int c; @@ -510,8 +518,7 @@ rl_forward_word (count, key) /* Move backward a word. We do what Emacs does. Handles multibyte chars. */ int -rl_backward_word (count, key) - int count, key; +rl_backward_word (int count, int key) { int c, p; @@ -560,8 +567,7 @@ rl_backward_word (count, key) /* Clear the current line. Numeric argument to C-l does this. */ int -rl_refresh_line (ignore1, ignore2) - int ignore1, ignore2; +rl_refresh_line (int ignore1, int ignore2) { int curr_line; @@ -582,8 +588,7 @@ rl_refresh_line (ignore1, ignore2) the prompt and the current input line. Given a numeric arg, redraw only the current line. */ int -rl_clear_screen (count, key) - int count, key; +rl_clear_screen (int count, int key) { if (rl_explicit_arg) { @@ -599,8 +604,25 @@ rl_clear_screen (count, key) } int -rl_skip_csi_sequence (count, key) - int count, key; +rl_previous_screen_line (int count, int key) +{ + int c; + + c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1); + return (rl_backward_char (c, key)); +} + +int +rl_next_screen_line (int count, int key) +{ + int c; + + c = _rl_term_autowrap ? _rl_screenwidth : (_rl_screenwidth + 1); + return (rl_forward_char (c, key)); +} + +int +rl_skip_csi_sequence (int count, int key) { int ch; @@ -614,8 +636,7 @@ rl_skip_csi_sequence (count, key) } int -rl_arrow_keys (count, c) - int count, c; +rl_arrow_keys (int count, int key) { int ch; @@ -672,8 +693,7 @@ static mbstate_t ps = {0}; If C introduces a multibyte sequence, we read the whole sequence and then insert the multibyte char into the line buffer. */ int -_rl_insert_char (count, c) - int count, c; +_rl_insert_char (int count, int c) { register int i; char *string; @@ -695,6 +715,12 @@ _rl_insert_char (count, c) incoming[1] = '\0'; incoming_length = 1; } + else if (_rl_utf8locale && (c & 0x80) == 0) + { + incoming[0] = c; + incoming[1] = '\0'; + incoming_length = 1; + } else { wchar_t wc; @@ -739,6 +765,12 @@ _rl_insert_char (count, c) effect of mbstate is undefined. */ memset (&ps, 0, sizeof (mbstate_t)); } + else if (ret == 1) + { + incoming[0] = pending_bytes[0]; + incoming[incoming_length = 1] = '\0'; + pending_bytes_length = 0; + } else { /* We successfully read a single multibyte character. */ @@ -761,8 +793,13 @@ _rl_insert_char (count, c) i = 0; while (i < string_size) { - strncpy (string + i, incoming, incoming_length); - i += incoming_length; + if (incoming_length == 1) + string[i++] = *incoming; + else + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } } incoming_length = 0; stored_count = 0; @@ -790,8 +827,13 @@ _rl_insert_char (count, c) i = 0; while (i < string_size) { - strncpy (string + i, incoming, incoming_length); - i += incoming_length; + if (incoming_length == 1) + string[i++] = *incoming; + else + { + strncpy (string + i, incoming, incoming_length); + i += incoming_length; + } } while (count) @@ -857,8 +899,7 @@ _rl_insert_char (count, c) If C introduces a multibyte character sequence, read the entire sequence before starting the overwrite loop. */ int -_rl_overwrite_char (count, c) - int count, c; +_rl_overwrite_char (int count, int c) { int i; #if defined (HANDLE_MULTIBYTE) @@ -891,8 +932,7 @@ _rl_overwrite_char (count, c) } int -rl_insert (count, c) - int count, c; +rl_insert (int count, int c) { int r, n, x; @@ -902,6 +942,7 @@ rl_insert (count, c) x = 0; n = (unsigned short)-2; while (_rl_optimize_typeahead && + rl_num_chars_to_read == 0 && (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available () == 0 && _rl_input_queued (0) && @@ -941,8 +982,7 @@ rl_insert (count, c) /* Insert the next typed character verbatim. */ static int -_rl_insert_next (count) - int count; +_rl_insert_next (int count) { int c; @@ -966,24 +1006,37 @@ _rl_insert_next (count) #if defined (READLINE_CALLBACKS) static int -_rl_insert_next_callback (data) - _rl_callback_generic_arg *data; +_rl_insert_next_callback (_rl_callback_generic_arg *data) { - int count; + int count, r; count = data->count; + r = 0; + + if (count < 0) + { + data->count++; + r = _rl_insert_next (1); + _rl_want_redisplay = 1; + /* If we should keep going, leave the callback function installed */ + if (data->count < 0 && r == 0) + return r; + count = 0; /* data->count == 0 || r != 0; force break below */ + } /* Deregister function, let rl_callback_read_char deallocate data */ _rl_callback_func = 0; _rl_want_redisplay = 1; - + + if (count == 0) + return r; + return _rl_insert_next (count); } #endif int -rl_quoted_insert (count, key) - int count, key; +rl_quoted_insert (int count, int key) { /* Let's see...should the callback interface futz with signal handling? */ #if defined (HANDLE_SIGNALS) @@ -999,14 +1052,24 @@ rl_quoted_insert (count, key) return (0); } #endif - + + /* A negative count means to quote the next -COUNT characters. */ + if (count < 0) + { + int r; + + do + r = _rl_insert_next (1); + while (r == 0 && ++count < 0); + return r; + } + return _rl_insert_next (count); } /* Insert a tab character. */ int -rl_tab_insert (count, key) - int count, key; +rl_tab_insert (int count, int key) { return (_rl_insert_char (count, '\t')); } @@ -1015,8 +1078,7 @@ rl_tab_insert (count, key) KEY is the key that invoked this command. I guess it could have meaning in the future. */ int -rl_newline (count, key) - int count, key; +rl_newline (int count, int key) { rl_done = 1; @@ -1049,8 +1111,7 @@ rl_newline (count, key) is just a stub, you bind keys to it and the code in _rl_dispatch () is special cased. */ int -rl_do_lowercase_version (ignore1, ignore2) - int ignore1, ignore2; +rl_do_lowercase_version (int ignore1, int ignore2) { return 0; } @@ -1059,8 +1120,7 @@ rl_do_lowercase_version (ignore1, ignore2) rubout in overwrite mode has one oddity: it replaces a control character that's displayed as two characters (^X) with two spaces. */ int -_rl_overwrite_rubout (count, key) - int count, key; +_rl_overwrite_rubout (int count, int key) { int opoint; int i, l; @@ -1102,8 +1162,7 @@ _rl_overwrite_rubout (count, key) /* Rubout the character behind point. */ int -rl_rubout (count, key) - int count, key; +rl_rubout (int count, int key) { if (count < 0) return (rl_delete (-count, key)); @@ -1121,8 +1180,7 @@ rl_rubout (count, key) } int -_rl_rubout_char (count, key) - int count, key; +_rl_rubout_char (int count, int key) { int orig_point; unsigned char c; @@ -1167,8 +1225,7 @@ _rl_rubout_char (count, key) /* Delete the character under the cursor. Given a numeric argument, kill that many characters instead. */ int -rl_delete (count, key) - int count, key; +rl_delete (int count, int key) { int xpoint; @@ -1205,8 +1262,7 @@ rl_delete (count, key) behind the cursor is deleted. COUNT is obeyed and may be used to delete forward or backward that many characters. */ int -rl_rubout_or_delete (count, key) - int count, key; +rl_rubout_or_delete (int count, int key) { if (rl_end != 0 && rl_point == rl_end) return (_rl_rubout_char (count, key)); @@ -1216,8 +1272,7 @@ rl_rubout_or_delete (count, key) /* Delete all spaces and tabs around point. */ int -rl_delete_horizontal_space (count, ignore) - int count, ignore; +rl_delete_horizontal_space (int count, int ignore) { int start; @@ -1245,8 +1300,7 @@ rl_delete_horizontal_space (count, ignore) is caught before this is invoked, so this really does the same thing as delete-char-or-list-or-eof, as long as it's bound to the eof character. */ int -rl_delete_or_show_completions (count, key) - int count, key; +rl_delete_or_show_completions (int count, int key) { if (rl_end != 0 && rl_point == rl_end) return (rl_possible_completions (count, key)); @@ -1261,8 +1315,7 @@ rl_delete_or_show_completions (count, key) /* Turn the current line into a comment in shell history. A K*rn shell style function. */ int -rl_insert_comment (count, key) - int count, key; +rl_insert_comment (int count, int key) { char *rl_comment_text; int rl_comment_len; @@ -1300,24 +1353,21 @@ rl_insert_comment (count, key) /* Uppercase the word at point. */ int -rl_upcase_word (count, key) - int count, key; +rl_upcase_word (int count, int key) { return (rl_change_case (count, UpCase)); } /* Lowercase the word at point. */ int -rl_downcase_word (count, key) - int count, key; +rl_downcase_word (int count, int key) { return (rl_change_case (count, DownCase)); } /* Upcase the first letter, downcase the rest. */ int -rl_capitalize_word (count, key) - int count, key; +rl_capitalize_word (int count, int key) { return (rl_change_case (count, CapCase)); } @@ -1328,11 +1378,11 @@ rl_capitalize_word (count, key) If a negative argument is given, leave point where it started, otherwise, leave it where it moves to. */ static int -rl_change_case (count, op) - int count, op; +rl_change_case (int count, int op) { int start, next, end; - int inword, c, nc, nop; + int inword, nc, nop; + wchar_t c; #if defined (HANDLE_MULTIBYTE) wchar_t wc, nwc; char mb[MB_LEN_MAX+1]; @@ -1382,7 +1432,10 @@ rl_change_case (count, op) } else nop = op; - if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c)) + /* Can't check isascii here; some languages (e.g, Turkish) have + multibyte upper and lower case equivalents of single-byte ascii + characters */ + if (MB_CUR_MAX == 1 || rl_byte_oriented) { nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); rl_line_buffer[start] = nc; @@ -1398,11 +1451,35 @@ rl_change_case (count, op) nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); if (nwc != wc) /* just skip unchanged characters */ { + char *s, *e; mlen = wcrtomb (mb, nwc, &mps); if (mlen > 0) mb[mlen] = '\0'; - /* Assume the same width */ - strncpy (rl_line_buffer + start, mb, mlen); + /* what to do if m != mlen? adjust below */ + /* m == length of old char, mlen == length of new char */ + s = rl_line_buffer + start; + e = rl_line_buffer + rl_end; + if (m == mlen) + memcpy (s, mb, mlen); + else if (m > mlen) + { + memcpy (s, mb, mlen); + memmove (s + mlen, s + m, (e - s) - m); + next -= m - mlen; /* next char changes */ + end -= m - mlen; /* end of word changes */ + rl_end -= m - mlen; /* end of line changes */ + rl_line_buffer[rl_end] = 0; + } + else if (m < mlen) + { + rl_extend_line_buffer (mlen - m + 1); + memmove (s + mlen, s + m, (e - s) - m); + memcpy (s, mb, mlen); + next += mlen - m; /* next char changes */ + end += mlen - m; /* end of word changes */ + rl_end += mlen - m; /* end of line changes */ + rl_line_buffer[rl_end] = 0; + } } } #endif @@ -1423,8 +1500,7 @@ rl_change_case (count, op) /* Transpose the words at point. If point is at the end of the line, transpose the two words before point. */ int -rl_transpose_words (count, key) - int count, key; +rl_transpose_words (int count, int key) { char *word1, *word2; int w1_beg, w1_end, w2_beg, w2_end; @@ -1484,8 +1560,7 @@ rl_transpose_words (count, key) /* Transpose the characters at point. If point is at the end of the line, then transpose the characters before point. */ int -rl_transpose_chars (count, key) - int count, key; +rl_transpose_chars (int count, int key) { #if defined (HANDLE_MULTIBYTE) char *dummy; @@ -1549,13 +1624,9 @@ rl_transpose_chars (count, key) int #if defined (HANDLE_MULTIBYTE) -_rl_char_search_internal (count, dir, smbchar, len) - int count, dir; - char *smbchar; - int len; +_rl_char_search_internal (int count, int dir, char *smbchar, int len) #else -_rl_char_search_internal (count, dir, schar) - int count, dir, schar; +_rl_char_search_internal (int count, int dir, int schar) #endif { int pos, inc; @@ -1619,8 +1690,7 @@ _rl_char_search_internal (count, dir, schar) that there are two separate versions of this function. */ #if defined (HANDLE_MULTIBYTE) static int -_rl_char_search (count, fdir, bdir) - int count, fdir, bdir; +_rl_char_search (int count, int fdir, int bdir) { char mbchar[MB_LEN_MAX]; int mb_len; @@ -1637,8 +1707,7 @@ _rl_char_search (count, fdir, bdir) } #else /* !HANDLE_MULTIBYTE */ static int -_rl_char_search (count, fdir, bdir) - int count, fdir, bdir; +_rl_char_search (int count, int fdir, int bdir) { int c; @@ -1669,8 +1738,7 @@ _rl_char_search_callback (data) #endif int -rl_char_search (count, key) - int count, key; +rl_char_search (int count, int key) { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -1687,8 +1755,7 @@ rl_char_search (count, key) } int -rl_backward_char_search (count, key) - int count, key; +rl_backward_char_search (int count, int key) { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -1712,10 +1779,9 @@ rl_backward_char_search (count, key) /* Set the mark at POSITION. */ int -_rl_set_mark_at_pos (position) - int position; +_rl_set_mark_at_pos (int position) { - if (position > rl_end) + if (position < 0 || position > rl_end) return 1; rl_mark = position; @@ -1724,23 +1790,22 @@ _rl_set_mark_at_pos (position) /* A bindable command to set the mark. */ int -rl_set_mark (count, key) - int count, key; +rl_set_mark (int count, int key) { return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point)); } /* Exchange the position of mark and point. */ int -rl_exchange_point_and_mark (count, key) - int count, key; +rl_exchange_point_and_mark (int count, int key) { if (rl_mark > rl_end) rl_mark = -1; - if (rl_mark == -1) + if (rl_mark < 0) { rl_ding (); + rl_mark = 0; /* like _RL_FIX_POINT */ return 1; } else diff --git a/readline/tilde.c b/readline/tilde.c index 95bc421..9d0f296 100644 --- a/readline/tilde.c +++ b/readline/tilde.c @@ -1,6 +1,6 @@ /* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ -/* Copyright (C) 1988-2009 Free Software Foundation, Inc. +/* Copyright (C) 1988-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -125,9 +125,7 @@ static char *glue_prefix_and_suffix PARAMS((char *, const char *, int)); the tilde which starts the expansion. Place the length of the text which identified this tilde starter in LEN, excluding the tilde itself. */ static int -tilde_find_prefix (string, len) - const char *string; - int *len; +tilde_find_prefix (const char *string, int *len) { register int i, j, string_len; register char **prefixes; @@ -160,8 +158,7 @@ tilde_find_prefix (string, len) /* Find the end of a tilde expansion in STRING, and return the index of the character which ends the tilde definition. */ static int -tilde_find_suffix (string) - const char *string; +tilde_find_suffix (const char *string) { register int i, j, string_len; register char **suffixes; @@ -189,8 +186,7 @@ tilde_find_suffix (string) /* Return a new string which is the result of tilde expanding STRING. */ char * -tilde_expand (string) - const char *string; +tilde_expand (const char *string) { char *result; int result_size, result_index; @@ -267,9 +263,7 @@ tilde_expand (string) non-null, the index of the end of the prefix into FNAME is returned in the location it points to. */ static char * -isolate_tilde_prefix (fname, lenp) - const char *fname; - int *lenp; +isolate_tilde_prefix (const char *fname, int *lenp) { char *ret; int i; @@ -293,9 +287,7 @@ isolate_tilde_prefix (fname, lenp) function. Right now, it just calls tilde_find_suffix and allocates new memory, but it can be expanded to do different things later. */ char * -tilde_find_word (fname, flags, lenp) - const char *fname; - int flags, *lenp; +tilde_find_word (const char *fname, int flags, int *lenp) { int x; char *r; @@ -323,10 +315,7 @@ tilde_find_word (fname, flags, lenp) /* Return a string that is PREFIX concatenated with SUFFIX starting at SUFFIND. */ static char * -glue_prefix_and_suffix (prefix, suffix, suffind) - char *prefix; - const char *suffix; - int suffind; +glue_prefix_and_suffix (char *prefix, const char *suffix, int suffind) { char *ret; int plen, slen; @@ -344,8 +333,7 @@ glue_prefix_and_suffix (prefix, suffix, suffind) tilde. If there is no expansion, call tilde_expansion_failure_hook. This always returns a newly-allocated string, never static storage. */ char * -tilde_expand_word (filename) - const char *filename; +tilde_expand_word (const char *filename) { char *dirname, *expansion, *username; int user_len; @@ -434,9 +422,7 @@ tilde_expand_word (filename) #undef NULL #include <stdio.h> -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { char *result, line[512]; int done = 0; @@ -464,11 +450,10 @@ main (argc, argv) exit (0); } -static void memory_error_and_abort (); +static void memory_error_and_abort (void); static void * -xmalloc (bytes) - size_t bytes; +xmalloc (size_t bytes) { void *temp = (char *)malloc (bytes); @@ -478,9 +463,7 @@ xmalloc (bytes) } static void * -xrealloc (pointer, bytes) - void *pointer; - int bytes; +xrealloc (void *pointer, int bytes) { void *temp; @@ -496,7 +479,7 @@ xrealloc (pointer, bytes) } static void -memory_error_and_abort () +memory_error_and_abort (void) { fprintf (stderr, "readline: out of virtual memory\n"); abort (); diff --git a/readline/undo.c b/readline/undo.c index 5836304..ae65d38 100644 --- a/readline/undo.c +++ b/readline/undo.c @@ -1,6 +1,6 @@ /* undo.c - manage list of changes to lines, offering opportunity to undo them */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -51,6 +51,8 @@ extern void _hs_replace_history_data PARAMS((int, histdata_t *, histdata_t *)); +extern HIST_ENTRY *_rl_saved_line_for_history; + /* Non-zero tells rl_delete_text and rl_insert_text to not add to the undo list. */ int _rl_doing_an_undo = 0; @@ -68,10 +70,7 @@ UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL; /* **************************************************************** */ static UNDO_LIST * -alloc_undo_entry (what, start, end, text) - enum undo_code what; - int start, end; - char *text; +alloc_undo_entry (enum undo_code what, int start, int end, char *text) { UNDO_LIST *temp; @@ -88,10 +87,7 @@ alloc_undo_entry (what, start, end, text) /* Remember how to undo something. Concatenate some undos if that seems right. */ void -rl_add_undo (what, start, end, text) - enum undo_code what; - int start, end; - char *text; +rl_add_undo (enum undo_code what, int start, int end, char *text) { UNDO_LIST *temp; @@ -102,8 +98,7 @@ rl_add_undo (what, start, end, text) /* Free an UNDO_LIST */ void -_rl_free_undo_list (ul) - UNDO_LIST *ul; +_rl_free_undo_list (UNDO_LIST *ul) { UNDO_LIST *release; @@ -121,7 +116,7 @@ _rl_free_undo_list (ul) /* Free the existing undo list. */ void -rl_free_undo_list () +rl_free_undo_list (void) { UNDO_LIST *release, *orig_list; @@ -132,8 +127,7 @@ rl_free_undo_list () } UNDO_LIST * -_rl_copy_undo_entry (entry) - UNDO_LIST *entry; +_rl_copy_undo_entry (UNDO_LIST *entry) { UNDO_LIST *new; @@ -143,8 +137,7 @@ _rl_copy_undo_entry (entry) } UNDO_LIST * -_rl_copy_undo_list (head) - UNDO_LIST *head; +_rl_copy_undo_list (UNDO_LIST *head) { UNDO_LIST *list, *new, *roving, *c; @@ -173,9 +166,9 @@ _rl_copy_undo_list (head) /* Undo the next thing in the list. Return 0 if there is nothing to undo, or non-zero if there was. */ int -rl_do_undo () +rl_do_undo (void) { - UNDO_LIST *release; + UNDO_LIST *release, *search; int waiting_for_begin, start, end; HIST_ENTRY *cur, *temp; @@ -232,6 +225,7 @@ rl_do_undo () release = rl_undo_list; rl_undo_list = rl_undo_list->next; + release->next = 0; /* XXX */ /* If we are editing a history entry, make sure the change is replicated in the history entry's line */ @@ -244,8 +238,30 @@ rl_do_undo () xfree (temp); } + /* Make sure there aren't any history entries with that undo list */ _hs_replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list); + /* And make sure this list isn't anywhere in the saved line for history */ + if (_rl_saved_line_for_history && _rl_saved_line_for_history->data) + { + /* Brute force; no finesse here */ + search = (UNDO_LIST *)_rl_saved_line_for_history->data; + if (search == release) + _rl_saved_line_for_history->data = rl_undo_list; + else + { + while (search->next) + { + if (search->next == release) + { + search->next = rl_undo_list; + break; + } + search = search->next; + } + } + } + xfree (release); } while (waiting_for_begin); @@ -255,8 +271,7 @@ rl_do_undo () #undef TRANS int -_rl_fix_last_undo_of_type (type, start, end) - int type, start, end; +_rl_fix_last_undo_of_type (int type, int start, int end) { UNDO_LIST *rl; @@ -274,7 +289,7 @@ _rl_fix_last_undo_of_type (type, start, end) /* Begin a group. Subsequent undos are undone as an atomic operation. */ int -rl_begin_undo_group () +rl_begin_undo_group (void) { rl_add_undo (UNDO_BEGIN, 0, 0, 0); _rl_undo_group_level++; @@ -283,7 +298,7 @@ rl_begin_undo_group () /* End an undo group started with rl_begin_undo_group (). */ int -rl_end_undo_group () +rl_end_undo_group (void) { rl_add_undo (UNDO_END, 0, 0, 0); _rl_undo_group_level--; @@ -292,8 +307,7 @@ rl_end_undo_group () /* Save an undo entry for the text from START to END. */ int -rl_modifying (start, end) - int start, end; +rl_modifying (int start, int end) { if (start > end) { @@ -313,8 +327,7 @@ rl_modifying (start, end) /* Revert the current line to its previous state. */ int -rl_revert_line (count, key) - int count, key; +rl_revert_line (int count, int key) { if (rl_undo_list == 0) rl_ding (); @@ -333,8 +346,7 @@ rl_revert_line (count, key) /* Do some undoing of things that were done. */ int -rl_undo_command (count, key) - int count, key; +rl_undo_command (int count, int key) { if (count < 0) return 0; /* Nothing to do. */ diff --git a/readline/util.c b/readline/util.c index 28a9d9d..e8ae9d7 100644 --- a/readline/util.c +++ b/readline/util.c @@ -1,6 +1,6 @@ /* util.c -- readline utility functions */ -/* Copyright (C) 1987-2015 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -70,8 +70,7 @@ int _rl_allow_pathname_alphabetic_chars = 0; static const char * const pathname_alphabetic_chars = "/-_=~.#$"; int -rl_alphabetic (c) - int c; +rl_alphabetic (int c) { if (ALPHABETIC (c)) return (1); @@ -97,7 +96,7 @@ _rl_walphabetic (wchar_t wc) /* How to abort things. */ int -_rl_abort_internal () +_rl_abort_internal (void) { rl_ding (); rl_clear_message (); @@ -117,22 +116,19 @@ _rl_abort_internal () } int -rl_abort (count, key) - int count, key; +rl_abort (int count, int key) { return (_rl_abort_internal ()); } int -_rl_null_function (count, key) - int count, key; +_rl_null_function (int count, int key) { return 0; } int -rl_tty_status (count, key) - int count, key; +rl_tty_status (int count, int key) { #if defined (TIOCSTAT) ioctl (1, TIOCSTAT, (char *)0); @@ -146,8 +142,7 @@ rl_tty_status (count, key) /* Return a copy of the string between FROM and TO. FROM is inclusive, TO is not. */ char * -rl_copy_text (from, to) - int from, to; +rl_copy_text (int from, int to) { register int length; char *copy; @@ -166,8 +161,7 @@ rl_copy_text (from, to) /* Increase the size of RL_LINE_BUFFER until it has enough space to hold LEN characters. */ void -rl_extend_line_buffer (len) - int len; +rl_extend_line_buffer (int len) { while (len >= rl_line_buffer_len) { @@ -181,8 +175,7 @@ rl_extend_line_buffer (len) /* A function for simple tilde expansion. */ int -rl_tilde_expand (ignore, key) - int ignore, key; +rl_tilde_expand (int ignore, int key) { register int start, end; char *homedir, *temp; @@ -200,7 +193,7 @@ rl_tilde_expand (ignore, key) } else if (start >= 0 && rl_line_buffer[start] != '~') { - for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) + for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--) ; start++; } @@ -324,8 +317,7 @@ _rl_errmsg (format, arg1, arg2) /* Determine if s2 occurs in s1. If so, return a pointer to the match in s1. The compare is case insensitive. */ char * -_rl_strindex (s1, s2) - register const char *s1, *s2; +_rl_strindex (const char *s1, const char *s2) { register int i, l, len; @@ -339,8 +331,7 @@ _rl_strindex (s1, s2) /* Find the first occurrence in STRING1 of any character from STRING2. Return a pointer to the character in STRING1. */ char * -_rl_strpbrk (string1, string2) - const char *string1, *string2; +_rl_strpbrk (const char *string1, const char *string2) { register const char *scan; #if defined (HANDLE_MULTIBYTE) @@ -374,10 +365,7 @@ _rl_strpbrk (string1, string2) /* Compare at most COUNT characters from string1 to string2. Case doesn't matter (strncasecmp). */ int -_rl_strnicmp (string1, string2, count) - const char *string1; - const char *string2; - int count; +_rl_strnicmp (const char *string1, const char *string2, int count) { register const char *s1; register const char *s2; @@ -404,9 +392,7 @@ _rl_strnicmp (string1, string2, count) /* strcmp (), but caseless (strcasecmp). */ int -_rl_stricmp (string1, string2) - const char *string1; - const char *string2; +_rl_stricmp (const char *string1, const char *string2) { register const char *s1; register const char *s2; @@ -431,8 +417,7 @@ _rl_stricmp (string1, string2) /* Stupid comparison routine for qsort () ing strings. */ int -_rl_qsort_string_compare (s1, s2) - char **s1, **s2; +_rl_qsort_string_compare (char **s1, char **s2) { #if defined (HAVE_STRCOLL) return (strcoll (*s1, *s2)); @@ -448,7 +433,7 @@ _rl_qsort_string_compare (s1, s2) } /* Function equivalents for the macros defined in chardefs.h. */ -#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } +#define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); } FUNCTION_FOR_MACRO (_rl_digit_p) FUNCTION_FOR_MACRO (_rl_digit_value) @@ -461,8 +446,7 @@ FUNCTION_FOR_MACRO (_rl_uppercase_p) /* A convenience function, to force memory deallocation to be performed by readline. DLLs on Windows apparently require this. */ void -rl_free (mem) - void *mem; +rl_free (void *mem) { if (mem) free (mem); @@ -472,8 +456,7 @@ rl_free (mem) all `public' readline header files. */ #undef _rl_savestring char * -_rl_savestring (s) - const char *s; +_rl_savestring (const char *s) { return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); } @@ -512,7 +495,7 @@ _rl_trace (va_alist) } int -_rl_tropen () +_rl_tropen (void) { char fnbuf[128], *x; @@ -521,7 +504,7 @@ _rl_tropen () #if defined (_WIN32) && !defined (__CYGWIN__) /* Windows doesn't have /var/tmp, so open the trace file in the user's temporary directory instead. */ - sprintf (fnbuf, "%s/rltrace.%ld", + snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", (sh_get_env_value ("TEMP") ? sh_get_env_value ("TEMP") : "."), @@ -535,7 +518,7 @@ _rl_tropen () } int -_rl_trclose () +_rl_trclose (void) { int r; @@ -545,8 +528,7 @@ _rl_trclose () } void -_rl_settracefp (fp) - FILE *fp; +_rl_settracefp (FILE *fp) { _rl_tracefp = fp; } @@ -562,8 +544,7 @@ _rl_settracefp (fp) /* Report STRING to the audit system. */ void -_rl_audit_tty (string) - char *string; +_rl_audit_tty (char *string) { struct audit_message req; struct sockaddr_nl addr; diff --git a/readline/vi_keymap.c b/readline/vi_keymap.c index e5da2e0..045258b 100644 --- a/readline/vi_keymap.c +++ b/readline/vi_keymap.c @@ -1,6 +1,6 @@ /* vi_keymap.c -- the keymap for vi_mode in readline (). */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. diff --git a/readline/vi_mode.c b/readline/vi_mode.c index 56d2e72..836371c 100644 --- a/readline/vi_mode.c +++ b/readline/vi_mode.c @@ -1,7 +1,7 @@ /* vi_mode.c -- A vi emulation mode for Bash. Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ -/* Copyright (C) 1987-2016 Free Software Foundation, Inc. +/* Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -63,6 +63,21 @@ #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) #endif +/* Increment START to the next character in RL_LINE_BUFFER, handling multibyte chars */ +#if defined (HANDLE_MULTIBYTE) +#define INCREMENT_POS(start) \ + do { \ + if (MB_CUR_MAX == 1 || rl_byte_oriented) \ + start++; \ + else \ + start = _rl_find_next_mbchar (rl_line_buffer, start, 1, MB_FIND_ANY); \ + } while (0) +#else /* !HANDLE_MULTIBYTE */ +#define INCREMENT_POS(start) (start)++ +#endif /* !HANDLE_MULTIBYTE */ + +/* This is global so other parts of the code can check whether the last + command was a text modification command. */ int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */ _rl_vimotion_cxt *_rl_vimvcxt = 0; @@ -99,7 +114,7 @@ static int _rl_vi_last_search_mblen; #else static int _rl_vi_last_search_char; #endif -static int _rl_vi_last_replacement; +static char _rl_vi_last_replacement[MB_LEN_MAX+1]; /* reserve for trailing NULL */ static int _rl_vi_last_key_before_insert; @@ -116,7 +131,7 @@ static void _rl_vi_save_insert PARAMS((UNDO_LIST *)); static void vi_save_insert_buffer PARAMS ((int, int)); -static void _rl_vi_backup PARAMS((void)); +static inline void _rl_vi_backup PARAMS((void)); static int _rl_vi_arg_dispatch PARAMS((int)); static int rl_digit_loop1 PARAMS((void)); @@ -124,6 +139,9 @@ static int rl_digit_loop1 PARAMS((void)); static int _rl_vi_set_mark PARAMS((void)); static int _rl_vi_goto_mark PARAMS((void)); +static inline int _rl_vi_advance_point PARAMS((void)); +static inline int _rl_vi_backup_point PARAMS((void)); + static void _rl_vi_append_forward PARAMS((int)); static int _rl_vi_callback_getchar PARAMS((char *, int)); @@ -146,7 +164,7 @@ static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *)); static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *)); void -_rl_vi_initialize_line () +_rl_vi_initialize_line (void) { register int i, n; @@ -158,7 +176,7 @@ _rl_vi_initialize_line () } void -_rl_vi_reset_last () +_rl_vi_reset_last (void) { _rl_vi_last_command = 'i'; _rl_vi_last_repeat = 1; @@ -167,8 +185,7 @@ _rl_vi_reset_last () } void -_rl_vi_set_last (key, repeat, sign) - int key, repeat, sign; +_rl_vi_set_last (int key, int repeat, int sign) { _rl_vi_last_command = key; _rl_vi_last_repeat = repeat; @@ -178,31 +195,28 @@ _rl_vi_set_last (key, repeat, sign) /* A convenience function that calls _rl_vi_set_last to save the last command information and enters insertion mode. */ void -rl_vi_start_inserting (key, repeat, sign) - int key, repeat, sign; +rl_vi_start_inserting (int key, int repeat, int sign) { _rl_vi_set_last (key, repeat, sign); + rl_begin_undo_group (); /* ensure inserts aren't concatenated */ rl_vi_insertion_mode (1, key); } /* Is the command C a VI mode text modification command? */ int -_rl_vi_textmod_command (c) - int c; +_rl_vi_textmod_command (int c) { return (member (c, vi_textmod)); } int -_rl_vi_motion_command (c) - int c; +_rl_vi_motion_command (int c) { return (member (c, vi_motion)); } static void -_rl_vi_replace_insert (count) - int count; +_rl_vi_replace_insert (int count) { int nchars; @@ -217,8 +231,7 @@ _rl_vi_replace_insert (count) } static void -_rl_vi_stuff_insert (count) - int count; +_rl_vi_stuff_insert (int count) { rl_begin_undo_group (); while (count--) @@ -230,8 +243,7 @@ _rl_vi_stuff_insert (count) redo a text modification command. The default for _rl_vi_last_command puts you back into insert mode. */ int -rl_vi_redo (count, c) - int count, c; +rl_vi_redo (int count, int c) { int r; @@ -296,16 +308,14 @@ rl_vi_redo (count, c) /* A placeholder for further expansion. */ int -rl_vi_undo (count, key) - int count, key; +rl_vi_undo (int count, int key) { return (rl_undo_command (count, key)); } /* Yank the nth arg from the previous line into this line at point. */ int -rl_vi_yank_arg (count, key) - int count, key; +rl_vi_yank_arg (int count, int key) { /* Readline thinks that the first word on a line is the 0th, while vi thinks the first word on a line is the 1st. Compensate. */ @@ -320,8 +330,7 @@ rl_vi_yank_arg (count, key) /* With an argument, move back that many history lines, else move to the beginning of history. */ int -rl_vi_fetch_history (count, c) - int count, c; +rl_vi_fetch_history (int count, int c) { int wanted; @@ -345,8 +354,7 @@ rl_vi_fetch_history (count, c) /* Search again for the last thing searched for. */ int -rl_vi_search_again (count, key) - int count, key; +rl_vi_search_again (int count, int key) { switch (key) { @@ -363,8 +371,7 @@ rl_vi_search_again (count, key) /* Do a vi style search. */ int -rl_vi_search (count, key) - int count, key; +rl_vi_search (int count, int key) { switch (key) { @@ -387,14 +394,13 @@ rl_vi_search (count, key) /* Completion, from vi's point of view. */ int -rl_vi_complete (ignore, key) - int ignore, key; +rl_vi_complete (int ignore, int key) { if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) { if (!whitespace (rl_line_buffer[rl_point + 1])) rl_vi_end_word (1, 'E'); - rl_point++; + _rl_vi_advance_point (); } if (key == '*') @@ -414,8 +420,7 @@ rl_vi_complete (ignore, key) /* Tilde expansion for vi mode. */ int -rl_vi_tilde_expand (ignore, key) - int ignore, key; +rl_vi_tilde_expand (int ignore, int key) { rl_tilde_expand (0, key); rl_vi_start_inserting (key, 1, rl_arg_sign); @@ -424,8 +429,7 @@ rl_vi_tilde_expand (ignore, key) /* Previous word in vi mode. */ int -rl_vi_prev_word (count, key) - int count, key; +rl_vi_prev_word (int count, int key) { if (count < 0) return (rl_vi_next_word (-count, key)); @@ -446,8 +450,7 @@ rl_vi_prev_word (count, key) /* Next word in vi mode. */ int -rl_vi_next_word (count, key) - int count, key; +rl_vi_next_word (int count, int key) { if (count < 0) return (rl_vi_prev_word (-count, key)); @@ -465,10 +468,72 @@ rl_vi_next_word (count, key) return (0); } +static inline int +_rl_vi_advance_point (void) +{ + int point; + + point = rl_point; + if (rl_point < rl_end) +#if defined (HANDLE_MULTIBYTE) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point++; + else + { + point = rl_point; + rl_point = _rl_forward_char_internal (1); + if (point == rl_point || rl_point > rl_end) + rl_point = rl_end; + } + } +#else + rl_point++; +#endif + + return point; +} + +/* Move the cursor back one character. */ +static inline void +_rl_vi_backup (void) +{ + if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) + rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); + else + rl_point--; +} + +/* Move the point back one character, returning the starting value and not + doing anything at the beginning of the line */ +static inline int +_rl_vi_backup_point (void) +{ + int point; + + point = rl_point; + if (rl_point > 0) +#if defined (HANDLE_MULTIBYTE) + { + if (MB_CUR_MAX == 1 || rl_byte_oriented) + rl_point--; + else + { + point = rl_point; + rl_point = _rl_backward_char_internal (1); + if (rl_point < 0) + rl_point = 0; /* XXX - not really necessary */ + } + } +#else + rl_point--; +#endif + return point; +} + /* Move to the end of the ?next? word. */ int -rl_vi_end_word (count, key) - int count, key; +rl_vi_end_word (int count, int key) { if (count < 0) { @@ -485,25 +550,23 @@ rl_vi_end_word (count, key) /* Move forward a word the way that 'W' does. */ int -rl_vi_fWord (count, ignore) - int count, ignore; +rl_vi_fWord (int count, int ignore) { while (count-- && rl_point < (rl_end - 1)) { /* Skip until whitespace. */ while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) - rl_point++; + _rl_vi_advance_point (); /* Now skip whitespace. */ while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) - rl_point++; + _rl_vi_advance_point (); } return (0); } int -rl_vi_bWord (count, ignore) - int count, ignore; +rl_vi_bWord (int count, int ignore) { while (count-- && rl_point > 0) { @@ -514,141 +577,177 @@ rl_vi_bWord (count, ignore) rl_point--; while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) - rl_point--; + _rl_vi_backup_point (); if (rl_point > 0) { - while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point])); - rl_point++; + do + _rl_vi_backup_point (); + while (rl_point > 0 && !whitespace (rl_line_buffer[rl_point])); + if (rl_point > 0) /* hit whitespace */ + rl_point++; + + if (rl_point < 0) + rl_point = 0; } } return (0); } int -rl_vi_eWord (count, ignore) - int count, ignore; +rl_vi_eWord (int count, int ignore) { + int opoint; + while (count-- && rl_point < (rl_end - 1)) { - if (!whitespace (rl_line_buffer[rl_point])) - rl_point++; + if (whitespace (rl_line_buffer[rl_point]) == 0) + _rl_vi_advance_point (); /* Move to the next non-whitespace character (to the start of the next word). */ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) - rl_point++; + _rl_vi_advance_point (); if (rl_point && rl_point < rl_end) { + opoint = rl_point; + /* Skip whitespace. */ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) - rl_point++; + opoint = _rl_vi_advance_point (); /* XXX - why? */ /* Skip until whitespace. */ while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point])) - rl_point++; + opoint = _rl_vi_advance_point (); /* Move back to the last character of the word. */ - rl_point--; + rl_point = opoint; } } return (0); } int -rl_vi_fword (count, ignore) - int count, ignore; +rl_vi_fword (int count, int ignore) { + int opoint; + while (count-- && rl_point < (rl_end - 1)) { /* Move to white space (really non-identifer). */ if (_rl_isident (rl_line_buffer[rl_point])) { while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end) - rl_point++; + _rl_vi_advance_point (); } else /* if (!whitespace (rl_line_buffer[rl_point])) */ { while (!_rl_isident (rl_line_buffer[rl_point]) && !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) - rl_point++; + _rl_vi_advance_point (); } + opoint = rl_point; + /* Move past whitespace. */ while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) - rl_point++; + opoint = _rl_vi_advance_point (); } return (0); } int -rl_vi_bword (count, ignore) - int count, ignore; +rl_vi_bword (int count, int ignore) { + int opoint; + while (count-- && rl_point > 0) { - int last_is_ident; + int prev_is_ident, cur_is_ident; /* If we are at the start of a word, move back to whitespace so we will go back to the start of the previous word. */ if (!whitespace (rl_line_buffer[rl_point]) && whitespace (rl_line_buffer[rl_point - 1])) - rl_point--; + if (--rl_point == 0) + break; /* If this character and the previous character are `opposite', move back so we don't get messed up by the rl_point++ down there in the while loop. Without this code, words like `l;' screw up the function. */ - last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]); - if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) || - (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident)) - rl_point--; + cur_is_ident = _rl_isident (rl_line_buffer[rl_point]); + opoint = _rl_vi_backup_point (); + prev_is_ident = _rl_isident (rl_line_buffer[rl_point]); + if ((cur_is_ident && !prev_is_ident) || (!cur_is_ident && prev_is_ident)) + ; /* leave point alone, we backed it up one character */ + else + rl_point = opoint; while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) - rl_point--; + _rl_vi_backup_point (); if (rl_point > 0) { + opoint = rl_point; if (_rl_isident (rl_line_buffer[rl_point])) - while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point])); + do + opoint = _rl_vi_backup_point (); + while (rl_point > 0 && _rl_isident (rl_line_buffer[rl_point])); else - while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) && + do + opoint = _rl_vi_backup_point (); + while (rl_point > 0 && !_rl_isident (rl_line_buffer[rl_point]) && !whitespace (rl_line_buffer[rl_point])); - rl_point++; + + if (rl_point > 0) + rl_point = opoint; + + if (rl_point < 0) + rl_point = 0; } } return (0); } int -rl_vi_eword (count, ignore) - int count, ignore; +rl_vi_eword (int count, int ignore) { - while (count-- && rl_point < rl_end - 1) + int opoint; + + while (count-- && rl_point < (rl_end - 1)) { - if (!whitespace (rl_line_buffer[rl_point])) - rl_point++; + if (whitespace (rl_line_buffer[rl_point]) == 0) + _rl_vi_advance_point (); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) - rl_point++; + _rl_vi_advance_point (); + opoint = rl_point; if (rl_point < rl_end) { if (_rl_isident (rl_line_buffer[rl_point])) - while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); + do + { + opoint = _rl_vi_advance_point (); + } + while (rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point])); else - while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) + do + { + opoint = _rl_vi_advance_point (); + } + while (rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point]) && !whitespace (rl_line_buffer[rl_point])); } - rl_point--; + rl_point = opoint; } return (0); } int -rl_vi_insert_beg (count, key) - int count, key; +rl_vi_insert_beg (int count, int key) { rl_beg_of_line (1, key); rl_vi_insert_mode (1, key); @@ -656,32 +755,13 @@ rl_vi_insert_beg (count, key) } static void -_rl_vi_append_forward (key) - int key; +_rl_vi_append_forward (int key) { - int point; - - if (rl_point < rl_end) - { - if (MB_CUR_MAX == 1 || rl_byte_oriented) - rl_point++; - else - { - point = rl_point; -#if 0 - rl_forward_char (1, key); -#else - rl_point = _rl_forward_char_internal (1); -#endif - if (point == rl_point) - rl_point = rl_end; - } - } + _rl_vi_advance_point (); } int -rl_vi_append_mode (count, key) - int count, key; +rl_vi_append_mode (int count, int key) { _rl_vi_append_forward (key); rl_vi_start_inserting (key, 1, rl_arg_sign); @@ -689,8 +769,7 @@ rl_vi_append_mode (count, key) } int -rl_vi_append_eol (count, key) - int count, key; +rl_vi_append_eol (int count, int key) { rl_end_of_line (1, key); rl_vi_append_mode (1, key); @@ -699,8 +778,7 @@ rl_vi_append_eol (count, key) /* What to do in the case of C-d. */ int -rl_vi_eof_maybe (count, c) - int count, c; +rl_vi_eof_maybe (int count, int c) { return (rl_newline (1, '\n')); } @@ -710,8 +788,7 @@ rl_vi_eof_maybe (count, c) /* Switching from one mode to the other really just involves switching keymaps. */ int -rl_vi_insertion_mode (count, key) - int count, key; +rl_vi_insertion_mode (int count, int key) { _rl_keymap = vi_insertion_keymap; _rl_vi_last_key_before_insert = key; @@ -721,16 +798,14 @@ rl_vi_insertion_mode (count, key) } int -rl_vi_insert_mode (count, key) - int count, key; +rl_vi_insert_mode (int count, int key) { rl_vi_start_inserting (key, 1, rl_arg_sign); return (0); } static void -vi_save_insert_buffer (start, len) - int start, len; +vi_save_insert_buffer (int start, int len) { /* Same code as _rl_vi_save_insert below */ if (len >= vi_insert_buffer_size) @@ -743,7 +818,7 @@ vi_save_insert_buffer (start, len) } static void -_rl_vi_save_replace () +_rl_vi_save_replace (void) { int len, start, end; UNDO_LIST *up; @@ -766,8 +841,7 @@ _rl_vi_save_replace () } static void -_rl_vi_save_insert (up) - UNDO_LIST *up; +_rl_vi_save_insert (UNDO_LIST *up) { int len, start, end; @@ -786,7 +860,7 @@ _rl_vi_save_insert (up) } void -_rl_vi_done_inserting () +_rl_vi_done_inserting (void) { if (_rl_vi_doing_insert) { @@ -821,8 +895,7 @@ _rl_vi_done_inserting () } int -rl_vi_movement_mode (count, key) - int count, key; +rl_vi_movement_mode (int count, int key) { if (rl_point > 0) rl_backward_char (1, key); @@ -843,8 +916,7 @@ rl_vi_movement_mode (count, key) } int -rl_vi_arg_digit (count, c) - int count, c; +rl_vi_arg_digit (int count, int c) { if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg) return (rl_beg_of_line (1, c)); @@ -855,8 +927,7 @@ rl_vi_arg_digit (count, c) /* Change the case of the next COUNT characters. */ #if defined (HANDLE_MULTIBYTE) static int -_rl_vi_change_mbchar_case (count) - int count; +_rl_vi_change_mbchar_case (int count) { wchar_t wc; char mb[MB_LEN_MAX+1]; @@ -895,7 +966,7 @@ _rl_vi_change_mbchar_case (count) rl_begin_undo_group (); rl_vi_delete (1, 0); if (rl_point < p) /* Did we retreat at EOL? */ - rl_point++; /* XXX - should we advance more than 1 for mbchar? */ + _rl_vi_advance_point (); rl_insert_text (mb); rl_end_undo_group (); rl_vi_check (); @@ -909,8 +980,7 @@ _rl_vi_change_mbchar_case (count) #endif int -rl_vi_change_case (count, ignore) - int count, ignore; +rl_vi_change_case (int count, int ignore) { int c, p; @@ -956,8 +1026,7 @@ rl_vi_change_case (count, ignore) } int -rl_vi_put (count, key) - int count, key; +rl_vi_put (int count, int key) { if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); @@ -969,36 +1038,26 @@ rl_vi_put (count, key) return (0); } -static void -_rl_vi_backup () -{ - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); - else - rl_point--; -} - +/* Move the cursor back one character if you're at the end of the line */ int -rl_vi_check () +rl_vi_check (void) { if (rl_point && rl_point == rl_end) - { - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO); - else - rl_point--; - } + _rl_vi_backup (); return (0); } +/* Move to the character position specified by COUNT */ int -rl_vi_column (count, key) - int count, key; +rl_vi_column (int count, int key) { if (count > rl_end) rl_end_of_line (1, key); else - rl_point = count - 1; + { + rl_point = 0; + rl_point = _rl_forward_char_internal (count - 1); + } return (0); } @@ -1006,8 +1065,7 @@ rl_vi_column (count, key) argument should be aborted, 0 if we should not read any more chars, and 1 if we should continue to read chars. */ static int -_rl_vi_arg_dispatch (c) - int c; +_rl_vi_arg_dispatch (int c) { int key; @@ -1041,7 +1099,7 @@ _rl_vi_arg_dispatch (c) Don't recognize minus sign? Should this do rl_save_prompt/rl_restore_prompt? */ static int -rl_digit_loop1 () +rl_digit_loop1 (void) { int c, r; @@ -1061,10 +1119,12 @@ rl_digit_loop1 () return (0); } +/* This set of functions is basically to handle the commands that take a + motion argument while in callback mode: read the command, read the motion + command modifier, find the extent of the text to affect, and dispatch the + command for execution. */ static void -_rl_mvcxt_init (m, op, key) - _rl_vimotion_cxt *m; - int op, key; +_rl_mvcxt_init (_rl_vimotion_cxt *m, int op, int key) { m->op = op; m->state = m->flags = 0; @@ -1077,8 +1137,7 @@ _rl_mvcxt_init (m, op, key) } static _rl_vimotion_cxt * -_rl_mvcxt_alloc (op, key) - int op, key; +_rl_mvcxt_alloc (int op, int key) { _rl_vimotion_cxt *m; @@ -1088,15 +1147,13 @@ _rl_mvcxt_alloc (op, key) } static void -_rl_mvcxt_dispose (m) - _rl_vimotion_cxt *m; +_rl_mvcxt_dispose (_rl_vimotion_cxt *m) { xfree (m); } static int -rl_domove_motion_callback (m) - _rl_vimotion_cxt *m; +rl_domove_motion_callback (_rl_vimotion_cxt *m) { int c; @@ -1129,9 +1186,7 @@ rl_domove_motion_callback (m) } int -_rl_vi_domove_motion_cleanup (c, m) - int c; - _rl_vimotion_cxt *m; +_rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m) { int r; @@ -1153,7 +1208,7 @@ _rl_vi_domove_motion_cleanup (c, m) non-whitespace character, move back one (presumably to whitespace). */ if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark && !whitespace (rl_line_buffer[rl_point])) - rl_point--; + rl_point--; /* XXX */ /* If cw or cW, back up to the end of a word, so the behaviour of ce or cE is the actual result. Brute-force, no subtlety. */ @@ -1166,14 +1221,14 @@ _rl_vi_domove_motion_cleanup (c, m) /* Posix.2 says that if cw or cW moves the cursor towards the end of the line, the character under the cursor should be deleted. */ if (rl_point == rl_mark) - rl_point++; + _rl_vi_advance_point (); else { /* Move past the end of the word so that the kill doesn't remove the last letter of the previous word. Only do this if we are not at the end of the line. */ if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point])) - rl_point++; + _rl_vi_advance_point (); } } @@ -1193,8 +1248,7 @@ _rl_vi_domove_motion_cleanup (c, m) #define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG)) static int -rl_domove_read_callback (m) - _rl_vimotion_cxt *m; +rl_domove_read_callback (_rl_vimotion_cxt *m) { int c, save; @@ -1260,8 +1314,7 @@ rl_domove_read_callback (m) } static int -rl_vi_domove_getchar (m) - _rl_vimotion_cxt *m; +rl_vi_domove_getchar (_rl_vimotion_cxt *m) { int c; @@ -1274,8 +1327,7 @@ rl_vi_domove_getchar (m) #if defined (READLINE_CALLBACKS) int -_rl_vi_domove_callback (m) - _rl_vimotion_cxt *m; +_rl_vi_domove_callback (_rl_vimotion_cxt *m) { int c, r; @@ -1288,10 +1340,9 @@ _rl_vi_domove_callback (m) } #endif -/* This code path taken when not in callback mode. */ +/* This code path is taken when not in callback mode. */ int -rl_vi_domove (x, ignore) - int x, *ignore; +rl_vi_domove (int x, int *ignore) { int r; _rl_vimotion_cxt *m; @@ -1309,22 +1360,20 @@ rl_vi_domove (x, ignore) } static int -vi_delete_dispatch (m) - _rl_vimotion_cxt *m; +vi_delete_dispatch (_rl_vimotion_cxt *m) { /* These are the motion commands that do not require adjusting the mark. */ if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) && (rl_mark < rl_end)) - rl_mark++; + INCREMENT_POS (rl_mark); rl_kill_text (rl_point, rl_mark); return (0); } int -rl_vi_delete_to (count, key) - int count, key; +rl_vi_delete_to (int count, int key) { int c, r; @@ -1373,15 +1422,14 @@ rl_vi_delete_to (count, key) } static int -vi_change_dispatch (m) - _rl_vimotion_cxt *m; +vi_change_dispatch (_rl_vimotion_cxt *m) { /* These are the motion commands that do not require adjusting the mark. c[wW] are handled by special-case code in rl_vi_domove(), and already leave the mark at the correct location. */ if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) && (rl_mark < rl_end)) - rl_mark++; + INCREMENT_POS (rl_mark); /* The cursor never moves with c[wW]. */ if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start) @@ -1413,8 +1461,7 @@ vi_change_dispatch (m) } int -rl_vi_change_to (count, key) - int count, key; +rl_vi_change_to (int count, int key) { int c, r; @@ -1463,14 +1510,13 @@ rl_vi_change_to (count, key) } static int -vi_yank_dispatch (m) - _rl_vimotion_cxt *m; +vi_yank_dispatch (_rl_vimotion_cxt *m) { /* These are the motion commands that do not require adjusting the mark. */ if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) && (rl_mark < rl_end)) - rl_mark++; + INCREMENT_POS (rl_mark); rl_begin_undo_group (); rl_kill_text (rl_point, rl_mark); @@ -1482,8 +1528,7 @@ vi_yank_dispatch (m) } int -rl_vi_yank_to (count, key) - int count, key; +rl_vi_yank_to (int count, int key) { int c, r; @@ -1532,8 +1577,7 @@ rl_vi_yank_to (count, key) } static int -vidomove_dispatch (m) - _rl_vimotion_cxt *m; +vidomove_dispatch (_rl_vimotion_cxt *m) { int r; @@ -1559,8 +1603,7 @@ vidomove_dispatch (m) } int -rl_vi_rubout (count, key) - int count, key; +rl_vi_rubout (int count, int key) { int opoint; @@ -1590,8 +1633,7 @@ rl_vi_rubout (count, key) } int -rl_vi_delete (count, key) - int count, key; +rl_vi_delete (int count, int key) { int end; @@ -1626,8 +1668,7 @@ rl_vi_delete (count, key) #define vi_unix_word_boundary(c) (whitespace(c) || ispunct(c)) int -rl_vi_unix_word_rubout (count, key) - int count, key; +rl_vi_unix_word_rubout (int count, int key) { int orig_point; @@ -1665,8 +1706,8 @@ rl_vi_unix_word_rubout (count, key) while (rl_point && vi_unix_word_boundary (rl_line_buffer[rl_point - 1])) rl_point--; else if (rl_point > 0 && vi_unix_word_boundary (rl_line_buffer[rl_point]) == 0) - while (rl_point && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0)) - rl_point--; + while (rl_point > 0 && (vi_unix_word_boundary (rl_line_buffer[rl_point - 1]) == 0)) + _rl_vi_backup_point (); } rl_kill_text (orig_point, rl_point); @@ -1677,8 +1718,7 @@ rl_vi_unix_word_rubout (count, key) int -rl_vi_back_to_indent (count, key) - int count, key; +rl_vi_back_to_indent (int count, int key) { rl_beg_of_line (1, key); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point])) @@ -1687,8 +1727,7 @@ rl_vi_back_to_indent (count, key) } int -rl_vi_first_print (count, key) - int count, key; +rl_vi_first_print (int count, int key) { return (rl_vi_back_to_indent (1, key)); } @@ -1697,8 +1736,7 @@ static int _rl_cs_dir, _rl_cs_orig_dir; #if defined (READLINE_CALLBACKS) static int -_rl_vi_callback_char_search (data) - _rl_callback_generic_arg *data; +_rl_vi_callback_char_search (_rl_callback_generic_arg *data) { int c; #if defined (HANDLE_MULTIBYTE) @@ -1732,8 +1770,7 @@ _rl_vi_callback_char_search (data) #endif int -rl_vi_char_search (count, key) - int count, key; +rl_vi_char_search (int count, int key) { int c; #if defined (HANDLE_MULTIBYTE) @@ -1826,8 +1863,7 @@ rl_vi_char_search (count, key) /* Match brackets */ int -rl_vi_match (ignore, key) - int ignore, key; +rl_vi_match (int ignore, int key) { int count = 1, brack, pos, tmp, pre; @@ -1916,8 +1952,7 @@ rl_vi_match (ignore, key) } int -rl_vi_bracktype (c) - int c; +rl_vi_bracktype (int c) { switch (c) { @@ -1932,9 +1967,7 @@ rl_vi_bracktype (c) } static int -_rl_vi_change_char (count, c, mb) - int count, c; - char *mb; +_rl_vi_change_char (int count, int c, char *mb) { int p; @@ -1947,7 +1980,7 @@ _rl_vi_change_char (count, c, mb) p = rl_point; rl_vi_delete (1, c); if (rl_point < p) /* Did we retreat at EOL? */ - rl_point++; + _rl_vi_append_forward (c); #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) rl_insert_text (mb); @@ -1965,9 +1998,7 @@ _rl_vi_change_char (count, c, mb) } static int -_rl_vi_callback_getchar (mb, mlen) - char *mb; - int mlen; +_rl_vi_callback_getchar (char *mb, int mlen) { int c; @@ -1988,13 +2019,18 @@ _rl_vi_callback_getchar (mb, mlen) #if defined (READLINE_CALLBACKS) static int -_rl_vi_callback_change_char (data) - _rl_callback_generic_arg *data; +_rl_vi_callback_change_char (_rl_callback_generic_arg *data) { int c; - char mb[MB_LEN_MAX]; + char mb[MB_LEN_MAX+1]; - _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); + c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); +#if defined (HANDLE_MULTIBYTE) + strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX); +#else + _rl_vi_last_replacement[0] = c; +#endif + _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */ if (c < 0) return -1; @@ -2007,17 +2043,16 @@ _rl_vi_callback_change_char (data) #endif int -rl_vi_change_char (count, key) - int count, key; +rl_vi_change_char (int count, int key) { int c; - char mb[MB_LEN_MAX]; + char mb[MB_LEN_MAX+1]; if (_rl_vi_redoing) { - c = _rl_vi_last_replacement; - mb[0] = c; - mb[1] = '\0'; + strncpy (mb, _rl_vi_last_replacement, MB_LEN_MAX); + c = (unsigned char)_rl_vi_last_replacement[0]; /* XXX */ + mb[MB_LEN_MAX] = '\0'; } #if defined (READLINE_CALLBACKS) else if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -2028,7 +2063,15 @@ rl_vi_change_char (count, key) } #endif else - _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); + { + c = _rl_vi_callback_getchar (mb, MB_LEN_MAX); +#ifdef HANDLE_MULTIBYTE + strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX); +#else + _rl_vi_last_replacement[0] = c; +#endif + _rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */ + } if (c < 0) return -1; @@ -2037,8 +2080,7 @@ rl_vi_change_char (count, key) } int -rl_vi_subst (count, key) - int count, key; +rl_vi_subst (int count, int key) { /* If we are redoing, rl_vi_change_to will stuff the last motion char */ if (_rl_vi_redoing == 0) @@ -2048,8 +2090,7 @@ rl_vi_subst (count, key) } int -rl_vi_overstrike (count, key) - int count, key; +rl_vi_overstrike (int count, int key) { if (_rl_vi_doing_insert == 0) { @@ -2067,8 +2108,7 @@ rl_vi_overstrike (count, key) } int -rl_vi_overstrike_delete (count, key) - int count, key; +rl_vi_overstrike_delete (int count, int key) { int i, s; @@ -2098,8 +2138,7 @@ rl_vi_overstrike_delete (count, key) } int -rl_vi_replace (count, key) - int count, key; +rl_vi_replace (int count, int key) { int i; @@ -2130,6 +2169,9 @@ rl_vi_replace (count, key) vi_insertion_keymap[CTRL ('H')].function == rl_rubout) vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + /* Make sure this is the value we need. */ + vi_replace_map[ANYOTHERKEY].type = ISFUNC; + vi_replace_map[ANYOTHERKEY].function = (rl_command_func_t *)NULL; } rl_vi_start_inserting (key, 1, rl_arg_sign); @@ -2145,7 +2187,7 @@ rl_vi_replace (count, key) the previous character. A space matches everything. Word delimiters are space and ;. */ int -rl_vi_possible_completions() +rl_vi_possible_completions (void) { int save_pos = rl_point; @@ -2153,7 +2195,7 @@ rl_vi_possible_completions() { while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';') - rl_point++; + _rl_vi_advance_point (); } else if (rl_line_buffer[rl_point - 1] == ';') { @@ -2170,7 +2212,7 @@ rl_vi_possible_completions() /* Functions to save and restore marks. */ static int -_rl_vi_set_mark () +_rl_vi_set_mark (void) { int ch; @@ -2190,8 +2232,7 @@ _rl_vi_set_mark () #if defined (READLINE_CALLBACKS) static int -_rl_vi_callback_set_mark (data) - _rl_callback_generic_arg *data; +_rl_vi_callback_set_mark (_rl_callback_generic_arg *data) { _rl_callback_func = 0; _rl_want_redisplay = 1; @@ -2201,8 +2242,7 @@ _rl_vi_callback_set_mark (data) #endif int -rl_vi_set_mark (count, key) - int count, key; +rl_vi_set_mark (int count, int key) { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) @@ -2217,7 +2257,7 @@ rl_vi_set_mark (count, key) } static int -_rl_vi_goto_mark () +_rl_vi_goto_mark (void) { int ch; @@ -2248,8 +2288,7 @@ _rl_vi_goto_mark () #if defined (READLINE_CALLBACKS) static int -_rl_vi_callback_goto_mark (data) - _rl_callback_generic_arg *data; +_rl_vi_callback_goto_mark (_rl_callback_generic_arg *data) { _rl_callback_func = 0; _rl_want_redisplay = 1; @@ -2259,8 +2298,7 @@ _rl_vi_callback_goto_mark (data) #endif int -rl_vi_goto_mark (count, key) - int count, key; +rl_vi_goto_mark (int count, int key) { #if defined (READLINE_CALLBACKS) if (RL_ISSTATE (RL_STATE_CALLBACK)) diff --git a/readline/xfree.c b/readline/xfree.c index 37a81e6..c199b29 100644 --- a/readline/xfree.c +++ b/readline/xfree.c @@ -1,6 +1,6 @@ /* xfree.c -- safe version of free that ignores attempts to free NUL */ -/* Copyright (C) 1991-2010 Free Software Foundation, Inc. +/* Copyright (C) 1991-2010,2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -42,8 +42,7 @@ /* Use this as the function to call when adding unwind protects so we don't need to know what free() returns. */ void -xfree (string) - PTR_T string; +xfree (PTR_T string) { if (string) free (string); diff --git a/readline/xmalloc.c b/readline/xmalloc.c index c77d763..5d01d75 100644 --- a/readline/xmalloc.c +++ b/readline/xmalloc.c @@ -1,6 +1,6 @@ /* xmalloc.c -- safe versions of malloc and realloc */ -/* Copyright (C) 1991-2009 Free Software Foundation, Inc. +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -42,8 +42,7 @@ /* **************************************************************** */ static void -memory_error_and_abort (fname) - char *fname; +memory_error_and_abort (char *fname) { fprintf (stderr, "%s: out of virtual memory\n", fname); exit (2); @@ -53,8 +52,7 @@ memory_error_and_abort (fname) to hold BYTES number of bytes. If the memory cannot be allocated, print an error message and abort. */ PTR_T -xmalloc (bytes) - size_t bytes; +xmalloc (size_t bytes) { PTR_T temp; @@ -65,9 +63,7 @@ xmalloc (bytes) } PTR_T -xrealloc (pointer, bytes) - PTR_T pointer; - size_t bytes; +xrealloc (PTR_T pointer, size_t bytes) { PTR_T temp; |