1 /* Test mbrtoc8.
2 Copyright (C) 2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <locale.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <uchar.h>
24 #include <wchar.h>
25 #include <support/check.h>
26 #include <support/support.h>
27
28 static int
test_utf8(void)29 test_utf8 (void)
30 {
31 xsetlocale (LC_ALL, "de_DE.UTF-8");
32
33 /* No inputs. */
34 {
35 const char *mbs = "";
36 char8_t buf[1] = { 0 };
37 mbstate_t s = { 0 };
38
39 TEST_COMPARE (mbrtoc8 (buf, mbs, 0, &s), (size_t) -2); /* no input */
40 TEST_VERIFY (mbsinit (&s));
41 }
42
43 /* Null character. */
44 {
45 const char *mbs = "\x00"; /* 0x00 => U+0000 */
46 char8_t buf[1] = { 0 };
47 mbstate_t s = { 0 };
48
49 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 0);
50 mbs += 1;
51 TEST_COMPARE (buf[0], 0x00);
52 TEST_VERIFY (mbsinit (&s));
53 }
54
55 /* First non-null character in the code point range that maps to a single
56 code unit. */
57 {
58 const char *mbs = "\x01"; /* 0x01 => U+0001 */
59 char8_t buf[1] = { 0 };
60 mbstate_t s = { 0 };
61
62 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 1);
63 mbs += 1;
64 TEST_COMPARE (buf[0], 0x01);
65 TEST_VERIFY (mbsinit (&s));
66 }
67
68 /* Last character in the code point range that maps to a single code unit. */
69 {
70 const char *mbs = "\x7F"; /* 0x7F => U+007F */
71 char8_t buf[1] = { 0 };
72 mbstate_t s = { 0 };
73
74 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 1);
75 mbs += 1;
76 TEST_COMPARE (buf[0], 0x7F);
77 TEST_VERIFY (mbsinit (&s));
78 }
79
80 /* First character in the code point range that maps to two code units. */
81 {
82 const char *mbs = "\xC2\x80"; /* 0xC2 0x80 => U+0080 */
83 char8_t buf[1] = { 0 };
84 mbstate_t s = { 0 };
85
86 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 2);
87 mbs += 2;
88 TEST_COMPARE (buf[0], 0xC2);
89 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
90 TEST_COMPARE (buf[0], 0x80);
91 TEST_VERIFY (mbsinit (&s));
92 }
93
94 /* Same as last test, but one code unit at a time. */
95 {
96 const char *mbs = "\xC2\x80"; /* 0xC2 0x80 => U+0080 */
97 char8_t buf[1] = { 0 };
98 mbstate_t s = { 0 };
99
100 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
101 mbs += 1;
102 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
103 mbs += 1;
104 TEST_COMPARE (buf[0], 0xC2);
105 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
106 TEST_COMPARE (buf[0], 0x80);
107 TEST_VERIFY (mbsinit (&s));
108 }
109
110 /* Last character in the code point range that maps to two code units. */
111 {
112 const char *mbs = "\xDF\xBF"; /* 0xDF 0xBF => U+07FF */
113 char8_t buf[1] = { 0 };
114 mbstate_t s = { 0 };
115
116 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 2);
117 mbs += 2;
118 TEST_COMPARE (buf[0], 0xDF);
119 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
120 TEST_COMPARE (buf[0], 0xBF);
121 TEST_VERIFY (mbsinit (&s));
122 }
123
124 /* Same as last test, but one code unit at a time. */
125 {
126 const char *mbs = "\xDF\xBF"; /* 0xDF 0xBF => U+07FF */
127 char8_t buf[1] = { 0 };
128 mbstate_t s = { 0 };
129
130 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
131 mbs += 1;
132 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
133 mbs += 1;
134 TEST_COMPARE (buf[0], 0xDF);
135 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
136 TEST_COMPARE (buf[0], 0xBF);
137 TEST_VERIFY (mbsinit (&s));
138 }
139
140 /* First character in the code point range that maps to three code units. */
141 {
142 const char *mbs = u8"\xE0\xA0\x80"; /* 0xE0 0xA0 0x80 => U+0800 */
143 char8_t buf[1] = { 0 };
144 mbstate_t s = { 0 };
145
146 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
147 mbs += 3;
148 TEST_COMPARE (buf[0], 0xE0);
149 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
150 TEST_COMPARE (buf[0], 0xA0);
151 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
152 TEST_COMPARE (buf[0], 0x80);
153 TEST_VERIFY (mbsinit (&s));
154 }
155
156 /* Same as last test, but one code unit at a time. */
157 {
158 const char *mbs = u8"\xE0\xA0\x80"; /* 0xE0 0xA0 0x80 => U+0800 */
159 char8_t buf[1] = { 0 };
160 mbstate_t s = { 0 };
161
162 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
163 mbs += 1;
164 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
165 mbs += 1;
166 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
167 mbs += 1;
168 TEST_COMPARE (buf[0], 0xE0);
169 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
170 TEST_COMPARE (buf[0], 0xA0);
171 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
172 TEST_COMPARE (buf[0], 0x80);
173 TEST_VERIFY (mbsinit (&s));
174 }
175
176 /* Last character in the code point range that maps to three code units
177 before the surrogate code point range. */
178 {
179 const char *mbs = "\xED\x9F\xBF"; /* 0xED 0x9F 0xBF => U+D7FF */
180 char8_t buf[1] = { 0 };
181 mbstate_t s = { 0 };
182
183 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
184 mbs += 3;
185 TEST_COMPARE (buf[0], 0xED);
186 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
187 TEST_COMPARE (buf[0], 0x9F);
188 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
189 TEST_COMPARE (buf[0], 0xBF);
190 TEST_VERIFY (mbsinit (&s));
191 }
192
193 /* Same as last test, but one code unit at a time. */
194 {
195 const char *mbs = "\xED\x9F\xBF"; /* 0xED 0x9F 0xBF => U+D7FF */
196 char8_t buf[1] = { 0 };
197 mbstate_t s = { 0 };
198
199 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
200 mbs += 1;
201 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
202 mbs += 1;
203 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
204 mbs += 1;
205 TEST_COMPARE (buf[0], 0xED);
206 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
207 TEST_COMPARE (buf[0], 0x9F);
208 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
209 TEST_COMPARE (buf[0], 0xBF);
210 TEST_VERIFY (mbsinit (&s));
211 }
212
213 /* First character in the code point range that maps to three code units
214 after the surrogate code point range. */
215 {
216 const char *mbs = "\xEE\x80\x80"; /* 0xEE 0x80 0x80 => U+E000 */
217 char8_t buf[1] = { 0 };
218 mbstate_t s = { 0 };
219
220 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
221 mbs += 3;
222 TEST_COMPARE (buf[0], 0xEE);
223 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
224 TEST_COMPARE (buf[0], 0x80);
225 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
226 TEST_COMPARE (buf[0], 0x80);
227 TEST_VERIFY (mbsinit (&s));
228 }
229
230 /* Same as last test, but one code unit at a time. */
231 {
232 const char *mbs = "\xEE\x80\x80"; /* 0xEE 0x80 0x80 => U+E000 */
233 char8_t buf[1] = { 0 };
234 mbstate_t s = { 0 };
235
236 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
237 mbs += 1;
238 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
239 mbs += 1;
240 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
241 mbs += 1;
242 TEST_COMPARE (buf[0], 0xEE);
243 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
244 TEST_COMPARE (buf[0], 0x80);
245 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
246 TEST_COMPARE (buf[0], 0x80);
247 TEST_VERIFY (mbsinit (&s));
248 }
249
250 /* Not a BOM. */
251 {
252 const char *mbs = "\xEF\xBB\xBF"; /* 0xEF 0xBB 0xBF => U+FEFF */
253 char8_t buf[1] = { 0 };
254 mbstate_t s = { 0 };
255
256 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
257 mbs += 3;
258 TEST_COMPARE (buf[0], 0xEF);
259 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
260 TEST_COMPARE (buf[0], 0xBB);
261 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
262 TEST_COMPARE (buf[0], 0xBF);
263 TEST_VERIFY (mbsinit (&s));
264 }
265
266 /* Same as last test, but one code unit at a time. */
267 {
268 const char *mbs = "\xEF\xBB\xBF"; /* 0xEF 0xBB 0xBF => U+FEFF */
269 char8_t buf[1] = { 0 };
270 mbstate_t s = { 0 };
271
272 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
273 mbs += 1;
274 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
275 mbs += 1;
276 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
277 mbs += 1;
278 TEST_COMPARE (buf[0], 0xEF);
279 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
280 TEST_COMPARE (buf[0], 0xBB);
281 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
282 TEST_COMPARE (buf[0], 0xBF);
283 TEST_VERIFY (mbsinit (&s));
284 }
285
286 /* Replacement character. */
287 {
288 const char *mbs = "\xEF\xBF\xBD"; /* 0xEF 0xBF 0xBD => U+FFFD */
289 char8_t buf[1] = { 0 };
290 mbstate_t s = { 0 };
291
292 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
293 mbs += 3;
294 TEST_COMPARE (buf[0], 0xEF);
295 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
296 TEST_COMPARE (buf[0], 0xBF);
297 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
298 TEST_COMPARE (buf[0], 0xBD);
299 TEST_VERIFY (mbsinit (&s));
300 }
301
302 /* Same as last test, but one code unit at a time. */
303 {
304 const char *mbs = "\xEF\xBF\xBD"; /* 0xEF 0xBF 0xBD => U+FFFD */
305 char8_t buf[1] = { 0 };
306 mbstate_t s = { 0 };
307
308 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
309 mbs += 1;
310 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
311 mbs += 1;
312 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
313 mbs += 1;
314 TEST_COMPARE (buf[0], 0xEF);
315 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
316 TEST_COMPARE (buf[0], 0xBF);
317 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
318 TEST_COMPARE (buf[0], 0xBD);
319 TEST_VERIFY (mbsinit (&s));
320 }
321
322 /* Last character in the code point range that maps to three code units. */
323 {
324 const char *mbs = "\xEF\xBF\xBF"; /* 0xEF 0xBF 0xBF => U+FFFF */
325 char8_t buf[1] = { 0 };
326 mbstate_t s = { 0 };
327
328 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 3);
329 mbs += 3;
330 TEST_COMPARE (buf[0], 0xEF);
331 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
332 TEST_COMPARE (buf[0], 0xBF);
333 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
334 TEST_COMPARE (buf[0], 0xBF);
335 TEST_VERIFY (mbsinit (&s));
336 }
337
338 /* Same as last test, but one code unit at a time. */
339 {
340 const char *mbs = "\xEF\xBF\xBF"; /* 0xEF 0xBF 0xBF => U+FFFF */
341 char8_t buf[1] = { 0 };
342 mbstate_t s = { 0 };
343
344 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
345 mbs += 1;
346 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
347 mbs += 1;
348 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
349 mbs += 1;
350 TEST_COMPARE (buf[0], 0xEF);
351 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
352 TEST_COMPARE (buf[0], 0xBF);
353 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
354 TEST_COMPARE (buf[0], 0xBF);
355 TEST_VERIFY (mbsinit (&s));
356 }
357
358 /* First character in the code point range that maps to four code units. */
359 {
360 const char *mbs = "\xF0\x90\x80\x80"; /* 0xF0 0x90 0x80 0x80 => U+10000 */
361 char8_t buf[1] = { 0 };
362 mbstate_t s = { 0 };
363
364 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 4);
365 mbs += 4;
366 TEST_COMPARE (buf[0], 0xF0);
367 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
368 TEST_COMPARE (buf[0], 0x90);
369 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
370 TEST_COMPARE (buf[0], 0x80);
371 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
372 TEST_COMPARE (buf[0], 0x80);
373 TEST_VERIFY (mbsinit (&s));
374 }
375
376 /* Same as last test, but one code unit at a time. */
377 {
378 const char *mbs = "\xF0\x90\x80\x80"; /* 0xF0 0x90 0x80 0x80 => U+10000 */
379 char8_t buf[1] = { 0 };
380 mbstate_t s = { 0 };
381
382 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
383 mbs += 1;
384 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
385 mbs += 1;
386 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
387 mbs += 1;
388 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
389 mbs += 1;
390 TEST_COMPARE (buf[0], 0xF0);
391 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
392 TEST_COMPARE (buf[0], 0x90);
393 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
394 TEST_COMPARE (buf[0], 0x80);
395 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
396 TEST_COMPARE (buf[0], 0x80);
397 TEST_VERIFY (mbsinit (&s));
398 }
399
400 /* Last character in the code point range that maps to four code units. */
401 {
402 const char *mbs = "\xF4\x8F\xBF\xBF"; /* 0xF4 0x8F 0xBF 0xBF => U+10FFFF */
403 char8_t buf[1] = { 0 };
404 mbstate_t s = { 0 };
405
406 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 4);
407 mbs += 4;
408 TEST_COMPARE (buf[0], 0xF4);
409 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
410 TEST_COMPARE (buf[0], 0x8F);
411 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
412 TEST_COMPARE (buf[0], 0xBF);
413 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
414 TEST_COMPARE (buf[0], 0xBF);
415 TEST_VERIFY (mbsinit (&s));
416 }
417
418 /* Same as last test, but one code unit at a time. */
419 {
420 const char *mbs = "\xF4\x8F\xBF\xBF"; /* 0xF4 0x8F 0xBF 0xBF => U+10FFFF */
421 char8_t buf[1] = { 0 };
422 mbstate_t s = { 0 };
423
424 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
425 mbs += 1;
426 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
427 mbs += 1;
428 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
429 mbs += 1;
430 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
431 mbs += 1;
432 TEST_COMPARE (buf[0], 0xF4);
433 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
434 TEST_COMPARE (buf[0], 0x8F);
435 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
436 TEST_COMPARE (buf[0], 0xBF);
437 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
438 TEST_COMPARE (buf[0], 0xBF);
439 TEST_VERIFY (mbsinit (&s));
440 }
441
442 return 0;
443 }
444
445 static int
test_big5_hkscs(void)446 test_big5_hkscs (void)
447 {
448 xsetlocale (LC_ALL, "zh_HK.BIG5-HKSCS");
449
450 /* A double byte character that maps to a pair of two byte UTF-8 code unit
451 sequences. */
452 {
453 const char *mbs = "\x88\x62"; /* 0x88 0x62 => U+00CA U+0304 */
454 char8_t buf[1] = { 0 };
455 mbstate_t s = { 0 };
456
457 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 2);
458 mbs += 2;
459 TEST_COMPARE (buf[0], 0xC3);
460 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
461 TEST_COMPARE (buf[0], 0x8A);
462 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
463 TEST_COMPARE (buf[0], 0xCC);
464 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
465 TEST_COMPARE (buf[0], 0x84);
466 TEST_VERIFY (mbsinit (&s));
467 }
468
469 /* Same as last test, but one code unit at a time. */
470 {
471 const char *mbs = "\x88\x62"; /* 0x88 0x62 => U+00CA U+0304 */
472 char8_t buf[1] = { 0 };
473 mbstate_t s = { 0 };
474
475 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
476 mbs += 1;
477 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
478 mbs += 1;
479 TEST_COMPARE (buf[0], 0xC3);
480 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
481 TEST_COMPARE (buf[0], 0x8A);
482 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
483 TEST_COMPARE (buf[0], 0xCC);
484 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
485 TEST_COMPARE (buf[0], 0x84);
486 TEST_VERIFY (mbsinit (&s));
487 }
488
489 /* Another double byte character that maps to a pair of two byte UTF-8 code
490 unit sequences. */
491 {
492 const char *mbs = "\x88\xA5"; /* 0x88 0xA5 => U+00EA U+030C */
493 char8_t buf[1] = { 0 };
494 mbstate_t s = { 0 };
495
496 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) 2);
497 mbs += 2;
498 TEST_COMPARE (buf[0], 0xC3);
499 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
500 TEST_COMPARE (buf[0], 0xAA);
501 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
502 TEST_COMPARE (buf[0], 0xCC);
503 TEST_COMPARE (mbrtoc8 (buf, mbs, strlen (mbs) + 1, &s), (size_t) -3);
504 TEST_COMPARE (buf[0], 0x8C);
505 TEST_VERIFY (mbsinit (&s));
506 }
507
508 /* Same as last test, but one code unit at a time. */
509 {
510 const char *mbs = "\x88\xA5"; /* 0x88 0xA5 => U+00EA U+030C */
511 char8_t buf[1] = { 0 };
512 mbstate_t s = { 0 };
513
514 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -2);
515 mbs += 1;
516 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) 1);
517 mbs += 1;
518 TEST_COMPARE (buf[0], 0xC3);
519 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
520 TEST_COMPARE (buf[0], 0xAA);
521 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
522 TEST_COMPARE (buf[0], 0xCC);
523 TEST_COMPARE (mbrtoc8 (buf, mbs, 1, &s), (size_t) -3);
524 TEST_COMPARE (buf[0], 0x8C);
525 TEST_VERIFY (mbsinit (&s));
526 }
527
528 return 0;
529 }
530
531 static int
do_test(void)532 do_test (void)
533 {
534 test_utf8 ();
535 test_big5_hkscs ();
536 return 0;
537 }
538
539 #include <support/test-driver.c>
540