commit bash-20040113 snapshot
authorChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 17:53:26 +0000 (12:53 -0500)
committerChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 17:53:26 +0000 (12:53 -0500)
CHANGES
CWRU/CWRU.chlog
autom4te.cache/requests
lib/readline/display.c
lib/readline/mbutil.c
locale.c
tests/RUN-ONE-TEST

diff --git a/CHANGES b/CHANGES
index 0c4b8ae..673b765 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -83,6 +83,11 @@ e.  Fixed a bug that could cause incorrect filename quoting when
 f.  Fixed a bug in redisplay triggered when the prompt string contains
     invisible characters.
 
+g.  Fixed some display (and other) bugs encountered in multibyte locales
+    when a non-ascii character was the last character on a line.
+
+h.  Fixed some display bugs caused by multibyte characters in prompt strings.
+
 3.  New Features in Bash
 
 a.  printf builtin understands two new escape sequences:  \" and \?.
index 4f54714..fb44ae1 100644 (file)
@@ -8964,3 +8964,33 @@ subst.c
          avoids the N**2 behavior of having to count from the beginning
          of the string each time you want to back up one character.  Changes
          to remove_pattern and match_pattern
+
+                                  1/12
+                                  ----
+lib/readline/display.c
+       - make expand_prompt count multbyte characters in the prompt string
+         by using _rl_find_next_mbchar (and copying possibly more than one
+         byte) instead of a simple increment and single byte copy
+
+                                  1/13
+                                  ----
+lib/readline/display.c
+       - expand_prompt takes a new reference argument -- it returns
+         the actual count of (possibly multibyte) characters displayed
+         on the screen
+       - don't short-circuit in expand_prompt unless we're not going to
+         be using any multibyte characters
+       - change calls  to expand_prompt to pass an argument for the
+         number of physical characters the prompt occupies
+         (prompt_physical_chars)
+       - initialize `lpos' (the physical cursor position) from
+         prompt_physical_chars in rl_redisplay
+
+lib/readline/mbutil.c
+       - in _rl_find_prev_mbchar_internal, if mbrtowc returns -1 or -2, and
+         we assume that the character is a single-byte char, make sure we
+         update `prev' so it doesn't get lost.  Fixes problems encountered
+         when a non-ascii char is the last char on the line and we're moving
+         back past it with ^B, and other display problems caused by the same
+         situation
+
index b8bdf11..cca258e 100644 (file)
                         'configure.in'
                       ],
                       {
-                        'AC_FUNC_FORK' => 1,
-                        'AC_SUBST' => 1,
-                        'AC_CONFIG_AUX_DIR' => 1,
-                        'AC_CANONICAL_HOST' => 1,
-                        'AC_HEADER_MAJOR' => 1,
-                        'AC_C_INLINE' => 1,
-                        'AC_FUNC_MALLOC' => 1,
-                        'm4_pattern_allow' => 1,
-                        'AC_FUNC_GETGROUPS' => 1,
-                        'AC_TYPE_MODE_T' => 1,
-                        'AC_FUNC_FSEEKO' => 1,
-                        'AM_PROG_CC_C_O' => 1,
                         'AC_STRUCT_ST_BLOCKS' => 1,
-                        'AC_FUNC_GETLOADAVG' => 1,
-                        'AC_C_VOLATILE' => 1,
-                        'AC_FUNC_LSTAT' => 1,
-                        'AC_FUNC_GETPGRP' => 1,
-                        'AC_PROG_AWK' => 1,
-                        'AC_FUNC_SETPGRP' => 1,
-                        'AC_CONFIG_SUBDIRS' => 1,
-                        'AC_FUNC_OBSTACK' => 1,
-                        'AC_FUNC_MMAP' => 1,
-                        'AM_MAINTAINER_MODE' => 1,
-                        'AC_FUNC_MEMCMP' => 1,
-                        'AM_AUTOMAKE_VERSION' => 1,
-                        'AC_FUNC_STRCOLL' => 1,
+                        'AC_FUNC_CLOSEDIR_VOID' => 1,
                         'AC_CHECK_TYPES' => 1,
-                        'AC_HEADER_DIRENT' => 1,
-                        'AC_CHECK_MEMBERS' => 1,
-                        'm4_include' => 1,
-                        'AC_TYPE_SIGNAL' => 1,
-                        'AC_TYPE_PID_T' => 1,
-                        'AC_FUNC_SETVBUF_REVERSED' => 1,
-                        'AC_CHECK_FUNCS' => 1,
-                        'AC_CHECK_LIB' => 1,
-                        'AC_HEADER_STAT' => 1,
-                        'AC_PROG_LEX' => 1,
-                        'AC_TYPE_SIZE_T' => 1,
-                        'AC_HEADER_TIME' => 1,
-                        'AC_FUNC_STRTOD' => 1,
-                        'include' => 1,
-                        'AC_STRUCT_TIMEZONE' => 1,
-                        'AC_HEADER_STDC' => 1,
-                        'AC_PROG_LIBTOOL' => 1,
-                        'AM_GNU_GETTEXT' => 1,
-                        'AC_FUNC_STRFTIME' => 1,
-                        'AC_FUNC_ALLOCA' => 1,
-                        'AC_C_CONST' => 1,
-                        'AC_INIT' => 1,
-                        'AM_CONDITIONAL' => 1,
-                        'AC_LIBSOURCE' => 1,
-                        'AC_PROG_GCC_TRADITIONAL' => 1,
+                        'AC_PROG_CC' => 1,
                         'AC_TYPE_OFF_T' => 1,
-                        'AC_CHECK_HEADERS' => 1,
-                        'AC_FUNC_WAIT3' => 1,
-                        'AC_FUNC_STRERROR_R' => 1,
-                        'AC_FUNC_UTIME_NULL' => 1,
-                        'AC_PATH_X' => 1,
+                        'AC_PROG_YACC' => 1,
                         'AC_PROG_CPP' => 1,
-                        'AC_FUNC_ERROR_AT_LINE' => 1,
-                        'AC_DECL_SYS_SIGLIST' => 1,
-                        'AC_PROG_LN_S' => 1,
-                        'AC_PROG_CXX' => 1,
-                        'AC_FUNC_VPRINTF' => 1,
-                        'AC_FUNC_CHOWN' => 1,
-                        'm4_pattern_forbid' => 1,
+                        'AC_C_INLINE' => 1,
                         'AC_TYPE_UID_T' => 1,
+                        'AC_STRUCT_TM' => 1,
+                        'AC_FUNC_MKTIME' => 1,
+                        'AC_FUNC_MEMCMP' => 1,
+                        'AC_CONFIG_HEADERS' => 1,
+                        'AC_CHECK_HEADERS' => 1,
+                        'AC_HEADER_SYS_WAIT' => 1,
+                        'AC_CHECK_MEMBERS' => 1,
+                        'AC_HEADER_MAJOR' => 1,
+                        'AC_PROG_LIBTOOL' => 1,
+                        'AC_FUNC_REALLOC' => 1,
                         'AC_FUNC_MBRTOWC' => 1,
                         'AC_FUNC_SELECT_ARGTYPES' => 1,
-                        'AC_STRUCT_TM' => 1,
-                        'AC_PROG_CC' => 1,
-                        'AC_PROG_INSTALL' => 1,
-                        'AC_PROG_RANLIB' => 1,
                         'AH_OUTPUT' => 1,
-                        'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
-                        'AC_FUNC_STAT' => 1,
-                        'AC_FUNC_REALLOC' => 1,
-                        'AC_CANONICAL_SYSTEM' => 1,
+                        'AC_FUNC_MMAP' => 1,
+                        'AC_FUNC_SETVBUF_REVERSED' => 1,
+                        'AC_FUNC_ERROR_AT_LINE' => 1,
+                        'AC_FUNC_STRCOLL' => 1,
+                        'AC_C_VOLATILE' => 1,
+                        'AC_FUNC_GETPGRP' => 1,
+                        'AC_TYPE_PID_T' => 1,
+                        'm4_pattern_allow' => 1,
+                        'AC_FUNC_UTIME_NULL' => 1,
+                        'AC_PROG_RANLIB' => 1,
+                        'm4_include' => 1,
+                        'AC_FUNC_STRERROR_R' => 1,
+                        'AC_FUNC_GETMNTENT' => 1,
+                        'AC_PROG_GCC_TRADITIONAL' => 1,
+                        'AC_STRUCT_TIMEZONE' => 1,
+                        'include' => 1,
+                        'AM_AUTOMAKE_VERSION' => 1,
+                        'AC_LIBSOURCE' => 1,
+                        'AC_SUBST' => 1,
+                        'AC_CHECK_LIB' => 1,
+                        'AC_C_CONST' => 1,
+                        'AC_FUNC_VPRINTF' => 1,
+                        'AC_TYPE_SIGNAL' => 1,
+                        'AC_FUNC_GETGROUPS' => 1,
+                        'AC_CANONICAL_HOST' => 1,
+                        'AC_HEADER_STDC' => 1,
+                        'AC_FUNC_STRTOD' => 1,
+                        'AC_PROG_LEX' => 1,
+                        'AC_FUNC_OBSTACK' => 1,
+                        'AM_MAINTAINER_MODE' => 1,
+                        'AC_INIT' => 1,
+                        'AC_PROG_LN_S' => 1,
+                        'AC_FUNC_SETPGRP' => 1,
+                        'AC_CONFIG_SUBDIRS' => 1,
                         'AC_PROG_MAKE_SET' => 1,
-                        'AC_CONFIG_HEADERS' => 1,
-                        'AC_FUNC_CLOSEDIR_VOID' => 1,
+                        'AC_HEADER_TIME' => 1,
+                        'AC_FUNC_FORK' => 1,
+                        'AC_PROG_AWK' => 1,
+                        'AC_FUNC_CHOWN' => 1,
                         'AC_FUNC_STRNLEN' => 1,
-                        'AC_HEADER_SYS_WAIT' => 1,
                         'AM_INIT_AUTOMAKE' => 1,
+                        'AC_FUNC_ALLOCA' => 1,
+                        'AC_DEFINE_TRACE_LITERAL' => 1,
+                        'AC_FUNC_STRFTIME' => 1,
+                        'AC_PATH_X' => 1,
                         'AC_REPLACE_FNMATCH' => 1,
+                        'AC_FUNC_WAIT3' => 1,
+                        'm4_pattern_forbid' => 1,
+                        'AC_CHECK_FUNCS' => 1,
+                        'AC_FUNC_STAT' => 1,
+                        'AC_CONFIG_AUX_DIR' => 1,
+                        'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
+                        'AC_FUNC_MALLOC' => 1,
+                        'AC_FUNC_GETLOADAVG' => 1,
+                        'AC_PROG_INSTALL' => 1,
+                        'AC_HEADER_DIRENT' => 1,
+                        'AM_PROG_CC_C_O' => 1,
+                        'AC_TYPE_SIZE_T' => 1,
+                        'AC_FUNC_FSEEKO' => 1,
+                        'AC_TYPE_MODE_T' => 1,
+                        'AC_DECL_SYS_SIGLIST' => 1,
+                        'AM_GNU_GETTEXT' => 1,
+                        'AM_CONDITIONAL' => 1,
                         'AC_CONFIG_FILES' => 1,
-                        'AC_PROG_YACC' => 1,
-                        'AC_FUNC_GETMNTENT' => 1,
-                        'AC_DEFINE_TRACE_LITERAL' => 1,
-                        'AC_FUNC_MKTIME' => 1
+                        'AC_FUNC_LSTAT' => 1,
+                        'AC_CANONICAL_SYSTEM' => 1,
+                        'AC_HEADER_STAT' => 1,
+                        'AC_PROG_CXX' => 1
                       }
                     ], 'Request' )
            );
