diff --git a/CHANGES b/CHANGES index b2999bf0..139dc3a4 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,14 @@ l. Fixed a bug that left readline's signal handlers installed while running a m. Fixed the `fc' builtin to clamp out of range history specifications at the boundaries of the history list for POSIX conformance. +n. Fixed a bug that caused ${foo@a} to treat foo as an unset variable if it + was an array without a value for subscript 0/"0" but had other set + elements. + +o. Fixed a bug that caused the history code to attempt to parse command + substitutions looking for shell comments before adding them to the history, + even while parsing here-documents. + 2. New Features in Bash a. If the hash builtin is listing hashed filenames portably, don't print @@ -480,8 +488,8 @@ dd. New `U', `u', and `L' parameter transformations to convert to uppercase, convert first character to uppercase, and convert to lowercase, respectively. -ee. PROMPT_COMMANDS: a new array variable, each element of which can contain a - command to be executed like PROMPT_COMMAND. +ee. PROMPT_COMMAND: can now be an array variable, each element of which can + contain a command to be executed like a string PROMPT_COMMAND variable. ff. `ulimit' has a -R option to report and set the RLIMIT_RTTIME resource. diff --git a/CHANGES-5.1 b/CHANGES-5.1 index 85b5d766..e0eef4ef 100644 --- a/CHANGES-5.1 +++ b/CHANGES-5.1 @@ -41,6 +41,14 @@ l. Fixed a bug that left readline's signal handlers installed while running a m. Fixed the `fc' builtin to clamp out of range history specifications at the boundaries of the history list for POSIX conformance. +n. Fixed a bug that caused ${foo@a} to treat foo as an unset variable if it + was an array without a value for subscript 0/"0" but had other set + elements. + +o. Fixed a bug that caused the history code to attempt to parse command + substitutions looking for shell comments before adding them to the history, + even while parsing here-documents. + 2. New Features in Bash a. If the hash builtin is listing hashed filenames portably, don't print @@ -476,8 +484,8 @@ dd. New `U', `u', and `L' parameter transformations to convert to uppercase, convert first character to uppercase, and convert to lowercase, respectively. -ee. PROMPT_COMMANDS: a new array variable, each element of which can contain a - command to be executed like PROMPT_COMMAND. +ee. PROMPT_COMMAND: can now be an array variable, each element of which can + contain a command to be executed like a string PROMPT_COMMAND variable. ff. `ulimit' has a -R option to report and set the RLIMIT_RTTIME resource. diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index f70b07fd..b0b90bf5 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8913,3 +8913,21 @@ bashhist.c if we are in the middle of adding a here-document, since it may call the parser recursively on data that is not guaranteed to be valid input. From a report by Hyunho Cho + + 8/24 + ---- +lib/readline/complete.c + - compare_match: compare TEXT from the line buffer and MATCH, a + possible completion for TEXT, after dequoting TEXT if necessary + - rl_complete_internal,rl_menu_complete : if show-all-if-unmodified is + set, use compare_match instead of a straight strcmp to determine if + the match has changed the text to complete, so we can use it for + filenames that require quoting. Report and pointer to fix from + Abon B + + 8/25 + ---- +eval.c + - execute_prompt_command: PROMPT_COMMAND can now be an array, subsuming + PROMPT_COMMANDS, which bash no longer looks for. Prompted by a + suggestion from Martijn Dekker diff --git a/NEWS b/NEWS index 98b37c00..1d421256 100644 --- a/NEWS +++ b/NEWS @@ -94,8 +94,8 @@ dd. New `U', `u', and `L' parameter transformations to convert to uppercase, convert first character to uppercase, and convert to lowercase, respectively. -ee. PROMPT_COMMANDS: a new array variable, each element of which can contain a - command to be executed like PROMPT_COMMAND. +ee. PROMPT_COMMAND: can now be an array variable, each element of which can + contain a command to be executed like a string PROMPT_COMMAND variable. ff. `ulimit' has a -R option to report and set the RLIMIT_RTTIME resource. diff --git a/NEWS-5.1 b/NEWS-5.1 index e6aa1d12..922fe1a0 100644 --- a/NEWS-5.1 +++ b/NEWS-5.1 @@ -94,8 +94,8 @@ dd. New `U', `u', and `L' parameter transformations to convert to uppercase, convert first character to uppercase, and convert to lowercase, respectively. -ee. PROMPT_COMMANDS: a new array variable, each element of which can contain a - command to be executed like PROMPT_COMMAND. +ee. PROMPT_COMMAND: can now be an array variable, each element of which can + contain a command to be executed like a string PROMPT_COMMAND variable. ff. `ulimit' has a -R option to report and set the RLIMIT_RTTIME resource. diff --git a/doc/bash.1 b/doc/bash.1 index 47a66610..0f4e37f9 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet.ramey@case.edu .\" -.\" Last Change: Mon Aug 3 14:10:13 EDT 2020 +.\" Last Change: Tue Aug 25 09:58:55 EDT 2020 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2020 August 3" "GNU Bash 5.1" +.TH BASH 1 "2020 August 25" "GNU Bash 5.1" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -2475,13 +2475,12 @@ had been executed. When the shell enters \fIposix mode\fP, it sets this variable if it was not already set. .TP -.B PROMPT_COMMANDS -If this array variable is set, +.B PROMPT_COMMAND +If this variable is set, and is an array, the value of each set element is executed as a command prior to issuing each primary prompt. -If this is not set, but -.B PROMPT_COMMAND -is set to a value, its value is used as a command to execute instead. +If this is set but not an array variable, +its value is used as a command to execute instead. .TP .B PROMPT_DIRTRIM If set to a number greater than zero, the value is used as the number of diff --git a/doc/bashref.texi b/doc/bashref.texi index 519d7a15..3943b85b 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -6283,13 +6283,12 @@ not already set. The process @sc{id} of the shell's parent process. This variable is readonly. -@item PROMPT_COMMANDS -If this array variable is set, +@item PROMPT_COMMAND +If this variable is set, and is an array, the value of each set element is interpreted as a command to execute before printing the primary prompt (@env{$PS1}). -If this is not set, but -@env{PROMPT_COMMAND} -is set to a value, its value is used as a command to execute instead. +If this is set but not an array variable, +its value is used as a command to execute instead. @item PROMPT_DIRTRIM If set to a number greater than zero, the value is used as the number of diff --git a/doc/version.texi b/doc/version.texi index 5ef321f2..4a548f91 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,11 +2,10 @@ Copyright (C) 1988-2020 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Mon Aug 3 14:09:53 EDT 2020 - +@set LASTCHANGE Tue Aug 25 09:58:38 EDT 2020 @set EDITION 5.1 @set VERSION 5.1 -@set UPDATED 3 August 2020 +@set UPDATED 25 August 2020 @set UPDATED-MONTH August 2020 diff --git a/eval.c b/eval.c index 6f28f89f..ed3b0f24 100644 --- a/eval.c +++ b/eval.c @@ -282,19 +282,26 @@ static void execute_prompt_command () { char *command_to_execute; -#if defined (ARRAY_VARS) SHELL_VAR *pcv; +#if defined (ARRAY_VARS) ARRAY *pcmds; - - GET_ARRAY_FROM_VAR ("PROMPT_COMMANDS", pcv, pcmds); - if (pcv && var_isset (pcv) && pcmds && array_num_elements (pcmds) > 0) - { - array_walk (pcmds, execute_array_command, "PROMPT_COMMANDS"); - return; - } #endif - command_to_execute = get_string_value ("PROMPT_COMMAND"); + pcv = find_variable ("PROMPT_COMMAND"); + if (pcv == 0 || var_isset (pcv) == 0 || invisible_p (pcv)) + return; +#if defined (ARRAY_VARS) + if (array_p (pcv)) + { + if ((pcmds = array_cell (pcv)) && array_num_elements (pcmds) > 0) + array_walk (pcmds, execute_array_command, "PROMPT_COMMAND"); + return; + } + else if (assoc_p (pcv)) + return; +#endif + + command_to_execute = value_cell (pcv); if (command_to_execute && *command_to_execute) execute_variable_command (command_to_execute, "PROMPT_COMMAND"); } @@ -313,7 +320,7 @@ parse_command () /* Allow the execution of a random command just before the printing of each primary prompt. If the shell variable PROMPT_COMMAND - is set then the value of it is the command to execute. */ + is set then its value (array or string) is the command(s) to execute. */ /* The tests are a combination of SHOULD_PROMPT() and prompt_again() from parse.y, which are the conditions under which the prompt is actually printed. */ diff --git a/lib/readline/complete.c b/lib/readline/complete.c index 989b15c2..7af79ef7 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -1,6 +1,6 @@ /* complete.c -- filename completion for readline. */ -/* Copyright (C) 1987-2019 Free Software Foundation, Inc. +/* Copyright (C) 1987-2020 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. @@ -148,6 +148,7 @@ static int complete_fncmp PARAMS((const char *, int, const char *, int)); static void display_matches PARAMS((char **)); static int compute_lcd_of_matches PARAMS((char **, int, const char *)); static int postprocess_matches PARAMS((char ***, int)); +static int compare_match PARAMS((const char *, const char *)); static int complete_get_screenwidth PARAMS((void)); static char *make_quoted_replacement PARAMS((char *, int, char *)); @@ -1964,6 +1965,26 @@ _rl_free_match_list (char **matches) xfree (matches); } +/* Compare a possibly-quoted filename TEXT from the line buffer and a possible + MATCH that is the product of filename completion, which acts on the dequoted + text. */ +static int +compare_match (const char *text, const char *match) +{ + char *temp; + int r; + + if (rl_filename_completion_desired && rl_filename_quoting_desired && + rl_completion_found_quote && rl_filename_dequoting_function) + { + temp = (*rl_filename_dequoting_function) (text, rl_completion_quote_character); + r = strcmp (temp, match); + free (temp); + return r; + } + return (strcmp (text, match)); +} + /* Complete the word at or before point. WHAT_TO_DO says what to do with the completion. `?' means list the possible completions. @@ -2010,7 +2031,7 @@ rl_complete_internal (int what_to_do) matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char); /* nontrivial_lcd is set if the common prefix adds something to the word being completed. */ - nontrivial_lcd = matches && strcmp (text, matches[0]) != 0; + nontrivial_lcd = matches && compare_match (text, matches[0]) != 0; if (what_to_do == '!' || what_to_do == '@') tlen = strlen (text); xfree (text); @@ -2772,7 +2793,7 @@ rl_old_menu_complete (int count, int invoking_key) { insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); append_to_match (matches[match_list_index], delimiter, quote_char, - strcmp (orig_text, matches[match_list_index])); + compare_match (orig_text, matches[match_list_index])); } completion_changed_buffer = 1; @@ -2846,7 +2867,7 @@ rl_menu_complete (int count, int ignore) matches = gen_completion_matches (orig_text, orig_start, orig_end, our_func, found_quote, quote_char); - nontrivial_lcd = matches && strcmp (orig_text, matches[0]) != 0; + nontrivial_lcd = matches && compare_match (orig_text, matches[0]) != 0; /* If we are matching filenames, the attempted completion function will have set rl_filename_completion_desired to a non-zero value. The basic @@ -2953,7 +2974,7 @@ rl_menu_complete (int count, int ignore) { insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); append_to_match (matches[match_list_index], delimiter, quote_char, - strcmp (orig_text, matches[match_list_index])); + compare_match (orig_text, matches[match_list_index])); } completion_changed_buffer = 1; diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index c8bef8dd..0b063810 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/bash/bash-current +BUILD_DIR=/usr/local/build/chet/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR