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 <wchar.h>
8
wcsrtombs(char * restrict s,const wchar_t ** restrict ws,size_t n,mbstate_t * restrict st)9 size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
10 {
11 const wchar_t *ws2;
12 char buf[4];
13 size_t N = n, l;
14 if (!s) {
15 for (n=0, ws2=*ws; *ws2; ws2++) {
16 if (*ws2 >= 0x80u) {
17 l = wcrtomb(buf, *ws2, 0);
18 if (!(l+1)) return -1;
19 n += l;
20 } else n++;
21 }
22 return n;
23 }
24 while (n>=4) {
25 if (**ws-1u >= 0x7fu) {
26 if (!**ws) {
27 *s = 0;
28 *ws = 0;
29 return N-n;
30 }
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) {
42 if (**ws-1u >= 0x7fu) {
43 if (!**ws) {
44 *s = 0;
45 *ws = 0;
46 return N-n;
47 }
48 l = wcrtomb(buf, **ws, 0);
49 if (!(l+1)) return -1;
50 if (l>n) return N-n;
51 wcrtomb(s, **ws, 0);
52 s += l;
53 n -= l;
54 } else {
55 *s++ = **ws;
56 n--;
57 }
58 (*ws)++;
59 }
60 return N;
61 }
62