Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcr120/tests/msvcr120.c | 75 ++++++++++++++++++++++++++++++++++ dlls/msvcrt/tests/string.c | 73 +++++++++++++++++++++++++++++++++ dlls/ucrtbase/tests/string.c | 68 ++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index a055feeac9..97862c0eaf 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -174,6 +174,7 @@ static double (CDECL *p_remainder)(double, double); static int* (CDECL *p_errno)(void); static int (CDECL *p_fegetenv)(fenv_t*); static int (CDECL *p__clearfp)(void); +static _locale_t (__cdecl *p_create_locale)(int, const char *); static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *); static void (__cdecl *p_free_locale)(_locale_t); static unsigned short (__cdecl *p_wctype)(const char*); @@ -185,6 +186,8 @@ static float (__cdecl *p_nexttowardf)(float, double); static double (__cdecl *p_nexttowardl)(double, double); static wctrans_t (__cdecl *p_wctrans)(const char*); static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t); +static int (__cdecl *p_iswctype)(int, int); +static int (__cdecl *p__iswctype_l)(int, int, _locale_t);
/* make sure we use the correct errno */ #undef errno @@ -237,8 +240,10 @@ static BOOL init(void) p_wcstof = (void*)GetProcAddress(module, "wcstof"); p_remainder = (void*)GetProcAddress(module, "remainder"); p_errno = (void*)GetProcAddress(module, "_errno"); + p_create_locale = (void*)GetProcAddress(module, "_create_locale"); p_wcreate_locale = (void*)GetProcAddress(module, "_wcreate_locale"); p_free_locale = (void*)GetProcAddress(module, "_free_locale"); + p__iswctype_l = (void*)GetProcAddress(module, "_iswctype_l"); SET(p_wctype, "wctype"); SET(p_fegetenv, "fegetenv"); SET(p__clearfp, "_clearfp"); @@ -250,6 +255,7 @@ static BOOL init(void) SET(p_nexttowardl, "nexttowardl"); SET(p_wctrans, "wctrans"); SET(p_towctrans, "towctrans"); + SET(p_iswctype, "iswctype"); if(sizeof(void*) == 8) { /* 64-bit initialization */ SET(p_critical_section_ctor, "??0critical_section@Concurrency@@QEAA@XZ"); @@ -1065,6 +1071,74 @@ static void test_towctrans(void) ok(ret == 'T', "towctrans('T', 1) returned %c, expected T\n", ret); }
+static void test_iswctype(void) +{ + unsigned int c, i; + unsigned short types = 0; + unsigned short base_wctype[65536]; + const char *locales[] = { NULL, "zh_CN", "en_US", "hi_IN", "es_ES", + "ar_EG", "ms_MY", "ru_RU", "pt_BR", "fr_FR" }; + static const struct + { + unsigned int c; + unsigned int wctype; + } + iswctype_tests[] = + { + { '\t', C1_CNTRL | C1_SPACE }, + { 0xa0, C1_SPACE }, + { 0x85, C1_CNTRL }, + { 0xad, C1_PUNCT }, + { 0xaa, C1_PUNCT }, + { 0xb5, C1_PUNCT }, + { 0xba, C1_PUNCT }, + { 0xb2, C1_PUNCT }, + { 0xb3, C1_PUNCT }, + { 0xb9, C1_PUNCT }, + }; + + for (c = 0; c <= 0xff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + + for (c = 0x100; c <= 0xffff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + ok(types == 0x3ff, "Unexpected wctype bits present\n"); + + for (i = 0; i < ARRAY_SIZE(iswctype_tests); i++) + { + todo_wine { + ok(base_wctype[iswctype_tests[i].c] == iswctype_tests[i].wctype, + "Unexpected wctype %#x for char %#x\n", + base_wctype[iswctype_tests[i].c], iswctype_tests[i].c); + } + } + + if (!p__iswctype_l || !p_create_locale) + { + win_skip("_iswctype_l tests\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(locales); i++) + { + _locale_t locale = locales[i] ? p_create_locale(LC_ALL, locales[i]) : NULL; + for (c = 0; c <= 0xffff; c++) + { + unsigned short wct = p__iswctype_l(c, 0xffff, locale); + todo_wine_if(wct & 0xf000) { + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); + } + } + } +} + START_TEST(msvcr120) { if (!init()) return; @@ -1086,4 +1160,5 @@ START_TEST(msvcr120) test__Cbuild(); test_nexttoward(); test_towctrans(); + test_iswctype(); } diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 08bc0781e1..940e8166ae 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -110,6 +110,8 @@ static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned c static int (__cdecl *p__memicmp)(const char*, const char*, size_t); static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t); static size_t (__cdecl *p___strncnt)(const char*, size_t); +static int (__cdecl *p_iswctype)(int, int); +static int (__cdecl *p__iswctype_l)(int, int, _locale_t);
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y) @@ -4050,6 +4052,74 @@ static void test_iswdigit(void) } }
+static void test_iswctype(void) +{ + unsigned int c, i; + unsigned short types = 0; + unsigned short base_wctype[65536]; + const char *locales[] = { NULL, "zh_CN", "en_US", "hi_IN", "es_ES", + "ar_EG", "ms_MY", "ru_RU", "pt_BR", "fr_FR" }; + static const struct + { + unsigned int c; + unsigned int wctype; + } + iswctype_tests[] = + { + { '\t', C1_CNTRL | C1_SPACE | C1_BLANK }, + { 0xa0, C1_SPACE | C1_BLANK }, + { 0x85, C1_CNTRL }, + { 0xad, C1_PUNCT }, + { 0xaa, C1_PUNCT }, + { 0xb5, C1_PUNCT }, + { 0xba, C1_PUNCT }, + { 0xb2, C1_PUNCT | C1_DIGIT }, + { 0xb3, C1_PUNCT | C1_DIGIT }, + { 0xb9, C1_PUNCT | C1_DIGIT }, + }; + + for (c = 0; c <= 0xff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + + for (c = 0x100; c <= 0xffff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + ok(types == 0x3ff, "Unexpected wctype bits present\n"); + + for (i = 0; i < ARRAY_SIZE(iswctype_tests); i++) + { + todo_wine { + ok(base_wctype[iswctype_tests[i].c] == iswctype_tests[i].wctype, + "Unexpected wctype %#x for char %#x\n", + base_wctype[iswctype_tests[i].c], iswctype_tests[i].c); + } + } + + if (!p__iswctype_l || !p__create_locale) + { + win_skip("_iswctype_l tests\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(locales); i++) + { + _locale_t locale = locales[i] ? p__create_locale(LC_ALL, locales[i]) : NULL; + for (c = 0; c <= 0xffff; c++) + { + unsigned short wct = p__iswctype_l(c, 0xffff, locale); + todo_wine_if(wct & 0xf000) { + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); + } + } + } +} + START_TEST(string) { char mem[100]; @@ -4117,6 +4187,8 @@ START_TEST(string) p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp"); p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l"); p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt"); + p_iswctype = (void*)GetProcAddress(hMsvcrt, "iswctype"); + p__iswctype_l = (void*)GetProcAddress(hMsvcrt, "_iswctype_l");
/* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -4192,4 +4264,5 @@ START_TEST(string) test_C_locale(); test_strstr(); test_iswdigit(); + test_iswctype(); } diff --git a/dlls/ucrtbase/tests/string.c b/dlls/ucrtbase/tests/string.c index 0bb3feaa2f..ca219a97ce 100644 --- a/dlls/ucrtbase/tests/string.c +++ b/dlls/ucrtbase/tests/string.c @@ -25,6 +25,7 @@
#include <windef.h> #include <winbase.h> +#include <winnls.h> #include "wine/test.h"
#include <math.h> @@ -83,6 +84,8 @@ static void (__cdecl *p__free_locale)(_locale_t); static int (__cdecl *p__getmbcp)(void); static int (__cdecl *p__setmbcp)(int); static size_t (__cdecl *p__mbsspn)(const unsigned char*, const unsigned char*); +static int (__cdecl *p_iswctype)(int, int); +static int (__cdecl *p__iswctype_l)(int, int, _locale_t);
static BOOL init(void) { @@ -110,6 +113,8 @@ static BOOL init(void) p__getmbcp = (void*)GetProcAddress(module, "_getmbcp"); p__setmbcp = (void*)GetProcAddress(module, "_setmbcp"); p__mbsspn = (void*)GetProcAddress(module, "_mbsspn"); + p_iswctype = (void*)GetProcAddress(module, "iswctype"); + p__iswctype_l = (void*)GetProcAddress(module, "_iswctype_l"); return TRUE; }
@@ -398,6 +403,68 @@ static void test_mbsspn( void) p__setmbcp(cp); }
+static void test_iswctype(void) +{ + unsigned int c, i; + unsigned short types = 0; + unsigned short base_wctype[65536]; + const char *locales[] = { NULL, "zh_CN", "en_US", "hi_IN", "es_ES", + "ar_EG", "ms_MY", "ru_RU", "pt_BR", "fr_FR" }; + static const struct + { + unsigned int c; + unsigned int wctype; + } + iswctype_tests[] = + { + { '\t', C1_CNTRL | C1_SPACE }, + { 0xa0, C1_SPACE }, + { 0x85, C1_CNTRL | C1_SPACE }, + { 0xad, C1_PUNCT | C1_CNTRL }, + { 0xaa, C1_PUNCT | C1_LOWER | C1_ALPHA }, + { 0xb5, C1_PUNCT | C1_LOWER | C1_ALPHA }, + { 0xba, C1_PUNCT | C1_LOWER | C1_ALPHA }, + { 0xb2, C1_PUNCT | C1_DIGIT }, + { 0xb3, C1_PUNCT | C1_DIGIT }, + { 0xb9, C1_PUNCT | C1_DIGIT }, + }; + + for (c = 0; c <= 0xff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + + for (c = 0x100; c <= 0xffff; c++) + { + base_wctype[c] = p_iswctype(c, 0xffff); + types |= base_wctype[c]; + } + ok(types == 0x3ff, "Unexpected wctype bits present\n"); + + for (i = 0; i < ARRAY_SIZE(iswctype_tests); i++) + { + todo_wine { + ok(base_wctype[iswctype_tests[i].c] == iswctype_tests[i].wctype, + "Unexpected wctype %#x for char %#x\n", + base_wctype[iswctype_tests[i].c], iswctype_tests[i].c); + } + } + + for (i = 0; i < ARRAY_SIZE(locales); i++) + { + _locale_t locale = locales[i] ? p__create_locale(LC_ALL, locales[i]) : NULL; + for (c = 0; c <= 0xffff; c++) + { + unsigned short wct = p__iswctype_l(c, 0xffff, locale); + todo_wine_if(wct & 0xf000) { + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); + } + } + } +} + START_TEST(string) { if (!init()) return; @@ -407,4 +474,5 @@ START_TEST(string) test___strncnt(); test_C_locale(); test_mbsspn(); + test_iswctype(); }