| 1 | #include <stdlib.h> |
| 2 | #include <wchar.h> |
| 3 | #include <errno.h> |
| 4 | #include "internal.h" |
| 5 | |
| 6 | size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st) |
| 7 | { |
| 8 | 	if (!s) return 1; |
| 9 | 	if ((unsigned)wc < 0x80) { |
| 10 | 		*s = wc; |
| 11 | 		return 1; |
| 12 | 	} else if (MB_CUR_MAX == 1) { |
| 13 | 		if (!IS_CODEUNIT(wc)) { |
| 14 | 			errno = EILSEQ; |
| 15 | 			return -1; |
| 16 | 		} |
| 17 | 		*s = wc; |
| 18 | 		return 1; |
| 19 | 	} else if ((unsigned)wc < 0x800) { |
| 20 | 		*s++ = 0xc0 | (wc>>6); |
| 21 | 		*s = 0x80 | (wc&0x3f); |
| 22 | 		return 2; |
| 23 | 	} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) { |
| 24 | 		*s++ = 0xe0 | (wc>>12); |
| 25 | 		*s++ = 0x80 | ((wc>>6)&0x3f); |
| 26 | 		*s = 0x80 | (wc&0x3f); |
| 27 | 		return 3; |
| 28 | 	} else if ((unsigned)wc-0x10000 < 0x100000) { |
| 29 | 		*s++ = 0xf0 | (wc>>18); |
| 30 | 		*s++ = 0x80 | ((wc>>12)&0x3f); |
| 31 | 		*s++ = 0x80 | ((wc>>6)&0x3f); |
| 32 | 		*s = 0x80 | (wc&0x3f); |
| 33 | 		return 4; |
| 34 | 	} |
| 35 | 	errno = EILSEQ; |
| 36 | 	return -1; |
| 37 | } |