From: Chet Ramey Date: Tue, 16 Jul 2024 13:48:33 +0000 (-0400) Subject: fix case changing for invalid multibyte characters; fix for case-insensitive completi... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d718829a95ca77db7586251cec49aecb5d5bf512;p=thirdparty%2Freadline.git fix case changing for invalid multibyte characters; fix for case-insensitive completion of multibyte characters; fix for undo list management with incremental search; fixes for some examples; fix for undo list history entry management with non-incremental search --- diff --git a/CHANGELOG b/CHANGELOG index 239db4e..8fd9513 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1480,3 +1480,9 @@ configure.ac - AC_PROG_GCC_TRADITIONAL: remove - need to note in CHANGES that configure now supports --enable-year2038. THIS IS AN ABI CHANGE IF YOU ENABLE IT + + 7/7 + --- +configure.ac + - add ncursesw as a possible value for TERMCAP_PKG_CONFIG_LIB, with + corresponding changes to aclocal.m4, which is shared with bash diff --git a/aclocal.m4 b/aclocal.m4 index ac42dbf..cb2f06f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -935,8 +935,8 @@ AC_CACHE_VAL(bash_cv_termcap_lib, [AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap, [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, - [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, + [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, + [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, bash_cv_termcap_lib=gnutermcap)])])])])])]) if test "X$_bash_needmsg" = "Xyes"; then AC_MSG_CHECKING(which library has the termcap functions) @@ -952,6 +952,9 @@ TERMCAP_DEP= elif test $bash_cv_termcap_lib = libtinfo; then TERMCAP_LIB=-ltinfo TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libncursesw; then +TERMCAP_LIB=-lncursesw +TERMCAP_DEP= elif test $bash_cv_termcap_lib = libncurses; then TERMCAP_LIB=-lncurses TERMCAP_DEP= diff --git a/complete.c b/complete.c index f564a47..76bc252 100644 --- a/complete.c +++ b/complete.c @@ -77,6 +77,10 @@ extern int errno; # include "colors.h" #endif +#ifndef MIN +#define MIN(x,y) (((x) < (y)) ? (x): (y)) +#endif + typedef int QSFUNC (const void *, const void *); #ifdef HAVE_LSTAT @@ -1355,9 +1359,9 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) int low; /* Count of max-matched characters. */ int lx; char *dtext; /* dequoted TEXT, if needed */ + size_t si1, si2; size_t len1, len2; #if defined (HANDLE_MULTIBYTE) - int v; size_t v1, v2; mbstate_t ps1, ps2; WCHAR_T wc1, wc2; @@ -1385,7 +1389,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) len1 = strlen (match_list[i]); len2 = strlen (match_list[i + 1]); - for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++) + for (si1 = si2 = 0; (c1 = match_list[i][si1]) && (c2 = match_list[i + 1][si2]); si1++,si2++) { if (_rl_completion_case_fold) { @@ -1395,8 +1399,8 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { - v1 = MBRTOWC (&wc1, match_list[i]+si, len1 - si, &ps1); - v2 = MBRTOWC (&wc2, match_list[i+1]+si, len2 - si, &ps2); + v1 = MBRTOWC (&wc1, match_list[i]+si1, len1 - si1, &ps1); + v2 = MBRTOWC (&wc2, match_list[i+1]+si2, len2 - si2, &ps2); if (MB_INVALIDCH (v1) || MB_INVALIDCH (v2)) { if (c1 != c2) /* do byte comparison */ @@ -1410,8 +1414,11 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) } if (wc1 != wc2) break; - else if (v1 > 1) - si += v1 - 1; + + if (v1 > 1) + si1 += v1 - 1; + if (v2 > 1) + si2 += v2 - 1; } else #endif @@ -1419,6 +1426,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) break; } + si = MIN (si1, si2); /* use shorter of matches of different length */ if (low > si) low = si; } diff --git a/configure.ac b/configure.ac index 9ca0f7b..295e13c 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 8.3, version 2.99]) +AC_REVISION([for Readline 8.3, version 2.100]) AC_INIT(readline, 8.3, bug-readline@gnu.org) @@ -222,6 +222,7 @@ esac case "$TERMCAP_LIB" in -ltinfo) TERMCAP_PKG_CONFIG_LIB=tinfo ;; -lcurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; +-lncursesw) TERMCAP_PKG_CONFIG_LIB=ncursesw ;; -lncurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;; -ltermcap) TERMCAP_PKG_CONFIG_LIB=termcap ;; *) TERMCAP_PKG_CONFIG_LIB=termcap ;; diff --git a/display.c b/display.c index 7fdf23b..466703e 100644 --- a/display.c +++ b/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987-2023 Free Software Foundation, Inc. +/* Copyright (C) 1987-2024 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. @@ -1732,7 +1732,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l { char *ofd, *ols, *oe, *nfd, *nls, *ne; char *ofdf, *nfdf, *olsf, *nlsf; - int temp, lendiff, wsatend, od, nd, twidth, o_cpos; + int temp, lendiff, wsatend, od, nd, o_cpos; int current_invis_chars; int col_lendiff, col_temp; int bytes_to_insert; @@ -1863,7 +1863,7 @@ update_line (char *old, char *old_face, char *new, char *new_face, int current_l _rl_output_some_chars below. */ if (newwidth > 0) { - int count, i, j; + int i, j; char *optr; puts_face (new, new_face, newbytes); diff --git a/doc/readline.3 b/doc/readline.3 index b5ca022..b36333d 100644 --- a/doc/readline.3 +++ b/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Fri Mar 29 11:54:44 EDT 2024 +.\" Last Change: Sat May 11 12:44:56 EDT 2024 .\" -.TH READLINE 3 "2024 March 29" "GNU Readline 8.3" +.TH READLINE 3 "2024 May 11" "GNU Readline 8.3" .\" .ie \n(.g \{\ .ds ' \(aq @@ -895,9 +895,11 @@ The text between the point and mark is referred to as the \fIregion\fP. .TP .B beginning\-of\-line (C\-a) Move to the start of the current line. +This may also be bound to the Home key on some keyboards. .TP .B end\-of\-line (C\-e) Move to the end of the line. +This may also be bound to the End key on some keyboards. .TP .B forward\-char (C\-f) Move forward a character. @@ -1007,12 +1009,14 @@ between the start of the current line and the current cursor position (the \fIpoint\fP). The search string must match at the beginning of a history line. This is a non-incremental search. +This may be bound to the Page Up key on some keyboards. .TP .B history\-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 must match at the beginning of a history line. This is a non-incremental search. +This may be bound to the Page Down key on some keyboards. .TP .B history\-substring\-search\-backward Search backward through the history for the string of characters @@ -1119,15 +1123,18 @@ Capitalize the current (or following) word. With a negative argument, capitalize the previous word, but do not move point. .TP .B overwrite\-mode -Toggle overwrite mode. With an explicit positive numeric argument, -switches to overwrite mode. With an explicit non-positive numeric -argument, switches to insert mode. This command affects only -\fBemacs\fP mode; \fBvi\fP mode does overwrite differently. +Toggle overwrite mode. +With an explicit positive numeric argument, switches to overwrite mode. +With an explicit non-positive numeric argument, switches to insert mode. +This command affects only \fBemacs\fP mode; +\fBvi\fP mode does overwrite differently. Each call to \fIreadline()\fP starts in insert mode. In overwrite mode, characters bound to \fBself\-insert\fP replace the text at point rather than pushing the text to the right. Characters bound to \fBbackward\-delete\-char\fP replace the character -before point with a space. By default, this command is unbound. +before point with a space. +By default, this command is unbound, +but may be bound to the Insert key on some keyboards. .PD .SS Killing and Yanking .PD 0 diff --git a/doc/rltech.texi b/doc/rltech.texi index 497cd4d..56519d5 100644 --- a/doc/rltech.texi +++ b/doc/rltech.texi @@ -1526,16 +1526,8 @@ invert_case_line (count, key) if (rl_point >= rl_end) return (0); - if (count < 0) - @{ - direction = -1; - count = -count; - @} - else - direction = 1; - /* Find the end of the range to modify. */ - end = start + (count * direction); + end = start + count; /* Force it to be within range. */ if (end > rl_end) @@ -1546,6 +1538,11 @@ invert_case_line (count, key) if (start == end) return (0); + /* For positive arguments, put point after the last changed character. For + negative arguments, put point before the last changed character. */ + rl_point = end; + + /* Swap start and end if we are moving backwards */ if (start > end) @{ int temp = start; @@ -1564,8 +1561,7 @@ invert_case_line (count, key) else if (_rl_lowercase_p (rl_line_buffer[i])) rl_line_buffer[i] = _rl_to_upper (rl_line_buffer[i]); @} - /* Move point to on top of the last character changed. */ - rl_point = (direction == 1) ? end - 1 : start; + return (0); @} @end example @@ -1583,7 +1579,6 @@ It understands the EOF character or "exit" to exit the program. #include #include #include -#include /* Used for select(2) */ #include @@ -1591,12 +1586,19 @@ It understands the EOF character or "exit" to exit the program. #include +#include #include +#include + /* Standard readline include files. */ #include #include +#if !defined (errno) +extern int errno; +#endif + static void cb_linehandler (char *); static void sighandler (int); @@ -1664,7 +1666,7 @@ main (int c, char **v) while (running) @{ FD_ZERO (&fds); - FD_SET (fileno (rl_instream), &fds); + FD_SET (fileno (rl_instream), &fds); r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); if (r < 0 && errno != EINTR) diff --git a/doc/rluser.texi b/doc/rluser.texi index 45e8a85..bc57ccf 100644 --- a/doc/rluser.texi +++ b/doc/rluser.texi @@ -1229,9 +1229,11 @@ The text between the point and mark is referred to as the @dfn{region}. @ftable @code @item beginning-of-line (C-a) Move to the start of the current line. +This may also be bound to the Home key on some keyboards. @item end-of-line (C-e) Move to the end of the line. +This may also be bound to the End key on some keyboards. @item forward-char (C-f) Move forward a character. @@ -1342,29 +1344,31 @@ through the history as necessary using a non-incremental search for a string supplied by the user. The search string may match anywhere in a history line. -@item history-search-forward () -Search forward through the history for the string of characters +@item history-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 must match at the beginning of a history line. This is a non-incremental search. -By default, this command is unbound. +By default, this command is unbound, but may be bound to the Page Down +key on some keyboards. -@item history-search-backward () -Search backward through the history for the string of characters +@item history-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 must match at the beginning of a history line. This is a non-incremental search. -By default, this command is unbound. +By default, this command is unbound, but may be bound to the Page Up +key on some keyboards. -@item history-substring-search-forward () -Search forward through the history for the string of characters +@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. This is a non-incremental search. By default, this command is unbound. -@item history-substring-search-backward () -Search backward through the history for the string of characters +@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. @@ -1506,7 +1510,8 @@ the text at point rather than pushing the text to the right. Characters bound to @code{backward-delete-char} replace the character before point with a space. -By default, this command is unbound. +By default, this command is unbound, but may be bound to the Insert +key on some keyboards. @end ftable diff --git a/doc/version.texi b/doc/version.texi index 9c820a9..9c8540c 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -5,7 +5,7 @@ Copyright (C) 1988-2024 Free Software Foundation, Inc. @set EDITION 8.3 @set VERSION 8.3 -@set UPDATED 19 January 2024 -@set UPDATED-MONTH January 2024 +@set UPDATED 11 May 2024 +@set UPDATED-MONTH May 2024 -@set LASTCHANGE Fri Jan 19 11:01:44 EST 2024 +@set LASTCHANGE Sat May 11 12:41:28 EDT 2024 diff --git a/examples/._rlwrap-0.46.1.tar.gz b/examples/._rlwrap-0.46.1.tar.gz index 53ca00c..0547919 100644 Binary files a/examples/._rlwrap-0.46.1.tar.gz and b/examples/._rlwrap-0.46.1.tar.gz differ diff --git a/examples/autoconf/BASH_CHECK_LIB_TERMCAP b/examples/autoconf/BASH_CHECK_LIB_TERMCAP index 7047d72..11de3c2 100644 --- a/examples/autoconf/BASH_CHECK_LIB_TERMCAP +++ b/examples/autoconf/BASH_CHECK_LIB_TERMCAP @@ -11,8 +11,8 @@ AC_CACHE_VAL(bash_cv_termcap_lib, [AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap, [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, - [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, + [AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw, + [AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses, bash_cv_termcap_lib=gnutermcap)])])])])])]) if test "X$_bash_needmsg" = "Xyes"; then AC_MSG_CHECKING(which library has the termcap functions) @@ -28,6 +28,9 @@ TERMCAP_DEP= elif test $bash_cv_termcap_lib = libtinfo; then TERMCAP_LIB=-ltinfo TERMCAP_DEP= +elif test $bash_cv_termcap_lib = libncursesw; then +TERMCAP_LIB=-lncursesw +TERMCAP_DEP= elif test $bash_cv_termcap_lib = libncurses; then TERMCAP_LIB=-lncurses TERMCAP_DEP= diff --git a/examples/excallback.c b/examples/excallback.c index 04ecb14..3f2744e 100644 --- a/examples/excallback.c +++ b/examples/excallback.c @@ -19,7 +19,7 @@ My example shows how, using the alternate interface, you can interactively change the prompt (which is very nice imo). Also, I point out that you must roll your own terminal setting when using the alternate interface because readline depreps (using your parlance) the -terminal while in the user callback. I try to demostrate what I mean +terminal while in the user callback. I try to demonstrate what I mean with an example. I've included the program below. To compile, I just put the program in the examples directory and made @@ -54,8 +54,10 @@ Copyright (C) 1999 Jeff Solomon #ifdef READLINE_LIBRARY # include "readline.h" +# include "history.h" #else # include +# include #endif #ifndef STDIN_FILENO @@ -72,7 +74,7 @@ Copyright (C) 1999 Jeff Solomon * alternate interface. The first is the ability to interactively change the * prompt, which can't be done using the regular interface since rl_prompt is * read-only. - * + * * The second feature really highlights a subtle point when using the alternate * interface. That is, readline will not alter the terminal when inside your * callback handler. So let's so, your callback executes a user command that @@ -92,7 +94,7 @@ Copyright (C) 1999 Jeff Solomon */ void process_line(char *line); -int change_prompt(void); +int change_prompt(int, int); char *get_prompt(void); int prompt = 1; @@ -101,7 +103,7 @@ tcflag_t old_lflag; cc_t old_vtime; struct termios term; -int +int main(int c, char **v) { fd_set fds; @@ -170,31 +172,20 @@ process_line(char *line) } int -change_prompt(void) +change_prompt(int count, int key) { /* toggle the prompt variable */ prompt = !prompt; - /* save away the current contents of the line */ - strcpy(line_buf, rl_line_buffer); - - /* install a new handler which will change the prompt and erase the current line */ - rl_callback_handler_install(get_prompt(), process_line); - - /* insert the old text on the new line */ - rl_insert_text(line_buf); - - /* redraw the current line - this is an undocumented function. It invokes the - * redraw-current-line command. - */ - rl_refresh_line(0, 0); + rl_set_prompt (get_prompt ()); + return 0; } char * get_prompt(void) { /* The prompts can even be different lengths! */ - sprintf(prompt_buf, "%s", + sprintf(prompt_buf, "%s", prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); return prompt_buf; } diff --git a/examples/histexamp.c b/examples/histexamp.c index 2e946ac..d592b7e 100644 --- a/examples/histexamp.c +++ b/examples/histexamp.c @@ -110,7 +110,7 @@ main (int argc, char **argv) int which; if ((sscanf (line + 6, "%d", &which)) == 1) { - HIST_ENTRY *entry = remove_history (which); + HIST_ENTRY *entry = remove_history (which - history_base); if (!entry) fprintf (stderr, "No such entry %d\n", which); else diff --git a/examples/manexamp.c b/examples/manexamp.c index c8e11d5..ce33877 100644 --- a/examples/manexamp.c +++ b/examples/manexamp.c @@ -94,16 +94,8 @@ invert_case_line (int count, int key) start = rl_point; - if (count < 0) - { - direction = -1; - count = -count; - } - else - direction = 1; - /* Find the end of the range to modify. */ - end = start + (count * direction); + end = start + count; /* Force it to be within range. */ if (end > rl_end) @@ -111,6 +103,14 @@ invert_case_line (int count, int key) else if (end < 0) end = -1; + if (start == end) + return 0; + + /* For positive arguments, put point after the last changed character. For + negative arguments, put point before the last changed character. */ + rl_point = end; + + /* Swap start and end if we are moving backwards */ if (start > end) { int temp = start; @@ -118,14 +118,11 @@ invert_case_line (int count, int key) end = temp; } - if (start == end) - return 0; - /* Tell readline that we are modifying the line, so save the undo information. */ rl_modifying (start, end); - for (; start != end; start += direction) + for (; start != end; start++) { if (_rl_uppercase_p (rl_line_buffer[start])) rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); @@ -133,7 +130,5 @@ invert_case_line (int count, int key) rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); } - /* Move point to on top of the last character changed. */ - rl_point = end - direction; return 0; } diff --git a/examples/rl-callbacktest.c b/examples/rl-callbacktest.c index 7febacd..b6b38e8 100644 --- a/examples/rl-callbacktest.c +++ b/examples/rl-callbacktest.c @@ -23,12 +23,15 @@ # include #endif +#if !defined (errno) extern int errno; +#endif static void cb_linehandler (char *); static void signandler (int); -int running, sigwinch_received; +int running; +int sigwinch_received; const char *prompt = "rltest$ "; /* Handle SIGWINCH and window size changes when readline is not active and @@ -73,9 +76,11 @@ main (int c, char **v) fd_set fds; int r; + /* Set the default locale values according to environment variables. */ setlocale (LC_ALL, ""); - /* Handle SIGWINCH */ + /* Handle window size changes when readline is not active and reading + characters. */ signal (SIGWINCH, sighandler); /* Install the line handler. */ diff --git a/examples/rl-callbacktest2.c b/examples/rl-callbacktest2.c index 0bf0641..84904d5 100644 --- a/examples/rl-callbacktest2.c +++ b/examples/rl-callbacktest2.c @@ -6,13 +6,14 @@ /* Used for select(2) */ #include #include -#include #include -#include +#include #include +#include + /* Standard readline include files. */ #if defined (READLINE_LIBRARY) # include "readline.h" @@ -22,6 +23,10 @@ # include #endif +#if !defined (errno) +extern int errno; +#endif + static void cb_linehandler (char *); static void sigint_sighandler (int); static int sigint_handler (int); @@ -51,18 +56,18 @@ cb_readline (void) fd_set fds; int r, err; char *not_done = ""; - + /* Install the line handler. */ rl_callback_handler_install (prompt, cb_linehandler); -if (RL_ISSTATE (RL_STATE_ISEARCH)) - fprintf(stderr, "cb_readline: after handler install, state (ISEARCH) = %d", rl_readline_state); -else if (RL_ISSTATE (RL_STATE_NSEARCH)) - fprintf(stderr, "cb_readline: after handler install, state (NSEARCH) = %d", rl_readline_state); -/* MULTIKEY VIMOTION NUMERICARG _rl_callback_func */ + if (RL_ISSTATE (RL_STATE_ISEARCH)) + fprintf(stderr, "cb_readline: after handler install, state (ISEARCH) = %lu", rl_readline_state); + else if (RL_ISSTATE (RL_STATE_NSEARCH)) + fprintf(stderr, "cb_readline: after handler install, state (NSEARCH) = %lu", rl_readline_state); + /* MULTIKEY VIMOTION NUMERICARG _rl_callback_func */ FD_ZERO (&fds); - FD_SET (fileno (rl_instream), &fds); + FD_SET (fileno (rl_instream), &fds); input_string = not_done; @@ -76,10 +81,10 @@ else if (RL_ISSTATE (RL_STATE_NSEARCH)) while (r == 0) { struct timeval timeout = {0, 100000}; - struct timeval *timeoutp = NULL; + struct timeval *timeoutp = NULL; timeoutp = &timeout; - FD_SET (fileno (rl_instream), &fds); + FD_SET (fileno (rl_instream), &fds); r = select (FD_SETSIZE, &fds, NULL, NULL, timeoutp); err = errno; } @@ -115,7 +120,6 @@ sigint_handler (int s) rl_cleanup_after_signal (); rl_callback_handler_remove (); saw_signal = 0; -fprintf(stderr, "sigint_handler: readline state = %d\r\n", rl_readline_state); return s; } diff --git a/examples/rlptytest.c b/examples/rlptytest.c index 021a868..2264441 100644 --- a/examples/rlptytest.c +++ b/examples/rlptytest.c @@ -19,6 +19,7 @@ #include +/* Need a configure check here to turn this into a real application. */ #if 1 /* LINUX */ #include #else @@ -31,10 +32,14 @@ #ifdef READLINE_LIBRARY # include "readline.h" +# include "history.h" #else # include +# include #endif +int tty_reset(int fd); + /** * Master/Slave PTY used to keep readline off of stdin/stdout. */ @@ -301,7 +306,8 @@ tty_off_xon_xoff (int fd) * * Returns: 0 on success, -1 on error */ -int tty_reset(int fd) +int +tty_reset(int fd) { if(ttystate != TCBREAK) return (0); diff --git a/examples/rlwrap-0.30.tar.gz b/examples/rlwrap-0.30.tar.gz deleted file mode 100644 index 73381a2..0000000 Binary files a/examples/rlwrap-0.30.tar.gz and /dev/null differ diff --git a/funmap.c b/funmap.c index 548cfb5..28af364 100644 --- a/funmap.c +++ b/funmap.c @@ -265,6 +265,7 @@ rl_funmap_names (void) result[result_index + 1] = (char *)NULL; } - qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); + if (result) + qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare); return (result); } diff --git a/histfile.c b/histfile.c index e4d0b37..e115922 100644 --- a/histfile.c +++ b/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989-2019,2023 Free Software Foundation, Inc. +/* Copyright (C) 1989-2019,2023-2024 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. diff --git a/input.c b/input.c index 9807453..a16546f 100644 --- a/input.c +++ b/input.c @@ -548,6 +548,15 @@ reset_alarm () setitimer (ITIMER_REAL, &it, NULL); } # else +# if defined (__MINGW32_MAJOR_VERSION) +/* mingw.org's MinGW doesn't have alarm(3). */ +unsigned int +alarm (unsigned int seconds) +{ + return 0; +} +# endif + static int set_alarm (unsigned int *secs, unsigned int *usecs) { diff --git a/kill.c b/kill.c index 972c7d9..ca92ea1 100644 --- a/kill.c +++ b/kill.c @@ -1,6 +1,6 @@ /* kill.c -- kill ring management. */ -/* Copyright (C) 1994-2023 Free Software Foundation, Inc. +/* Copyright (C) 1994-2024 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. @@ -737,12 +737,9 @@ _rl_bracketed_text (size_t *lenp) } RL_UNSETSTATE (RL_STATE_MOREINPUT); - if (c >= 0) - { - if (len == cap) - buf = xrealloc (buf, cap + 1); - buf[len] = '\0'; - } + if (len == cap) + buf = xrealloc (buf, cap + 1); + buf[len] = '\0'; if (lenp) *lenp = len; diff --git a/mbutil.c b/mbutil.c index 33588cc..8ee47f0 100644 --- a/mbutil.c +++ b/mbutil.c @@ -1,6 +1,6 @@ /* mbutil.c -- readline multibyte character utility functions */ -/* Copyright (C) 2001-2021,2023 Free Software Foundation, Inc. +/* Copyright (C) 2001-2024 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/misc.c b/misc.c index 96c82b5..7f28cbd 100644 --- a/misc.c +++ b/misc.c @@ -332,7 +332,7 @@ _rl_free_history_entry (HIST_ENTRY *entry) /* Perhaps put back the current line if it has changed. */ int -rl_maybe_replace_line (void) +_rl_maybe_replace_line (int clear_undo) { HIST_ENTRY *temp; @@ -350,12 +350,19 @@ rl_maybe_replace_line (void) if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == rl_undo_list) _rl_saved_line_for_history->data = 0; /* Do we want to set rl_undo_list = 0 here since we just saved it into - a history entry? */ - rl_undo_list = 0; + a history entry? We let the caller decide. */ + if (clear_undo) + rl_undo_list = 0; } return 0; } +int +rl_maybe_replace_line (void) +{ + return (_rl_maybe_replace_line (0)); +} + void _rl_unsave_line (HIST_ENTRY *entry) { diff --git a/nls.c b/nls.c index 8c027d6..e04991d 100644 --- a/nls.c +++ b/nls.c @@ -107,12 +107,13 @@ static int utf8locale (char *lspec) { char *cp; - size_t len; #if HAVE_LANGINFO_CODESET cp = nl_langinfo (CODESET); return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); #else + size_t len; + cp = find_codeset (lspec, &len); if (cp == 0 || len < 4 || len > 5) diff --git a/rlmbutil.h b/rlmbutil.h index fe6f4dc..9aa6170 100644 --- a/rlmbutil.h +++ b/rlmbutil.h @@ -1,6 +1,6 @@ /* rlmbutil.h -- utility functions for multibyte characters. */ -/* Copyright (C) 2001-2021,2023 Free Software Foundation, Inc. +/* Copyright (C) 2001-2024 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/rlprivate.h b/rlprivate.h index 61d04a4..23cf8d3 100644 --- a/rlprivate.h +++ b/rlprivate.h @@ -332,6 +332,7 @@ extern int _rl_timeout_handle_sigalrm (void); /* use as a sentinel for fd_set, struct timeval, and sigset_t definitions */ #if defined (__MINGW32__) +/* still doesn't work; no alarm() so we provide a non-working stub. */ # define RL_TIMEOUT_USE_SIGALRM #elif defined (HAVE_SELECT) || defined (HAVE_PSELECT) # define RL_TIMEOUT_USE_SELECT @@ -399,6 +400,7 @@ extern void _rl_free_saved_line (HIST_ENTRY *); extern void _rl_unsave_line (HIST_ENTRY *); #endif extern int _rl_free_saved_history_line (void); +extern int _rl_maybe_replace_line (int); extern void _rl_set_insert_mode (int, int); diff --git a/search.c b/search.c index a22c43d..96bb83a 100644 --- a/search.c +++ b/search.c @@ -101,7 +101,7 @@ _rl_unsave_saved_search_line (void) from a history entry. We assume the undo list does not come from a history entry if we are at the end of the history, entering a new line. - The call to rl_maybe_replace_line() has already ensured that any undo + The call to _rl_maybe_replace_line() has already ensured that any undo list pointing to a history entry has already been saved back to the history and set rl_undo_list to NULL. */ @@ -271,8 +271,9 @@ _rl_nsearch_init (int dir, int pchar) cxt->direction = dir; cxt->history_pos = cxt->save_line; - /* If the current line has changed, put it back into the history if necessary. */ - rl_maybe_replace_line (); + /* If the current line has changed, put it back into the history if necessary + and clear the undo list. */ + _rl_maybe_replace_line (1); _rl_saved_line_for_search = _rl_alloc_saved_line (); @@ -603,12 +604,15 @@ rl_history_search_internal (int count, int dir) int ret, oldpos, newcol; char *t; - /* If the current line has changed, put it back into the history if necessary. */ - rl_maybe_replace_line (); + /* If the current line has changed, put it back into the history if necessary + and clear the undo list. */ + _rl_maybe_replace_line (1); _rl_saved_line_for_search = _rl_alloc_saved_line (); temp = (HIST_ENTRY *)NULL; + oldpos = where_history (); + /* Search COUNT times through the history for a line matching history_search_string. If history_search_string[0] == '^', the line must match from the start; otherwise any substring can match. @@ -623,10 +627,8 @@ rl_history_search_internal (int count, int dir) /* Get the history entry we found. */ _rl_history_search_pos = ret; - oldpos = where_history (); history_set_pos (_rl_history_search_pos); temp = current_history (); /* will never be NULL after successful search */ - history_set_pos (oldpos); /* Don't find multiple instances of the same line. */ if (prev_line_found && STREQ (prev_line_found, temp->line)) @@ -635,7 +637,7 @@ rl_history_search_internal (int count, int dir) count--; } - /* If we didn't find anything at all, return. */ + /* If we didn't find anything at all, return without changing history offset */ if (temp == 0) { _rl_unsave_saved_search_line (); diff --git a/text.c b/text.c index c5281ef..e8d4f5f 100644 --- a/text.c +++ b/text.c @@ -1449,11 +1449,11 @@ rl_change_case (int count, int op) int start, next, end; int inword, nc, nop; WCHAR_T c; + unsigned char uc; #if defined (HANDLE_MULTIBYTE) WCHAR_T wc, nwc; char mb[MB_LEN_MAX+1]; - int mlen; - size_t m; + size_t m, mlen; mbstate_t mps; #endif @@ -1503,7 +1503,9 @@ rl_change_case (int count, int op) characters */ if (MB_CUR_MAX == 1 || rl_byte_oriented) { - nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c); +change_singlebyte: + uc = c; + nc = (nop == UpCase) ? _rl_to_upper (uc) : _rl_to_lower (uc); rl_line_buffer[start] = nc; } #if defined (HANDLE_MULTIBYTE) @@ -1511,9 +1513,16 @@ rl_change_case (int count, int op) { m = MBRTOWC (&wc, rl_line_buffer + start, end - start, &mps); if (MB_INVALIDCH (m)) - wc = (WCHAR_T)rl_line_buffer[start]; + { + c = rl_line_buffer[start]; + next = start + 1; /* potentially redundant */ + goto change_singlebyte; + } else if (MB_NULLWCH (m)) - wc = L'\0'; + { + start = next; /* don't bother with null wide characters */ + continue; + } nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc); if (nwc != wc) /* just skip unchanged characters */ { @@ -1522,12 +1531,13 @@ rl_change_case (int count, int op) memset (&ts, 0, sizeof (mbstate_t)); mlen = WCRTOMB (mb, nwc, &ts); - if (mlen < 0) + + if (MB_INVALIDCH (mlen)) { nwc = wc; memset (&ts, 0, sizeof (mbstate_t)); mlen = WCRTOMB (mb, nwc, &ts); - if (mlen < 0) /* should not happen */ + if (MB_INVALIDCH (mlen)) /* should not happen */ strncpy (mb, rl_line_buffer + start, mlen = m); } if (mlen > 0) @@ -2001,9 +2011,7 @@ _rl_readstr_init (int pchar, int flags) cxt = _rl_rscxt_alloc (flags); - rl_maybe_replace_line (); _rl_saved_line_for_readstr = _rl_alloc_saved_line (); - rl_undo_list = 0; rl_line_buffer[0] = 0; @@ -2355,8 +2363,13 @@ rl_execute_named_command (int count, int key) command = _rl_read_command_name (); if (command == 0 || *command == '\0') - return 1; - if (func = rl_named_function (command)) + { + free (command); + return 1; + } + func = rl_named_function (command); + free (command); + if (func) { int prev, ostate; @@ -2375,6 +2388,5 @@ rl_execute_named_command (int count, int key) r = 1; } - free (command); return r; } diff --git a/tilde.c b/tilde.c index 734b208..0e82acf 100644 --- a/tilde.c +++ b/tilde.c @@ -1,6 +1,6 @@ /* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ -/* Copyright (C) 1988-2020,2023 Free Software Foundation, Inc. +/* Copyright (C) 1988-2020,2023-2024 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/util.c b/util.c index 2a24703..2bcc776 100644 --- a/util.c +++ b/util.c @@ -536,7 +536,10 @@ _rl_audit_tty (char *string) size = strlen (string) + 1; if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH) - return; + { + close (fd); + return; + } memset (&req, 0, sizeof(req)); req.nlh.nlmsg_len = NLMSG_SPACE (size);