From: Chet Ramey Date: Sat, 3 Dec 2011 17:53:26 +0000 (-0500) Subject: commit bash-20040113 snapshot X-Git-Tag: bash-3.0-beta~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43cdcad8f4a4b33f1f2f38d690290f305e545eb9;p=thirdparty%2Fbash.git commit bash-20040113 snapshot --- diff --git a/CHANGES b/CHANGES index 0c4b8aeec..673b76570 100644 --- 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 \?. diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 4f5471486..fb44ae1a6 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + diff --git a/autom4te.cache/requests b/autom4te.cache/requests index b8bdf11a2..cca258e09 100644 --- a/autom4te.cache/requests +++ b/autom4te.cache/requests @@ -15,96 +15,96 @@ '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' ) ); diff --git a/lib/readline/display.c b/lib/readline/display.c index 3ad1226fd..28f69b5ef 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -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. */ diff --git a/lib/readline/mbutil.c b/lib/readline/mbutil.c index 645125469..597638bc9 100644 --- a/lib/readline/mbutil.c +++ b/lib/readline/mbutil.c @@ -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? */ diff --git a/locale.c b/locale.c index cbb790ab8..dbd237212 100644 --- 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 () { diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 72ec06a2c..3efcf32d6 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