1570af302Sopenharmony_ci#include <wchar.h>
2570af302Sopenharmony_ci
3570af302Sopenharmony_cisize_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
4570af302Sopenharmony_ci{
5570af302Sopenharmony_ci	const wchar_t *ws2;
6570af302Sopenharmony_ci	char buf[4];
7570af302Sopenharmony_ci	size_t N = n, l;
8570af302Sopenharmony_ci	if (!s) {
9570af302Sopenharmony_ci		for (n=0, ws2=*ws; *ws2; ws2++) {
10570af302Sopenharmony_ci			if (*ws2 >= 0x80u) {
11570af302Sopenharmony_ci				l = wcrtomb(buf, *ws2, 0);
12570af302Sopenharmony_ci				if (!(l+1)) return -1;
13570af302Sopenharmony_ci				n += l;
14570af302Sopenharmony_ci			} else n++;
15570af302Sopenharmony_ci		}
16570af302Sopenharmony_ci		return n;
17570af302Sopenharmony_ci	}
18570af302Sopenharmony_ci	while (n>=4) {
19570af302Sopenharmony_ci		if (**ws-1u >= 0x7fu) {
20570af302Sopenharmony_ci			if (!**ws) {
21570af302Sopenharmony_ci				*s = 0;
22570af302Sopenharmony_ci				*ws = 0;
23570af302Sopenharmony_ci				return N-n;
24570af302Sopenharmony_ci			}
25570af302Sopenharmony_ci			l = wcrtomb(s, **ws, 0);
26570af302Sopenharmony_ci			if (!(l+1)) return -1;
27570af302Sopenharmony_ci			s += l;
28570af302Sopenharmony_ci			n -= l;
29570af302Sopenharmony_ci		} else {
30570af302Sopenharmony_ci			*s++ = **ws;
31570af302Sopenharmony_ci			n--;
32570af302Sopenharmony_ci		}
33570af302Sopenharmony_ci		(*ws)++;
34570af302Sopenharmony_ci	}
35570af302Sopenharmony_ci	while (n) {
36570af302Sopenharmony_ci		if (**ws-1u >= 0x7fu) {
37570af302Sopenharmony_ci			if (!**ws) {
38570af302Sopenharmony_ci				*s = 0;
39570af302Sopenharmony_ci				*ws = 0;
40570af302Sopenharmony_ci				return N-n;
41570af302Sopenharmony_ci			}
42570af302Sopenharmony_ci			l = wcrtomb(buf, **ws, 0);
43570af302Sopenharmony_ci			if (!(l+1)) return -1;
44570af302Sopenharmony_ci			if (l>n) return N-n;
45570af302Sopenharmony_ci			wcrtomb(s, **ws, 0);
46570af302Sopenharmony_ci			s += l;
47570af302Sopenharmony_ci			n -= l;
48570af302Sopenharmony_ci		} else {
49570af302Sopenharmony_ci			*s++ = **ws;
50570af302Sopenharmony_ci			n--;
51570af302Sopenharmony_ci		}
52570af302Sopenharmony_ci		(*ws)++;
53570af302Sopenharmony_ci	}
54570af302Sopenharmony_ci	return N;
55570af302Sopenharmony_ci}
56