1 /* Test c16rtomb handling of surrogate pairs (DR#488, bug 23794).
2 Copyright (C) 2018-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
25 #include <array_length.h>
26 #include <support/check.h>
31 TEST_VERIFY_EXIT (setlocale (LC_ALL
, "de_DE.UTF-8") != NULL
);
32 /* Test conversions of surrogate pairs. */
33 for (char32_t c
= 0x10000; c
<= 0x10ffff; c
+= 0x123)
35 char32_t c_pos
= c
- 0x10000;
36 char16_t c_hi
= (c_pos
>> 10) + 0xd800;
37 char16_t c_lo
= (c_pos
& 0x3ff) + 0xdc00;
38 printf ("testing U+0x%08x (0x%x 0x%x)\n",
39 (unsigned int) c
, (unsigned int) c_hi
, (unsigned int) c_lo
);
41 size_t ret_hi
= c16rtomb (buf
, c_hi
, NULL
);
42 TEST_COMPARE (ret_hi
, 0);
43 size_t ret_lo
= c16rtomb (buf
, c_lo
, NULL
);
44 TEST_COMPARE (ret_lo
, 4);
46 size_t ret_wc
= mbrtowc (&wc
, buf
, 4, NULL
);
47 TEST_COMPARE (ret_wc
, 4);
48 TEST_COMPARE (wc
, (wchar_t) c
);
50 /* Test errors for invalid conversions. */
51 static const char16_t err_cases
[][2] =
53 /* High surrogate followed by non-surrogate. */
55 /* High surrogate followed by another high surrogate. */
57 /* Low surrogate not following high surrogate. */
60 for (size_t i
= 0; i
< array_length (err_cases
); i
++)
62 char16_t c_hi
= err_cases
[i
][0];
63 char16_t c_lo
= err_cases
[i
][1];
64 printf ("testing error case: 0x%x 0x%x\n", (unsigned int) c_hi
,
66 c16rtomb (NULL
, 0, NULL
);
69 size_t ret_hi
= c16rtomb (buf
, c_hi
, NULL
);
72 /* Unmatched low surrogate in first place. */
73 TEST_COMPARE (ret_hi
, (size_t) -1);
74 TEST_COMPARE (errno
, EILSEQ
);
78 /* High surrogate; error in second place. */
79 TEST_COMPARE (ret_hi
, 0);
81 size_t ret_lo
= c16rtomb (buf
, c_lo
, NULL
);
82 TEST_COMPARE (ret_lo
, (size_t) -1);
83 TEST_COMPARE (errno
, EILSEQ
);
89 #include <support/test-driver.c>