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