index 3ad1226..28f69b5 100644 (file)
@@ -178,12 +178,15 @@ static int prompt_invis_chars_first_line;
 
 static int prompt_last_screen_line;
 
+static int prompt_physical_chars;
+
 /* Expand the prompt string S and return the number of visible
    characters in *LP, if LP is not null.  This is currently more-or-less
    a placeholder for expansion.  LIP, if non-null is a place to store the
    index of the last invisible character in the returned string. NIFLP,
    if non-zero, is a place to store the number of invisible characters in
-   the first prompt line. */
+   the first prompt line.  The previous are used as byte counts -- indexes
+   into a character buffer. */
 
 /* Current implementation:
        \001 (^A) start non-visible characters
@@ -193,19 +196,25 @@ static int prompt_last_screen_line;
    \002 are assumed to be `visible'. */        
 
 static char *
-expand_prompt (pmt, lp, lip, niflp)
+expand_prompt (pmt, lp, lip, niflp, vlp)
      char *pmt;
-     int *lp, *lip, *niflp;
+     int *lp, *lip, *niflp, *vlp;
 {
   char *r, *ret, *p;
-  int l, rl, last, ignoring, ninvis, invfl;
+  int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
 
   /* Short-circuit if we can. */
-  if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
+  if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
     {
       r = savestring (pmt);
       if (lp)
        *lp = strlen (r);
+      if (lip)
+       *lip = 0;
+      if (niflp)
+       *niflp = 0;
+      if (vlp)
+       *vlp = lp ? *lp : strlen (r);
       return r;
     }
 
@@ -214,7 +223,7 @@ expand_prompt (pmt, lp, lip, niflp)
 
   invfl = 0;   /* invisible chars in first line of prompt */
 
-  for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
+  for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
     {
       /* This code strips the invisible character string markers
         RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
@@ -231,13 +240,35 @@ expand_prompt (pmt, lp, lip, niflp)
        }
       else
        {
-         *r++ = *p;
-         if (!ignoring)
-           rl++;
+#if defined (HANDLE_MULTIBYTE)
+         if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+           {
+             pind = p - pmt;
+             ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
+             l = ind - pind;
+             while (l--)
+               *r++ = *p++;
+             if (!ignoring)
+               rl += ind - pind;
+             else
+               ninvis += ind - pind;
+             p--;                      /* compensate for later increment */
+           }
          else
-           ninvis++;
-         if (rl == _rl_screenwidth)
+#endif
+           {
+             *r++ = *p;
+             if (!ignoring)
+               rl++;                   /* visible length byte counter */
+             else
+               ninvis++;               /* invisible chars byte counter */
+           }
+
+         if (rl >= _rl_screenwidth)
            invfl = ninvis;
+
+         if (ignoring == 0)
+           physchars++;
        }
     }
 
