]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20200124 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 27 Jan 2020 14:25:05 +0000 (09:25 -0500)
committerChet Ramey <chet.ramey@case.edu>
Mon, 27 Jan 2020 14:25:05 +0000 (09:25 -0500)
CWRU/CWRU.chlog
builtins/printf.def
general.h
lib/readline/bind.c
lib/readline/display.c
lib/readline/kill.c
lib/readline/rlprivate.h
lib/readline/text.c
lib/readline/vi_mode.c
variables.c

index 5cfbebdde9a7989ee1663f664e42f9904d96aef4..a841242dfc798414c93031219e0abb97e266d8a9 100644 (file)
@@ -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 <myoga.murase@gmail.com>
+       - rl_invoking_keyseqs_in_map: make sure to consistently output
+         backslash as `\\' instead of producing `\C-\'
+         Fixes from Koichi Murase <myoga.murase@gmail.com>
index 64d1260bb211f09dd5a345ecfe94aa164c920b87..f477813178acd804ce659c41e34802edd0dcd7c6 100644 (file)
@@ -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)
index ada4da67bf6a85fa83b0996642ef4e2cd540302f..28b45cabfde0fc18834977bb8eb1b884f48eb703 100644 (file)
--- 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 *));
index 4faf984058eab14be2b0cc3896b0fb910151c403..9eb484d9899abfc5d2ad602c396d776699218c44 100644 (file)
@@ -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]);
index 147bf102782344b33b1db14b3876e0a8a4ab387d..67ef84a9c8cc935e6da23eb92fc7c0c98742f401 100644 (file)
@@ -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;
                }
            }
index 6a2e0c6a59500eaf8a9203cd5abff004497f2e29..2bea7d05b25dc6dba301c5cc9e8fa30db1d98f8e 100644 (file)
@@ -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;
 }
 
index 1a99a5ae33700d158ff6411ce936b8f775c65862..f1c6147484bc1d093c5d627df12acc13c3d47b69 100644 (file)
@@ -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));
index 5fe8089214c5c26be03ae2f8d7c2e8db42ee449c..7bd35d1e352a8f93b5bef67fac00bcff6e5fb828 100644 (file)
@@ -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 */
index 53eed15ee119163a998bea435c02d29514271365..035fb644ee17e27281f391f6155f363957b33dcc 100644 (file)
@@ -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;
 }
 
index acef9373d409559e306b32ed946f6a9188e08df2..276b3d44ca66982c38891fbdd73afd9d3e43a39e 100644 (file)
@@ -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,