lineedit: fixes for CONFIG_UNICODE_USING_LOCALE=y
No binary (build failed)
—
(log yok)
| @@ -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 | |
| @@ -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 | |