@@ -251,6 +282,8 @@ expand_prompt (pmt, lp, lip, niflp)
     *lip = last;
   if (niflp)
     *niflp = invfl;
+  if  (vlp)
+    *vlp = physchars;
   return ret;
 }
 
@@ -262,7 +295,7 @@ _rl_strip_prompt (pmt)
 {
   char *ret;
 
-  ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
+  ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
   return ret;
 }
 
@@ -306,7 +339,8 @@ rl_expand_prompt (prompt)
       /* The prompt is only one logical line, though it might wrap. */
       local_prompt = expand_prompt (prompt, &prompt_visible_length,
                                            &prompt_last_invisible,
-                                           &prompt_invis_chars_first_line);
+                                           &prompt_invis_chars_first_line,
+                                           &prompt_physical_chars);
       local_prompt_prefix = (char *)0;
       return (prompt_visible_length);
     }
@@ -316,13 +350,15 @@ rl_expand_prompt (prompt)
       t = ++p;
       local_prompt = expand_prompt (p, &prompt_visible_length,
                                       &prompt_last_invisible,
+                                      (int *)NULL,
                                       (int *)NULL);
       c = *t; *t = '\0';
       /* The portion of the prompt string up to and including the
         final newline is now null-terminated. */
       local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
                                                   (int *)NULL,
