OLD | NEW |
(Empty) | |
| 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, mbstat
e_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 } |
OLD | NEW |