]>
Commit | Line | Data |
---|---|---|
30de3b18 RM |
1 | /* Copyright (C) 1996 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. | |
07a4742f | 3 | Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. |
30de3b18 RM |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
17 | not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | Boston, MA 02111-1307, USA. */ | |
19 | ||
20 | #include <errno.h> | |
21 | #include <wchar.h> | |
22 | ||
80bcb410 RM |
23 | #ifndef EILSEQ |
24 | #define EILSEQ EINVAL | |
25 | #endif | |
30de3b18 | 26 | |
07a4742f RM |
27 | static const wchar_t encoding_mask[] = |
28 | { | |
29 | ~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff | |
30 | }; | |
31 | ||
32 | static const unsigned char encoding_byte[] = | |
33 | { | |
34 | 0xc0, 0xe0, 0xf0, 0xf8, 0xfc | |
35 | }; | |
6dbe2837 | 36 | |
07a4742f | 37 | /* The state is for this UTF8 encoding not used. */ |
6dbe2837 RM |
38 | static mbstate_t internal; |
39 | ||
30de3b18 | 40 | size_t |
23396375 | 41 | __wcrtomb (char *s, wchar_t wc, mbstate_t *ps) |
30de3b18 | 42 | { |
6dbe2837 | 43 | char fake[1]; |
07a4742f | 44 | size_t written = 0; |
6dbe2837 RM |
45 | |
46 | if (ps == NULL) | |
503054c0 | 47 | ps = &internal; |
6dbe2837 | 48 | |
30de3b18 RM |
49 | if (s == NULL) |
50 | { | |
51 | s = fake; | |
52 | wc = L'\0'; | |
53 | } | |
54 | ||
07a4742f RM |
55 | /* Store the UTF8 representation of WC. */ |
56 | if (wc < 0 || wc > 0x7fffffff) | |
30de3b18 | 57 | { |
07a4742f | 58 | /* This is no correct ISO 10646 character. */ |
c4029823 | 59 | __set_errno (EILSEQ); |
07a4742f RM |
60 | return (size_t) -1; |
61 | } | |
62 | ||
63 | if (wc < 0x80) | |
64 | { | |
65 | /* It's a one byte sequence. */ | |
66 | if (s != NULL) | |
67 | *s = (char) wc; | |
30de3b18 RM |
68 | return 1; |
69 | } | |
70 | ||
07a4742f RM |
71 | for (written = 2; written < 6; ++written) |
72 | if ((wc & encoding_mask[written - 2]) == 0) | |
73 | break; | |
74 | ||
75 | if (s != NULL) | |
30de3b18 | 76 | { |
07a4742f RM |
77 | size_t cnt = written; |
78 | s[0] = encoding_byte[cnt - 2]; | |
79 | ||
80 | --cnt; | |
81 | do | |
82 | { | |
83 | s[cnt] = 0x80 | (wc & 0x3f); | |
84 | wc >>= 6; | |
85 | } | |
86 | while (--cnt > 0); | |
87 | s[0] |= wc; | |
30de3b18 RM |
88 | } |
89 | ||
07a4742f | 90 | return written; |
30de3b18 | 91 | } |
23396375 | 92 | weak_alias (__wcrtomb, wcrtomb) |