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