openat: don’t close (-1)
[gnulib.git] / tests / test-mbrtoc32-w32.c
blob07f4d3ccf9ca77411de5d559fb5bb3906206c845
1 /* Test of conversion of multibyte character to 32-bit wide character.
2 Copyright (C) 2008-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include <uchar.h>
21 #include <errno.h>
22 #include <locale.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <wchar.h>
28 #include "localcharset.h"
29 #include "macros.h"
31 #if defined _WIN32 && !defined __CYGWIN__
33 static int
34 test_one_locale (const char *name, int codepage)
36 mbstate_t state;
37 char32_t wc;
38 size_t ret;
40 # if 1
41 /* Portable code to set the locale. */
43 char name_with_codepage[1024];
45 sprintf (name_with_codepage, "%s.%d", name, codepage);
47 /* Set the locale. */
48 if (setlocale (LC_ALL, name_with_codepage) == NULL)
49 return 77;
51 # else
52 /* Hacky way to set a locale.codepage combination that setlocale() refuses
53 to set. */
55 /* Codepage of the current locale, set with setlocale().
56 Not necessarily the same as GetACP(). */
57 extern __declspec(dllimport) unsigned int __lc_codepage;
59 /* Set the locale. */
60 if (setlocale (LC_ALL, name) == NULL)
61 return 77;
63 /* Clobber the codepage and MB_CUR_MAX, both set by setlocale(). */
64 __lc_codepage = codepage;
65 switch (codepage)
67 case 1252:
68 case 1256:
69 MB_CUR_MAX = 1;
70 break;
71 case 932:
72 case 950:
73 case 936:
74 MB_CUR_MAX = 2;
75 break;
76 case 54936:
77 case 65001:
78 MB_CUR_MAX = 4;
79 break;
82 /* Test whether the codepage is really available. */
83 memset (&state, '\0', sizeof (mbstate_t));
84 if (mbrtoc32 (&wc, " ", 1, &state) == (size_t)(-1))
85 return 77;
87 # endif
89 /* Test zero-length input. */
91 memset (&state, '\0', sizeof (mbstate_t));
92 wc = (char32_t) 0xBADFACE;
93 ret = mbrtoc32 (&wc, "x", 0, &state);
94 ASSERT (ret == (size_t)(-2));
95 ASSERT (mbsinit (&state));
98 /* Test NUL byte input. */
100 memset (&state, '\0', sizeof (mbstate_t));
101 wc = (char32_t) 0xBADFACE;
102 ret = mbrtoc32 (&wc, "", 1, &state);
103 ASSERT (ret == 0);
104 ASSERT (wc == 0);
105 ASSERT (mbsinit (&state));
106 ret = mbrtoc32 (NULL, "", 1, &state);
107 ASSERT (ret == 0);
108 ASSERT (mbsinit (&state));
111 /* Test single-byte input. */
113 int c;
114 char buf[1];
116 memset (&state, '\0', sizeof (mbstate_t));
117 for (c = 0; c < 0x100; c++)
118 switch (c)
120 case '\t': case '\v': case '\f':
121 case ' ': case '!': case '"': case '#': case '%':
122 case '&': case '\'': case '(': case ')': case '*':
123 case '+': case ',': case '-': case '.': case '/':
124 case '0': case '1': case '2': case '3': case '4':
125 case '5': case '6': case '7': case '8': case '9':
126 case ':': case ';': case '<': case '=': case '>':
127 case '?':
128 case 'A': case 'B': case 'C': case 'D': case 'E':
129 case 'F': case 'G': case 'H': case 'I': case 'J':
130 case 'K': case 'L': case 'M': case 'N': case 'O':
131 case 'P': case 'Q': case 'R': case 'S': case 'T':
132 case 'U': case 'V': case 'W': case 'X': case 'Y':
133 case 'Z':
134 case '[': case '\\': case ']': case '^': case '_':
135 case 'a': case 'b': case 'c': case 'd': case 'e':
136 case 'f': case 'g': case 'h': case 'i': case 'j':
137 case 'k': case 'l': case 'm': case 'n': case 'o':
138 case 'p': case 'q': case 'r': case 's': case 't':
139 case 'u': case 'v': case 'w': case 'x': case 'y':
140 case 'z': case '{': case '|': case '}': case '~':
141 /* c is in the ISO C "basic character set". */
142 buf[0] = c;
143 wc = (char32_t) 0xBADFACE;
144 ret = mbrtoc32 (&wc, buf, 1, &state);
145 ASSERT (ret == 1);
146 ASSERT (wc == c);
147 ASSERT (mbsinit (&state));
148 ret = mbrtoc32 (NULL, buf, 1, &state);
149 ASSERT (ret == 1);
150 ASSERT (mbsinit (&state));
151 break;
155 /* Test special calling convention, passing a NULL pointer. */
157 memset (&state, '\0', sizeof (mbstate_t));
158 wc = (char32_t) 0xBADFACE;
159 ret = mbrtoc32 (&wc, NULL, 5, &state);
160 ASSERT (ret == 0);
161 ASSERT (wc == (char32_t) 0xBADFACE);
162 ASSERT (mbsinit (&state));
165 switch (codepage)
167 case 1252:
168 /* Locale encoding is CP1252, an extension of ISO-8859-1. */
170 char input[] = "B\374\337er"; /* "Büßer" */
171 memset (&state, '\0', sizeof (mbstate_t));
173 wc = (char32_t) 0xBADFACE;
174 ret = mbrtoc32 (&wc, input, 1, &state);
175 ASSERT (ret == 1);
176 ASSERT (wc == 'B');
177 ASSERT (mbsinit (&state));
178 input[0] = '\0';
180 wc = (char32_t) 0xBADFACE;
181 ret = mbrtoc32 (&wc, input + 1, 1, &state);
182 ASSERT (ret == 1);
183 ASSERT (c32tob (wc) == (unsigned char) '\374');
184 ASSERT (wc == 0x00FC); /* expect Unicode encoding */
185 ASSERT (mbsinit (&state));
186 input[1] = '\0';
188 /* Test support of NULL first argument. */
189 ret = mbrtoc32 (NULL, input + 2, 3, &state);
190 ASSERT (ret == 1);
191 ASSERT (mbsinit (&state));
193 wc = (char32_t) 0xBADFACE;
194 ret = mbrtoc32 (&wc, input + 2, 3, &state);
195 ASSERT (ret == 1);
196 ASSERT (c32tob (wc) == (unsigned char) '\337');
197 ASSERT (wc == 0x00DF); /* expect Unicode encoding */
198 ASSERT (mbsinit (&state));
199 input[2] = '\0';
201 wc = (char32_t) 0xBADFACE;
202 ret = mbrtoc32 (&wc, input + 3, 2, &state);
203 ASSERT (ret == 1);
204 ASSERT (wc == 'e');
205 ASSERT (mbsinit (&state));
206 input[3] = '\0';
208 wc = (char32_t) 0xBADFACE;
209 ret = mbrtoc32 (&wc, input + 4, 1, &state);
210 ASSERT (ret == 1);
211 ASSERT (wc == 'r');
212 ASSERT (mbsinit (&state));
214 return 0;
216 case 1256:
217 /* Locale encoding is CP1256, not the same as ISO-8859-6. */
219 char input[] = "x\302\341\346y"; /* "xآلوy" */
220 memset (&state, '\0', sizeof (mbstate_t));
222 wc = (char32_t) 0xBADFACE;
223 ret = mbrtoc32 (&wc, input, 1, &state);
224 ASSERT (ret == 1);
225 ASSERT (wc == 'x');
226 ASSERT (mbsinit (&state));
227 input[0] = '\0';
229 wc = (char32_t) 0xBADFACE;
230 ret = mbrtoc32 (&wc, input + 1, 1, &state);
231 ASSERT (ret == 1);
232 ASSERT (c32tob (wc) == (unsigned char) '\302');
233 ASSERT (wc == 0x0622); /* expect Unicode encoding */
234 ASSERT (mbsinit (&state));
235 input[1] = '\0';
237 /* Test support of NULL first argument. */
238 ret = mbrtoc32 (NULL, input + 2, 3, &state);
239 ASSERT (ret == 1);
240 ASSERT (mbsinit (&state));
242 wc = (char32_t) 0xBADFACE;
243 ret = mbrtoc32 (&wc, input + 2, 3, &state);
244 ASSERT (ret == 1);
245 ASSERT (c32tob (wc) == (unsigned char) '\341');
246 ASSERT (wc == 0x0644); /* expect Unicode encoding */
247 ASSERT (mbsinit (&state));
248 input[2] = '\0';
250 wc = (char32_t) 0xBADFACE;
251 ret = mbrtoc32 (&wc, input + 3, 2, &state);
252 ASSERT (ret == 1);
253 ASSERT (c32tob (wc) == (unsigned char) '\346');
254 ASSERT (wc == 0x0648); /* expect Unicode encoding */
255 ASSERT (mbsinit (&state));
256 input[3] = '\0';
258 wc = (char32_t) 0xBADFACE;
259 ret = mbrtoc32 (&wc, input + 4, 1, &state);
260 ASSERT (ret == 1);
261 ASSERT (wc == 'y');
262 ASSERT (mbsinit (&state));
264 return 0;
266 case 65001:
267 /* Locale encoding is CP65001 = UTF-8. */
268 if (strcmp (locale_charset (), "UTF-8") != 0)
269 return 77;
271 char input[] = "s\303\274\303\237\360\237\230\213!"; /* "süß😋!" */
272 memset (&state, '\0', sizeof (mbstate_t));
274 wc = (char32_t) 0xBADFACE;
275 ret = mbrtoc32 (&wc, input, 1, &state);
276 ASSERT (ret == 1);
277 ASSERT (wc == 's');
278 ASSERT (mbsinit (&state));
279 input[0] = '\0';
281 wc = (char32_t) 0xBADFACE;
282 ret = mbrtoc32 (&wc, input + 1, 1, &state);
283 ASSERT (ret == (size_t)(-2));
284 ASSERT (wc == (char32_t) 0xBADFACE);
285 ASSERT (!mbsinit (&state));
286 input[1] = '\0';
288 wc = (char32_t) 0xBADFACE;
289 ret = mbrtoc32 (&wc, input + 2, 7, &state);
290 ASSERT (ret == 1);
291 ASSERT (c32tob (wc) == EOF);
292 ASSERT (wc == 0x00FC); /* expect Unicode encoding */
293 ASSERT (mbsinit (&state));
294 input[2] = '\0';
296 /* Test support of NULL first argument. */
297 ret = mbrtoc32 (NULL, input + 3, 6, &state);
298 ASSERT (ret == 2);
299 ASSERT (mbsinit (&state));
301 wc = (char32_t) 0xBADFACE;
302 ret = mbrtoc32 (&wc, input + 3, 6, &state);
303 ASSERT (ret == 2);
304 ASSERT (c32tob (wc) == EOF);
305 ASSERT (wc == 0x00DF); /* expect Unicode encoding */
306 ASSERT (mbsinit (&state));
307 input[3] = '\0';
308 input[4] = '\0';
310 /* Test support of NULL first argument. */
311 ret = mbrtoc32 (NULL, input + 5, 4, &state);
312 ASSERT (ret == 4);
313 ASSERT (mbsinit (&state));
315 wc = (char32_t) 0xBADFACE;
316 ret = mbrtoc32 (&wc, input + 5, 4, &state);
317 ASSERT (ret == 4);
318 ASSERT (c32tob (wc) == EOF);
319 ASSERT (wc == 0x1F60B); /* expect Unicode encoding */
320 ASSERT (mbsinit (&state));
321 input[5] = '\0';
322 input[6] = '\0';
323 input[7] = '\0';
324 input[8] = '\0';
326 wc = (char32_t) 0xBADFACE;
327 ret = mbrtoc32 (&wc, input + 9, 1, &state);
328 ASSERT (ret == 1);
329 ASSERT (wc == '!');
330 ASSERT (mbsinit (&state));
332 /* Test some invalid input. */
333 memset (&state, '\0', sizeof (mbstate_t));
334 wc = (char32_t) 0xBADFACE;
335 ret = mbrtoc32 (&wc, "\377", 1, &state); /* 0xFF */
336 ASSERT (ret == (size_t)-1);
337 ASSERT (errno == EILSEQ);
339 memset (&state, '\0', sizeof (mbstate_t));
340 wc = (char32_t) 0xBADFACE;
341 ret = mbrtoc32 (&wc, "\303\300", 2, &state); /* 0xC3 0xC0 */
342 ASSERT (ret == (size_t)-1);
343 ASSERT (errno == EILSEQ);
345 memset (&state, '\0', sizeof (mbstate_t));
346 wc = (char32_t) 0xBADFACE;
347 ret = mbrtoc32 (&wc, "\343\300", 2, &state); /* 0xE3 0xC0 */
348 ASSERT (ret == (size_t)-1);
349 ASSERT (errno == EILSEQ);
351 memset (&state, '\0', sizeof (mbstate_t));
352 wc = (char32_t) 0xBADFACE;
353 ret = mbrtoc32 (&wc, "\343\300\200", 3, &state); /* 0xE3 0xC0 0x80 */
354 ASSERT (ret == (size_t)-1);
355 ASSERT (errno == EILSEQ);
357 memset (&state, '\0', sizeof (mbstate_t));
358 wc = (char32_t) 0xBADFACE;
359 ret = mbrtoc32 (&wc, "\343\200\300", 3, &state); /* 0xE3 0x80 0xC0 */
360 ASSERT (ret == (size_t)-1);
361 ASSERT (errno == EILSEQ);
363 memset (&state, '\0', sizeof (mbstate_t));
364 wc = (char32_t) 0xBADFACE;
365 ret = mbrtoc32 (&wc, "\363\300", 2, &state); /* 0xF3 0xC0 */
366 ASSERT (ret == (size_t)-1);
367 ASSERT (errno == EILSEQ);
369 memset (&state, '\0', sizeof (mbstate_t));
370 wc = (char32_t) 0xBADFACE;
371 ret = mbrtoc32 (&wc, "\363\300\200\200", 4, &state); /* 0xF3 0xC0 0x80 0x80 */
372 ASSERT (ret == (size_t)-1);
373 ASSERT (errno == EILSEQ);
375 memset (&state, '\0', sizeof (mbstate_t));
376 wc = (char32_t) 0xBADFACE;
377 ret = mbrtoc32 (&wc, "\363\200\300", 3, &state); /* 0xF3 0x80 0xC0 */
378 ASSERT (ret == (size_t)-1);
379 ASSERT (errno == EILSEQ);
381 memset (&state, '\0', sizeof (mbstate_t));
382 wc = (char32_t) 0xBADFACE;
383 ret = mbrtoc32 (&wc, "\363\200\300\200", 4, &state); /* 0xF3 0x80 0xC0 0x80 */
384 ASSERT (ret == (size_t)-1);
385 ASSERT (errno == EILSEQ);
387 memset (&state, '\0', sizeof (mbstate_t));
388 wc = (char32_t) 0xBADFACE;
389 ret = mbrtoc32 (&wc, "\363\200\200\300", 4, &state); /* 0xF3 0x80 0x80 0xC0 */
390 ASSERT (ret == (size_t)-1);
391 ASSERT (errno == EILSEQ);
393 return 0;
395 case 932:
396 /* Locale encoding is CP932, similar to Shift_JIS. */
398 char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
399 memset (&state, '\0', sizeof (mbstate_t));
401 wc = (char32_t) 0xBADFACE;
402 ret = mbrtoc32 (&wc, input, 1, &state);
403 ASSERT (ret == 1);
404 ASSERT (wc == '<');
405 ASSERT (mbsinit (&state));
406 input[0] = '\0';
408 wc = (char32_t) 0xBADFACE;
409 ret = mbrtoc32 (&wc, input + 1, 2, &state);
410 ASSERT (ret == 2);
411 ASSERT (c32tob (wc) == EOF);
412 ASSERT (wc == 0x65E5); /* expect Unicode encoding */
413 ASSERT (mbsinit (&state));
414 input[1] = '\0';
415 input[2] = '\0';
417 wc = (char32_t) 0xBADFACE;
418 ret = mbrtoc32 (&wc, input + 3, 1, &state);
419 ASSERT (ret == (size_t)(-2));
420 ASSERT (wc == (char32_t) 0xBADFACE);
421 ASSERT (!mbsinit (&state));
422 input[3] = '\0';
424 wc = (char32_t) 0xBADFACE;
425 ret = mbrtoc32 (&wc, input + 4, 4, &state);
426 ASSERT (ret == 1);
427 ASSERT (c32tob (wc) == EOF);
428 ASSERT (wc == 0x672C); /* expect Unicode encoding */
429 ASSERT (mbsinit (&state));
430 input[4] = '\0';
432 /* Test support of NULL first argument. */
433 ret = mbrtoc32 (NULL, input + 5, 3, &state);
434 ASSERT (ret == 2);
435 ASSERT (mbsinit (&state));
437 wc = (char32_t) 0xBADFACE;
438 ret = mbrtoc32 (&wc, input + 5, 3, &state);
439 ASSERT (ret == 2);
440 ASSERT (c32tob (wc) == EOF);
441 ASSERT (wc == 0x8A9E); /* expect Unicode encoding */
442 ASSERT (mbsinit (&state));
443 input[5] = '\0';
444 input[6] = '\0';
446 wc = (char32_t) 0xBADFACE;
447 ret = mbrtoc32 (&wc, input + 7, 1, &state);
448 ASSERT (ret == 1);
449 ASSERT (wc == '>');
450 ASSERT (mbsinit (&state));
452 /* Test some invalid input. */
453 memset (&state, '\0', sizeof (mbstate_t));
454 wc = (char32_t) 0xBADFACE;
455 ret = mbrtoc32 (&wc, "\377", 1, &state); /* 0xFF */
456 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
458 memset (&state, '\0', sizeof (mbstate_t));
459 wc = (char32_t) 0xBADFACE;
460 ret = mbrtoc32 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
461 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == 0x30FB));
463 return 0;
465 case 950:
466 /* Locale encoding is CP950, similar to Big5. */
468 char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
469 memset (&state, '\0', sizeof (mbstate_t));
471 wc = (char32_t) 0xBADFACE;
472 ret = mbrtoc32 (&wc, input, 1, &state);
473 ASSERT (ret == 1);
474 ASSERT (wc == '<');
475 ASSERT (mbsinit (&state));
476 input[0] = '\0';
478 wc = (char32_t) 0xBADFACE;
479 ret = mbrtoc32 (&wc, input + 1, 2, &state);
480 ASSERT (ret == 2);
481 ASSERT (c32tob (wc) == EOF);
482 ASSERT (wc == 0x65E5); /* expect Unicode encoding */
483 ASSERT (mbsinit (&state));
484 input[1] = '\0';
485 input[2] = '\0';
487 wc = (char32_t) 0xBADFACE;
488 ret = mbrtoc32 (&wc, input + 3, 1, &state);
489 ASSERT (ret == (size_t)(-2));
490 ASSERT (wc == (char32_t) 0xBADFACE);
491 ASSERT (!mbsinit (&state));
492 input[3] = '\0';
494 wc = (char32_t) 0xBADFACE;
495 ret = mbrtoc32 (&wc, input + 4, 4, &state);
496 ASSERT (ret == 1);
497 ASSERT (c32tob (wc) == EOF);
498 ASSERT (wc == 0x672C); /* expect Unicode encoding */
499 ASSERT (mbsinit (&state));
500 input[4] = '\0';
502 /* Test support of NULL first argument. */
503 ret = mbrtoc32 (NULL, input + 5, 3, &state);
504 ASSERT (ret == 2);
505 ASSERT (mbsinit (&state));
507 wc = (char32_t) 0xBADFACE;
508 ret = mbrtoc32 (&wc, input + 5, 3, &state);
509 ASSERT (ret == 2);
510 ASSERT (c32tob (wc) == EOF);
511 ASSERT (wc == 0x8A9E); /* expect Unicode encoding */
512 ASSERT (mbsinit (&state));
513 input[5] = '\0';
514 input[6] = '\0';
516 wc = (char32_t) 0xBADFACE;
517 ret = mbrtoc32 (&wc, input + 7, 1, &state);
518 ASSERT (ret == 1);
519 ASSERT (wc == '>');
520 ASSERT (mbsinit (&state));
522 /* Test some invalid input. */
523 memset (&state, '\0', sizeof (mbstate_t));
524 wc = (char32_t) 0xBADFACE;
525 ret = mbrtoc32 (&wc, "\377", 1, &state); /* 0xFF */
526 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
528 memset (&state, '\0', sizeof (mbstate_t));
529 wc = (char32_t) 0xBADFACE;
530 ret = mbrtoc32 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
531 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
533 return 0;
535 case 936:
536 /* Locale encoding is CP936 = GBK, an extension of GB2312. */
538 char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
539 memset (&state, '\0', sizeof (mbstate_t));
541 wc = (char32_t) 0xBADFACE;
542 ret = mbrtoc32 (&wc, input, 1, &state);
543 ASSERT (ret == 1);
544 ASSERT (wc == '<');
545 ASSERT (mbsinit (&state));
546 input[0] = '\0';
548 wc = (char32_t) 0xBADFACE;
549 ret = mbrtoc32 (&wc, input + 1, 2, &state);
550 ASSERT (ret == 2);
551 ASSERT (c32tob (wc) == EOF);
552 ASSERT (wc == 0x65E5); /* expect Unicode encoding */
553 ASSERT (mbsinit (&state));
554 input[1] = '\0';
555 input[2] = '\0';
557 wc = (char32_t) 0xBADFACE;
558 ret = mbrtoc32 (&wc, input + 3, 1, &state);
559 ASSERT (ret == (size_t)(-2));
560 ASSERT (wc == (char32_t) 0xBADFACE);
561 ASSERT (!mbsinit (&state));
562 input[3] = '\0';
564 wc = (char32_t) 0xBADFACE;
565 ret = mbrtoc32 (&wc, input + 4, 4, &state);
566 ASSERT (ret == 1);
567 ASSERT (c32tob (wc) == EOF);
568 ASSERT (wc == 0x672C); /* expect Unicode encoding */
569 ASSERT (mbsinit (&state));
570 input[4] = '\0';
572 /* Test support of NULL first argument. */
573 ret = mbrtoc32 (NULL, input + 5, 3, &state);
574 ASSERT (ret == 2);
575 ASSERT (mbsinit (&state));
577 wc = (char32_t) 0xBADFACE;
578 ret = mbrtoc32 (&wc, input + 5, 3, &state);
579 ASSERT (ret == 2);
580 ASSERT (c32tob (wc) == EOF);
581 ASSERT (wc == 0x8A9E); /* expect Unicode encoding */
582 ASSERT (mbsinit (&state));
583 input[5] = '\0';
584 input[6] = '\0';
586 wc = (char32_t) 0xBADFACE;
587 ret = mbrtoc32 (&wc, input + 7, 1, &state);
588 ASSERT (ret == 1);
589 ASSERT (wc == '>');
590 ASSERT (mbsinit (&state));
592 /* Test some invalid input. */
593 memset (&state, '\0', sizeof (mbstate_t));
594 wc = (char32_t) 0xBADFACE;
595 ret = mbrtoc32 (&wc, "\377", 1, &state); /* 0xFF */
596 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
598 memset (&state, '\0', sizeof (mbstate_t));
599 wc = (char32_t) 0xBADFACE;
600 ret = mbrtoc32 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
601 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
603 return 0;
605 case 54936:
606 /* Locale encoding is CP54936 = GB18030. */
607 if (strcmp (locale_charset (), "GB18030") != 0)
608 return 77;
610 char input[] = "s\250\271\201\060\211\070\224\071\375\067!"; /* "süß😋!" */
611 memset (&state, '\0', sizeof (mbstate_t));
613 wc = (char32_t) 0xBADFACE;
614 ret = mbrtoc32 (&wc, input, 1, &state);
615 ASSERT (ret == 1);
616 ASSERT (wc == 's');
617 ASSERT (mbsinit (&state));
618 input[0] = '\0';
620 wc = (char32_t) 0xBADFACE;
621 ret = mbrtoc32 (&wc, input + 1, 1, &state);
622 ASSERT (ret == (size_t)(-2));
623 ASSERT (wc == (char32_t) 0xBADFACE);
624 ASSERT (!mbsinit (&state));
625 input[1] = '\0';
627 wc = (char32_t) 0xBADFACE;
628 ret = mbrtoc32 (&wc, input + 2, 9, &state);
629 ASSERT (ret == 1);
630 ASSERT (c32tob (wc) == EOF);
631 ASSERT (wc == 0x00FC); /* expect Unicode encoding */
632 ASSERT (mbsinit (&state));
633 input[2] = '\0';
635 /* Test support of NULL first argument. */
636 ret = mbrtoc32 (NULL, input + 3, 8, &state);
637 ASSERT (ret == 4);
638 ASSERT (mbsinit (&state));
640 wc = (char32_t) 0xBADFACE;
641 ret = mbrtoc32 (&wc, input + 3, 8, &state);
642 ASSERT (ret == 4);
643 ASSERT (c32tob (wc) == EOF);
644 ASSERT (wc == 0x00DF); /* expect Unicode encoding */
645 ASSERT (mbsinit (&state));
646 input[3] = '\0';
647 input[4] = '\0';
648 input[5] = '\0';
649 input[6] = '\0';
651 /* Test support of NULL first argument. */
652 ret = mbrtoc32 (NULL, input + 7, 4, &state);
653 ASSERT (ret == 4);
654 ASSERT (mbsinit (&state));
656 wc = (char32_t) 0xBADFACE;
657 ret = mbrtoc32 (&wc, input + 7, 4, &state);
658 ASSERT (ret == 4);
659 ASSERT (c32tob (wc) == EOF);
660 ASSERT (wc == 0x1F60B); /* expect Unicode encoding */
661 ASSERT (mbsinit (&state));
662 input[7] = '\0';
663 input[8] = '\0';
664 input[9] = '\0';
665 input[10] = '\0';
667 wc = (char32_t) 0xBADFACE;
668 ret = mbrtoc32 (&wc, input + 11, 1, &state);
669 ASSERT (ret == 1);
670 ASSERT (wc == '!');
671 ASSERT (mbsinit (&state));
673 /* Test some invalid input. */
674 memset (&state, '\0', sizeof (mbstate_t));
675 wc = (char32_t) 0xBADFACE;
676 ret = mbrtoc32 (&wc, "\377", 1, &state); /* 0xFF */
677 ASSERT (ret == (size_t)-1);
678 ASSERT (errno == EILSEQ);
680 memset (&state, '\0', sizeof (mbstate_t));
681 wc = (char32_t) 0xBADFACE;
682 ret = mbrtoc32 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
683 ASSERT (ret == (size_t)-1);
684 ASSERT (errno == EILSEQ);
686 memset (&state, '\0', sizeof (mbstate_t));
687 wc = (char32_t) 0xBADFACE;
688 ret = mbrtoc32 (&wc, "\201\045", 2, &state); /* 0x81 0x25 */
689 ASSERT (ret == (size_t)-1);
690 ASSERT (errno == EILSEQ);
692 memset (&state, '\0', sizeof (mbstate_t));
693 wc = (char32_t) 0xBADFACE;
694 ret = mbrtoc32 (&wc, "\201\060\377", 3, &state); /* 0x81 0x30 0xFF */
695 ASSERT (ret == (size_t)-1);
696 ASSERT (errno == EILSEQ);
698 memset (&state, '\0', sizeof (mbstate_t));
699 wc = (char32_t) 0xBADFACE;
700 ret = mbrtoc32 (&wc, "\201\060\377\064", 4, &state); /* 0x81 0x30 0xFF 0x34 */
701 ASSERT (ret == (size_t)-1);
702 ASSERT (errno == EILSEQ);
704 memset (&state, '\0', sizeof (mbstate_t));
705 wc = (char32_t) 0xBADFACE;
706 ret = mbrtoc32 (&wc, "\201\060\211\072", 4, &state); /* 0x81 0x30 0x89 0x3A */
707 ASSERT (ret == (size_t)-1);
708 ASSERT (errno == EILSEQ);
710 return 0;
712 default:
713 return 1;
718 main (int argc, char *argv[])
720 int codepage = atoi (argv[argc - 1]);
721 int result;
722 int i;
724 result = 77;
725 for (i = 1; i < argc - 1; i++)
727 int ret = test_one_locale (argv[i], codepage);
729 if (ret != 77)
730 result = ret;
733 if (result == 77)
735 if (test_exit_status != EXIT_SUCCESS)
736 return test_exit_status;
737 fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
738 codepage);
740 return (result ? result : test_exit_status);
743 #else
746 main (int argc, char *argv[])
748 fputs ("Skipping test: not a native Windows system\n", stderr);
749 return 77;
752 #endif