-                                                  &prompt_invis_chars_first_line);
+                                                  &prompt_invis_chars_first_line,
+                                                  &prompt_physical_chars);
       *t = c;
       return (prompt_prefix_length);
     }
@@ -381,7 +417,7 @@ rl_redisplay ()
   register int in, out, c, linenum, cursor_linenum;
   register char *line;
   int c_pos, inv_botlin, lb_botlin, lb_linenum;
-  int newlines, lpos, temp;
+  int newlines, lpos, temp, modmark;
   char *prompt_this_line;
 #if defined (HANDLE_MULTIBYTE)
   wchar_t wc;
@@ -411,10 +447,12 @@ rl_redisplay ()
 
   /* Mark the line as modified or not.  We only do this for history
      lines. */
+  modmark = 0;
   if (_rl_mark_modified_lines && current_history () && rl_undo_list)
     {
       line[out++] = '*';
       line[out] = '\0';
+      modmark = 1;
     }
 
   /* If someone thought that the redisplay was handled, but the currently
@@ -527,7 +565,12 @@ rl_redisplay ()
 
   /* inv_lbreaks[i] is where line i starts in the buffer. */
   inv_lbreaks[newlines = 0] = 0;
+#if 0
   lpos = out - wrap_offset;
+#else
+  lpos = prompt_physical_chars + modmark;
+#endif
+
 #if defined (HANDLE_MULTIBYTE)
   memset (_rl_wrapped_line, 0, vis_lbsize);
 #endif
