implement mbtowc directly, not as a wrapper for mbrtowc
[musl] / src / multibyte / wcsrtombs.c
1 /* 
2  * This code was written by Rich Felker in 2010; no copyright is claimed.
3  * This code is in the public domain. Attribution is appreciated but
4  * unnecessary.
5  */
6
7 #include <stdlib.h>
8 #include <inttypes.h>
9 #include <wchar.h>
10 #include <errno.h>
11
12 #include "internal.h"
13
14 size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
15 {
16         const wchar_t *ws2;
17         char buf[4];
18         size_t N = n, l;
19         if (!s) {
20                 for (n=0, ws2=*ws; *ws2; ws2++) {
21                         if (*ws2 >= 0x80u) {
22                                 l = wcrtomb(buf, *ws2, 0);
23                                 if (!(l+1)) return -1;
24                                 n += l;
25                         } else n++;
26                 }
27                 return n;
28         }
29         while (n>=4 && **ws) {
30                 if (**ws >= 0x80u) {
31                         l = wcrtomb(s, **ws, 0);
32                         if (!(l+1)) return -1;
33                         s += l;
34                         n -= l;
35                 } else {
36                         *s++ = **ws;
37                         n--;
38                 }
39                 (*ws)++;
40         }
41         while (n && **ws) {
42                 if (**ws >= 0x80u) {
43                         l = wcrtomb(buf, **ws, 0);
44                         if (!(l+1)) return -1;
45                         if (l>n) return N-n;
46                         wcrtomb(s, **ws, 0);
47                         s += l;
48                         n -= l;
49                 } else {
50                         *s++ = **ws;
51                         n--;
52                 }
53                 (*ws)++;
54         }
55         if (n) *s = 0;
56         *ws = 0;
57         return N-n;
58 }