diff -urN bash-2.05b/lib/readline/complete.c bash/lib/readline/complete.c --- bash-2.05b/lib/readline/complete.c 2002-05-07 21:39:32.000000000 +0200 +++ bash/lib/readline/complete.c 2003-05-10 00:37:29.000000000 +0200 @@ -105,6 +105,7 @@ static int get_y_or_n PARAMS((int)); static int _rl_internal_pager PARAMS((int)); static char *printable_part PARAMS((char *)); +static int filename_width PARAMS((const char *)); static int print_filename PARAMS((char *, char *)); static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int)); @@ -520,53 +521,132 @@ return ++temp; } +/* Compute width of STRING on screen, as printed by print_filename (). */ +static int +filename_width (string) + const char *string; +{ + int width, pos; +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps = {0}; + int left; + + left = strlen (string) + 1; +#endif + width = 0; + pos = 0; + while (string[pos] != 0) + { + if (CTRL_CHAR (*string)) + { + width += 2; + pos++; + } + else if (*string == RUBOUT) + { + width += 2; + pos++; + } + else + { +#if defined (HANDLE_MULTIBYTE) + size_t char_len; + wchar_t wc; + + char_len = mbrtowc (&wc, string + pos, left - pos, &ps); + if (char_len == (size_t)-1 || char_len == (size_t)-2) + { + width++; + pos++; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (char_len == 0) + break; + else + { + int w; + + pos += char_len; + w = wcwidth (wc); + width += (w >= 0) ? w : 1; + } +#else + width++; + pos++; +#endif + } + } + return width; +} + /* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we are using it, check for and output a single character for `special' filenames. Return the number of characters we output. */ - -#define PUTX(c) \ - do { \ - if (CTRL_CHAR (c)) \ - { \ - putc ('^', rl_outstream); \ - putc (UNCTRL (c), rl_outstream); \ - printed_len += 2; \ - } \ - else if (c == RUBOUT) \ - { \ - putc ('^', rl_outstream); \ - putc ('?', rl_outstream); \ - printed_len += 2; \ - } \ - else \ - { \ - putc (c, rl_outstream); \ - printed_len++; \ - } \ - } while (0) - static int print_filename (to_print, full_pathname) char *to_print, *full_pathname; { int printed_len = 0; -#if !defined (VISIBLE_STATS) char *s; - - for (s = to_print; *s; s++) - { - PUTX (*s); - } -#else - char *s, c, *new_full_pathname; +#if defined (VISIBLE_STATS) + char c, *new_full_pathname; int extension_char, slen, tlen; +#endif +#if defined (HANDLE_MULTIBYTE) + mbstate_t ps = {0}; + char *end; - for (s = to_print; *s; s++) + end = to_print + strlen (to_print) + 1; +#endif + + s = to_print; + while (*s) { - PUTX (*s); + if (CTRL_CHAR (*s)) + { + putc ('^', rl_outstream); + putc (UNCTRL (*s), rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else if (*s == RUBOUT) + { + putc ('^', rl_outstream); + putc ('?', rl_outstream); + printed_len += 2; + s++; +#if defined (HANDLE_MULTIBYTE) + memset (&ps, 0, sizeof (mbstate_t)); +#endif + } + else + { +#if defined (HANDLE_MULTIBYTE) + size_t tmp; + + tmp = mbrlen (s, end - s, &ps); + if (tmp == (size_t)-1 || tmp == (size_t)-2) + { + tmp = 1; + memset (&ps, 0, sizeof (mbstate_t)); + } + else if (tmp == 0) + break; + fwrite (s, 1, tmp, rl_outstream); + s += tmp; +#else + putc (*s, rl_outstream); + s++; +#endif + printed_len++; + } } - if (rl_filename_completion_desired && rl_visible_stats) +#if defined (VISIBLE_STATS) + if (rl_filename_completion_desired && rl_visible_stats) { /* If to_print != full_pathname, to_print is the basename of the path passed. In this case, we try to expand the directory @@ -1203,7 +1283,7 @@ for (max = 0, i = 1; matches[i]; i++) { temp = printable_part (matches[i]); - len = strlen (temp); + len = filename_width (temp); if (len > max) max = len;