Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/mbrtowc.c @ 17605:23cb5b2fd95b
relocatable-perl: like relocatable-script, but for Perl scripts
* build-aux/relocatable.pl.in: Add.
* doc/relocatable-maint.texi: Add documentation.
* modules/relocatable-perl: Add.
author | Reuben Thomas <rrt@sc3d.org> |
---|---|
date | Thu, 09 Jan 2014 22:31:42 +0000 |
parents | 344018b6e5d7 |
children | ea9dc06bfca8 |
rev | line source |
---|---|
10906 | 1 /* Convert multibyte character to wide character. |
17587 | 2 Copyright (C) 1999-2002, 2005-2014 Free Software Foundation, Inc. |
10906 | 3 Written by Bruno Haible <bruno@clisp.org>, 2008. |
4 | |
5 This program is free software: you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 3 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program 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 | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | |
18 #include <config.h> | |
19 | |
20 /* Specification. */ | |
21 #include <wchar.h> | |
22 | |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
23 #if GNULIB_defined_mbstate_t |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
24 /* Implement mbrtowc() on top of mbtowc(). */ |
10906 | 25 |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
26 # include <errno.h> |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
27 # include <stdlib.h> |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
28 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
29 # include "localcharset.h" |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
30 # include "streq.h" |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
31 # include "verify.h" |
10906 | 32 |
33 | |
10909 | 34 verify (sizeof (mbstate_t) >= 4); |
35 | |
10906 | 36 static char internal_state[4]; |
37 | |
38 size_t | |
39 mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) | |
40 { | |
41 char *pstate = (char *)ps; | |
42 | |
43 if (s == NULL) | |
44 { | |
45 pwc = NULL; | |
46 s = ""; | |
47 n = 1; | |
48 } | |
49 | |
50 if (n == 0) | |
51 return (size_t)(-2); | |
52 | |
53 /* Here n > 0. */ | |
14374
85a5ffbc0cb3
mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
54 |
85a5ffbc0cb3
mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
55 if (pstate == NULL) |
85a5ffbc0cb3
mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
56 pstate = internal_state; |
85a5ffbc0cb3
mbrtowc: Tiny optimization.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
57 |
10906 | 58 { |
59 size_t nstate = pstate[0]; | |
60 char buf[4]; | |
61 const char *p; | |
62 size_t m; | |
63 | |
64 switch (nstate) | |
65 { | |
66 case 0: | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
67 p = s; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
68 m = n; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
69 break; |
10906 | 70 case 3: |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
71 buf[2] = pstate[3]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
72 /*FALLTHROUGH*/ |
10906 | 73 case 2: |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
74 buf[1] = pstate[2]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
75 /*FALLTHROUGH*/ |
10906 | 76 case 1: |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
77 buf[0] = pstate[1]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
78 p = buf; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
79 m = nstate; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
80 buf[m++] = s[0]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
81 if (n >= 2 && m < 4) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
82 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
83 buf[m++] = s[1]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
84 if (n >= 3 && m < 4) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
85 buf[m++] = s[2]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
86 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
87 break; |
10906 | 88 default: |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
89 errno = EINVAL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
90 return (size_t)(-1); |
10906 | 91 } |
92 | |
11211 | 93 /* Here m > 0. */ |
10906 | 94 |
13885 | 95 # if __GLIBC__ || defined __UCLIBC__ |
10906 | 96 /* Work around bug <http://sourceware.org/bugzilla/show_bug.cgi?id=9674> */ |
97 mbtowc (NULL, NULL, 0); | |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
98 # endif |
10906 | 99 { |
100 int res = mbtowc (pwc, p, m); | |
101 | |
102 if (res >= 0) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
103 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
104 if (pwc != NULL && ((*pwc == 0) != (res == 0))) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
105 abort (); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
106 if (nstate >= (res > 0 ? res : 1)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
107 abort (); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
108 res -= nstate; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
109 pstate[0] = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
110 return res; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
111 } |
10906 | 112 |
113 /* mbtowc does not distinguish between invalid and incomplete multibyte | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
114 sequences. But mbrtowc needs to make this distinction. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
115 There are two possible approaches: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
116 - Use iconv() and its return value. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
117 - Use built-in knowledge about the possible encodings. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
118 Given the low quality of implementation of iconv() on the systems that |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
119 lack mbrtowc(), we use the second approach. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
120 The possible encodings are: |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
121 - 8-bit encodings, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
122 - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
123 - UTF-8. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
124 Use specialized code for each. */ |
10906 | 125 if (m >= 4 || m >= MB_CUR_MAX) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
126 goto invalid; |
10906 | 127 /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ |
128 { | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
129 const char *encoding = locale_charset (); |
10906 | 130 |
16385 | 131 if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
132 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
133 /* Cf. unistr/u8-mblen.c. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
134 unsigned char c = (unsigned char) p[0]; |
10906 | 135 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
136 if (c >= 0xc2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
137 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
138 if (c < 0xe0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
139 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
140 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
141 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
142 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
143 else if (c < 0xf0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
144 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
145 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
146 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
147 if (m == 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
148 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
149 unsigned char c2 = (unsigned char) p[1]; |
10906 | 150 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
151 if ((c2 ^ 0x80) < 0x40 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
152 && (c >= 0xe1 || c2 >= 0xa0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
153 && (c != 0xed || c2 < 0xa0)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
154 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
155 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
156 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
157 else if (c <= 0xf4) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
158 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
159 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
160 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
161 else /* m == 2 || m == 3 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
162 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
163 unsigned char c2 = (unsigned char) p[1]; |
10906 | 164 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
165 if ((c2 ^ 0x80) < 0x40 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
166 && (c >= 0xf1 || c2 >= 0x90) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
167 && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
168 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
169 if (m == 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
170 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
171 else /* m == 3 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
172 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
173 unsigned char c3 = (unsigned char) p[2]; |
10906 | 174 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
175 if ((c3 ^ 0x80) < 0x40) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
176 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
177 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
178 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
179 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
180 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
181 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
182 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
183 } |
10906 | 184 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
185 /* As a reference for this code, you can use the GNU libiconv |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
186 implementation. Look for uses of the RET_TOOFEW macro. */ |
10906 | 187 |
16385 | 188 if (STREQ_OPT (encoding, |
189 "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
190 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
191 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
192 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
193 unsigned char c = (unsigned char) p[0]; |
10906 | 194 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
195 if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
196 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
197 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
198 if (m == 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
199 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
200 unsigned char c = (unsigned char) p[0]; |
10906 | 201 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
202 if (c == 0x8f) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
203 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
204 unsigned char c2 = (unsigned char) p[1]; |
10906 | 205 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
206 if (c2 >= 0xa1 && c2 < 0xff) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
207 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
208 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
209 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
210 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
211 } |
16385 | 212 if (STREQ_OPT (encoding, |
213 "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) | |
214 || STREQ_OPT (encoding, | |
215 "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) | |
216 || STREQ_OPT (encoding, | |
217 "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
218 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
219 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
220 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
221 unsigned char c = (unsigned char) p[0]; |
10906 | 222 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
223 if (c >= 0xa1 && c < 0xff) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
224 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
225 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
226 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
227 } |
16385 | 228 if (STREQ_OPT (encoding, |
229 "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
230 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
231 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
232 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
233 unsigned char c = (unsigned char) p[0]; |
10906 | 234 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
235 if ((c >= 0xa1 && c < 0xff) || c == 0x8e) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
236 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
237 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
238 else /* m == 2 || m == 3 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
239 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
240 unsigned char c = (unsigned char) p[0]; |
10906 | 241 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
242 if (c == 0x8e) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
243 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
244 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
245 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
246 } |
16385 | 247 if (STREQ_OPT (encoding, |
248 "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
249 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
250 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
251 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
252 unsigned char c = (unsigned char) p[0]; |
11087
05091c173f76
Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents:
10924
diff
changeset
|
253 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
254 if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
255 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
256 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
257 else /* m == 2 || m == 3 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
258 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
259 unsigned char c = (unsigned char) p[0]; |
11087
05091c173f76
Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents:
10924
diff
changeset
|
260 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
261 if (c >= 0x90 && c <= 0xe3) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
262 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
263 unsigned char c2 = (unsigned char) p[1]; |
11087
05091c173f76
Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents:
10924
diff
changeset
|
264 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
265 if (c2 >= 0x30 && c2 <= 0x39) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
266 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
267 if (m == 2) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
268 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
269 else /* m == 3 */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
270 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
271 unsigned char c3 = (unsigned char) p[2]; |
11087
05091c173f76
Add support for the GB18030 encoding.
Bruno Haible <bruno@clisp.org>
parents:
10924
diff
changeset
|
272 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
273 if (c3 >= 0x81 && c3 <= 0xfe) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
274 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
275 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
276 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
277 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
278 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
279 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
280 } |
16385 | 281 if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
282 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
283 if (m == 1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
284 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
285 unsigned char c = (unsigned char) p[0]; |
10906 | 286 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
287 if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
288 || (c >= 0xf0 && c <= 0xf9)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
289 goto incomplete; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
290 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
291 goto invalid; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
292 } |
10906 | 293 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
294 /* An unknown multibyte encoding. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
295 goto incomplete; |
10906 | 296 } |
297 | |
298 incomplete: | |
299 { | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
300 size_t k = nstate; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
301 /* Here 0 <= k < m < 4. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
302 pstate[++k] = s[0]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
303 if (k < m) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
304 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
305 pstate[++k] = s[1]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
306 if (k < m) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
307 pstate[++k] = s[2]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
308 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
309 if (k != m) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
310 abort (); |
10906 | 311 } |
312 pstate[0] = m; | |
313 return (size_t)(-2); | |
314 | |
315 invalid: | |
316 errno = EILSEQ; | |
317 /* The conversion state is undefined, says POSIX. */ | |
318 return (size_t)(-1); | |
319 } | |
320 } | |
321 } | |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
322 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
323 #else |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
324 /* Override the system's mbrtowc() function. */ |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
325 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
326 # undef mbrtowc |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
327 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
328 size_t |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
329 rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
330 { |
14042
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
331 # if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
332 if (s == NULL) |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
333 { |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
334 pwc = NULL; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
335 s = ""; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
336 n = 1; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
337 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
338 # endif |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
339 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
340 # if MBRTOWC_RETVAL_BUG |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
341 { |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
342 static mbstate_t internal_state; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
343 |
14561
ed6716f98fb1
maint: change "can not" to "cannot"
Jim Meyering <meyering@redhat.com>
parents:
14374
diff
changeset
|
344 /* Override mbrtowc's internal state. We cannot call mbsinit() on the |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
345 hidden internal state, but we can call it on our variable. */ |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
346 if (ps == NULL) |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
347 ps = &internal_state; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
348 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
349 if (!mbsinit (ps)) |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
350 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
351 /* Parse the rest of the multibyte character byte for byte. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
352 size_t count = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
353 for (; n > 0; s++, n--) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
354 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
355 wchar_t wc; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
356 size_t ret = mbrtowc (&wc, s, 1, ps); |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
357 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
358 if (ret == (size_t)(-1)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
359 return (size_t)(-1); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
360 count++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
361 if (ret != (size_t)(-2)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
362 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
363 /* The multibyte character has been completed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
364 if (pwc != NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
365 *pwc = wc; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
366 return (wc == 0 ? 0 : count); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
367 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
368 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
369 return (size_t)(-2); |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
370 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
371 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
372 # endif |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
373 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
374 # if MBRTOWC_NUL_RETVAL_BUG |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
375 { |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
376 wchar_t wc; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
377 size_t ret = mbrtowc (&wc, s, n, ps); |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
378 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
379 if (ret != (size_t)(-1) && ret != (size_t)(-2)) |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
380 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
381 if (pwc != NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
382 *pwc = wc; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
383 if (wc == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11211
diff
changeset
|
384 ret = 0; |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
385 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
386 return ret; |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
387 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
388 # else |
14042
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
389 { |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
390 # if MBRTOWC_NULL_ARG1_BUG |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
391 wchar_t dummy; |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
392 |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
393 if (pwc == NULL) |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
394 pwc = &dummy; |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
395 # endif |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
396 |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
397 return mbrtowc (pwc, s, n, ps); |
1a75c9206d28
mbrtowc: Work around a Solaris 7 bug.
Bruno Haible <bruno@clisp.org>
parents:
13885
diff
changeset
|
398 } |
10924
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
399 # endif |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
400 } |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
401 |
6f547b3710c7
Work around mbrtowc bugs on AIX, HP-UX, OSF/1, Solaris.
Bruno Haible <bruno@clisp.org>
parents:
10909
diff
changeset
|
402 #endif |