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 | |
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>
-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 |