blob: 99329f2f7c73f2c4dd324528a2098d9b1a23bb39 [file] [log] [blame]
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void set_conversion_state (mbstate_t *state, int bytes) {
#ifdef _UCRT
state->_Wchar = bytes;
#else
*state = bytes;
#endif
}
int main (void) {
#ifdef _UCRT
return 77;
#endif
mbstate_t state = {0};
/**
* Test "C" locale
*/
assert (setlocale (LC_ALL, "C") != NULL);
assert (MB_CUR_MAX == 1);
/**
* All values in range [0,255] are valid and must convert to themselves
*/
for (wchar_t wc = 0; wc < 0x100; ++wc) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == 1);
assert ((unsigned char) c == wc);
assert (errno == 0);
assert (mbsinit (&state));
}
/**
* Detect invalid conversion state
*
* NOTE: this is optional error condition specified in POSIX.
* This check fails with CRT's wcrtomb.
*/
set_conversion_state (&state, 1);
if (1) {
char c = EOF;
assert (wcrtomb (&c, L'\0', &state) == (size_t) -1);
assert (c == EOF);
assert (errno == EINVAL);
assert (!mbsinit (&state));
// reset errno
_set_errno (0);
}
/**
* Set conversion state to initial state
*/
assert (wcrtomb (NULL, WEOF, &state) == 1);
assert (errno == 0);
assert (mbsinit (&state));
/**
* Try convert character which cannot be repesented by a single byte
*/
if (1) {
char buffer = EOF;
assert (wcrtomb (&buffer, L'語', &state) == (size_t) -1);
assert (buffer == EOF);
assert (errno == EILSEQ);
assert (mbsinit (&state));
// reset errno
_set_errno (0);
}
/**
* Try to convert low and high surrogates
*/
for (wchar_t wc = 0;; ++wc) {
if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == (size_t) -1);
assert (c == EOF);
assert (errno = EILSEQ);
assert (mbsinit (&state));
// reset errno
_set_errno (0);
}
if (wc == WEOF) {
break;
}
}
/**
* Test SBCS code page
* NOTE: Code page 28951 is ISO-8859-1
*/
assert (setlocale (LC_ALL, "English_United States.28591") != NULL);
assert (MB_CUR_MAX == 1);
/**
* All values in range [0,255] must convert to themselves
*/
for (wchar_t wc = 0; wc < 0x100; ++wc) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == 1);
assert ((unsigned char) c == wc);
assert (errno == 0);
assert (mbsinit (&state));
}
/**
* Try to convert low and high surrogates
*/
for (wchar_t wc = 0;; ++wc) {
if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == (size_t) -1);
/* This assertion fails with CRT's version */
assert (c == EOF);
assert (errno = EILSEQ);
assert (mbsinit (&state));
// reset errno
_set_errno (0);
}
if (wc == WEOF) {
break;
}
}
/**
* Disable tests for DBCS code pages with msvcrt10.dll since it does not
* support multibyte characters.
*
* Calling setlocale with locale string which requests DBCS code page
* result in runtime error.
*/
#if __MSVCRT_VERSION__ != 0x0100
/**
* Test DBCS code page
*/
assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL);
assert (MB_CUR_MAX == 2);
/**
* All values in range [0,127] are valid ASCII characters
*/
for (wchar_t wc = 0; wc < 0x80; ++wc) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == 1);
assert ((unsigned char) c == wc);
assert (errno == 0);
assert (mbsinit (&state));
}
/**
* Try convert multibyte characters
*/
wchar_t DBCS[] = {L'日', L'本', L'語', L'。'};
for (size_t i = 0; i < _countof (DBCS); ++i) {
char buffer[2] = {0};
assert (wcrtomb (buffer, DBCS[i], &state) == 2);
assert (buffer[0] != 0 && buffer[1] != 0);
assert (errno == 0);
assert (mbsinit (&state));
}
/**
* Try to convert low and high surrogates
*/
for (wchar_t wc = 0;; ++wc) {
if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
char c = EOF;
assert (wcrtomb (&c, wc, &state) == (size_t) -1);
/* This assertion fails with CRT's version */
assert (c == EOF);
assert (errno = EILSEQ);
assert (mbsinit (&state));
// reset errno
_set_errno (0);
}
if (wc == WEOF) {
break;
}
}
#endif
return 0;
}