From: Chet Ramey Date: Sun, 29 Jan 2017 19:02:42 +0000 (-0500) Subject: commit readline-20170129 snapshot X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=982e4d1c55856028b2d47795e360390463ae9d6e;p=thirdparty%2Freadline.git commit readline-20170129 snapshot --- diff --git a/._complete.c b/._complete.c new file mode 100644 index 0000000..f2127f5 Binary files /dev/null and b/._complete.c differ diff --git a/CHANGELOG b/CHANGELOG index 6794591..2aa4c6a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1304,3 +1304,9 @@ 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 diff --git a/complete.c b/complete.c index 0a81129..1d79dcb 100644 --- a/complete.c +++ b/complete.c @@ -625,7 +625,10 @@ stat_char (filename) #endif if (r == -1) - return (0); + { + xfree (f); + return (0); + } character = 0; if (S_ISDIR (finfo.st_mode)) diff --git a/config.h.in b/config.h.in index d03ebe0..6de47b5 100644 --- a/config.h.in +++ b/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/configure b/configure index aa98bce..be87faf 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Readline 7.0, version 2.81. +# From configure.ac for Readline 7.0, version 2.82. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for readline 7.0. # @@ -1900,6 +1900,189 @@ $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 +#include +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 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -4590,7 +4773,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` @@ -6521,6 +6704,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 diff --git a/configure.ac b/configure.ac index f81809b..fd0cec4 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ 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 . -AC_REVISION([for Readline 7.0, version 2.81]) +AC_REVISION([for Readline 7.0, version 2.82]) AC_INIT(readline, 7.0, bug-readline@gnu.org) @@ -132,7 +132,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) diff --git a/doc/hsuser.texi b/doc/hsuser.texi index 04e192e..7999eb5 100644 --- a/doc/hsuser.texi +++ b/doc/hsuser.texi @@ -198,8 +198,12 @@ 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 -a Append the new history lines to the history file. diff --git a/doc/readline.3 b/doc/readline.3 index b57f00b..b371ee9 100644 --- a/doc/readline.3 +++ b/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: Wed Nov 30 10:06:13 PST 2016 .\" -.TH READLINE 3 "2016 February 28" "GNU Readline 7.0" +.TH READLINE 3 "2016 November 30" "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. @@ -438,6 +438,15 @@ can be set to either or .BR vi . .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 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 +515,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 @@ -1120,9 +1120,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/doc/rluser.texi b/doc/rluser.texi index 4c094c8..63a6b9d 100644 --- a/doc/rluser.texi +++ b/doc/rluser.texi @@ -1216,14 +1216,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. @@ -1590,9 +1590,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 @@ -1721,7 +1722,7 @@ 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. -@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 diff --git a/doc/version.texi b/doc/version.texi index 9dc2998..f74d629 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -4,7 +4,7 @@ Copyright (C) 1988-2016 Free Software Foundation, Inc. @set EDITION 7.0 @set VERSION 7.0 -@set UPDATED 16 July 2016 -@set UPDATED-MONTH July 2016 +@set UPDATED 30 November 2016 +@set UPDATED-MONTH November 2016 -@set LASTCHANGE Sat Jul 16 13:43:15 EDT 2016 +@set LASTCHANGE Wed Nov 30 10:06:36 PST 2016 diff --git a/histlib.h b/histlib.h index 28cad14..9986a2e 100644 --- a/histlib.h +++ b/histlib.h @@ -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/history.c b/history.c index a21d0d8..ef293c7 100644 --- a/history.c +++ b/history.c @@ -279,6 +279,7 @@ add_history (string) const char *string; { HIST_ENTRY *temp; + int new_length; if (history_stifled && (history_length == history_max_entries)) { @@ -295,13 +296,9 @@ add_history (string) /* Copy the rest of the entries, moving down one slot. Copy includes trailing NULL. */ -#if 0 - for (i = 0; i < history_length; i++) - the_history[i] = the_history[i + 1]; -#else memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *)); -#endif + new_length = history_length; history_base++; } else @@ -315,7 +312,7 @@ add_history (string) else history_size = DEFAULT_HISTORY_INITIAL_SIZE; the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *)); - history_length = 1; + new_length = 1; } else { @@ -325,14 +322,15 @@ add_history (string) the_history = (HIST_ENTRY **) xrealloc (the_history, history_size * sizeof (HIST_ENTRY *)); } - history_length++; + new_length = history_length + 1; } } temp = alloc_history_entry ((char *)string, hist_inittime ()); - the_history[history_length] = (HIST_ENTRY *)NULL; - the_history[history_length - 1] = temp; + the_history[new_length] = (HIST_ENTRY *)NULL; + the_history[new_length - 1] = temp; + history_length = new_length; } /* Change the time stamp of the most recent history entry to STRING. */ @@ -500,20 +498,70 @@ remove_history (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 (first, last) + int first, 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) @@ -575,4 +623,5 @@ clear_history () } history_offset = history_length = 0; + history_base = 1; /* reset history base to default */ } diff --git a/history.h b/history.h index 8ce7c80..fceb99c 100644 --- a/history.h +++ b/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 *)); diff --git a/histsearch.c b/histsearch.c index 1ad55d2..ab18f97 100644 --- a/histsearch.c +++ b/histsearch.c @@ -39,8 +39,13 @@ # include #endif +#if defined (HAVE_FNMATCH) +# include +#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,24 @@ static int history_search_internal PARAMS((const char *, int, int)); returned. */ static int -history_search_internal (string, direction, anchored) +history_search_internal (string, direction, flags) const char *string; - int direction, anchored; + int direction, 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 +109,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 +118,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 +142,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 +174,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,6 +197,51 @@ history_search_internal (string, direction, anchored) } } +int +_hs_history_patsearch (string, direction, flags) + const char *string; + int direction, flags; +{ + char *pat; + size_t len; + 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 + 2); + /* 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, 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) diff --git a/input.c b/input.c index 286897d..10ce4e0 100644 --- a/input.c +++ b/input.c @@ -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; @@ -512,10 +516,15 @@ rl_getc (stream) #endif result = 0; #if defined (HAVE_PSELECT) - sigemptyset (&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)); diff --git a/rlprivate.h b/rlprivate.h index 1269e5c..b11a6bf 100644 --- a/rlprivate.h +++ b/rlprivate.h @@ -64,6 +64,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 { diff --git a/search.c b/search.c index 45d95d2..131d12d 100644 --- a/search.c +++ b/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-2016 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)); @@ -112,11 +112,13 @@ 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) +noninc_search_from_pos (string, pos, dir, flags, ncp) char *string; - int pos, dir; + int pos, dir, flags; + int *ncp; { - int ret, old; + int ret, old, sflags; + char *s; if (pos < 0) return -1; @@ -126,12 +128,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 (string, 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 +161,10 @@ 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) +noninc_dosearch (string, dir, flags) char *string; int dir; + int flags; { int oldpos, pos; HIST_ENTRY *entry; @@ -156,7 +175,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. */ @@ -197,6 +216,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; @@ -340,7 +363,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 @@ -400,7 +423,8 @@ rl_noninc_reverse_search (count, key) } /* 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; @@ -412,12 +436,18 @@ 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; @@ -429,7 +459,12 @@ 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); } @@ -455,7 +490,7 @@ rl_history_search_internal (count, dir) int count, dir; { HIST_ENTRY *temp; - int ret, oldpos; + int ret, oldpos, newcol; char *t; rl_maybe_save_line (); @@ -469,7 +504,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 +547,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; diff --git a/signals.c b/signals.c index 927f532..768c5d1 100644 --- a/signals.c +++ b/signals.c @@ -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 */ @@ -442,8 +446,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 +488,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 } @@ -506,8 +517,6 @@ rl_clear_signals () 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