diff options
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); |