From: Chet Ramey Date: Mon, 27 Jan 2020 14:25:05 +0000 (-0500) Subject: commit bash-20200124 snapshot X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=11bb038e13b58a8fd07ddd2f32d488948da6b5b1;p=thirdparty%2Fbash.git commit bash-20200124 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 5cfbebdde..a841242df 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -7171,3 +7171,66 @@ test.c - for the `-v' operator, use a clever trick from Martijn Dekker and just test whether N is between 0 and $#. + 1/21 + ---- +lib/readline/text.c + - rl_change_case: fix argument to rl_extend_line_buffer; make sure to + reset s and e after call in case rl_line_buffer was reallocated + +lib/readline/vi_mode.c + - _rl_vi_save_replace: if start ends up being less than zero, make + sure we don't read before the start of rl_line_buffer + - rl_vi_overstrike_kill_line,rl_vi_overstrike_kill_word: replacement + functions for ^U and ^W in vi overstrike mode, to keep right value + for vi_replace_count. + - rl_vi_overstrike_yank: similar for ^Y and rl_yank + + 1/22 + ---- +lib/readline/display.c + - update_line: if we're trying to wrap lines on an autowrap terminal, + punt and do a dumb update if the number of bytes in the first char + on the new line is greater than the number of bytes in the first char + of the old line. There's no guarantee we'll be able to extend the + old line buffer enough to accommodate the new bytes + - update_line: try to avoid some operations when wrapping lines if the + number of bytes in the first characters of the old and new lines is + the same + - update_line: when updating vis_lbreaks after fixing up the lines when + wrapping, make sure we don't exceed an index of _rl_vis_botlin when + updating the line break offsets + +lib/readline/text.c + - rl_delete_text: if deleting text leaves the mark past rl_end, adjust + it to rl_end + +lib/readline/vi_mode.c + - _rl_vi_goto_mark: make sure to call _rl_fix_point after setting + rl_point to rl_mark + + 1/23 + ---- +lib/readline/kill.c + - rl_kill_region,region_kill_internal: call _rl_fix_point + +lib/readline/text.c,lib/readline/rlprivate.h + - _rl_fix_mark: new function to clamp rl_mark between 0 and rl_end + + 1/24 + ---- +lib/readline/bind.c + - rl_translate_keyseq: rework how key sequences are translated with + the intent of normalizing backslash treatment. Since the current + behavior of, e.g., \C-\\, is inconsistent, this change chooses to + effectively treat and display \\ as \\ instead of \C-\. This is not + completely backwards compatible, but it seems like the most reasonable + choice. This allows things like \M-\a but is not compatible with + pre-bash-4.4 (readline 7.0) handling of \C-\, which is now treated + like \C-\0. If that proves to be a problem, we can add code to + understand \C-\ as equivalent to \C-\\. Since attempting to bind + "\C-\" has generated an error for a long time, it doesn't seem like + it will be too much of a problem. + Fixes from Koichi Murase + - rl_invoking_keyseqs_in_map: make sure to consistently output + backslash as `\\' instead of producing `\C-\' + Fixes from Koichi Murase diff --git a/builtins/printf.def b/builtins/printf.def index 64d1260bb..f47781317 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -220,7 +220,7 @@ static floatmax_t getfloatmax __P((void)); static intmax_t asciicode __P((void)); -static WORD_LIST *garglist; +static WORD_LIST *garglist, *orig_arglist; static int retval; static int conversion_error; @@ -311,7 +311,7 @@ printf_builtin (list) format = list->word->word; tw = 0; - garglist = list->next; + garglist = orig_arglist = list->next; /* If the format string is empty after preprocessing, return immediately. */ if (format == 0 || *format == 0) diff --git a/general.h b/general.h index ada4da67b..28b45cabf 100644 --- a/general.h +++ b/general.h @@ -308,7 +308,6 @@ extern char *get_posix_options __P((char *)); extern void set_posix_options __P((const char *)); extern void save_posix_options __P((void)); -#define save_posix_options() saved_posix_vars = get_posix_options (saved_posix_vars) #if defined (RLIMTYPE) extern RLIMTYPE string_to_rlimtype __P((char *)); diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 4faf98405..9eb484d98 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -509,17 +509,6 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map) return 0; } -#define ADD_NORMAL_CHAR(c) \ - do { \ - if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii) \ - { \ - array[l++] = ESC; \ - array[l++] = UNMETA (c); \ - } \ - else \ - array[l++] = (c); \ - } while (0) - /* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, an array of characters. LEN gets the final length of ARRAY. Return non-zero if there was an error parsing SEQ. */ @@ -527,64 +516,37 @@ int rl_translate_keyseq (const char *seq, char *array, int *len) { register int i, l, temp; + int has_control, has_meta; unsigned char c; - for (i = l = 0; c = seq[i]; i++) + has_control = 0; + has_meta = 0; + + /* When there are incomplete prefixes \C- or \M- (has_control || has_meta) + without base character at the end of SEQ, they are processed as the + prefixes for '\0'. + */ + for (i = l = 0; (c = seq[i]) || has_control || has_meta; i++) { - if (c == '\\') + /* Only backslashes followed by a non-null character are handled + specially. Trailing backslash (backslash followed by '\0') is + processed as a normal character. + */ + if (c == '\\' && seq[i + 1] != '\0') { c = seq[++i]; - if (c == 0) + /* Handle \C- and \M- prefixes. */ + if (c == 'C' && seq[i + 1] == '-') { - array[l++] = '\\'; /* preserve trailing backslash */ - break; + i++; + has_control = 1; + continue; } - - /* Handle \C- and \M- prefixes. */ - if ((c == 'C' || c == 'M') && seq[i + 1] == '-') + else if (c == 'M' && seq[i + 1] == '-') { - /* Handle special case of backwards define. */ - if (strncmp (&seq[i], "C-\\M-", 5) == 0) - { - array[l++] = ESC; /* ESC is meta-prefix */ - i += 5; - array[l++] = CTRL (_rl_to_upper (seq[i])); - } - else if (c == 'M') - { - i++; /* seq[i] == '-' */ - /* XXX - obey convert-meta setting, convert to key seq */ - /* XXX - doesn't yet handle \M-\C-n if convert-meta is on */ - if (_rl_convert_meta_chars_to_ascii) - { - array[l++] = ESC; /* ESC is meta-prefix */ - i++; - array[l++] = UNMETA (seq[i]); /* UNMETA just in case */ - } - else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-') - { - i += 4; - temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); - array[l++] = META (temp); - } - else - { - /* This doesn't yet handle things like \M-\a, which may - or may not have any reasonable meaning. You're - probably better off using straight octal or hex. */ - i++; - array[l++] = META (seq[i]); - } - } - else if (c == 'C') - { - i += 2; - /* Special hack for C-?... */ - array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); - } - if (seq[i] == '\0') - break; + i++; + has_meta = 1; continue; } @@ -595,34 +557,34 @@ rl_translate_keyseq (const char *seq, char *array, int *len) switch (c) { case 'a': - array[l++] = '\007'; + c = '\007'; break; case 'b': - array[l++] = '\b'; + c = '\b'; break; case 'd': - array[l++] = RUBOUT; /* readline-specific */ + c = RUBOUT; /* readline-specific */ break; case 'e': - array[l++] = ESC; + c = ESC; break; case 'f': - array[l++] = '\f'; + c = '\f'; break; case 'n': - array[l++] = NEWLINE; + c = NEWLINE; break; case 'r': - array[l++] = RETURN; + c = RETURN; break; case 't': - array[l++] = TAB; + c = TAB; break; case 'v': - array[l++] = 0x0B; + c = 0x0B; break; case '\\': - array[l++] = '\\'; + c = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': @@ -631,7 +593,6 @@ rl_translate_keyseq (const char *seq, char *array, int *len) c = (c * 8) + OCTVALUE (seq[i]); i--; /* auto-increment in for loop */ c &= largest_char; - ADD_NORMAL_CHAR (c); break; case 'x': i++; @@ -641,17 +602,39 @@ rl_translate_keyseq (const char *seq, char *array, int *len) c = 'x'; i--; /* auto-increment in for loop */ c &= largest_char; - ADD_NORMAL_CHAR (c); break; default: /* backslashes before non-special chars just add the char */ c &= largest_char; - ADD_NORMAL_CHAR (c); break; /* the backslash is stripped */ } - continue; } - ADD_NORMAL_CHAR (c); + /* Process \C- and \M- flags */ + if (has_control) + { + /* Special treatment for C-? */ + c = (c == '?') ? RUBOUT : CTRL (_rl_to_upper (c)); + has_control = 0; + } + if (has_meta) + { + c = META (c); + has_meta = 0; + } + + /* If convert-meta is turned on, convert a meta char to a key sequence */ + if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii) + { + array[l++] = ESC; /* ESC is meta-prefix */ + array[l++] = UNMETA (c); + } + else + array[l++] = (c); + + /* Null characters may be processed for incomplete prefixes at the end of + sequence */ + if (seq[i] == '\0') + break; } *len = l; @@ -2637,20 +2620,22 @@ rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map) else sprintf (keyname, "\\e"); } - else if (CTRL_CHAR (key)) - sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); - else if (key == RUBOUT) - sprintf (keyname, "\\C-?"); - else if (key == '\\' || key == '"') - { - keyname[0] = '\\'; - keyname[1] = (char) key; - keyname[2] = '\0'; - } else { - keyname[0] = (char) key; - keyname[1] = '\0'; + int c = key, l = 0; + if (CTRL_CHAR (c) || c == RUBOUT) + { + keyname[l++] = '\\'; + keyname[l++] = 'C'; + keyname[l++] = '-'; + c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c)); + } + + if (c == '\\' || c == '"') + keyname[l++] = '\\'; + + keyname[l++] = (char) c; + keyname[l++] = '\0'; } strcat (keyname, seqs[i]); diff --git a/lib/readline/display.c b/lib/readline/display.c index 147bf1027..67ef84a9c 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1663,8 +1663,11 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv _rl_last_v_pos++; /* 5a. If the number of screen positions doesn't match, punt - and do a dumb update. */ - if (newwidth != oldwidth) + and do a dumb update. + 5b. If the number of bytes is greater in the new line than + the old, do a dumb update, because there is no guarantee we + can extend the old line enough to fit the new bytes. */ + if (newwidth != oldwidth || newbytes > oldbytes) { oe = old + omax; ne = new + nmax; @@ -1680,13 +1683,15 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv memmove call to copy the trailing NUL. */ /* (strlen(old+oldbytes) == (omax - oldbytes - 1)) */ - memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1); + /* Don't bother trying to fit the bytes if the number of bytes + doesn't change. */ + if (oldbytes != newbytes) + memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1); memcpy (old, new, newbytes); j = newbytes - oldbytes; - omax += j; /* Fix up indices if we copy data from one line to another */ - for (i = current_line+1; i <= inv_botlin+1; i++) + for (i = current_line+1; j != 0 && i <= inv_botlin+1 && i <=_rl_vis_botlin+1; i++) vis_lbreaks[i] += j; } } diff --git a/lib/readline/kill.c b/lib/readline/kill.c index 6a2e0c6a5..2bea7d05b 100644 --- a/lib/readline/kill.c +++ b/lib/readline/kill.c @@ -408,6 +408,7 @@ region_kill_internal (int delete) _rl_copy_to_kill_ring (text, rl_point < rl_mark); } + _rl_fix_point (1); _rl_last_command_was_kill++; return 0; } @@ -427,8 +428,8 @@ rl_kill_region (int count, int key) npoint = (rl_point < rl_mark) ? rl_point : rl_mark; r = region_kill_internal (1); - _rl_fix_point (1); rl_point = npoint; + _rl_fix_point (1); return r; } diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index 1a99a5ae3..f1c614748 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -387,6 +387,7 @@ extern void _rl_set_cursor PARAMS((int, int)); /* text.c */ extern void _rl_fix_point PARAMS((int)); +extern void _rl_fix_mark PARAMS((void)); extern int _rl_replace_text PARAMS((const char *, int, int)); extern int _rl_forward_char_internal PARAMS((int)); extern int _rl_backward_char_internal PARAMS((int)); diff --git a/lib/readline/text.c b/lib/readline/text.c index 5fe808921..7bd35d1e3 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -154,6 +154,7 @@ rl_delete_text (int from, int to) rl_end -= diff; rl_line_buffer[rl_end] = '\0'; + _rl_fix_mark (); return (diff); } @@ -176,6 +177,12 @@ _rl_fix_point (int fix_mark_too) if (fix_mark_too) _RL_FIX_POINT (rl_mark); } + +void +_rl_fix_mark (void) +{ + _RL_FIX_POINT (rl_mark); +} #undef _RL_FIX_POINT /* Replace the contents of the line buffer between START and END with @@ -1487,7 +1494,9 @@ rl_change_case (int count, int op) } else if (m < mlen) { - rl_extend_line_buffer (mlen - m + 1); + rl_extend_line_buffer (rl_end + mlen + (e - s) - m + 2); + s = rl_line_buffer + start; /* have to redo this */ + e = rl_line_buffer + rl_end; memmove (s + mlen, s + m, (e - s) - m); memcpy (s, mb, mlen); next += mlen - m; /* next char changes */ diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index 53eed15ee..035fb644e 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -1,7 +1,7 @@ /* vi_mode.c -- A vi emulation mode for Bash. Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */ -/* Copyright (C) 1987-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. @@ -837,6 +837,12 @@ _rl_vi_save_replace (void) start = end - vi_replace_count + 1; len = vi_replace_count + 1; + if (start < 0) + { + len = end + 1; + start = 0; + } + vi_save_insert_buffer (start, len); } @@ -2104,7 +2110,7 @@ rl_vi_overstrike_delete (int count, int key) s = rl_point; if (rl_do_undo ()) - vi_replace_count--; + vi_replace_count--; /* XXX */ if (rl_point == s) rl_backward_char (1, key); @@ -2119,6 +2125,39 @@ rl_vi_overstrike_delete (int count, int key) return (0); } +static int +rl_vi_overstrike_kill_line (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_unix_line_discard (count, key); + vi_replace_count -= end - rl_end; + return r; +} + +static int +rl_vi_overstrike_kill_word (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_vi_unix_word_rubout (count, key); + vi_replace_count -= end - rl_end; + return r; +} + +static int +rl_vi_overstrike_yank (int count, int key) +{ + int r, end; + + end = rl_end; + r = rl_yank (count, key); + vi_replace_count += rl_end - end; + return r; +} + /* Read bracketed paste mode pasted text and insert it in overwrite mode */ static int rl_vi_overstrike_bracketed_paste (int count, int key) @@ -2179,6 +2218,21 @@ rl_vi_replace (int count, int key) vi_insertion_keymap[CTRL ('H')].function == rl_rubout) vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete; + /* Same for ^U and unix-line-discard. */ + if (vi_insertion_keymap[CTRL ('U')].type == ISFUNC && + vi_insertion_keymap[CTRL ('U')].function == rl_unix_line_discard) + vi_replace_map[CTRL ('U')].function = rl_vi_overstrike_kill_line; + + /* And for ^W and unix-word-rubout. */ + if (vi_insertion_keymap[CTRL ('W')].type == ISFUNC && + vi_insertion_keymap[CTRL ('W')].function == rl_vi_unix_word_rubout) + vi_replace_map[CTRL ('W')].function = rl_vi_overstrike_kill_word; + + /* And finally for ^Y and yank. */ + if (vi_insertion_keymap[CTRL ('Y')].type == ISFUNC && + vi_insertion_keymap[CTRL ('Y')].function == rl_yank) + vi_replace_map[CTRL ('Y')].function = rl_vi_overstrike_yank; + /* Make sure this is the value we need. */ vi_replace_map[ANYOTHERKEY].type = ISFUNC; vi_replace_map[ANYOTHERKEY].function = (rl_command_func_t *)NULL; @@ -2281,6 +2335,7 @@ _rl_vi_goto_mark (void) if (ch == '`') { rl_point = rl_mark; + _rl_fix_point (1); return 0; } else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */ @@ -2296,6 +2351,7 @@ _rl_vi_goto_mark (void) return 1; } rl_point = vi_mark_chars[ch]; + _rl_fix_point (1); return 0; } diff --git a/variables.c b/variables.c index acef9373d..276b3d44c 100644 --- a/variables.c +++ b/variables.c @@ -3789,7 +3789,13 @@ assign_in_env (word, flags) array_needs_making = 1; if (flags) - stupidly_hack_special_variables (newname); + { +#if 0 /* TAG:bash-5.1 from Martijn Dekker */ + if (STREQ (newname, "POSIXLY_CORRECT") || STREQ (newname, "POSIX_PEDANDTIC")) + save_posix_options (); /* XXX one level of saving right now */ +#endif + stupidly_hack_special_variables (newname); + } if (echo_command_at_execute) /* The Korn shell prints the `+ ' in front of assignment statements,