diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-27 01:18:07 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-27 01:18:07 +0100 |
| commit | 353680aa46dc91ecfd80dd19db131de7aa90bd22 (patch) | |
| tree | 05de26c20457b407fa59501708d3b31d2aa081f5 /libbb | |
| parent | 19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff) | |
| download | busybox-w32-353680aa46dc91ecfd80dd19db131de7aa90bd22.tar.gz busybox-w32-353680aa46dc91ecfd80dd19db131de7aa90bd22.tar.bz2 busybox-w32-353680aa46dc91ecfd80dd19db131de7aa90bd22.zip | |
lineedit: fixes for CONFIG_UNICODE_USING_LOCALE=y
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>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/lineedit.c | 107 | ||||
| -rw-r--r-- | libbb/unicode.c | 7 |
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) | |||
| 204 | #if ENABLE_UNICODE_SUPPORT | 204 | #if ENABLE_UNICODE_SUPPORT |
| 205 | static size_t load_string(const char *src, int maxsize) | 205 | static size_t load_string(const char *src, int maxsize) |
| 206 | { | 206 | { |
| 207 | ssize_t len = mbstowcs(command_ps, src, maxsize - 1); | 207 | if (unicode_status == UNICODE_ON) { |
| 208 | if (len < 0) | 208 | ssize_t len = mbstowcs(command_ps, src, maxsize - 1); |
| 209 | len = 0; | 209 | if (len < 0) |
| 210 | command_ps[len] = BB_NUL; | 210 | len = 0; |
| 211 | return len; | 211 | command_ps[len] = BB_NUL; |
| 212 | return len; | ||
| 213 | } else { | ||
| 214 | unsigned i = 0; | ||
| 215 | while ((command_ps[i] = src[i]) != 0) | ||
| 216 | i++; | ||
| 217 | return i; | ||
| 218 | } | ||
| 212 | } | 219 | } |
| 213 | static unsigned save_string(char *dst, unsigned maxsize) | 220 | static unsigned save_string(char *dst, unsigned maxsize) |
| 214 | { | 221 | { |
| 222 | if (unicode_status == UNICODE_ON) { | ||
| 215 | # if !ENABLE_UNICODE_PRESERVE_BROKEN | 223 | # if !ENABLE_UNICODE_PRESERVE_BROKEN |
| 216 | ssize_t len = wcstombs(dst, command_ps, maxsize - 1); | 224 | ssize_t len = wcstombs(dst, command_ps, maxsize - 1); |
| 217 | if (len < 0) | 225 | if (len < 0) |
| 218 | len = 0; | 226 | len = 0; |
| 219 | dst[len] = '\0'; | 227 | dst[len] = '\0'; |
| 220 | return len; | 228 | return len; |
| 221 | # else | 229 | # else |
| 222 | unsigned dstpos = 0; | 230 | unsigned dstpos = 0; |
| 223 | unsigned srcpos = 0; | 231 | unsigned srcpos = 0; |
| 224 | 232 | ||
| 225 | maxsize--; | 233 | maxsize--; |
| 226 | while (dstpos < maxsize) { | 234 | while (dstpos < maxsize) { |
| 227 | wchar_t wc; | 235 | wchar_t wc; |
| 228 | int n = srcpos; | 236 | int n = srcpos; |
| 229 | 237 | ||
| 230 | /* Convert up to 1st invalid byte (or up to end) */ | 238 | /* Convert up to 1st invalid byte (or up to end) */ |
| 231 | while ((wc = command_ps[srcpos]) != BB_NUL | 239 | while ((wc = command_ps[srcpos]) != BB_NUL |
| 232 | && !unicode_is_raw_byte(wc) | 240 | && !unicode_is_raw_byte(wc) |
| 233 | ) { | 241 | ) { |
| 242 | srcpos++; | ||
| 243 | } | ||
| 244 | command_ps[srcpos] = BB_NUL; | ||
| 245 | n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); | ||
| 246 | if (n < 0) /* should not happen */ | ||
| 247 | break; | ||
| 248 | dstpos += n; | ||
| 249 | if (wc == BB_NUL) /* usually is */ | ||
| 250 | break; | ||
| 251 | |||
| 252 | /* We do have invalid byte here! */ | ||
| 253 | command_ps[srcpos] = wc; /* restore it */ | ||
| 234 | srcpos++; | 254 | srcpos++; |
| 255 | if (dstpos == maxsize) | ||
| 256 | break; | ||
| 257 | dst[dstpos++] = (char) wc; | ||
| 235 | } | 258 | } |
| 236 | command_ps[srcpos] = BB_NUL; | 259 | dst[dstpos] = '\0'; |
| 237 | n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); | 260 | return dstpos; |
| 238 | if (n < 0) /* should not happen */ | ||
| 239 | break; | ||
| 240 | dstpos += n; | ||
| 241 | if (wc == BB_NUL) /* usually is */ | ||
| 242 | break; | ||
| 243 | |||
| 244 | /* We do have invalid byte here! */ | ||
| 245 | command_ps[srcpos] = wc; /* restore it */ | ||
| 246 | srcpos++; | ||
| 247 | if (dstpos == maxsize) | ||
| 248 | break; | ||
| 249 | dst[dstpos++] = (char) wc; | ||
| 250 | } | ||
| 251 | dst[dstpos] = '\0'; | ||
| 252 | return dstpos; | ||
| 253 | # endif | 261 | # endif |
| 262 | } else { | ||
| 263 | unsigned i = 0; | ||
| 264 | while ((dst[i] = command_ps[i]) != 0) | ||
| 265 | i++; | ||
| 266 | return i; | ||
| 267 | } | ||
| 254 | } | 268 | } |
| 255 | /* I thought just fputwc(c, stdout) would work. But no... */ | 269 | /* I thought just fputwc(c, stdout) would work. But no... */ |
| 256 | static void BB_PUTCHAR(wchar_t c) | 270 | static void BB_PUTCHAR(wchar_t c) |
| 257 | { | 271 | { |
| 258 | char buf[MB_CUR_MAX + 1]; | 272 | if (unicode_status == UNICODE_ON) { |
| 259 | mbstate_t mbst = { 0 }; | 273 | char buf[MB_CUR_MAX + 1]; |
| 260 | ssize_t len; | 274 | mbstate_t mbst = { 0 }; |
| 261 | 275 | ssize_t len = wcrtomb(buf, c, &mbst); | |
| 262 | len = wcrtomb(buf, c, &mbst); | 276 | if (len > 0) { |
| 263 | if (len > 0) { | 277 | buf[len] = '\0'; |
| 264 | buf[len] = '\0'; | 278 | fputs(buf, stdout); |
| 265 | fputs(buf, stdout); | 279 | } |
| 280 | } else { | ||
| 281 | /* In this case, c is always one byte */ | ||
| 282 | putchar(c); | ||
| 266 | } | 283 | } |
| 267 | } | 284 | } |
| 268 | # if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS | 285 | # 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; | |||
| 23 | 23 | ||
| 24 | /* Unicode support using libc locale support. */ | 24 | /* Unicode support using libc locale support. */ |
| 25 | 25 | ||
| 26 | void FAST_FUNC reinit_unicode(const char *LANG UNUSED_PARAM) | 26 | void FAST_FUNC reinit_unicode(const char *LANG) |
| 27 | { | 27 | { |
| 28 | static const char unicode_0x394[] = { 0xce, 0x94, 0 }; | 28 | static const char unicode_0x394[] = { 0xce, 0x94, 0 }; |
| 29 | size_t width; | 29 | size_t width; |
| 30 | 30 | ||
| 31 | //TODO: call setlocale(LC_ALL, LANG) here? | 31 | //TODO: avoid repeated calls by caching last string? |
| 32 | setlocale(LC_ALL, (LANG && LANG[0]) ? LANG : "C"); | ||
| 32 | 33 | ||
| 33 | /* In unicode, this is a one character string */ | 34 | /* In unicode, this is a one character string */ |
| 34 | // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused | 35 | // 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) | |||
| 39 | void FAST_FUNC init_unicode(void) | 40 | void FAST_FUNC init_unicode(void) |
| 40 | { | 41 | { |
| 41 | if (unicode_status == UNICODE_UNKNOWN) | 42 | if (unicode_status == UNICODE_UNKNOWN) |
| 42 | reinit_unicode(NULL /*getenv("LANG")*/); | 43 | reinit_unicode(getenv("LANG")); |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | #else | 46 | #else |