@@ -2032,7 +2075,7 @@ redraw_prompt (t)
      char *t;
 {
   char *oldp, *oldl, *oldlprefix;
-  int oldlen, oldlast, oldplen, oldninvis;
+  int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
 
   /* Geez, I should make this a struct. */
   oldp = rl_display_prompt;
@@ -2042,11 +2085,13 @@ redraw_prompt (t)
   oldplen = prompt_prefix_length;
   oldlast = prompt_last_invisible;
   oldninvis = prompt_invis_chars_first_line;
+  oldphyschars = prompt_physical_chars;
 
   rl_display_prompt = t;
   local_prompt = expand_prompt (t, &prompt_visible_length,
                                   &prompt_last_invisible,
-                                  &prompt_invis_chars_first_line);
+                                  &prompt_invis_chars_first_line,
+                                  &prompt_physical_chars);
   local_prompt_prefix = (char *)NULL;
   rl_forced_update_display ();
 
@@ -2057,6 +2102,7 @@ redraw_prompt (t)
   prompt_prefix_length = oldplen;
   prompt_last_invisible = oldlast;
   prompt_invis_chars_first_line = oldninvis;
+  prompt_physical_chars = oldphyschars;
 }
       
 /* Redisplay the current line after a SIGWINCH is received. */
index 6451254..597638b 100644 (file)
@@ -168,6 +168,10 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
          /* clear the state of the byte sequence, because
             in this case effect of mbstate is undefined  */
          memset(&ps, 0, sizeof (mbstate_t));
+
+         /* Since we're assuming that this byte represents a single
+            non-zero-width character, don't forget about it. */
+         prev = point;
        }
       else if (MB_NULLWCH (tmp))
        break;                  /* Found '\0' char.  Can this happen? */
index cbb790a..dbd2372 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -51,6 +51,8 @@ static char *lc_all;
    categories */
 static char *lang;
 
+/* Called to reset all of the locale variables to their appropriate values
+   if (and only if) LC_ALL has not been assigned a value. */
 static int reset_locale_vars __P((void));
 
 static void locale_setblanks __P((void));
@@ -256,6 +258,9 @@ get_locale_var (var)
   return (locale);
 }
 
+/* Called to reset all of the locale variables to their appropriate values
+   if (and only if) LC_ALL has not been assigned a value.  DO NOT CALL THIS
+   IF LC_ALL HAS BEEN ASSIGNED A VALUE. */
 static int
 reset_locale_vars ()
 {
index 72ec06a..3efcf32 100755 (executable)
@@ -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