aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-03-27 01:18:07 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-03-27 01:18:07 +0100
commit353680aa46dc91ecfd80dd19db131de7aa90bd22 (patch)
tree05de26c20457b407fa59501708d3b31d2aa081f5
parent19311bfa7b8e8c6effa9c375de9b0eb4338bee12 (diff)
downloadbusybox-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.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)
204#if ENABLE_UNICODE_SUPPORT 204#if ENABLE_UNICODE_SUPPORT
205static size_t load_string(const char *src, int maxsize) 205static 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}
213static unsigned save_string(char *dst, unsigned maxsize) 220static 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... */
256static void BB_PUTCHAR(wchar_t c) 270static 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
26void FAST_FUNC reinit_unicode(const char *LANG UNUSED_PARAM) 26void 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)
39void FAST_FUNC init_unicode(void) 40void 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