lineedit: fix column display for wide and combining chars in TAB completion
authorTomas Heinrich <heinrich.tomas@gmail.com>
Tue, 1 Jun 2010 06:33:18 +0000 (08:33 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 1 Jun 2010 06:33:18 +0000 (08:33 +0200)
function                                             old     new   delta
unicode_strwidth                                       -      20     +20
read_line_input                                     4945    4953      +8
unicode_strlen                                        31       -     -31
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 28/-31)             Total: -3 bytes

Signed-off-by: Tomas Heinrich <heinrich.tomas@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/unicode.h
libbb/lineedit.c
libbb/unicode.c

index eaf67c833faa8d7b6cfcc58e7f61dc78587c9610..e9e2bd14a7dda49de36c90714fd8b84c92762c05 100644 (file)
@@ -23,7 +23,8 @@ enum {
 
 #if !ENABLE_UNICODE_SUPPORT
 
-# define unicode_strlen(string) strlen(string)
+# define unicode_strlen(string)   strlen(string)
+# define unicode_strwidth(string) strlen(string)
 # define unicode_status UNICODE_OFF
 # define init_unicode() ((void)0)
 
@@ -49,7 +50,10 @@ enum {
 #  define ENABLE_UNICODE_BIDI_SUPPORT 0
 # endif
 
+/* Number of unicode chars. Falls back to strlen() on invalid unicode */
 size_t FAST_FUNC unicode_strlen(const char *string);
+/* Width on terminal */
+size_t FAST_FUNC unicode_strwidth(const char *string);
 enum {
        UNI_FLAG_PAD = (1 << 0),
 };
index 18664b8c1293c2b17f203758c7b9c48d3634ead0..8a2ea79747cca3f7bb795c42da0bdaac023236f4 100644 (file)
@@ -992,7 +992,7 @@ static void showfiles(void)
 
        /* find the longest file name - use that as the column width */
        for (row = 0; row < nrows; row++) {
-               l = unicode_strlen(matches[row]);
+               l = unicode_strwidth(matches[row]);
                if (column_width < l)
                        column_width = l;
        }
@@ -1012,10 +1012,13 @@ static void showfiles(void)
 
                for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) {
                        printf("%s%-*s", matches[n],
-                               (int)(column_width - unicode_strlen(matches[n])), ""
+                               (int)(column_width - unicode_strwidth(matches[n])), ""
                        );
                }
-               puts(matches[n]);
+               if (ENABLE_UNICODE_SUPPORT)
+                       puts(printable_string(NULL, matches[n]));
+               else
+                       puts(matches[n]);
        }
 }
 
index b2c28239b692775dd08588b2ace681bd43e6e9da..d6fcf7a43cb2e67ebe9457482c7fb062afad3282 100644 (file)
@@ -25,13 +25,15 @@ uint8_t unicode_status;
 
 void FAST_FUNC init_unicode(void)
 {
-       /* In unicode, this is a one character string */
        static const char unicode_0x394[] = { 0xce, 0x94, 0 };
+       size_t width;
 
        if (unicode_status != UNICODE_UNKNOWN)
                return;
-
-       unicode_status = unicode_strlen(unicode_0x394) == 1 ? UNICODE_ON : UNICODE_OFF;
+       /* In unicode, this is a one character string */
+// can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
+       width = mbstowcs(NULL, unicode_0x394, INT_MAX);
+       unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF);
 }
 
 #else
@@ -954,6 +956,7 @@ int FAST_FUNC unicode_bidi_is_neutral_wchar(wint_t wc)
 
 /* The rest is mostly same for libc and for "homegrown" support */
 
+#if 0 // UNUSED
 size_t FAST_FUNC unicode_strlen(const char *string)
 {
        size_t width = mbstowcs(NULL, string, INT_MAX);
@@ -961,6 +964,14 @@ size_t FAST_FUNC unicode_strlen(const char *string)
                return strlen(string);
        return width;
 }
+#endif
+
+size_t FAST_FUNC unicode_strwidth(const char *string)
+{
+       uni_stat_t uni_stat;
+       printable_string(&uni_stat, string);
+       return uni_stat.unicode_width;
+}
 
 static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
 {