/* Test of conversion of multibyte character to wide character on native Windows in the UTF-8 environment. Copyright (C) 2024-2025 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Written by Bruno Haible , 2024. */ #include #include #include #include #include #include #include #include "macros.h" int main (void) { #ifdef _UCRT /* Test that MB_CUR_MAX and mbrtowc() work as expected in a UTF-8 locale. */ mbstate_t state; wchar_t wc; size_t ret; if (setlocale (LC_ALL, "") == NULL) return 1; ASSERT (MB_CUR_MAX >= 4); { char input[] = "B\303\274\303\237er"; /* "Büßer" */ memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input, 1, &state); ASSERT (ret == 1); ASSERT (wc == 'B'); ASSERT (mbsinit (&state)); input[0] = '\0'; wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input + 1, 1, &state); ASSERT (ret == (size_t)(-2)); ASSERT (wc == (wchar_t) 0xBADFACE); ASSERT (!mbsinit (&state)); input[1] = '\0'; wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input + 2, 5, &state); ASSERT (ret == 1); ASSERT (wctob (wc) == EOF); ASSERT (wc == 0x00FC); ASSERT (mbsinit (&state)); input[2] = '\0'; /* Test support of NULL first argument. */ ret = mbrtowc (NULL, input + 3, 4, &state); ASSERT (ret == 2); ASSERT (mbsinit (&state)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input + 3, 4, &state); ASSERT (ret == 2); ASSERT (wctob (wc) == EOF); ASSERT (wc == 0x00DF); ASSERT (mbsinit (&state)); input[3] = '\0'; input[4] = '\0'; wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input + 5, 2, &state); ASSERT (ret == 1); ASSERT (wc == 'e'); ASSERT (mbsinit (&state)); input[5] = '\0'; wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, input + 6, 1, &state); ASSERT (ret == 1); ASSERT (wc == 'r'); ASSERT (mbsinit (&state)); /* Test some invalid input. */ memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\303\300", 2, &state); /* 0xC3 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\343\300", 2, &state); /* 0xE3 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\343\300\200", 3, &state); /* 0xE3 0xC0 0x80 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\343\200\300", 3, &state); /* 0xE3 0x80 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\363\300", 2, &state); /* 0xF3 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\363\300\200\200", 4, &state); /* 0xF3 0xC0 0x80 0x80 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\363\200\300", 3, &state); /* 0xF3 0x80 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\363\200\300\200", 4, &state); /* 0xF3 0x80 0xC0 0x80 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); memset (&state, '\0', sizeof (mbstate_t)); wc = (wchar_t) 0xBADFACE; ret = mbrtowc (&wc, "\363\200\200\300", 4, &state); /* 0xF3 0x80 0x80 0xC0 */ ASSERT (ret == (size_t)-1); ASSERT (errno == EILSEQ); } return test_exit_status; #else fputs ("Skipping test: not using the UCRT runtime\n", stderr); return 77; #endif }