diff options
author | Rich Felker <dalias@aerifal.cx> | 2015-06-16 04:44:17 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2015-06-16 05:28:48 +0000 |
commit | 1507ebf837334e9e07cfab1ca1c2e88449069a80 (patch) | |
tree | 92bad1f861e442f7e2d2fa4e178f471f4371509a /src/multibyte/mbsrtowcs.c | |
parent | 38e2f727237230300fea6aff68802db04625fd23 (diff) | |
download | musl-1507ebf837334e9e07cfab1ca1c2e88449069a80.tar.gz |
byte-based C locale, phase 1: multibyte character handling functions
this patch makes the functions which work directly on multibyte
characters treat the high bytes as individual abstract code units
rather than as multibyte sequences when MB_CUR_MAX is 1. since
MB_CUR_MAX is presently defined as a constant 4, all of the new code
added is dead code, and optimizing compilers' code generation should
not be affected at all. a future commit will activate the new code.
as abstract code units, bytes 0x80 to 0xff are represented by wchar_t
values 0xdf80 to 0xdfff, at the end of the surrogates range. this
ensures that they will never be misinterpreted as Unicode characters,
and that all wctype functions return false for these "characters"
without needing locale-specific logic. a high range outside of Unicode
such as 0x7fffff80 to 0x7fffffff was also considered, but since C11's
char16_t also needs to be able to represent conversions of these
bytes, the surrogate range was the natural choice.
Diffstat (limited to 'src/multibyte/mbsrtowcs.c')
-rw-r--r-- | src/multibyte/mbsrtowcs.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/multibyte/mbsrtowcs.c b/src/multibyte/mbsrtowcs.c index 3c1343ae..e23083d2 100644 --- a/src/multibyte/mbsrtowcs.c +++ b/src/multibyte/mbsrtowcs.c @@ -7,6 +7,8 @@ #include <stdint.h> #include <wchar.h> #include <errno.h> +#include <string.h> +#include <stdlib.h> #include "internal.h" size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st) @@ -24,6 +26,23 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs } } + if (MB_CUR_MAX==1) { + if (!ws) return strlen((const char *)s); + for (;;) { + if (!wn) { + *src = (const void *)s; + return wn0; + } + if (!*s) break; + c = *s++; + *ws++ = CODEUNIT(c); + wn--; + } + *ws = 0; + *src = 0; + return wn0-wn; + } + if (!ws) for (;;) { if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) { |