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 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