diff --git a/libbb/lineedit.c b/libbb/lineedit.c index afd28b75c..b7a2b31dc 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -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 diff --git a/libbb/unicode.c b/libbb/unicode.c index d01efd9a2..99dc1dfa6 100644 --- a/libbb/unicode.c +++ b/libbb/unicode.c @@ -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