diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2009-05-15 11:40:28 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2009-05-15 11:40:28 +0000 |
commit | 098a75dc51caa98f369d98a9809d773bc45329aa (patch) | |
tree | a441415fa099d4397975c99da216e6c928f67055 /newlib/libc/string/wcswidth.c | |
parent | 73535010d72d1a7d46e4f5c6c98f41fab90df489 (diff) | |
download | cygnal-098a75dc51caa98f369d98a9809d773bc45329aa.tar.gz cygnal-098a75dc51caa98f369d98a9809d773bc45329aa.tar.bz2 cygnal-098a75dc51caa98f369d98a9809d773bc45329aa.zip |
* libc/string/local.h: New file.
* libc/string/wcswidth.c (wcswidth): Convert japanese wide
characters to Unicode here. Handle surrogate pairs for UTF-16
systems. Call __wcwidth rather than wcwidth.
* libc/string/wcwidth.c: New implementation using Markus Kuhn's
wcwidth implementation for Unicode.
(bisearch): New static function.
(__wcwidth): New function. Take wint_t rather than wchar_t as
parameter to allow full Unicode handling on UTF-16 systems.
Move old wcwidth implementation here for non-multibyte aware
systems.
(wcwidth): Convert japanese wide characters to Unicode here.
Call __wcwidth rather than using iswprint/iswcntrl.
Diffstat (limited to 'newlib/libc/string/wcswidth.c')
-rw-r--r-- | newlib/libc/string/wcswidth.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/newlib/libc/string/wcswidth.c b/newlib/libc/string/wcswidth.c index 8a9670eb1..6c0efe63f 100644 --- a/newlib/libc/string/wcswidth.c +++ b/newlib/libc/string/wcswidth.c @@ -37,6 +37,7 @@ PORTABILITY #include <_ansi.h> #include <wchar.h> +#include "local.h" int _DEFUN (wcswidth, (pwcs, n), @@ -48,7 +49,23 @@ _DEFUN (wcswidth, (pwcs, n), if (!pwcs || n == 0) return 0; do { - if ((w = wcwidth (*pwcs)) < 0) + wint_t wi = *pwcs; + +#ifdef _MB_CAPABLE + wi = _jp2uc (wi); + /* First half of a surrogate pair? */ + if (sizeof (wchar_t) == 2 && wi >= 0xd800 && wi <= 0xdbff) + { + wint_t wi2; + + /* Extract second half and check for validity. */ + if (--n == 0 || (wi2 = _jp2uc (*++pwcs)) < 0xdc00 || wi2 > 0xdfff) + return -1; + /* Compute actual unicode value to use in call to __wcwidth. */ + wi = (((wi & 0x3ff) << 10) | (wi2 & 0x3ff)) + 0x10000; + } +#endif /* _MB_CAPABLE */ + if ((w = __wcwidth (wi)) < 0) return -1; len += w; } while (*pwcs++ && --n > 0); |