From: Chet Ramey Date: Tue, 11 Apr 2023 15:23:03 +0000 (-0400) Subject: asan fixes; fix for history truncation; ANSI/ISO C changes; special cases for char... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14144013617be12f94b99b05bf0928a8d1eba743;p=thirdparty%2Freadline.git asan fixes; fix for history truncation; ANSI/ISO C changes; special cases for char search motion commands --- diff --git a/aclocal.m4 b/aclocal.m4 index 37546c6..2a86c70 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -3,7 +3,7 @@ dnl Bash specific tests dnl dnl Some derived from PDKSH 5.1.3 autoconf tests dnl -dnl Copyright (C) 1987-2021 Free Software Foundation, Inc. +dnl Copyright (C) 1987-2023 Free Software Foundation, Inc. dnl dnl @@ -69,11 +69,7 @@ AC_DEFUN(BASH_DECL_PRINTF, AC_CACHE_VAL(bash_cv_printf_declared, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include -#ifdef __STDC__ typedef int (*_bashfunc)(const char *, ...); -#else -typedef int (*_bashfunc)(); -#endif #include int main() @@ -238,6 +234,9 @@ AC_CACHE_VAL(bash_cv_dup2_broken, #include #include #include +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ int main() { @@ -432,6 +431,7 @@ AC_CACHE_VAL(bash_cv_sizeof_rlim_cur, #endif #include #include +int main() { struct rlimit r; @@ -457,6 +457,7 @@ AC_CACHE_VAL(bash_cv_sizeof_quad_t, #include #endif +int main() { #if HAVE_QUAD_T @@ -558,18 +559,8 @@ AC_CACHE_VAL(bash_cv_getenv_redef, # include #endif #include -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif char * -getenv (name) -#if defined (__linux__) || defined (__bsdi__) || defined (convex) - const char *name; -#else - char const *name; -#endif /* !__linux__ && !__bsdi__ && !convex */ +getenv (const char *name) { return "42"; } @@ -599,7 +590,6 @@ fi # We should check for putenv before calling this AC_DEFUN(BASH_FUNC_STD_PUTENV, [ -AC_REQUIRE([AC_C_PROTOTYPES]) AC_CACHE_CHECK([for standard-conformant putenv declaration], bash_cv_std_putenv, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #if HAVE_STDLIB_H @@ -608,16 +598,7 @@ AC_CACHE_CHECK([for standard-conformant putenv declaration], bash_cv_std_putenv, #if HAVE_STDDEF_H #include #endif -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif -#ifdef PROTOTYPES extern int putenv (char *); -#else -extern int putenv (); -#endif ]], [[return (putenv == 0);]] )], [bash_cv_std_putenv=yes], [bash_cv_std_putenv=no] )]) @@ -629,7 +610,6 @@ fi # We should check for unsetenv before calling this AC_DEFUN(BASH_FUNC_STD_UNSETENV, [ -AC_REQUIRE([AC_C_PROTOTYPES]) AC_CACHE_CHECK([for standard-conformant unsetenv declaration], bash_cv_std_unsetenv, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #if HAVE_STDLIB_H @@ -638,16 +618,7 @@ AC_CACHE_CHECK([for standard-conformant unsetenv declaration], bash_cv_std_unset #if HAVE_STDDEF_H #include #endif -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif -#ifdef PROTOTYPES extern int unsetenv (const char *); -#else -extern int unsetenv (); -#endif ]], [[return (unsetenv == 0);]] )], [bash_cv_std_unsetenv=yes], [bash_cv_std_unsetenv=no] )]) @@ -841,9 +812,7 @@ AC_CACHE_VAL(bash_cv_func_strcoll_broken, #include int -main(c, v) -int c; -char *v[]; +main(int c, char **v) { int r1, r2; char *deflocale, *defcoll; @@ -1345,15 +1314,13 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers, #endif #include -typedef void sigfunc(); +typedef void sigfunc(int); volatile int nsigint; #ifdef HAVE_POSIX_SIGNALS sigfunc * -set_signal_handler(sig, handler) - int sig; - sigfunc *handler; +set_signal_handler(int sig, sigfunc *handler) { struct sigaction act, oact; act.sa_handler = handler; @@ -1368,8 +1335,7 @@ set_signal_handler(sig, handler) #endif void -sigint(s) -int s; +sigint(int s) { nsigint++; } @@ -1836,9 +1802,7 @@ bash_cv_wcwidth_broken, #include int -main(c, v) -int c; -char **v; +main(int c, char **v) { int w; @@ -2095,31 +2059,17 @@ AC_DEFUN([BASH_FUNC_VSNPRINTF], if test X$ac_cv_func_vsnprintf = Xyes; then AC_CACHE_CHECK([for standard-conformant vsnprintf], [bash_cv_func_vsnprintf], [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#if HAVE_STDARG_H #include -#else -#include -#endif #include #include static int -#if HAVE_STDARG_H foo(const char *fmt, ...) -#else -foo(format, va_alist) - const char *format; - va_dcl -#endif { va_list args; int n; -#if HAVE_STDARG_H va_start(args, fmt); -#else - va_start(args); -#endif n = vsnprintf(0, 0, fmt, args); va_end (args); return n; @@ -2156,9 +2106,7 @@ AC_CACHE_VAL(bash_cv_wexitstatus_offset, #include int -main(c, v) - int c; - char **v; +main(int c, char **v) { pid_t pid, p; int s, i, n; diff --git a/ansi_stdlib.h b/ansi_stdlib.h index 7dc2ee0..3cb3e07 100644 --- a/ansi_stdlib.h +++ b/ansi_stdlib.h @@ -2,7 +2,7 @@ /* A minimal stdlib.h containing extern declarations for those functions that bash uses. */ -/* Copyright (C) 1993 Free Software Foundation, Inc. +/* Copyright (C) 1993,2023 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -32,13 +32,7 @@ extern double strtod (); /* Memory allocation functions. */ /* Generic pointer type. */ #ifndef PTR_T - -#if defined (__STDC__) # define PTR_T void * -#else -# define PTR_T char * -#endif - #endif /* PTR_T */ extern PTR_T malloc (); diff --git a/bind.c b/bind.c index 54ee5cd..ee6d6e1 100644 --- a/bind.c +++ b/bind.c @@ -65,20 +65,12 @@ extern int errno; #include "rlshell.h" #include "xmalloc.h" -#if !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif /* !strchr && !__STDC__ */ - /* Variables exported by this file. */ Keymap rl_binding_keymap; static int _rl_skip_to_delim (char *, int, int); -#if defined (USE_VARARGS) && defined (PREFER_STDARG) static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2))); -#else -static void _rl_init_file_error (); -#endif static rl_command_func_t *_rl_function_of_keyseq_internal (const char *, size_t, Keymap, int *); @@ -1129,25 +1121,11 @@ _rl_read_init_file (const char *filename, int include_level) } static void -#if defined (PREFER_STDARG) _rl_init_file_error (const char *format, ...) -#else -_rl_init_file_error (va_alist) - va_dcl -#endif { va_list args; -#if defined (PREFER_VARARGS) - char *format; -#endif -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif - fprintf (stderr, "readline: "); if (currently_reading_init_file) fprintf (stderr, "%s: line %d: ", current_readline_init_file, @@ -1167,9 +1145,7 @@ _rl_init_file_error (va_alist) /* **************************************************************** */ static int -parse_comparison_op (s, indp) - const char *s; - int *indp; +parse_comparison_op (const char *s, int *indp) { int i, peekc, op; diff --git a/complete.c b/complete.c index 2016d39..bf7cc85 100644 --- a/complete.c +++ b/complete.c @@ -77,11 +77,7 @@ extern int errno; # include "colors.h" #endif -#ifdef __STDC__ typedef int QSFUNC (const void *, const void *); -#else -typedef int QSFUNC (); -#endif #ifdef HAVE_LSTAT # define LSTAT lstat @@ -1630,7 +1626,7 @@ rl_display_match_list (char **matches, int len, int max) if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count) { lines = _rl_internal_pager (lines); - if (lines < 0) + if (lines < 0 || _rl_complete_display_matches_interrupt) return; } } @@ -1658,7 +1654,7 @@ rl_display_match_list (char **matches, int len, int max) if (_rl_page_completions && lines >= _rl_screenheight - 1) { lines = _rl_internal_pager (lines); - if (lines < 0) + if (lines < 0 || _rl_complete_display_matches_interrupt) return; } } @@ -1745,7 +1741,9 @@ display_matches (char **matches) } } - rl_display_match_list (matches, len, max); + /* We rely on the caller to set MATCHES to 0 when this returns. */ + if (_rl_complete_display_matches_interrupt == 0) + rl_display_match_list (matches, len, max); rl_forced_update_display (); rl_display_fixed = 1; diff --git a/configure b/configure index 72ec539..a78bac7 100755 --- a/configure +++ b/configure @@ -6166,15 +6166,13 @@ else $as_nop #endif #include -typedef void sigfunc(); +typedef void sigfunc(int); volatile int nsigint; #ifdef HAVE_POSIX_SIGNALS sigfunc * -set_signal_handler(sig, handler) - int sig; - sigfunc *handler; +set_signal_handler(int sig, sigfunc *handler) { struct sigaction act, oact; act.sa_handler = handler; @@ -6189,8 +6187,7 @@ set_signal_handler(sig, handler) #endif void -sigint(s) -int s; +sigint(int s) { nsigint++; } @@ -6376,9 +6373,7 @@ else $as_nop #include int -main(c, v) -int c; -char *v[]; +main(int c, char **v) { int r1, r2; char *deflocale, *defcoll; @@ -7741,9 +7736,7 @@ else $as_nop #include int -main(c, v) -int c; -char **v; +main(int c, char **v) { int w; diff --git a/display.c b/display.c index ce9dacd..fb10c60 100644 --- a/display.c +++ b/display.c @@ -1,6 +1,6 @@ /* display.c -- readline redisplay facility. */ -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. +/* Copyright (C) 1987-2023 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. @@ -59,10 +59,6 @@ #include "rlprivate.h" #include "xmalloc.h" -#if !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif /* !strchr && !__STDC__ */ - static void putc_face (int, int, char *); static void puts_face (const char *, const char *, int); static void norm_face (char *, int); @@ -3019,29 +3015,15 @@ rl_character_len (int c, int pos) mini-modeline. */ static int msg_saved_prompt = 0; -#if defined (USE_VARARGS) int -#if defined (PREFER_STDARG) rl_message (const char *format, ...) -#else -rl_message (va_alist) - va_dcl -#endif { va_list args; -#if defined (PREFER_VARARGS) - char *format; -#endif #if defined (HAVE_VSNPRINTF) int bneed; #endif -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif if (msg_buf == 0) msg_buf = xmalloc (msg_bufsiz = 128); @@ -3054,12 +3036,7 @@ rl_message (va_alist) msg_buf = xrealloc (msg_buf, msg_bufsiz); va_end (args); -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif vsnprintf (msg_buf, msg_bufsiz - 1, format, args); } #else @@ -3090,40 +3067,6 @@ rl_message (va_alist) return 0; } -#else /* !USE_VARARGS */ -int -rl_message (format, arg1, arg2) - char *format; -{ - if (msg_buf == 0) - msg_buf = xmalloc (msg_bufsiz = 128); - - sprintf (msg_buf, format, arg1, arg2); - msg_buf[msg_bufsiz - 1] = '\0'; /* overflow? */ - - rl_display_prompt = msg_buf; - if (saved_local_prompt == 0) - { - rl_save_prompt (); - msg_saved_prompt = 1; - } - else if (local_prompt != saved_local_prompt) - { - FREE (local_prompt); - FREE (local_prompt_prefix); - local_prompt = (char *)NULL; - } - local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length, - &prompt_last_invisible, - &prompt_invis_chars_first_line, - &prompt_physical_chars); - local_prompt_prefix = (char *)NULL; - local_prompt_len = local_prompt ? strlen (local_prompt) : 0; - (*rl_redisplay_function) (); - - return 0; -} -#endif /* !USE_VARARGS */ /* How to clear things from the "echo-area". */ int diff --git a/doc/hstech.texi b/doc/hstech.texi index 7a6d762..5d4efe5 100644 --- a/doc/hstech.texi +++ b/doc/hstech.texi @@ -517,9 +517,8 @@ The following program demonstrates simple use of the @sc{gnu} History Library. #include #include -main (argc, argv) - int argc; - char **argv; +int +main (int argc, char **argv) @{ char line[1024], *t; int len, done = 0; diff --git a/doc/rltech.texi b/doc/rltech.texi index f40bc2b..db38a31 100644 --- a/doc/rltech.texi +++ b/doc/rltech.texi @@ -2425,8 +2425,8 @@ COMMAND commands[] = @{ @}; /* Forward declarations. */ -char *stripwhite (); -COMMAND *find_command (); +char *stripwhite (char *); +COMMAND *find_command (char *); /* The name of this program, as taken from argv[0]. */ char *progname; @@ -2435,8 +2435,7 @@ char *progname; int done; char * -dupstr (s) - char *s; +dupstr (char *s) @{ char *r; @@ -2445,9 +2444,8 @@ dupstr (s) return (r); @} -main (argc, argv) - int argc; - char **argv; +int +main (int argc, char **argv) @{ char *line, *s; @@ -2483,8 +2481,7 @@ main (argc, argv) /* Execute a command line. */ int -execute_line (line) - char *line; +execute_line (char *line) @{ register int i; COMMAND *command; @@ -2523,8 +2520,7 @@ execute_line (line) /* Look up NAME as the name of a command, and return a pointer to that command. Return a NULL pointer if NAME isn't a command name. */ COMMAND * -find_command (name) - char *name; +find_command (char *name) @{ register int i; @@ -2538,8 +2534,7 @@ find_command (name) /* Strip whitespace from the start and end of STRING. Return a pointer into STRING. */ char * -stripwhite (string) - char *string; +stripwhite (char *string) @{ register char *s, *t; @@ -2563,13 +2558,14 @@ stripwhite (string) /* */ /* **************************************************************** */ -char *command_generator PARAMS((const char *, int)); -char **fileman_completion PARAMS((const char *, int, int)); +char *command_generator (const char *, int); +char **fileman_completion (const char *, int, int); /* Tell the GNU Readline library how to complete. We want to try to complete on command names if this is the first word in the line, or on filenames if not. */ -initialize_readline () +void +initialize_readline (void) @{ /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; @@ -2584,9 +2580,7 @@ initialize_readline () in case we want to do some simple parsing. Return the array of matches, or NULL if there aren't any. */ char ** -fileman_completion (text, start, end) - const char *text; - int start, end; +fileman_completion (const char *text, int start, int end) @{ char **matches; @@ -2605,9 +2599,7 @@ fileman_completion (text, start, end) to start from scratch; without any state (i.e. STATE == 0), then we start at the top of the list. */ char * -command_generator (text, state) - const char *text; - int state; +command_generator (const char *text, int state) @{ static int list_index, len; char *name; @@ -2645,8 +2637,8 @@ command_generator (text, state) static char syscom[1024]; /* List the file(s) named in arg. */ -com_list (arg) - char *arg; +int +com_list (char *arg) @{ if (!arg) arg = ""; @@ -2655,8 +2647,8 @@ com_list (arg) return (system (syscom)); @} -com_view (arg) - char *arg; +int +com_view (char *arg) @{ if (!valid_argument ("view", arg)) return 1; @@ -2670,15 +2662,15 @@ com_view (arg) return (system (syscom)); @} -com_rename (arg) - char *arg; +int +com_rename (char *arg) @{ too_dangerous ("rename"); return (1); @} -com_stat (arg) - char *arg; +int +com_stat (char *arg) @{ struct stat finfo; @@ -2705,8 +2697,8 @@ com_stat (arg) return (0); @} -com_delete (arg) - char *arg; +int +com_delete (char *arg) @{ too_dangerous ("delete"); return (1); @@ -2714,8 +2706,8 @@ com_delete (arg) /* Print out help for ARG, or for all of the commands if ARG is not present. */ -com_help (arg) - char *arg; +int +com_help (char *arg) @{ register int i; int printed = 0; @@ -2753,8 +2745,8 @@ com_help (arg) @} /* Change to the directory ARG. */ -com_cd (arg) - char *arg; +int +com_cd (char *arg) @{ if (chdir (arg) == -1) @{ @@ -2767,8 +2759,8 @@ com_cd (arg) @} /* Print out the current working directory. */ -com_pwd (ignore) - char *ignore; +int +com_pwd (char *ignore) @{ char dir[1024], *s; @@ -2784,16 +2776,16 @@ com_pwd (ignore) @} /* The user wishes to quit using this program. Just set DONE non-zero. */ -com_quit (arg) - char *arg; +int +com_quit (char *arg) @{ done = 1; return (0); @} /* Function which tells you that you can't do this. */ -too_dangerous (caller) - char *caller; +void +too_dangerous (char *caller) @{ fprintf (stderr, "%s: Too dangerous for me to distribute. Write it yourself.\n", @@ -2803,8 +2795,7 @@ too_dangerous (caller) /* Return non-zero if ARG is a valid argument for CALLER, else print an error message and return zero. */ int -valid_argument (caller, arg) - char *caller, *arg; +valid_argument (char *caller, char *arg) @{ if (!arg || !*arg) @{ diff --git a/doc/rluser.texi b/doc/rluser.texi index f68a4d7..bb1a24f 100644 --- a/doc/rluser.texi +++ b/doc/rluser.texi @@ -1864,9 +1864,11 @@ pathname expansion. Display version information about the current instance of Bash. @item shell-expand-line (M-C-e) -Expand the line as the shell does. -This performs alias and history expansion as well as all of the shell -word expansions (@pxref{Shell Expansions}). +Expand the line by performing shell word expansions. +This performs alias and history expansion, +$'@var{string}' and $"@var{string}" quoting, +tilde expansion, parameter and variable expansion, arithmetic expansion, +word splitting, and quote removal. @item history-expand-line (M-^) Perform history expansion on the current line. diff --git a/doc/version.texi b/doc/version.texi index a72ee26..865a715 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -5,7 +5,7 @@ Copyright (C) 1988-2023 Free Software Foundation, Inc. @set EDITION 8.2 @set VERSION 8.2 -@set UPDATED 17 February 2023 -@set UPDATED-MONTH February 2023 +@set UPDATED 27 March 2023 +@set UPDATED-MONTH March 2023 -@set LASTCHANGE Fri Feb 17 11:03:17 EST 2023 +@set LASTCHANGE Mon Mar 27 11:41:20 EDT 2023 diff --git a/examples/histexamp.c b/examples/histexamp.c index 309d769..2e946ac 100644 --- a/examples/histexamp.c +++ b/examples/histexamp.c @@ -32,9 +32,7 @@ #include int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { char line[1024], *t; int len, done; @@ -91,6 +89,7 @@ main (argc, argv) register HIST_ENTRY **the_list; register int i; time_t tt; + struct tm *tm; char timestr[128]; the_list = history_list (); @@ -98,8 +97,9 @@ main (argc, argv) for (i = 0; the_list[i]; i++) { tt = history_get_time (the_list[i]); - if (tt) - strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt)); + tm = tt ? localtime (&tt) : 0; + if (tm) + strftime (timestr, sizeof (timestr), "%a %R", tm); else strcpy (timestr, "??"); printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line); diff --git a/examples/rl.c b/examples/rl.c index 39e5b8e..e04bbd6 100644 --- a/examples/rl.c +++ b/examples/rl.c @@ -5,7 +5,7 @@ * usage: rl [-p prompt] [-u unit] [-d default] [-n nchars] */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2023 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. @@ -55,10 +55,6 @@ extern void exit(); extern int optind; extern char *optarg; -#if !defined (strchr) && !defined (__STDC__) -extern char *strrchr(); -#endif - static char *progname; static char *deftext; diff --git a/funmap.c b/funmap.c index 0095c6b..affa0fd 100644 --- a/funmap.c +++ b/funmap.c @@ -40,11 +40,7 @@ #include "xmalloc.h" -#ifdef __STDC__ typedef int QSFUNC (const void *, const void *); -#else -typedef int QSFUNC (); -#endif extern int _rl_qsort_string_compare (char **, char **); diff --git a/histexpand.c b/histexpand.c index 25d962c..f2eb18f 100644 --- a/histexpand.c +++ b/histexpand.c @@ -509,7 +509,7 @@ postproc_subst_rhs (void) /* a single backslash protects the `&' from lhs interpolation */ if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') i++; - if (j >= new_size) + if (j + 1 >= new_size) new = (char *)xrealloc (new, new_size *= 2); new[j++] = subst_rhs[i]; } @@ -896,7 +896,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p #define ADD_CHAR(c) \ do \ { \ - if (j >= result_len - 1) \ + if ((j + 1) >= result_len) \ result = (char *)xrealloc (result, result_len += 64); \ result[j++] = c; \ result[j] = '\0'; \ @@ -1600,6 +1600,8 @@ get_word: if (nestdelim == 0 && delimiter == 0 && member (string[i], "<>$!@?+*") && string[i+1] == '(') /*)*/ { i += 2; + if (string[i] == 0) + break; /* could just return i here */ delimopen = '('; delimiter = ')'; nestdelim = 1; diff --git a/histfile.c b/histfile.c index a3c8d9b..2af71d3 100644 --- a/histfile.c +++ b/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989-2019 Free Software Foundation, Inc. +/* Copyright (C) 1989-2019,2023 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -578,6 +578,15 @@ history_truncate_file (const char *fname, int lines) goto truncate_exit; } + /* Don't bother with any of this if we're truncating to zero length. */ + if (lines == 0) + { + close (file); + buffer[chars_read = 0] = '\0'; + bp = buffer; + goto truncate_write; + } + chars_read = read (file, buffer, file_size); close (file); @@ -586,30 +595,38 @@ history_truncate_file (const char *fname, int lines) rv = (chars_read < 0) ? errno : 0; goto truncate_exit; } + buffer[chars_read] = '\0'; /* for the initial check of bp1[1] */ /* Count backwards from the end of buffer until we have passed LINES lines. bp1 is set funny initially. But since bp[1] can't be a comment character (since it's off the end) and *bp can't be - both a newline and the history comment character, it should be OK. */ - for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--) + both a newline and the history comment character, it should be OK. + If we are writing history timestamps, we need to add one to LINES + because we decrement it one extra time the first time through the loop + and we need the final timestamp line. */ + lines += history_write_timestamps; + for (bp1 = bp = buffer + chars_read - 1; lines > 0 && bp > buffer; bp--) { if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) lines--; bp1 = bp; } - /* If this is the first line, then the file contains exactly the + /* This is the right line, so move to its start. If we're writing history + timestamps, we want to go back until *bp == '\n' and bp1 starts a + history timestamp. If we're not, just move back to *bp == '\n'. + If this is the first line, then the file contains exactly the number of lines we want to truncate to, so we don't need to do - anything. It's the first line if we don't find a newline between - the current value of i and 0. Otherwise, write from the start of - this line until the end of the buffer. */ + anything, and we'll end up with bp == buffer. + Otherwise, write from the start of this line until the end of the + buffer. */ for ( ; bp > buffer; bp--) { - if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0) - { + if (*bp == '\n' && (history_write_timestamps == 0 || HIST_TIMESTAMP_START(bp1))) + { bp++; break; - } + } bp1 = bp; } @@ -623,15 +640,22 @@ history_truncate_file (const char *fname, int lines) goto truncate_exit; } +truncate_write: tempname = history_tempfile (filename); if ((file = open (tempname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1) { if (write (file, bp, chars_read - (bp - buffer)) < 0) - rv = errno; + { + rv = errno; + close (file); + } if (rv == 0 && fstat (file, &nfinfo) < 0) - rv = errno; + { + rv = errno; + close (file); + } if (rv == 0 && close (file) < 0) rv = errno; diff --git a/histlib.h b/histlib.h index 7189a07..da8e653 100644 --- a/histlib.h +++ b/histlib.h @@ -56,9 +56,6 @@ #endif #ifndef member -# if !defined (strchr) && !defined (__STDC__) -extern char *strchr (); -# endif /* !strchr && !__STDC__ */ #define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0) #endif diff --git a/history.c b/history.c index 4258030..ee52e82 100644 --- a/history.c +++ b/history.c @@ -42,6 +42,7 @@ # endif # include #endif +#include "posixtime.h" #include @@ -261,7 +262,7 @@ hist_inittime (void) time_t t; char ts[64], *ret; - t = (time_t) time ((time_t *)0); + t = getnow (); #if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */ snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t); #else diff --git a/history.h b/history.h index 9c2b099..49e1bf2 100644 --- a/history.h +++ b/history.h @@ -36,11 +36,7 @@ extern "C" { # include #endif -#ifdef __STDC__ typedef void *histdata_t; -#else -typedef char *histdata_t; -#endif /* Let's not step on anyone else's define for now, since we don't use this yet. */ #ifndef HS_HISTORY_VERSION diff --git a/mbutil.c b/mbutil.c index 0844e28..93d7b7b 100644 --- a/mbutil.c +++ b/mbutil.c @@ -482,7 +482,7 @@ _rl_char_value (const char *buf, int ind) if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind])) return ((WCHAR_T) buf[ind]); l = strlen (buf); - if (ind >= l - 1) + if (ind + 1 >= l) return ((WCHAR_T) buf[ind]); if (l < ind) /* Sanity check */ l = strlen (buf+ind); diff --git a/misc.c b/misc.c index c797ff7..e1cceca 100644 --- a/misc.c +++ b/misc.c @@ -340,9 +340,14 @@ rl_maybe_replace_line (void) xfree (temp->line); FREE (temp->timestamp); xfree (temp); - /* XXX - what about _rl_saved_line_for_history? if the saved undo list - is rl_undo_list, and we just put that into a history entry, should + /* What about _rl_saved_line_for_history? if the saved undo list is + rl_undo_list, and we just put that into a history entry, should we set the saved undo list to NULL? */ + 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; } return 0; } diff --git a/parens.c b/parens.c index 38b5e70..7f1e93f 100644 --- a/parens.c +++ b/parens.c @@ -47,10 +47,6 @@ # include #endif /* !HAVE_STRING_H */ -#if !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif /* !strchr && !__STDC__ */ - #include "readline.h" #include "rlprivate.h" diff --git a/posixtime.h b/posixtime.h index 319cb16..a731b00 100644 --- a/posixtime.h +++ b/posixtime.h @@ -52,6 +52,15 @@ struct timeval extern int gettimeofday (struct timeval * restrict, void * restrict); #endif +/* consistently use gettimeofday for time information */ +static inline time_t +getnow(void) +{ + struct timeval now; + gettimeofday (&now, 0); + return now.tv_sec; +} + /* These exist on BSD systems, at least. */ #if !defined (timerclear) # define timerclear(tvp) do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; } while (0) diff --git a/readline.h b/readline.h index 259e6b4..48f1210 100644 --- a/readline.h +++ b/readline.h @@ -1,6 +1,6 @@ /* Readline.h -- the names of functions callable from within readline. */ -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. +/* Copyright (C) 1987-2023 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. @@ -404,11 +404,7 @@ extern void rl_activate_mark (void); extern void rl_deactivate_mark (void); extern int rl_mark_active_p (void); -#if defined (USE_VARARGS) && defined (PREFER_STDARG) extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); -#else -extern int rl_message (); -#endif extern int rl_show_char (int); diff --git a/rldefs.h b/rldefs.h index c67b385..1ef0fbf 100644 --- a/rldefs.h +++ b/rldefs.h @@ -63,17 +63,7 @@ # include #endif /* !HAVE_STRING_H */ -#if !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif /* !strchr && !__STDC__ */ - -#if defined (PREFER_STDARG) -# include -#else -# if defined (PREFER_VARARGS) -# include -# endif -#endif +#include #if defined (HAVE_STRCASECMP) #define _rl_stricmp strcasecmp diff --git a/rlprivate.h b/rlprivate.h index e97ea90..5c0592b 100644 --- a/rlprivate.h +++ b/rlprivate.h @@ -1,7 +1,7 @@ /* rlprivate.h -- functions and variables global to the readline library, but not intended for use by applications. */ -/* Copyright (C) 1999-2022 Free Software Foundation, Inc. +/* Copyright (C) 1999-2023 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. @@ -459,15 +459,9 @@ extern UNDO_LIST *_rl_copy_undo_list (UNDO_LIST *); extern void _rl_free_undo_list (UNDO_LIST *); /* util.c */ -#if defined (USE_VARARGS) && defined (PREFER_STDARG) extern void _rl_ttymsg (const char *, ...) __attribute__((__format__ (printf, 1, 2))); extern void _rl_errmsg (const char *, ...) __attribute__((__format__ (printf, 1, 2))); extern void _rl_trace (const char *, ...) __attribute__((__format__ (printf, 1, 2))); -#else -extern void _rl_ttymsg (); -extern void _rl_errmsg (); -extern void _rl_trace (); -#endif extern void _rl_audit_tty (char *); extern int _rl_tropen (void); diff --git a/rlstdc.h b/rlstdc.h index 2aaa30b..0e5c4f4 100644 --- a/rlstdc.h +++ b/rlstdc.h @@ -1,6 +1,6 @@ /* stdc.h -- macros to make source compile on both ANSI C and K&R C compilers. */ -/* Copyright (C) 1993-2009 Free Software Foundation, Inc. +/* Copyright (C) 1993-2009,2023 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,16 +42,4 @@ # endif #endif -/* Moved from config.h.in because readline.h:rl_message depends on these - defines. */ -#if defined (__STDC__) && defined (HAVE_STDARG_H) -# define PREFER_STDARG -# define USE_VARARGS -#else -# if defined (HAVE_VARARGS_H) -# define PREFER_VARARGS -# define USE_VARARGS -# endif -#endif - #endif /* !_RL_STDC_H_ */ diff --git a/rltty.c b/rltty.c index d9b0cd1..337f0af 100644 --- a/rltty.c +++ b/rltty.c @@ -1,7 +1,7 @@ /* rltty.c -- functions to prepare and restore the terminal for readline's use. */ -/* Copyright (C) 1992-2022 Free Software Foundation, Inc. +/* Copyright (C) 1992-2023 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,8 +80,7 @@ static int ksrflow; /* Dummy call to force a backgrounded readline to stop before it tries to get the tty settings. */ static void -set_winsize (tty) - int tty; +set_winsize (int tty) { #if defined (TIOCGWINSZ) struct winsize w; diff --git a/rltypedefs.h b/rltypedefs.h index 1636549..b1ffeb0 100644 --- a/rltypedefs.h +++ b/rltypedefs.h @@ -31,17 +31,10 @@ extern "C" { #if !defined (_FUNCTION_DEF) # define _FUNCTION_DEF -#if defined(__GNUC__) || defined(__clang__) typedef int Function () __attribute__((deprecated)); typedef void VFunction () __attribute__((deprecated)); typedef char *CPFunction () __attribute__((deprecated)); typedef char **CPPFunction () __attribute__((deprecated)); -#else -typedef int Function (); -typedef void VFunction (); -typedef char *CPFunction (); -typedef char **CPPFunction (); -#endif #endif /* _FUNCTION_DEF */ diff --git a/text.c b/text.c index abe99b3..62e4da2 100644 --- a/text.c +++ b/text.c @@ -1764,8 +1764,7 @@ _rl_char_search (int count, int fdir, int bdir) #if defined (READLINE_CALLBACKS) static int -_rl_char_search_callback (data) - _rl_callback_generic_arg *data; +_rl_char_search_callback (_rl_callback_generic_arg *data) { _rl_callback_func = 0; _rl_want_redisplay = 1; diff --git a/tilde.c b/tilde.c index c31f921..734b208 100644 --- a/tilde.c +++ b/tilde.c @@ -68,14 +68,6 @@ extern struct passwd *getpwnam (const char *); #define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) #endif /* !savestring */ -#if !defined (NULL) -# if defined (__STDC__) -# define NULL ((void *) 0) -# else -# define NULL 0x0 -# endif /* !__STDC__ */ -#endif /* !NULL */ - /* If being compiled as part of bash, these will be satisfied from variables.o. If being compiled as part of readline, they will be satisfied from shell.o. */ diff --git a/undo.c b/undo.c index c9c2a5b..492894c 100644 --- a/undo.c +++ b/undo.c @@ -122,6 +122,8 @@ rl_free_undo_list (void) _rl_free_undo_list (rl_undo_list); rl_undo_list = (UNDO_LIST *)NULL; _hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL); + if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == orig_list) + _rl_saved_line_for_history->data = 0; } UNDO_LIST * diff --git a/util.c b/util.c index b68abdc..61c40be 100644 --- a/util.c +++ b/util.c @@ -229,26 +229,12 @@ rl_tilde_expand (int ignore, int key) return (0); } -#if defined (USE_VARARGS) void -#if defined (PREFER_STDARG) _rl_ttymsg (const char *format, ...) -#else -_rl_ttymsg (va_alist) - va_dcl -#endif { va_list args; -#if defined (PREFER_VARARGS) - char *format; -#endif -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif fprintf (stderr, "readline: "); vfprintf (stderr, format, args); @@ -261,24 +247,11 @@ _rl_ttymsg (va_alist) } void -#if defined (PREFER_STDARG) _rl_errmsg (const char *format, ...) -#else -_rl_errmsg (va_alist) - va_dcl -#endif { va_list args; -#if defined (PREFER_VARARGS) - char *format; -#endif -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif fprintf (stderr, "readline: "); vfprintf (stderr, format, args); @@ -288,28 +261,6 @@ _rl_errmsg (va_alist) va_end (args); } -#else /* !USE_VARARGS */ -void -_rl_ttymsg (format, arg1, arg2) - char *format; -{ - fprintf (stderr, "readline: "); - fprintf (stderr, format, arg1, arg2); - fprintf (stderr, "\n"); - - rl_forced_update_display (); -} - -void -_rl_errmsg (format, arg1, arg2) - char *format; -{ - fprintf (stderr, "readline: "); - fprintf (stderr, format, arg1, arg2); - fprintf (stderr, "\n"); -} -#endif /* !USE_VARARGS */ - /* **************************************************************** */ /* */ /* String Utility Functions */ @@ -507,28 +458,14 @@ _rl_savestring (const char *s) } #if defined (DEBUG) -#if defined (USE_VARARGS) static FILE *_rl_tracefp; void -#if defined (PREFER_STDARG) _rl_trace (const char *format, ...) -#else -_rl_trace (va_alist) - va_dcl -#endif { va_list args; -#if defined (PREFER_VARARGS) - char *format; -#endif -#if defined (PREFER_STDARG) va_start (args, format); -#else - va_start (args); - format = va_arg (args, char *); -#endif if (_rl_tracefp == 0) _rl_tropen (); @@ -574,7 +511,6 @@ _rl_settracefp (FILE *fp) { _rl_tracefp = fp; } -#endif #endif /* DEBUG */ diff --git a/vi_mode.c b/vi_mode.c index e85fd10..7396e31 100644 --- a/vi_mode.c +++ b/vi_mode.c @@ -1153,6 +1153,23 @@ _rl_mvcxt_dispose (_rl_vimotion_cxt *m) xfree (m); } +static inline int +vi_charsearch_command (int c) +{ + switch (c) + { + case 'f': + case 'F': + case 't': + case 'T': + case ';': + case ',': + return 1; + default: + return 0; + } +} + static int rl_domove_motion_callback (_rl_vimotion_cxt *m) { @@ -1173,7 +1190,7 @@ rl_domove_motion_callback (_rl_vimotion_cxt *m) /* Note in the context that the motion command failed. Right now we only do this for unsuccessful searches (ones where _rl_dispatch returns non-zero and point doesn't move). */ - if (r != 0 && rl_point == opoint && (c == 'f' || c == 'F')) + if (r != 0 && rl_point == opoint && vi_charsearch_command (c)) m->flags |= MOVE_FAILED; #if defined (READLINE_CALLBACKS) @@ -1211,6 +1228,14 @@ _rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m) didn't delete anything, as long as the motion command is valid. */ if (_rl_to_upper (m->key) == 'C' && _rl_vi_motion_command (c) && (m->flags & MOVE_FAILED) == 0) return (vidomove_dispatch (m)); + /* 'd' and 'D' must delete at least one character even if the motion + command doesn't move the cursor. */ + if (_rl_to_upper (m->key) == 'D' && _rl_vi_motion_command (c) && (m->flags & MOVE_FAILED) == 0) + return (vidomove_dispatch (m)); + /* 'y' and 'Y' must yank at least one character even if the motion + command doean't move the cursor. */ + if (_rl_to_upper (m->key) == 'Y' && _rl_vi_motion_command (c) && (m->flags & MOVE_FAILED) == 0) + return (vidomove_dispatch (m)); RL_UNSETSTATE (RL_STATE_VIMOTION); return (-1); } diff --git a/xmalloc.h b/xmalloc.h index 0fb9df9..c819804 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -1,6 +1,6 @@ /* xmalloc.h -- memory allocation that aborts on errors. */ -/* Copyright (C) 1999-2009,2010-2021 Free Software Foundation, Inc. +/* Copyright (C) 1999-2009,2010-2023 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. @@ -29,13 +29,7 @@ #endif #ifndef PTR_T - -#ifdef __STDC__ -# define PTR_T void * -#else -# define PTR_T char * -#endif - +# define PTR_T void * #endif /* !PTR_T */ extern PTR_T xmalloc (size_t);