fix broken thread list unlocking after fork
[musl] / src / multibyte / mbrtoc16.c
1 #include <uchar.h>
2 #include <wchar.h>
3
4 size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
5 {
6         static unsigned internal_state;
7         if (!ps) ps = (void *)&internal_state;
8         unsigned *pending = (unsigned *)ps;
9
10         if (!s) return mbrtoc16(0, "", 1, ps);
11
12         /* mbrtowc states for partial UTF-8 characters have the high bit set;
13          * we use nonzero states without high bit for pending surrogates. */
14         if ((int)*pending > 0) {
15                 if (pc16) *pc16 = *pending;
16                 *pending = 0;
17                 return -3;
18         }
19
20         wchar_t wc;
21         size_t ret = mbrtowc(&wc, s, n, ps);
22         if (ret <= 4) {
23                 if (wc >= 0x10000) {
24                         *pending = (wc & 0x3ff) + 0xdc00;
25                         wc = 0xd7c0 + (wc >> 10);
26                 }
27                 if (pc16) *pc16 = wc;
28         }
29         return ret;
30 }