aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbb/lineedit.c107
-rw-r--r--libbb/unicode.c7
2 files changed, 66 insertions, 48 deletions
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