openat: don’t close (-1)
[gnulib.git] / tests / test-mbrtoc16-w32.c
blob36528483a3ee059ef5cd96b1ad571d5ca52cd028
1 /* Test of conversion of multibyte character to 16-bit wide characters.
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 char16_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 (mbrtoc16 (&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 = (char16_t) 0xBADF;
93 ret = mbrtoc16 (&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 = (char16_t) 0xBADF;
102 ret = mbrtoc16 (&wc, "", 1, &state);
103 ASSERT (ret == 0);
104 ASSERT (wc == 0);
105 ASSERT (mbsinit (&state));
106 ret = mbrtoc16 (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 = (char16_t) 0xBADF;
144 ret = mbrtoc16 (&wc, buf, 1, &state);
145 ASSERT (ret == 1);
146 ASSERT (wc == c);
147 ASSERT (mbsinit (&state));
148 ret = mbrtoc16 (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 = (char16_t) 0xBADF;
159 ret = mbrtoc16 (&wc, NULL, 5, &state);
160 ASSERT (ret == 0);
161 ASSERT (wc == (char16_t) 0xBADF);
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 = (char16_t) 0xBADF;
174 ret = mbrtoc16 (&wc, input, 1, &state);
175 ASSERT (ret == 1);
176 ASSERT (wc == 'B');
177 ASSERT (mbsinit (&state));
178 input[0] = '\0';
180 wc = (char16_t) 0xBADF;
181 ret = mbrtoc16 (&wc, input + 1, 1, &state);
182 ASSERT (ret == 1);
183 ASSERT (c32tob (wc) == (unsigned char) '\374');
184 ASSERT (wc == 0x00FC);
185 ASSERT (mbsinit (&state));
186 input[1] = '\0';
188 /* Test support of NULL first argument. */
189 ret = mbrtoc16 (NULL, input + 2, 3, &state);
190 ASSERT (ret == 1);
191 ASSERT (mbsinit (&state));
193 wc = (char16_t) 0xBADF;
194 ret = mbrtoc16 (&wc, input + 2, 3, &state);
195 ASSERT (ret == 1);
196 ASSERT (c32tob (wc) == (unsigned char) '\337');
197 ASSERT (wc == 0x00DF);
198 ASSERT (mbsinit (&state));
199 input[2] = '\0';
201 wc = (char16_t) 0xBADF;
202 ret = mbrtoc16 (&wc, input + 3, 2, &state);
203 ASSERT (ret == 1);
204 ASSERT (wc == 'e');
205 ASSERT (mbsinit (&state));
206 input[3] = '\0';
208 wc = (char16_t) 0xBADF;
209 ret = mbrtoc16 (&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 = (char16_t) 0xBADF;
223 ret = mbrtoc16 (&wc, input, 1, &state);
224 ASSERT (ret == 1);
225 ASSERT (wc == 'x');
226 ASSERT (mbsinit (&state));
227 input[0] = '\0';
229 wc = (char16_t) 0xBADF;
230 ret = mbrtoc16 (&wc, input + 1, 1, &state);
231 ASSERT (ret == 1);
232 ASSERT (c32tob (wc) == (unsigned char) '\302');
233 ASSERT (wc == 0x0622);
234 ASSERT (mbsinit (&state));
235 input[1] = '\0';
237 /* Test support of NULL first argument. */
238 ret = mbrtoc16 (NULL, input + 2, 3, &state);
239 ASSERT (ret == 1);
240 ASSERT (mbsinit (&state));
242 wc = (char16_t) 0xBADF;
243 ret = mbrtoc16 (&wc, input + 2, 3, &state);
244 ASSERT (ret == 1);
245 ASSERT (c32tob (wc) == (unsigned char) '\341');
246 ASSERT (wc == 0x0644);
247 ASSERT (mbsinit (&state));
248 input[2] = '\0';
250 wc = (char16_t) 0xBADF;
251 ret = mbrtoc16 (&wc, input + 3, 2, &state);
252 ASSERT (ret == 1);
253 ASSERT (c32tob (wc) == (unsigned char) '\346');
254 ASSERT (wc == 0x0648);
255 ASSERT (mbsinit (&state));
256 input[3] = '\0';
258 wc = (char16_t) 0xBADF;
259 ret = mbrtoc16 (&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 = (char16_t) 0xBADF;
275 ret = mbrtoc16 (&wc, input, 1, &state);
276 ASSERT (ret == 1);
277 ASSERT (wc == 's');
278 ASSERT (mbsinit (&state));
279 input[0] = '\0';
281 wc = (char16_t) 0xBADF;
282 ret = mbrtoc16 (&wc, input + 1, 1, &state);
283 ASSERT (ret == (size_t)(-2));
284 ASSERT (wc == (char16_t) 0xBADF);
285 #if 0
286 ASSERT (!mbsinit (&state));
287 #endif
288 input[1] = '\0';
290 wc = (char16_t) 0xBADF;
291 ret = mbrtoc16 (&wc, input + 2, 7, &state);
292 ASSERT (ret == 1);
293 ASSERT (c32tob (wc) == EOF);
294 ASSERT (wc == 0x00FC);
295 ASSERT (mbsinit (&state));
296 input[2] = '\0';
298 /* Test support of NULL first argument. */
299 ret = mbrtoc16 (NULL, input + 3, 6, &state);
300 ASSERT (ret == 2);
301 ASSERT (mbsinit (&state));
303 wc = (char16_t) 0xBADF;
304 ret = mbrtoc16 (&wc, input + 3, 6, &state);
305 ASSERT (ret == 2);
306 ASSERT (c32tob (wc) == EOF);
307 ASSERT (wc == 0x00DF);
308 ASSERT (mbsinit (&state));
309 input[3] = '\0';
310 input[4] = '\0';
312 /* Test support of NULL first argument. */
313 ret = mbrtoc16 (NULL, input + 5, 4, &state);
314 ASSERT (ret == 4);
315 ret = mbrtoc16 (NULL, input + 9, 0, &state);
316 ASSERT (ret == (size_t)(-3));
317 ASSERT (mbsinit (&state));
319 wc = (char16_t) 0xBADF;
320 ret = mbrtoc16 (&wc, input + 5, 4, &state);
321 ASSERT (ret == 4);
322 ASSERT (c32tob (wc) == EOF);
323 ASSERT (wc == 0xD83D); /* expect UTF-16 encoding */
324 input[5] = '\0';
325 input[6] = '\0';
326 input[7] = '\0';
327 input[8] = '\0';
328 wc = (char16_t) 0xBADF;
329 ret = mbrtoc16 (&wc, input + 9, 0, &state);
330 ASSERT (ret == (size_t)(-3));
331 ASSERT (c32tob (wc) == EOF);
332 ASSERT (wc == 0xDE0B); /* expect UTF-16 encoding */
333 ASSERT (mbsinit (&state));
335 wc = (char16_t) 0xBADF;
336 ret = mbrtoc16 (&wc, input + 9, 1, &state);
337 ASSERT (ret == 1);
338 ASSERT (wc == '!');
339 ASSERT (mbsinit (&state));
341 /* Test some invalid input. */
342 memset (&state, '\0', sizeof (mbstate_t));
343 wc = (char16_t) 0xBADF;
344 ret = mbrtoc16 (&wc, "\377", 1, &state); /* 0xFF */
345 ASSERT (ret == (size_t)-1);
346 ASSERT (errno == EILSEQ);
348 memset (&state, '\0', sizeof (mbstate_t));
349 wc = (char16_t) 0xBADF;
350 ret = mbrtoc16 (&wc, "\303\300", 2, &state); /* 0xC3 0xC0 */
351 ASSERT (ret == (size_t)-1);
352 ASSERT (errno == EILSEQ);
354 memset (&state, '\0', sizeof (mbstate_t));
355 wc = (char16_t) 0xBADF;
356 ret = mbrtoc16 (&wc, "\343\300", 2, &state); /* 0xE3 0xC0 */
357 ASSERT (ret == (size_t)-1);
358 ASSERT (errno == EILSEQ);
360 memset (&state, '\0', sizeof (mbstate_t));
361 wc = (char16_t) 0xBADF;
362 ret = mbrtoc16 (&wc, "\343\300\200", 3, &state); /* 0xE3 0xC0 0x80 */
363 ASSERT (ret == (size_t)-1);
364 ASSERT (errno == EILSEQ);
366 memset (&state, '\0', sizeof (mbstate_t));
367 wc = (char16_t) 0xBADF;
368 ret = mbrtoc16 (&wc, "\343\200\300", 3, &state); /* 0xE3 0x80 0xC0 */
369 ASSERT (ret == (size_t)-1);
370 ASSERT (errno == EILSEQ);
372 memset (&state, '\0', sizeof (mbstate_t));
373 wc = (char16_t) 0xBADF;
374 ret = mbrtoc16 (&wc, "\363\300", 2, &state); /* 0xF3 0xC0 */
375 ASSERT (ret == (size_t)-1);
376 ASSERT (errno == EILSEQ);
378 memset (&state, '\0', sizeof (mbstate_t));
379 wc = (char16_t) 0xBADF;
380 ret = mbrtoc16 (&wc, "\363\300\200\200", 4, &state); /* 0xF3 0xC0 0x80 0x80 */
381 ASSERT (ret == (size_t)-1);
382 ASSERT (errno == EILSEQ);
384 memset (&state, '\0', sizeof (mbstate_t));
385 wc = (char16_t) 0xBADF;
386 ret = mbrtoc16 (&wc, "\363\200\300", 3, &state); /* 0xF3 0x80 0xC0 */
387 ASSERT (ret == (size_t)-1);
388 ASSERT (errno == EILSEQ);
390 memset (&state, '\0', sizeof (mbstate_t));
391 wc = (char16_t) 0xBADF;
392 ret = mbrtoc16 (&wc, "\363\200\300\200", 4, &state); /* 0xF3 0x80 0xC0 0x80 */
393 ASSERT (ret == (size_t)-1);
394 ASSERT (errno == EILSEQ);
396 memset (&state, '\0', sizeof (mbstate_t));
397 wc = (char16_t) 0xBADF;
398 ret = mbrtoc16 (&wc, "\363\200\200\300", 4, &state); /* 0xF3 0x80 0x80 0xC0 */
399 ASSERT (ret == (size_t)-1);
400 ASSERT (errno == EILSEQ);
402 return 0;
404 case 932:
405 /* Locale encoding is CP932, similar to Shift_JIS. */
407 char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
408 memset (&state, '\0', sizeof (mbstate_t));
410 wc = (char16_t) 0xBADF;
411 ret = mbrtoc16 (&wc, input, 1, &state);
412 ASSERT (ret == 1);
413 ASSERT (wc == '<');
414 ASSERT (mbsinit (&state));
415 input[0] = '\0';
417 wc = (char16_t) 0xBADF;
418 ret = mbrtoc16 (&wc, input + 1, 2, &state);
419 ASSERT (ret == 2);
420 ASSERT (c32tob (wc) == EOF);
421 ASSERT (wc == 0x65E5);
422 ASSERT (mbsinit (&state));
423 input[1] = '\0';
424 input[2] = '\0';
426 wc = (char16_t) 0xBADF;
427 ret = mbrtoc16 (&wc, input + 3, 1, &state);
428 ASSERT (ret == (size_t)(-2));
429 ASSERT (wc == (char16_t) 0xBADF);
430 #if 0
431 ASSERT (!mbsinit (&state));
432 #endif
433 input[3] = '\0';
435 wc = (char16_t) 0xBADF;
436 ret = mbrtoc16 (&wc, input + 4, 4, &state);
437 ASSERT (ret == 1);
438 ASSERT (c32tob (wc) == EOF);
439 ASSERT (wc == 0x672C);
440 ASSERT (mbsinit (&state));
441 input[4] = '\0';
443 /* Test support of NULL first argument. */
444 ret = mbrtoc16 (NULL, input + 5, 3, &state);
445 ASSERT (ret == 2);
446 ASSERT (mbsinit (&state));
448 wc = (char16_t) 0xBADF;
449 ret = mbrtoc16 (&wc, input + 5, 3, &state);
450 ASSERT (ret == 2);
451 ASSERT (c32tob (wc) == EOF);
452 ASSERT (wc == 0x8A9E);
453 ASSERT (mbsinit (&state));
454 input[5] = '\0';
455 input[6] = '\0';
457 wc = (char16_t) 0xBADF;
458 ret = mbrtoc16 (&wc, input + 7, 1, &state);
459 ASSERT (ret == 1);
460 ASSERT (wc == '>');
461 ASSERT (mbsinit (&state));
463 /* Test some invalid input. */
464 memset (&state, '\0', sizeof (mbstate_t));
465 wc = (char16_t) 0xBADF;
466 ret = mbrtoc16 (&wc, "\377", 1, &state); /* 0xFF */
467 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
469 memset (&state, '\0', sizeof (mbstate_t));
470 wc = (char16_t) 0xBADF;
471 ret = mbrtoc16 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
472 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == 0x30FB));
474 return 0;
476 case 950:
477 /* Locale encoding is CP950, similar to Big5. */
479 char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
480 memset (&state, '\0', sizeof (mbstate_t));
482 wc = (char16_t) 0xBADF;
483 ret = mbrtoc16 (&wc, input, 1, &state);
484 ASSERT (ret == 1);
485 ASSERT (wc == '<');
486 ASSERT (mbsinit (&state));
487 input[0] = '\0';
489 wc = (char16_t) 0xBADF;
490 ret = mbrtoc16 (&wc, input + 1, 2, &state);
491 ASSERT (ret == 2);
492 ASSERT (c32tob (wc) == EOF);
493 ASSERT (wc == 0x65E5);
494 ASSERT (mbsinit (&state));
495 input[1] = '\0';
496 input[2] = '\0';
498 wc = (char16_t) 0xBADF;
499 ret = mbrtoc16 (&wc, input + 3, 1, &state);
500 ASSERT (ret == (size_t)(-2));
501 ASSERT (wc == (char16_t) 0xBADF);
502 #if 0
503 ASSERT (!mbsinit (&state));
504 #endif
505 input[3] = '\0';
507 wc = (char16_t) 0xBADF;
508 ret = mbrtoc16 (&wc, input + 4, 4, &state);
509 ASSERT (ret == 1);
510 ASSERT (c32tob (wc) == EOF);
511 ASSERT (wc == 0x672C);
512 ASSERT (mbsinit (&state));
513 input[4] = '\0';
515 /* Test support of NULL first argument. */
516 ret = mbrtoc16 (NULL, input + 5, 3, &state);
517 ASSERT (ret == 2);
518 ASSERT (mbsinit (&state));
520 wc = (char16_t) 0xBADF;
521 ret = mbrtoc16 (&wc, input + 5, 3, &state);
522 ASSERT (ret == 2);
523 ASSERT (c32tob (wc) == EOF);
524 ASSERT (wc == 0x8A9E);
525 ASSERT (mbsinit (&state));
526 input[5] = '\0';
527 input[6] = '\0';
529 wc = (char16_t) 0xBADF;
530 ret = mbrtoc16 (&wc, input + 7, 1, &state);
531 ASSERT (ret == 1);
532 ASSERT (wc == '>');
533 ASSERT (mbsinit (&state));
535 /* Test some invalid input. */
536 memset (&state, '\0', sizeof (mbstate_t));
537 wc = (char16_t) 0xBADF;
538 ret = mbrtoc16 (&wc, "\377", 1, &state); /* 0xFF */
539 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
541 memset (&state, '\0', sizeof (mbstate_t));
542 wc = (char16_t) 0xBADF;
543 ret = mbrtoc16 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
544 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
546 return 0;
548 case 936:
549 /* Locale encoding is CP936 = GBK, an extension of GB2312. */
551 char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
552 memset (&state, '\0', sizeof (mbstate_t));
554 wc = (char16_t) 0xBADF;
555 ret = mbrtoc16 (&wc, input, 1, &state);
556 ASSERT (ret == 1);
557 ASSERT (wc == '<');
558 ASSERT (mbsinit (&state));
559 input[0] = '\0';
561 wc = (char16_t) 0xBADF;
562 ret = mbrtoc16 (&wc, input + 1, 2, &state);
563 ASSERT (ret == 2);
564 ASSERT (c32tob (wc) == EOF);
565 ASSERT (wc == 0x65E5);
566 ASSERT (mbsinit (&state));
567 input[1] = '\0';
568 input[2] = '\0';
570 wc = (char16_t) 0xBADF;
571 ret = mbrtoc16 (&wc, input + 3, 1, &state);
572 ASSERT (ret == (size_t)(-2));
573 ASSERT (wc == (char16_t) 0xBADF);
574 #if 0
575 ASSERT (!mbsinit (&state));
576 #endif
577 input[3] = '\0';
579 wc = (char16_t) 0xBADF;
580 ret = mbrtoc16 (&wc, input + 4, 4, &state);
581 ASSERT (ret == 1);
582 ASSERT (c32tob (wc) == EOF);
583 ASSERT (wc == 0x672C);
584 ASSERT (mbsinit (&state));
585 input[4] = '\0';
587 /* Test support of NULL first argument. */
588 ret = mbrtoc16 (NULL, input + 5, 3, &state);
589 ASSERT (ret == 2);
590 ASSERT (mbsinit (&state));
592 wc = (char16_t) 0xBADF;
593 ret = mbrtoc16 (&wc, input + 5, 3, &state);
594 ASSERT (ret == 2);
595 ASSERT (c32tob (wc) == EOF);
596 ASSERT (wc == 0x8A9E);
597 ASSERT (mbsinit (&state));
598 input[5] = '\0';
599 input[6] = '\0';
601 wc = (char16_t) 0xBADF;
602 ret = mbrtoc16 (&wc, input + 7, 1, &state);
603 ASSERT (ret == 1);
604 ASSERT (wc == '>');
605 ASSERT (mbsinit (&state));
607 /* Test some invalid input. */
608 memset (&state, '\0', sizeof (mbstate_t));
609 wc = (char16_t) 0xBADF;
610 ret = mbrtoc16 (&wc, "\377", 1, &state); /* 0xFF */
611 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
613 memset (&state, '\0', sizeof (mbstate_t));
614 wc = (char16_t) 0xBADF;
615 ret = mbrtoc16 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
616 ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
618 return 0;
620 case 54936:
621 /* Locale encoding is CP54936 = GB18030. */
622 if (strcmp (locale_charset (), "GB18030") != 0)
623 return 77;
625 char input[] = "s\250\271\201\060\211\070\224\071\375\067!"; /* "süß😋!" */
626 memset (&state, '\0', sizeof (mbstate_t));
628 wc = (char16_t) 0xBADF;
629 ret = mbrtoc16 (&wc, input, 1, &state);
630 ASSERT (ret == 1);
631 ASSERT (wc == 's');
632 ASSERT (mbsinit (&state));
633 input[0] = '\0';
635 wc = (char16_t) 0xBADF;
636 ret = mbrtoc16 (&wc, input + 1, 1, &state);
637 ASSERT (ret == (size_t)(-2));
638 ASSERT (wc == (char16_t) 0xBADF);
639 #if 0
640 ASSERT (!mbsinit (&state));
641 #endif
642 input[1] = '\0';
644 wc = (char16_t) 0xBADF;
645 ret = mbrtoc16 (&wc, input + 2, 9, &state);
646 ASSERT (ret == 1);
647 ASSERT (c32tob (wc) == EOF);
648 ASSERT (wc == 0x00FC);
649 ASSERT (mbsinit (&state));
650 input[2] = '\0';
652 /* Test support of NULL first argument. */
653 ret = mbrtoc16 (NULL, input + 3, 8, &state);
654 ASSERT (ret == 4);
655 ASSERT (mbsinit (&state));
657 wc = (char16_t) 0xBADF;
658 ret = mbrtoc16 (&wc, input + 3, 8, &state);
659 ASSERT (ret == 4);
660 ASSERT (c32tob (wc) == EOF);
661 ASSERT (wc == 0x00DF);
662 ASSERT (mbsinit (&state));
663 input[3] = '\0';
664 input[4] = '\0';
665 input[5] = '\0';
666 input[6] = '\0';
668 /* Test support of NULL first argument. */
669 ret = mbrtoc16 (NULL, input + 7, 4, &state);
670 ASSERT (ret == 4);
671 ret = mbrtoc16 (NULL, input + 11, 0, &state);
672 ASSERT (ret == (size_t)(-3));
673 ASSERT (mbsinit (&state));
675 wc = (char16_t) 0xBADF;
676 ret = mbrtoc16 (&wc, input + 7, 4, &state);
677 ASSERT (ret == 4);
678 ASSERT (c32tob (wc) == EOF);
679 ASSERT (wc == 0xD83D); /* expect UTF-16 encoding */
680 input[7] = '\0';
681 input[8] = '\0';
682 input[9] = '\0';
683 input[10] = '\0';
684 wc = (char16_t) 0xBADF;
685 ret = mbrtoc16 (&wc, input + 11, 0, &state);
686 ASSERT (ret == (size_t)(-3));
687 ASSERT (c32tob (wc) == EOF);
688 ASSERT (wc == 0xDE0B); /* expect UTF-16 encoding */
689 ASSERT (mbsinit (&state));
691 wc = (char16_t) 0xBADF;
692 ret = mbrtoc16 (&wc, input + 11, 1, &state);
693 ASSERT (ret == 1);
694 ASSERT (wc == '!');
695 ASSERT (mbsinit (&state));
697 /* Test some invalid input. */
698 memset (&state, '\0', sizeof (mbstate_t));
699 wc = (char16_t) 0xBADF;
700 ret = mbrtoc16 (&wc, "\377", 1, &state); /* 0xFF */
701 ASSERT (ret == (size_t)-1);
702 ASSERT (errno == EILSEQ);
704 memset (&state, '\0', sizeof (mbstate_t));
705 wc = (char16_t) 0xBADF;
706 ret = mbrtoc16 (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
707 ASSERT (ret == (size_t)-1);
708 ASSERT (errno == EILSEQ);
710 memset (&state, '\0', sizeof (mbstate_t));
711 wc = (char16_t) 0xBADF;
712 ret = mbrtoc16 (&wc, "\201\045", 2, &state); /* 0x81 0x25 */
713 ASSERT (ret == (size_t)-1);
714 ASSERT (errno == EILSEQ);
716 memset (&state, '\0', sizeof (mbstate_t));
717 wc = (char16_t) 0xBADF;
718 ret = mbrtoc16 (&wc, "\201\060\377", 3, &state); /* 0x81 0x30 0xFF */
719 ASSERT (ret == (size_t)-1);
720 ASSERT (errno == EILSEQ);
722 memset (&state, '\0', sizeof (mbstate_t));
723 wc = (char16_t) 0xBADF;
724 ret = mbrtoc16 (&wc, "\201\060\377\064", 4, &state); /* 0x81 0x30 0xFF 0x34 */
725 ASSERT (ret == (size_t)-1);
726 ASSERT (errno == EILSEQ);
728 memset (&state, '\0', sizeof (mbstate_t));
729 wc = (char16_t) 0xBADF;
730 ret = mbrtoc16 (&wc, "\201\060\211\072", 4, &state); /* 0x81 0x30 0x89 0x3A */
731 ASSERT (ret == (size_t)-1);
732 ASSERT (errno == EILSEQ);
734 return 0;
736 default:
737 return 1;
742 main (int argc, char *argv[])
744 int codepage = atoi (argv[argc - 1]);
745 int result;
746 int i;
748 result = 77;
749 for (i = 1; i < argc - 1; i++)
751 int ret = test_one_locale (argv[i], codepage);
753 if (ret != 77)
754 result = ret;
757 if (result == 77)
759 if (test_exit_status != EXIT_SUCCESS)
760 return test_exit_status;
761 fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
762 codepage);
764 return (result ? result : test_exit_status);
767 #else
770 main (int argc, char *argv[])
772 fputs ("Skipping test: not a native Windows system\n", stderr);
773 return 77;
776 #endif