lineedit: fixes for CONFIG_UNICODE_USING_LOCALE=y
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 27 Mar 2011 00:18:07 +0000 (01:18 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 27 Mar 2011 00:18:07 +0000 (01:18 +0100)
function                                             old     new   delta
load_string                                           45      91     +46
save_string                                           40      82     +42
reinit_unicode                                        34      61     +27
BB_PUTCHAR                                            97     120     +23
init_unicode                                          17      37     +20
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/0 up/down: 158/0)             Total: 158 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
libbb/lineedit.c
libbb/unicode.c

index afd28b75ccb6758e929afd0f5ea803797fa126a8..b7a2b31dc3dfa28887aaeda50cde76b1a31563a3 100644 (file)
@@ -204,65 +204,82 @@ static void deinit_S(void)
 #if ENABLE_UNICODE_SUPPORT
 static size_t load_string(const char *src, int maxsize)
 {
-       ssize_t len = mbstowcs(command_ps, src, maxsize - 1);
-       if (len < 0)
-               len = 0;
-       command_ps[len] = BB_NUL;
-       return len;
+       if (unicode_status == UNICODE_ON) {
+               ssize_t len = mbstowcs(command_ps, src, maxsize - 1);
+               if (len < 0)
+                       len = 0;
+               command_ps[len] = BB_NUL;
+               return len;
+       } else {
+               unsigned i = 0;
+               while ((command_ps[i] = src[i]) != 0)
+                       i++;
+               return i;
+       }
 }
 static unsigned save_string(char *dst, unsigned maxsize)
 {
+       if (unicode_status == UNICODE_ON) {
 # if !ENABLE_UNICODE_PRESERVE_BROKEN
-       ssize_t len = wcstombs(dst, command_ps, maxsize - 1);
-       if (len < 0)
-               len = 0;
-       dst[len] = '\0';
-       return len;
+               ssize_t len = wcstombs(dst, command_ps, maxsize - 1);
+               if (len < 0)
+                       len = 0;
+               dst[len] = '\0';
+               return len;
 # else
-       unsigned dstpos = 0;
-       unsigned srcpos = 0;
+               unsigned dstpos = 0;
+               unsigned srcpos = 0;
 
-       maxsize--;
-       while (dstpos < maxsize) {
-               wchar_t wc;
-               int n = srcpos;
+               maxsize--;
+               while (dstpos < maxsize) {
+                       wchar_t wc;
+                       int n = srcpos;
 
-               /* Convert up to 1st invalid byte (or up to end) */
-               while ((wc = command_ps[srcpos]) != BB_NUL
-                   && !unicode_is_raw_byte(wc)
-               ) {
+                       /* Convert up to 1st invalid byte (or up to end) */
+                       while ((wc = command_ps[srcpos]) != BB_NUL
+                           && !unicode_is_raw_byte(wc)
+                       ) {
+                               srcpos++;
+                       }
+                       command_ps[srcpos] = BB_NUL;
+                       n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos);
+                       if (n < 0) /* should not happen */
+                               break;
+                       dstpos += n;
+                       if (wc == BB_NUL) /* usually is */
+                               break;
+
+                       /* We do have invalid byte here! */
+                       command_ps[srcpos] = wc; /* restore it */
                        srcpos++;
+                       if (dstpos == maxsize)
+                               break;
+                       dst[dstpos++] = (char) wc;
                }
-               command_ps[srcpos] = BB_NUL;
-               n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos);
-               if (n < 0) /* should not happen */
-                       break;
-               dstpos += n;
-               if (wc == BB_NUL) /* usually is */
-                       break;
-
-               /* We do have invalid byte here! */
-               command_ps[srcpos] = wc; /* restore it */
-               srcpos++;
-               if (dstpos == maxsize)
-                       break;
-               dst[dstpos++] = (char) wc;
-       }
-       dst[dstpos] = '\0';
-       return dstpos;
+               dst[dstpos] = '\0';
+               return dstpos;
 # endif
+       } else {
+               unsigned i = 0;
+               while ((dst[i] = command_ps[i]) != 0)
+                       i++;
+               return i;
+       }
 }
 /* I thought just fputwc(c, stdout) would work. But no... */
 static void BB_PUTCHAR(wchar_t c)
 {
-       char buf[MB_CUR_MAX + 1];
-       mbstate_t mbst = { 0 };
-       ssize_t len;
-
-       len = wcrtomb(buf, c, &mbst);
-       if (len > 0) {
-               buf[len] = '\0';
-               fputs(buf, stdout);
+       if (unicode_status == UNICODE_ON) {
+               char buf[MB_CUR_MAX + 1];
+               mbstate_t mbst = { 0 };
+               ssize_t len = wcrtomb(buf, c, &mbst);
+               if (len > 0) {
+                       buf[len] = '\0';
+                       fputs(buf, stdout);
+               }
+       } else {
+               /* In this case, c is always one byte */
+               putchar(c);
        }
 }
 # if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS
index d01efd9a25a7b55d736cea115fe7bd2cf4df9d0a..99dc1dfa6afee28e7834b0f98fdd32a0ab79b6ac 100644 (file)
@@ -23,12 +23,13 @@ uint8_t unicode_status;
 
 /* Unicode support using libc locale support. */
 
-void FAST_FUNC reinit_unicode(const char *LANG UNUSED_PARAM)
+void FAST_FUNC reinit_unicode(const char *LANG)
 {
        static const char unicode_0x394[] = { 0xce, 0x94, 0 };
        size_t width;
 
-//TODO: call setlocale(LC_ALL, LANG) here?
+//TODO: avoid repeated calls by caching last string?
+       setlocale(LC_ALL, (LANG && LANG[0]) ? LANG : "C");
 
        /* In unicode, this is a one character string */
 // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
@@ -39,7 +40,7 @@ void FAST_FUNC reinit_unicode(const char *LANG UNUSED_PARAM)
 void FAST_FUNC init_unicode(void)
 {
        if (unicode_status == UNICODE_UNKNOWN)
-               reinit_unicode(NULL /*getenv("LANG")*/);
+               reinit_unicode(getenv("LANG"));
 }
 
 #else