Signed-off-by: Jeff Smith whydoubt@gmail.com --- This series essentially supersedes the series starting with https://source.winehq.org/patches/data/176232
It no longer contains anything regarding IsCharBlankW, as that is associated with a different instance of the wctype table, and this series is long enough as-is.
The first three patches are focused on ntdll, while the remainder are focused on msvcrt, ucrtbase, etc.
dlls/ntdll/tests/string.c | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index 12027e8899..3b62bde1a7 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -69,6 +69,13 @@ static int (__cdecl *p__strnicmp)(LPCSTR,LPCSTR,size_t);
static int (WINAPIV *p_sscanf)(const char *, const char *, ...);
+static int (__cdecl *p_iswctype)(int, int); +static int (__cdecl *p_iswalpha)(int); +static int (__cdecl *p_iswdigit)(int); +static int (__cdecl *p_iswlower)(int); +static int (__cdecl *p_iswspace)(int); +static int (__cdecl *p_iswxdigit)(int); + static void InitFunctionPtrs(void) { hntdll = LoadLibraryA("ntdll.dll"); @@ -113,6 +120,13 @@ static void InitFunctionPtrs(void) p__strnicmp = (void *)GetProcAddress(hntdll, "_strnicmp");
p_sscanf = (void *)GetProcAddress(hntdll, "sscanf"); + + p_iswctype = (void*)GetProcAddress(hntdll, "iswctype"); + p_iswalpha = (void*)GetProcAddress(hntdll, "iswalpha"); + p_iswdigit = (void*)GetProcAddress(hntdll, "iswdigit"); + p_iswlower = (void*)GetProcAddress(hntdll, "iswlower"); + p_iswspace = (void*)GetProcAddress(hntdll, "iswspace"); + p_iswxdigit = (void*)GetProcAddress(hntdll, "iswxdigit"); } /* if */ }
@@ -1501,6 +1515,63 @@ static void test_sscanf(void) ok(d == 0.0, "d = %lf\n", f); }
+static void test_iswctype(void) +{ + unsigned int c, i; + unsigned short types = 0; + unsigned short base_wctype[65536]; + 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++) + { + types = p_iswctype(c, 0xffff); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswctype for %#x\n", c); + types = p_iswalpha(c); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswalpha for %#x\n", c); + types = p_iswdigit(c); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswdigit for %#x\n", c); + types = p_iswlower(c); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswlower for %#x\n", c); + types = p_iswspace(c); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswspace for %#x\n", c); + types = p_iswxdigit(c); + todo_wine_if(types != 0) ok(types == 0, "Unexpected iswxdigit for %#x\n", c); + } + + 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); + } + } +} + START_TEST(string) { InitFunctionPtrs(); @@ -1545,4 +1616,5 @@ START_TEST(string) test_toupper(); test__strnicmp(); test_sscanf(); + test_iswctype(); }
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/crtdll/crtdll.spec | 6 +++--- dlls/msvcr100/msvcr100.spec | 6 +++--- dlls/msvcr110/msvcr110.spec | 6 +++--- dlls/msvcr120/msvcr120.spec | 6 +++--- dlls/msvcr70/msvcr70.spec | 6 +++--- dlls/msvcr71/msvcr71.spec | 6 +++--- dlls/msvcr80/msvcr80.spec | 6 +++--- dlls/msvcr90/msvcr90.spec | 6 +++--- dlls/msvcrt/msvcrt.spec | 6 +++--- dlls/msvcrt/wcs.c | 8 ++++++++ dlls/msvcrtd/msvcrtd.spec | 6 +++--- dlls/ucrtbase/ucrtbase.spec | 6 +++--- 12 files changed, 41 insertions(+), 33 deletions(-)
diff --git a/dlls/crtdll/crtdll.spec b/dlls/crtdll/crtdll.spec index 256845df38..9c88c2ac5a 100644 --- a/dlls/crtdll/crtdll.spec +++ b/dlls/crtdll/crtdll.spec @@ -394,7 +394,7 @@ @ cdecl getenv(str) MSVCRT_getenv @ cdecl gets(str) MSVCRT_gets @ cdecl gmtime(ptr) MSVCRT_gmtime -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -407,10 +407,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 63c3a9d8a0..bd1c310a07 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1703,7 +1703,7 @@ @ cdecl gets_s(ptr long) MSVCRT_gets_s @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -1716,10 +1716,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 366c771746..44358d8a02 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -2061,7 +2061,7 @@ @ cdecl gets_s(ptr long) MSVCRT_gets_s @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -2074,10 +2074,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 07ff5abdff..2079bbea94 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2212,7 +2212,7 @@ @ cdecl ilogbl(double) MSVCR120_ilogbl @ stub imaxabs @ stub imaxdiv -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl isblank(long) MSVCRT_isblank @@ -2226,11 +2226,11 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswblank(long) MSVCRT_iswblank @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index a014cf5036..79f0d6527b 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -738,7 +738,7 @@ @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar @ cdecl gmtime(ptr) MSVCRT_gmtime -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -751,10 +751,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 21b73d3a75..317fc0d3af 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -734,7 +734,7 @@ @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar @ cdecl gmtime(ptr) MSVCRT_gmtime -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -747,10 +747,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 14ed7f3553..a12c2b2ba7 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1385,7 +1385,7 @@ @ cdecl gets_s(ptr long) MSVCRT_gets_s @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -1398,10 +1398,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index acb976a7b0..84fb083282 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1358,7 +1358,7 @@ @ cdecl gets_s(ptr long) MSVCRT_gets_s @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -1371,10 +1371,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 4f55bcb45a..bf096f2cfa 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1324,7 +1324,7 @@ @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar @ cdecl gmtime(ptr) MSVCRT_gmtime -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -1337,10 +1337,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 1abe28b7d9..5d0a80ba4f 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -1952,6 +1952,14 @@ INT CDECL MSVCRT__iswctype_l( MSVCRT_wchar_t wc, MSVCRT_wctype_t type, MSVCRT__l return (get_char_typeW(wc) & 0xffff) & type; }
+/********************************************************************* + * iswctype (MSVCRT.@) + */ +INT CDECL MSVCRT_iswctype( MSVCRT_wchar_t wc, MSVCRT_wctype_t type ) +{ + return (get_char_typeW(wc) & 0xfff) & type; +} + /********************************************************************* * _iswblank_l (MSVCRT.@) */ diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index 4a0238e3e9..b502ed78d1 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -690,7 +690,7 @@ @ cdecl getwc(ptr) MSVCRT_getwc @ cdecl getwchar() MSVCRT_getwchar @ cdecl gmtime(ptr) MSVCRT_gmtime -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl iscntrl(long) MSVCRT_iscntrl @@ -703,10 +703,10 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index a262cc6345..41fdc496f4 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2346,7 +2346,7 @@ @ cdecl ilogbl(double) MSVCR120_ilogbl @ stub imaxabs @ stub imaxdiv -@ cdecl is_wctype(long long) ntdll.iswctype +@ cdecl is_wctype(long long) MSVCRT_iswctype @ cdecl isalnum(long) MSVCRT_isalnum @ cdecl isalpha(long) MSVCRT_isalpha @ cdecl isblank(long) MSVCRT_isblank @@ -2360,11 +2360,11 @@ @ cdecl isspace(long) MSVCRT_isspace @ cdecl isupper(long) MSVCRT_isupper @ cdecl iswalnum(long) MSVCRT_iswalnum -@ cdecl iswalpha(long) ntdll.iswalpha +@ cdecl iswalpha(long) MSVCRT_iswalpha @ cdecl iswascii(long) MSVCRT_iswascii @ cdecl iswblank(long) MSVCRT_iswblank @ cdecl iswcntrl(long) MSVCRT_iswcntrl -@ cdecl iswctype(long long) ntdll.iswctype +@ cdecl iswctype(long long) MSVCRT_iswctype @ cdecl iswdigit(long) MSVCRT_iswdigit @ cdecl iswgraph(long) MSVCRT_iswgraph @ cdecl iswlower(long) MSVCRT_iswlower
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/ntdll/tests/string.c | 22 +++++++++---------- dlls/ntdll/wcstring.c | 45 +++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index 3b62bde1a7..19b49dca88 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -1544,31 +1544,29 @@ static void test_iswctype(void) base_wctype[c] = p_iswctype(c, 0xffff); types |= base_wctype[c]; } - todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + ok(types == 0x1ff, "Unexpected wctype bits present\n");
for (c = 0x100; c <= 0xffff; c++) { types = p_iswctype(c, 0xffff); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswctype for %#x\n", c); + ok(types == 0, "Unexpected iswctype for %#x\n", c); types = p_iswalpha(c); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswalpha for %#x\n", c); + ok(types == 0, "Unexpected iswalpha for %#x\n", c); types = p_iswdigit(c); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswdigit for %#x\n", c); + ok(types == 0, "Unexpected iswdigit for %#x\n", c); types = p_iswlower(c); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswlower for %#x\n", c); + ok(types == 0, "Unexpected iswlower for %#x\n", c); types = p_iswspace(c); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswspace for %#x\n", c); + ok(types == 0, "Unexpected iswspace for %#x\n", c); types = p_iswxdigit(c); - todo_wine_if(types != 0) ok(types == 0, "Unexpected iswxdigit for %#x\n", c); + ok(types == 0, "Unexpected iswxdigit for %#x\n", c); }
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); - } + 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); } }
diff --git a/dlls/ntdll/wcstring.c b/dlls/ntdll/wcstring.c index acdb33ac24..98372ae8d2 100644 --- a/dlls/ntdll/wcstring.c +++ b/dlls/ntdll/wcstring.c @@ -33,6 +33,39 @@ #include "winternl.h" #include "wine/unicode.h"
+/* Some abbreviations to make the following table readable */ +#define _C_ C1_CNTRL +#define _S_ C1_SPACE +#define _P_ C1_PUNCT +#define _D_ C1_DIGIT +#define _H_ C1_XDIGIT +#define _U_ C1_UPPER|C1_ALPHA +#define _L_ C1_LOWER|C1_ALPHA +#define _B_ C1_BLANK + +static const WORD NTDLL_wctype [256] = { + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_|_B_, _S_|_C_, _S_|_C_, + _S_|_C_, _S_|_C_, _C_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _S_|_B_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, + _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, + _P_, _P_, _P_, _P_, _P_, _P_, + _P_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _P_, _P_, _P_, _P_, + _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_, _L_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _S_|_B_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, + _P_, _P_, _P_|_D_, _P_|_D_, _P_, _P_, _P_, _P_, _P_, _P_|_D_, _P_, _P_, _P_, _P_, _P_, _P_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_ +}; + /********************************************************************* * _wcsicmp (NTDLL.@) */ @@ -298,7 +331,7 @@ ULONG __cdecl NTDLL_wcstoul(LPCWSTR s, LPWSTR *end, INT base) */ INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct ) { - return (get_char_typeW(wc) & 0xfff) & wct; + return (wc > 0xff) ? 0 : NTDLL_wctype[wc] & wct; }
@@ -313,7 +346,7 @@ INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct ) */ INT __cdecl NTDLL_iswalpha( WCHAR wc ) { - return isalphaW(wc); + return NTDLL_iswctype( wc, C1_ALPHA|C1_LOWER|C1_UPPER ); }
@@ -328,7 +361,7 @@ INT __cdecl NTDLL_iswalpha( WCHAR wc ) */ INT __cdecl NTDLL_iswdigit( WCHAR wc ) { - return isdigitW(wc); + return NTDLL_iswctype( wc, C1_DIGIT ); }
@@ -343,7 +376,7 @@ INT __cdecl NTDLL_iswdigit( WCHAR wc ) */ INT __cdecl NTDLL_iswlower( WCHAR wc ) { - return islowerW(wc); + return NTDLL_iswctype( wc, C1_LOWER ); }
@@ -358,7 +391,7 @@ INT __cdecl NTDLL_iswlower( WCHAR wc ) */ INT __cdecl NTDLL_iswspace( WCHAR wc ) { - return isspaceW(wc); + return NTDLL_iswctype( wc, C1_SPACE ); }
@@ -373,7 +406,7 @@ INT __cdecl NTDLL_iswspace( WCHAR wc ) */ INT __cdecl NTDLL_iswxdigit( WCHAR wc ) { - return isxdigitW(wc); + return NTDLL_iswctype( wc, C1_XDIGIT ); }
Hi Jeff,
On 09.01.2020 07:53, Jeff Smith wrote:
+/* Some abbreviations to make the following table readable */ +#define_C_ C1_CNTRL +#define_S_ C1_SPACE +#define_P_ C1_PUNCT +#define_D_ C1_DIGIT +#define_H_ C1_XDIGIT +#define_U_ C1_UPPER|C1_ALPHA +#define_L_ C1_LOWER|C1_ALPHA +#define_B_ C1_BLANK
+static const WORD NTDLL_wctype [256] = { +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_S_|_C_|_B_,_S_|_C_,_S_|_C_, +_S_|_C_,_S_|_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_, +_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_,_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_P_,_P_,_P_,_P_, +_P_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_,_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_P_,_P_,_P_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_P_,_P_|_D_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_ +};
Those macros don't really make the table much more readable, IMHO. You could just use numeric literals and make it more compact. In fact, you could probably just copy the first chunk of wctype_table from kernelbase/wctype.c.
Thanks,
Jacek
On 09.01.2020 16:09, Jacek Caban wrote:
Hi Jeff,
On 09.01.2020 07:53, Jeff Smith wrote:
+/* Some abbreviations to make the following table readable */ +#define_C_Â C1_CNTRL +#define_S_Â C1_SPACE +#define_P_Â C1_PUNCT +#define_D_Â C1_DIGIT +#define_H_Â C1_XDIGIT +#define_U_Â C1_UPPER|C1_ALPHA +#define_L_Â C1_LOWER|C1_ALPHA +#define_B_Â C1_BLANK
+static const WORD NTDLL_wctype [256] = { +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_S_|_C_|_B_,_S_|_C_,_S_|_C_, +_S_|_C_,_S_|_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,
+_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_,_U_,_U_,_U_,_U_,
+_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_P_,_P_,_P_,_P_, +_P_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_,_L_,_L_,_L_,_L_,
+_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_P_,_P_,_P_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_P_,_P_|_D_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_,
+_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_ +};
Those macros don't really make the table much more readable, IMHO. You could just use numeric literals and make it more compact. In fact, you could probably just copy the first chunk of wctype_table from kernelbase/wctype.c.
Also, this patch needs a careful review of code that uses those function, most notably kernelbase.dll. A quick look suggests that it depends on working at least iswalpha for values above 255, so it will need to be changed first.
Thanks,
Jacek
On Thu, Jan 9, 2020 at 9:14 AM Jacek Caban jacek@codeweavers.com wrote:
On 09.01.2020 16:09, Jacek Caban wrote:
Hi Jeff,
On 09.01.2020 07:53, Jeff Smith wrote:
+/* Some abbreviations to make the following table readable */ +#define_C_ C1_CNTRL +#define_S_ C1_SPACE +#define_P_ C1_PUNCT +#define_D_ C1_DIGIT +#define_H_ C1_XDIGIT +#define_U_ C1_UPPER|C1_ALPHA +#define_L_ C1_LOWER|C1_ALPHA +#define_B_ C1_BLANK
+static const WORD NTDLL_wctype [256] = { +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_S_|_C_|_B_,_S_|_C_,_S_|_C_, +_S_|_C_,_S_|_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,_D_|_H_,
+_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_|_H_,_U_,_U_,_U_,_U_,_U_,
+_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_P_,_P_,_P_,_P_, +_P_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_|_H_,_L_,_L_,_L_,_L_,_L_,
+_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_P_,_P_,_P_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_,_C_, +_S_|_B_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_,_P_, +_P_,_P_,_P_|_D_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_|_D_,_P_,_P_,_P_,_P_,_P_,_P_,
+_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_U_, +_U_,_U_,_U_,_U_,_U_,_U_,_U_,_P_,_U_,_U_,_U_,_U_,_U_,_U_,_U_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_, +_L_,_L_,_L_,_L_,_L_,_L_,_L_,_P_,_L_,_L_,_L_,_L_,_L_,_L_,_L_,_L_ +};
Those macros don't really make the table much more readable, IMHO. You
Yeah, "readable" is certainly debatable. The comment and table was based on msvcrt/ctype.c which I filled out and reformatted to make sure every 16th entry was on a new line (then wrapped a few that were rather long). I still found this form slightly easier to work with, especially when it came to the creating the one for msvcrt/wcs.c.
could just use numeric literals and make it more compact. In fact, you could probably just copy the first chunk of wctype_table from kernelbase/wctype.c.
Well, it would need to be the first 32 lines starting after the "value" comment, and it would need to be filtered "| 0x1ff", but it would work. I don't think that would be more compact though.
Also, this patch needs a careful review of code that uses those function, most notably kernelbase.dll. A quick look suggests that it depends on working at least iswalpha for values above 255, so it will need to be changed first.
Agreed, that may be a bit of a chore, but still needed.
Thanks,
Jacek
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(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63060
Your paranoid android.
=== debian10 (32 bit report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614086 bytes) msvcrt:string prints too much data (54336411 bytes) ucrtbase:string prints too much data (53697300 bytes)
=== debian10 (32 bit French report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614078 bytes) msvcrt:string prints too much data (54336413 bytes) ucrtbase:string prints too much data (53697300 bytes)
=== debian10 (32 bit Japanese:Japan report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614078 bytes) msvcrt:string prints too much data (54336413 bytes) ucrtbase:string prints too much data (53697300 bytes)
=== debian10 (32 bit Chinese:China report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614086 bytes) msvcrt:string prints too much data (54336411 bytes) ucrtbase:string prints too much data (53697300 bytes)
=== debian10 (32 bit WoW report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614086 bytes) msvcrt:string prints too much data (54336411 bytes) ucrtbase:string prints too much data (53697300 bytes)
=== debian10 (64 bit WoW report) ===
Report errors: msvcr120:msvcr120 prints too much data (55614086 bytes) msvcrt:string prints too much data (54336411 bytes) ucrtbase:string prints too much data (53697300 bytes)
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcr120/tests/msvcr120.c | 4 +--- dlls/msvcrt/tests/string.c | 4 +--- dlls/msvcrt/wcs.c | 4 ++-- dlls/ucrtbase/tests/string.c | 4 +--- 4 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 97862c0eaf..9d8a5f0321 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -1132,9 +1132,7 @@ static void test_iswctype(void) 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]); - } + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); } } } diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 940e8166ae..3e52d56f00 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -4113,9 +4113,7 @@ static void test_iswctype(void) 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]); - } + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); } } } diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 5d0a80ba4f..600c4db008 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -1949,7 +1949,7 @@ int CDECL MSVCRT__iswxdigit_l( MSVCRT_wchar_t wc, MSVCRT__locale_t locale ) */ INT CDECL MSVCRT__iswctype_l( MSVCRT_wchar_t wc, MSVCRT_wctype_t type, MSVCRT__locale_t locale ) { - return (get_char_typeW(wc) & 0xffff) & type; + return (get_char_typeW(wc) & 0xfff) & type; }
/********************************************************************* @@ -1957,7 +1957,7 @@ INT CDECL MSVCRT__iswctype_l( MSVCRT_wchar_t wc, MSVCRT_wctype_t type, MSVCRT__l */ INT CDECL MSVCRT_iswctype( MSVCRT_wchar_t wc, MSVCRT_wctype_t type ) { - return (get_char_typeW(wc) & 0xfff) & type; + return MSVCRT__iswctype_l( wc, type, NULL ); }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/string.c b/dlls/ucrtbase/tests/string.c index ca219a97ce..2a77d8882a 100644 --- a/dlls/ucrtbase/tests/string.c +++ b/dlls/ucrtbase/tests/string.c @@ -458,9 +458,7 @@ static void test_iswctype(void) 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]); - } + ok(base_wctype[c] == wct, "Character %#x in %s does not match C locale.\n", c, locales[i]); } } }
Signed-off-by: Jeff Smith whydoubt@gmail.com --- .../api-ms-win-crt-string-l1-1-0.spec | 2 +- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/wcs.c | 58 +++++++++++++++++++ dlls/ucrtbase/ucrtbase.spec | 2 +- 12 files changed, 69 insertions(+), 11 deletions(-)
diff --git a/dlls/api-ms-win-crt-string-l1-1-0/api-ms-win-crt-string-l1-1-0.spec b/dlls/api-ms-win-crt-string-l1-1-0/api-ms-win-crt-string-l1-1-0.spec index ead56fbcb5..fe0fa012cd 100644 --- a/dlls/api-ms-win-crt-string-l1-1-0/api-ms-win-crt-string-l1-1-0.spec +++ b/dlls/api-ms-win-crt-string-l1-1-0/api-ms-win-crt-string-l1-1-0.spec @@ -96,7 +96,7 @@ @ cdecl _wcsupr_s(wstr long) ucrtbase._wcsupr_s @ cdecl _wcsupr_s_l(wstr long ptr) ucrtbase._wcsupr_s_l @ cdecl _wcsxfrm_l(ptr wstr long ptr) ucrtbase._wcsxfrm_l -@ stub _wctype +@ extern _wctype ucrtbase._wctype @ cdecl is_wctype(long long) ucrtbase.is_wctype @ cdecl isalnum(long) ucrtbase.isalnum @ cdecl isalpha(long) ucrtbase.isalpha diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index bd1c310a07..ff974b571d 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1531,7 +1531,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 44358d8a02..996b00691d 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1889,7 +1889,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 2079bbea94..d519c730c7 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1913,7 +1913,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index 89d240b567..ce95cbc1b8 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -1606,7 +1606,7 @@ @ cdecl _wctime64_s(ptr long ptr) msvcr120._wctime64_s @ cdecl _wctomb_l(ptr long ptr) msvcr120._wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) msvcr120._wctomb_s_l -# extern _wctype +@ extern _wctype msvcr120._wctype @ extern _wenviron msvcr120._wenviron @ cdecl _wfdopen(long wstr) msvcr120._wfdopen @ cdecl _wfindfirst32(wstr ptr) msvcr120._wfindfirst32 diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index 79f0d6527b..12f4ce6104 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -610,7 +610,7 @@ @ cdecl _wcsupr(wstr) MSVCRT__wcsupr @ cdecl _wctime(ptr) MSVCRT__wctime @ cdecl _wctime64(ptr) MSVCRT__wctime64 -# extern _wctype +@ extern _wctype MSVCRT__wctype @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) @ varargs _wexecle(wstr wstr) diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 317fc0d3af..131f0f471a 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -606,7 +606,7 @@ @ cdecl _wcsupr(wstr) MSVCRT__wcsupr @ cdecl _wctime(ptr) MSVCRT__wctime @ cdecl _wctime64(ptr) MSVCRT__wctime64 -# extern _wctype +@ extern _wctype MSVCRT__wctype @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) @ varargs _wexecle(wstr wstr) diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index a12c2b2ba7..59f2867734 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1210,7 +1210,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 84fb083282..f44c4d4c4c 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1186,7 +1186,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index bf096f2cfa..b9a5c2644c 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1141,7 +1141,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -# extern _wctype +@ extern _wctype MSVCRT__wctype @ extern _wenviron MSVCRT__wenviron @ varargs _wexecl(wstr wstr) @ varargs _wexecle(wstr wstr) diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 600c4db008..efb879a89d 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -40,6 +40,64 @@ static BOOL n_format_enabled = TRUE; #include "printf.h" #undef PRINTF_WIDE
+/* Some abbreviations to make the following table readable */ +#define _C_ MSVCRT__CONTROL +#define _S_ MSVCRT__SPACE +#define _P_ MSVCRT__PUNCT +#define _D_ MSVCRT__DIGIT +#define _H_ MSVCRT__HEX +#define _U_ MSVCRT__UPPER|0x100 +#define _L_ MSVCRT__LOWER|0x100 +#define _B_ MSVCRT__BLANK + +#if _MSVCR_VER==120 +#define _SUP_ _P_ +#else +#define _SUP_ _P_|_D_ +#endif + +#if _MSVCR_VER>=120 +#define _B120_ 0 +#else +#define _B120_ _B_ +#endif + +#if _MSVCR_VER>=140 +#define _S140_ _S_ +#define _C140_ _C_ +#define _L140_ _L_ +#else +#define _S140_ 0 +#define _C140_ 0 +#define _L140_ 0 +#endif + +WORD MSVCRT__wctype [257] = { + 0, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_|_B120_, _S_|_C_, _S_|_C_, + _S_|_C_, _S_|_C_, _C_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _S_|_B_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, + _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, + _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_, + _P_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _P_, _P_, _P_, _P_, + _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_|_S140_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, + _S_|_B120_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_|_L140_, _P_, + _P_, _P_|_C140_, _P_, _P_, + _P_, _P_, _SUP_, _SUP_, _P_, _P_|_L140_, _P_, _P_, _P_, _SUP_, _P_|_L140_, _P_, + _P_, _P_, _P_, _P_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, + _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, + _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_ +}; + #if _MSVCR_VER>=80
/********************************************************************* diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 41fdc496f4..8f174ee95a 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2062,7 +2062,7 @@ @ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l -@ stub _wctype +@ extern _wctype MSVCRT__wctype @ cdecl _wdupenv_s(ptr ptr wstr) @ varargs _wexecl(wstr wstr) @ varargs _wexecle(wstr wstr)
January 9, 2020 12:55 AM, "Jeff Smith" whydoubt@gmail.com wrote:
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 600c4db008..efb879a89d 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -40,6 +40,64 @@ static BOOL n_format_enabled = TRUE; #include "printf.h" #undef PRINTF_WIDE
+/* Some abbreviations to make the following table readable */ +#define _C_ MSVCRT__CONTROL +#define _S_ MSVCRT__SPACE +#define _P_ MSVCRT__PUNCT +#define _D_ MSVCRT__DIGIT +#define _H_ MSVCRT__HEX +#define _U_ MSVCRT__UPPER|0x100 +#define _L_ MSVCRT__LOWER|0x100 +#define _B_ MSVCRT__BLANK
+#if _MSVCR_VER==120 +#define _SUP_ _P_ +#else +#define _SUP_ _P_|_D_ +#endif
+#if _MSVCR_VER>=120 +#define _B120_ 0 +#else +#define _B120_ _B_ +#endif
+#if _MSVCR_VER>=140 +#define _S140_ _S_ +#define _C140_ _C_ +#define _L140_ _L_ +#else +#define _S140_ 0 +#define _C140_ 0 +#define _L140_ 0 +#endif
+WORD MSVCRT__wctype [257] = {
- 0,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_|_B120_, _S_|_C_, _S_|_C_,
_S_|_C_, _S_|_C_, _C_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _S_|_B_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_,
- _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_,
- _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_,
- _P_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_,
_U_, _U_, _U_, _U_, _U_, _U_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _P_, _P_, _P_, _P_,
- _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_, _L_, _L_,
_L_, _L_, _L_, _L_, _L_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_|_S140_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _S_|_B120_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_|_L140_, _P_,
_P_, _P_|_C140_, _P_, _P_,
- _P_, _P_, _SUP_, _SUP_, _P_, _P_|_L140_, _P_, _P_, _P_, _SUP_, _P_|_L140_, _P_,
_P_, _P_, _P_, _P_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_
+};
But wait, WEOF in msvcrt is not (wint_t)(-1) but (wint_t)0xffff. Passing WEOF to this array won't do what you think it does. Is this really what native has?
#if _MSVCR_VER>=80
/*********************************************************************
Chip
On Thu, Jan 9, 2020 at 12:32 PM Chip Davis cdavis@codeweavers.com wrote:
January 9, 2020 12:55 AM, "Jeff Smith" whydoubt@gmail.com wrote:
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 600c4db008..efb879a89d 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -40,6 +40,64 @@ static BOOL n_format_enabled = TRUE; #include "printf.h" #undef PRINTF_WIDE
+/* Some abbreviations to make the following table readable */ +#define _C_ MSVCRT__CONTROL +#define _S_ MSVCRT__SPACE +#define _P_ MSVCRT__PUNCT +#define _D_ MSVCRT__DIGIT +#define _H_ MSVCRT__HEX +#define _U_ MSVCRT__UPPER|0x100 +#define _L_ MSVCRT__LOWER|0x100 +#define _B_ MSVCRT__BLANK
+#if _MSVCR_VER==120 +#define _SUP_ _P_ +#else +#define _SUP_ _P_|_D_ +#endif
+#if _MSVCR_VER>=120 +#define _B120_ 0 +#else +#define _B120_ _B_ +#endif
+#if _MSVCR_VER>=140 +#define _S140_ _S_ +#define _C140_ _C_ +#define _L140_ _L_ +#else +#define _S140_ 0 +#define _C140_ 0 +#define _L140_ 0 +#endif
+WORD MSVCRT__wctype [257] = {
- 0,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_|_B120_, _S_|_C_, _S_|_C_,
_S_|_C_, _S_|_C_, _C_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _S_|_B_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_,
- _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_,
- _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_,
- _P_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_,
_U_, _U_, _U_, _U_, _U_, _U_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _P_, _P_, _P_, _P_,
- _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_, _L_, _L_, _L_,
_L_, _L_, _L_, _L_, _L_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_|_S140_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
- _S_|_B120_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_|_L140_, _P_,
_P_, _P_|_C140_, _P_, _P_,
- _P_, _P_, _SUP_, _SUP_, _P_, _P_|_L140_, _P_, _P_, _P_, _SUP_, _P_|_L140_, _P_,
_P_, _P_, _P_, _P_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_,
- _U_, _U_, _U_, _U_, _U_, _U_, _U_, _P_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_,
- _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_
+};
Hi Chip,
But wait, WEOF in msvcrt is not (wint_t)(-1) but (wint_t)0xffff. Passing WEOF to this array won't do what you think it does. Is this really what native has?
Also in msvcrt, the first parameter to iswctype is MSVCRT_wchar_t ... defined as an unsigned short. So I expected the values to be in the range 0..65535
Yes, this table does match the native _wctype table, which I've seen 3 versions of: one for msvcrt40-msvcr110, one for msvcr120, and one for ucrtbase. Then _pwctype (or the return value from calling __pwctype_func) points to the second entry of this table. In the testing I've done, the lower portion follows the library (e.g. msvcrt or msvcr120 or ucrtbase) vs the upper portion follows the OS (e.g. Win10 or WinXP).
In my implementation, for values 0..255, iswctype will return the value from the _pwctype table, for 256..65535 it will fall back to wine_wctype_table (via get_char_typeW).
Thanks, Jeff
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/crtdll/crtdll.spec | 2 +- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/wcs.c | 2 ++ dlls/msvcrt40/msvcrt40.spec | 2 +- dlls/msvcrtd/msvcrtd.spec | 2 +- 13 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/dlls/crtdll/crtdll.spec b/dlls/crtdll/crtdll.spec index 9c88c2ac5a..1a5b61c7a0 100644 --- a/dlls/crtdll/crtdll.spec +++ b/dlls/crtdll/crtdll.spec @@ -257,7 +257,7 @@ @ cdecl _putch(long) @ cdecl _putenv(str) @ cdecl _putw(long ptr) MSVCRT__putw -# extern _pwctype_dll +@ extern _pwctype_dll MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _rmdir(str) MSVCRT__rmdir @ cdecl _rmtmp() MSVCRT__rmtmp diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index ff974b571d..ca4081c4db 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1243,7 +1243,7 @@ @ cdecl _putwch(long) @ cdecl _putwch_nolock(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_crt(ptr long) MSVCRT_realloc @ cdecl _recalloc(ptr long long) diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 996b00691d..b8403c7b95 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -1600,7 +1600,7 @@ @ cdecl _putwch(long) @ cdecl _putwch_nolock(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_crt(ptr long) MSVCRT_realloc @ cdecl _recalloc(ptr long long) diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index d519c730c7..793814545d 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -1610,7 +1610,7 @@ @ cdecl _putwch(long) @ cdecl _putwch_nolock(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_crt(ptr long) MSVCRT_realloc @ cdecl _recalloc(ptr long long) diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index ce95cbc1b8..2805964d4c 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -1336,7 +1336,7 @@ @ cdecl _putw(long ptr) msvcr120._putw @ cdecl _putwc_nolock(long ptr) msvcr120._putwc_nolock @ cdecl _putws(wstr) msvcr120._putws -# extern _pwctype +@ extern _pwctype msvcr120._pwctype @ cdecl _read(long ptr long) msvcr120._read @ cdecl _realloc_crt(ptr long) msvcr120._realloc_crt @ cdecl _recalloc(ptr long long) msvcr120._recalloc diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index 12f4ce6104..d3a4413def 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -497,7 +497,7 @@ @ cdecl _putw(long ptr) MSVCRT__putw @ cdecl _putwch(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _resetstkoflw() MSVCRT__resetstkoflw @ cdecl _rmdir(str) MSVCRT__rmdir diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 131f0f471a..494f522505 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -492,7 +492,7 @@ @ cdecl _putw(long ptr) MSVCRT__putw @ cdecl _putwch(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _resetstkoflw() MSVCRT__resetstkoflw @ cdecl _rmdir(str) MSVCRT__rmdir diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 59f2867734..550d4432a8 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -917,7 +917,7 @@ @ cdecl _putwch(long) @ cdecl _putwch_nolock(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_crt(ptr long) MSVCRT_realloc @ cdecl _recalloc(ptr long long) diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index f44c4d4c4c..1280c7d901 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -893,7 +893,7 @@ @ cdecl _putwch(long) @ cdecl _putwch_nolock(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_crt(ptr long) MSVCRT_realloc @ cdecl _recalloc(ptr long long) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index b9a5c2644c..5d91891dcc 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -862,7 +862,7 @@ @ cdecl _putw(long ptr) MSVCRT__putw @ cdecl _putwch(long) @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read # stub _realloc_dbg(ptr long long str long) @ cdecl _resetstkoflw() MSVCRT__resetstkoflw diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index efb879a89d..32904ebb7e 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -98,6 +98,8 @@ WORD MSVCRT__wctype [257] = { _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_ };
+WORD *MSVCRT__pwctype = MSVCRT__wctype + 1; + #if _MSVCR_VER>=80
/********************************************************************* diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index c2cee6cfde..082b50f3c1 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -1183,7 +1183,7 @@ @ cdecl _putenv(str) msvcrt._putenv @ cdecl _putw(long ptr) msvcrt._putw @ cdecl _putws(wstr) msvcrt._putws -# extern _pwctype +@ extern _pwctype msvcrt._pwctype @ cdecl _read(long ptr long) msvcrt._read @ cdecl _rmdir(str) msvcrt._rmdir @ cdecl _rmtmp() msvcrt._rmtmp diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index b502ed78d1..2bb1d3d3b0 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -472,7 +472,7 @@ @ cdecl _putenv(str) @ cdecl _putw(long ptr) MSVCRT__putw @ cdecl _putws(wstr) MSVCRT__putws -# extern _pwctype +@ extern _pwctype MSVCRT__pwctype @ cdecl _read(long ptr long) MSVCRT__read @ cdecl _realloc_dbg(ptr long) MSVCRT_realloc @ cdecl _rmdir(str) MSVCRT__rmdir
Signed-off-by: Jeff Smith whydoubt@gmail.com --- .../api-ms-win-crt-locale-l1-1-0.spec | 2 +- dlls/msvcr100/msvcr100.spec | 4 ++-- dlls/msvcr110/msvcr110.spec | 4 ++-- dlls/msvcr120/msvcr120.spec | 4 ++-- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcr70/msvcr70.spec | 4 ++-- dlls/msvcr71/msvcr71.spec | 4 ++-- dlls/msvcr80/msvcr80.spec | 4 ++-- dlls/msvcr90/msvcr90.spec | 4 ++-- dlls/msvcrt/msvcrt.spec | 4 ++-- dlls/msvcrt/wcs.c | 16 ++++++++++++++++ dlls/msvcrtd/msvcrtd.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 13 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/dlls/api-ms-win-crt-locale-l1-1-0/api-ms-win-crt-locale-l1-1-0.spec b/dlls/api-ms-win-crt-locale-l1-1-0/api-ms-win-crt-locale-l1-1-0.spec index 12bbbe6133..dc2ec27220 100644 --- a/dlls/api-ms-win-crt-locale-l1-1-0/api-ms-win-crt-locale-l1-1-0.spec +++ b/dlls/api-ms-win-crt-locale-l1-1-0/api-ms-win-crt-locale-l1-1-0.spec @@ -5,7 +5,7 @@ @ cdecl ___mb_cur_max_l_func(ptr) ucrtbase.___mb_cur_max_l_func @ cdecl __initialize_lconv_for_unsigned_char() ucrtbase.__initialize_lconv_for_unsigned_char @ cdecl __pctype_func() ucrtbase.__pctype_func -@ stub __pwctype_func +@ cdecl __pwctype_func() ucrtbase.__pwctype_func @ cdecl _configthreadlocale(long) ucrtbase._configthreadlocale @ cdecl _create_locale(long str) ucrtbase._create_locale @ cdecl _free_locale(ptr) ucrtbase._free_locale diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index ca4081c4db..f5f2711f43 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -641,7 +641,7 @@ @ cdecl __p__mbctype() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -649,7 +649,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index b8403c7b95..52da18e39a 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -990,7 +990,7 @@ @ cdecl __p__mbctype() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -998,7 +998,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 793814545d..279aed8fa8 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -980,7 +980,7 @@ @ cdecl __p__mbctype() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -988,7 +988,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index 2805964d4c..29953c185e 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -960,7 +960,7 @@ @ cdecl __p__wpgmptr() msvcr120.__p__wpgmptr @ cdecl __pctype_func() msvcr120.__pctype_func @ extern __pioinfo msvcr120.__pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() msvcr120.__pwctype_func @ cdecl __pxcptinfoptrs() msvcr120.__pxcptinfoptrs @ stub __report_gsfailure @ extern __setlc_active msvcr120.__setlc_active diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index d3a4413def..d53e39b2e4 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -181,7 +181,7 @@ @ cdecl __p__osver() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -192,7 +192,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ cdecl __security_error_handler(long ptr) @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 494f522505..2bc3651b62 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -176,7 +176,7 @@ @ cdecl __p__osver() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -187,7 +187,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ cdecl __security_error_handler(long ptr) @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 550d4432a8..70b1ff15a0 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -287,7 +287,7 @@ @ cdecl __p__osver() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -298,7 +298,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 1280c7d901..ae2c733fa0 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -274,7 +274,7 @@ @ cdecl __p__mbctype() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln @@ -282,7 +282,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __set_app_type(long) MSVCRT___set_app_type diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 5d91891dcc..0c907a8278 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -265,7 +265,7 @@ @ cdecl -arch=i386 __p__osver() @ cdecl -arch=i386 __p__pctype() MSVCRT___p__pctype @ cdecl -arch=i386 __p__pgmptr() MSVCRT___p__pgmptr -@ stub -arch=i386 __p__pwctype() +@ cdecl -arch=i386 __p__pwctype() MSVCRT___p__pwctype @ cdecl -arch=i386 __p__timezone() MSVCRT___p__timezone @ cdecl -arch=i386 __p__tzname() @ cdecl -arch=i386 __p__wcmdln() MSVCRT___p__wcmdln @@ -276,7 +276,7 @@ @ cdecl -arch=i386 __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo -# stub __pwctype_func() +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ cdecl __set_app_type(long) MSVCRT___set_app_type @ extern __setlc_active MSVCRT___setlc_active diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 32904ebb7e..87e658f509 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -100,6 +100,22 @@ WORD MSVCRT__wctype [257] = {
WORD *MSVCRT__pwctype = MSVCRT__wctype + 1;
+/********************************************************************* + * __p__pwctype (MSVCRT.@) + */ +WORD** CDECL MSVCRT___p__pwctype(void) +{ + return &MSVCRT__pwctype; +} + +/********************************************************************* + * __pwctype_func (MSVCRT.@) + */ +const WORD* CDECL MSVCRT___pwctype_func(void) +{ + return MSVCRT__pwctype; +} + #if _MSVCR_VER>=80
/********************************************************************* diff --git a/dlls/msvcrtd/msvcrtd.spec b/dlls/msvcrtd/msvcrtd.spec index 2bb1d3d3b0..80d3690d53 100644 --- a/dlls/msvcrtd/msvcrtd.spec +++ b/dlls/msvcrtd/msvcrtd.spec @@ -173,7 +173,7 @@ @ cdecl __p__osver() @ cdecl __p__pctype() MSVCRT___p__pctype @ cdecl __p__pgmptr() MSVCRT___p__pgmptr -@ stub __p__pwctype() +@ cdecl __p__pwctype() MSVCRT___p__pwctype @ cdecl __p__timezone() MSVCRT___p__timezone @ cdecl __p__tzname() @ cdecl __p__wcmdln() MSVCRT___p__wcmdln diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 8f174ee95a..d591ed8b84 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -136,7 +136,7 @@ @ cdecl __p__wpgmptr() MSVCRT___p__wpgmptr @ cdecl __pctype_func() MSVCRT___pctype_func @ cdecl __processing_throw() -@ stub __pwctype_func +@ cdecl __pwctype_func() MSVCRT___pwctype_func @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcr120/tests/msvcr120.c | 10 ++++------ dlls/msvcrt/tests/string.c | 10 ++++------ dlls/msvcrt/wcs.c | 2 +- dlls/ucrtbase/tests/misc.c | 10 ++++------ dlls/ucrtbase/tests/string.c | 10 ++++------ 5 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 9d8a5f0321..d6444a07e7 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -1102,7 +1102,7 @@ static void test_iswctype(void) base_wctype[c] = p_iswctype(c, 0xffff); types |= base_wctype[c]; } - todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + ok(types == 0x1ff, "Unexpected wctype bits present\n");
for (c = 0x100; c <= 0xffff; c++) { @@ -1113,11 +1113,9 @@ static void test_iswctype(void)
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); - } + 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) diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 3e52d56f00..d3fb2b37de 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -4083,7 +4083,7 @@ static void test_iswctype(void) base_wctype[c] = p_iswctype(c, 0xffff); types |= base_wctype[c]; } - todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + ok(types == 0x1ff, "Unexpected wctype bits present\n");
for (c = 0x100; c <= 0xffff; c++) { @@ -4094,11 +4094,9 @@ static void test_iswctype(void)
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); - } + 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) diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index 87e658f509..2eba571726 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -2025,7 +2025,7 @@ int CDECL MSVCRT__iswxdigit_l( MSVCRT_wchar_t wc, MSVCRT__locale_t locale ) */ INT CDECL MSVCRT__iswctype_l( MSVCRT_wchar_t wc, MSVCRT_wctype_t type, MSVCRT__locale_t locale ) { - return (get_char_typeW(wc) & 0xfff) & type; + return (wc <= 0xff ? MSVCRT__pwctype[wc] : get_char_typeW(wc) & 0xfff) & type; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index f637997a0d..c186cca1a4 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -647,17 +647,15 @@ static void test_isblank(void) for(c = 0; c <= 0xffff; c++) { if(c == '\t' || c == ' ' || c == 0x3000 || c == 0xfeff) { if(c == '\t') - todo_wine ok(!p__iswctype_l(c, _BLANK, NULL), "tab shouldn't be blank\n"); + ok(!p__iswctype_l(c, _BLANK, NULL), "tab shouldn't be blank\n"); else ok(p__iswctype_l(c, _BLANK, NULL), "%d should be blank\n", c); ok(p_iswblank(c), "%d should be blank\n", c); ok(p__iswblank_l(c, NULL), "%d should be blank\n", c); } else { - todo_wine_if(c == 0xa0) { - ok(!p__iswctype_l(c, _BLANK, NULL), "%d shouldn't be blank\n", c); - ok(!p_iswblank(c), "%d shouldn't be blank\n", c); - ok(!p__iswblank_l(c, NULL), "%d shouldn't be blank\n", c); - } + ok(!p__iswctype_l(c, _BLANK, NULL), "%d shouldn't be blank\n", c); + ok(!p_iswblank(c), "%d shouldn't be blank\n", c); + ok(!p__iswblank_l(c, NULL), "%d shouldn't be blank\n", c); } } } diff --git a/dlls/ucrtbase/tests/string.c b/dlls/ucrtbase/tests/string.c index 2a77d8882a..3aa6ec9a0b 100644 --- a/dlls/ucrtbase/tests/string.c +++ b/dlls/ucrtbase/tests/string.c @@ -434,7 +434,7 @@ static void test_iswctype(void) base_wctype[c] = p_iswctype(c, 0xffff); types |= base_wctype[c]; } - todo_wine ok(types == 0x1ff, "Unexpected wctype bits present\n"); + ok(types == 0x1ff, "Unexpected wctype bits present\n");
for (c = 0x100; c <= 0xffff; c++) { @@ -445,11 +445,9 @@ static void test_iswctype(void)
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); - } + 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++)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63057
Your paranoid android.
=== debian10 (32 bit report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
=== debian10 (32 bit French report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
=== debian10 (32 bit Japanese:Japan report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
=== debian10 (32 bit Chinese:China report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
=== debian10 (32 bit WoW report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
=== debian10 (64 bit WoW report) ===
Report errors: ntdll:string prints too much data (7421640 bytes)
Hi Jeff,
On 09.01.2020 07:53, Jeff Smith wrote:
@@ -1501,6 +1515,63 @@ static void test_sscanf(void) ok(d == 0.0, "d = %lf\n", f); }
+static void test_iswctype(void) +{
- unsigned int c, i;
- unsigned short types = 0;
- unsigned short base_wctype[65536];
- 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");
How about copying NTDLL_wctype to tests so that you can test exact return values for 0..255 ranges? You wouldn't need base_wctype array. You could just iterate all values and compare iswctype result to the value from wctype array. Also, it would be nice to test return values of isw* functions for those characters.
Thanks,
Jacek
On Thu, Jan 9, 2020 at 8:56 AM Jacek Caban jacek@codeweavers.com wrote:
Hi Jeff,
On 09.01.2020 07:53, Jeff Smith wrote:
@@ -1501,6 +1515,63 @@ static void test_sscanf(void) ok(d == 0.0, "d = %lf\n", f); }
+static void test_iswctype(void) +{
- unsigned int c, i;
- unsigned short types = 0;
- unsigned short base_wctype[65536];
- 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");
Hi Jacek,
How about copying NTDLL_wctype to tests so that you can test exact return values for 0..255 ranges? You wouldn't need base_wctype array. You could just iterate all values and compare iswctype result to the value from wctype array. Also, it would be nice to test return values of isw* functions for those characters.
I like that idea for checking the whole table. Adding the isw tests shouldn't be too hard to do as well.
Thanks, Jeff