diff --git a/dlls/api-ms-win-crt-convert-l1-1-0/api-ms-win-crt-convert-l1-1-0.spec b/dlls/api-ms-win-crt-convert-l1-1-0/api-ms-win-crt-convert-l1-1-0.spec index a72ec0a4706..1b877e38728 100644 --- a/dlls/api-ms-win-crt-convert-l1-1-0/api-ms-win-crt-convert-l1-1-0.spec +++ b/dlls/api-ms-win-crt-convert-l1-1-0/api-ms-win-crt-convert-l1-1-0.spec @@ -119,4 +119,4 @@ @ cdecl wctob(long) ucrtbase.wctob @ cdecl wctomb(ptr long) ucrtbase.wctomb @ cdecl wctomb_s(ptr ptr long long) ucrtbase.wctomb_s -@ stub wctrans +@ cdecl wctrans(str) ucrtbase.wctrans 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 0a61576bb69..78544371d23 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 @@ -151,7 +151,7 @@ @ cdecl strxfrm(ptr str long) ucrtbase.strxfrm @ cdecl tolower(long) ucrtbase.tolower @ cdecl toupper(long) ucrtbase.toupper -@ stub towctrans +@ cdecl towctrans(long long) ucrtbase.towctrans @ cdecl towlower(long) ucrtbase.towlower @ cdecl towupper(long) ucrtbase.towupper @ cdecl wcscat(wstr wstr) ucrtbase.wcscat diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 4ddead9bc83..1b6ef354a99 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2414,7 +2414,7 @@ @ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper -@ stub towctrans +@ cdecl towctrans(long long) MSVCR120_towctrans @ cdecl towlower(long) MSVCRT_towlower @ cdecl towupper(long) MSVCRT_towupper @ cdecl trunc(double) MSVCR120_trunc @@ -2486,7 +2486,7 @@ @ cdecl wctob(long) MSVCRT_wctob @ cdecl wctomb(ptr long) MSVCRT_wctomb @ cdecl wctomb_s(ptr ptr long long) MSVCRT_wctomb_s -@ stub wctrans +@ cdecl wctrans(str) MSVCR120_wctrans @ cdecl wctype(str) @ cdecl wmemcpy_s(ptr long ptr long) @ cdecl wmemmove_s(ptr long ptr long) diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 3077a18c1ef..be5df27e937 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,8 @@ static double (__cdecl *p_creal)(_Dcomplex); static double (__cdecl *p_nexttoward)(double, double); 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); /* make sure we use the correct errno */ #undef errno @@ -268,6 +271,8 @@ static BOOL init(void) SET(p_nexttoward, "nexttoward"); SET(p_nexttowardf, "nexttowardf"); SET(p_nexttowardl, "nexttowardl"); + SET(p_wctrans, "wctrans"); + SET(p_towctrans, "towctrans"); if(sizeof(void*) == 8) { /* 64-bit initialization */ SET(p_critical_section_ctor, "??0critical_section@Concurrency@@QEAA@XZ"); @@ -1052,6 +1057,37 @@ static void test_nexttoward(void) ok(e == -1, "Expected no error, got %d.\n", e); } +static void test_towctrans(void) +{ + wchar_t ret; + + ret = p_wctrans("tolower"); + ok(ret == 2, "wctrans returned %d, expected 2\n", ret); + ret = p_wctrans("toupper"); + ok(ret == 1, "wctrans returned %d, expected 1\n", ret); + ret = p_wctrans("toLower"); + ok(ret == 0, "wctrans returned %d, expected 0\n", ret); + ret = p_wctrans(""); + ok(ret == 0, "wctrans returned %d, expected 0\n", ret); + if(0) { /* crashes on windows */ + ret = p_wctrans(NULL); + ok(ret == 0, "wctrans returned %d, expected 0\n", ret); + } + + ret = p_towctrans('t', 2); + ok(ret == 't', "towctrans('t', 2) returned %c, expected t\n", ret); + ret = p_towctrans('T', 2); + ok(ret == 't', "towctrans('T', 2) returned %c, expected t\n", ret); + ret = p_towctrans('T', 0); + ok(ret == 't', "towctrans('T', 0) returned %c, expected t\n", ret); + ret = p_towctrans('T', 3); + ok(ret == 't', "towctrans('T', 3) returned %c, expected t\n", ret); + ret = p_towctrans('t', 1); + ok(ret == 'T', "towctrans('t', 1) returned %c, expected T\n", ret); + ret = p_towctrans('T', 1); + ok(ret == 'T', "towctrans('T', 1) returned %c, expected T\n", ret); +} + START_TEST(msvcr120) { if (!init()) return; @@ -1072,4 +1108,5 @@ START_TEST(msvcr120) test_vsscanf(); test__Cbuild(); test_nexttoward(); + test_towctrans(); } diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index 54de44b209a..c6755951c2b 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -2076,7 +2076,7 @@ @ cdecl tmpnam_s(ptr long) msvcr120.tmpnam_s @ cdecl tolower(long) msvcr120.tolower @ cdecl toupper(long) msvcr120.toupper -@ stub towctrans +@ cdecl towctrans(long long) msvcr120.towctrans @ cdecl towlower(long) msvcr120.towlower @ cdecl towupper(long) msvcr120.towupper @ cdecl trunc(double) msvcr120.trunc @@ -2148,7 +2148,7 @@ @ cdecl wctob(long) msvcr120.wctob @ cdecl wctomb(ptr long) msvcr120.wctomb @ cdecl wctomb_s(ptr ptr long long) msvcr120.wctomb_s -@ stub wctrans +@ cdecl wctrans(str) msvcr120.wctrans @ cdecl wctype(str) msvcr120.wctype @ cdecl wmemcpy_s(ptr long ptr long) msvcr120.wmemcpy_s @ cdecl wmemmove_s(ptr long ptr long) msvcr120.wmemmove_s diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index a1e827d9e2b..4282fed7ff3 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -2069,3 +2069,30 @@ BOOL msvcrt_init_locale(void) _setmbcp(_MB_CP_ANSI); return TRUE; } + +#if _MSVCR_VER >= 120 +/********************************************************************* + * wctrans (MSVCR120.@) + */ +MSVCRT_wctrans_t CDECL MSVCR120_wctrans(const char *property) +{ + static const char str_tolower[] = "tolower"; + static const char str_toupper[] = "toupper"; + + if(!strcmp(property, str_tolower)) + return 2; + if(!strcmp(property, str_toupper)) + return 1; + return 0; +} + +/********************************************************************* + * towctrans (MSVCR120.@) + */ +MSVCRT_wint_t CDECL MSVCR120_towctrans(MSVCRT_wint_t c, MSVCRT_wctrans_t category) +{ + if(category == 1) + return MSVCRT__towupper_l(c, NULL); + return MSVCRT__towlower_l(c, NULL); +} +#endif diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 2fb26b94e42..60d7b4f0bc5 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -63,6 +63,7 @@ typedef unsigned char MSVCRT_bool; typedef unsigned short MSVCRT_wchar_t; typedef unsigned short MSVCRT_wint_t; +typedef unsigned short MSVCRT_wctrans_t; typedef unsigned short MSVCRT_wctype_t; typedef unsigned short MSVCRT__ino_t; typedef unsigned int MSVCRT__fsize_t; @@ -1143,6 +1144,8 @@ void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_ const MSVCRT_wchar_t *file, unsigned int line, MSVCRT_uintptr_t arg); int __cdecl MSVCRT__toupper_l(int,MSVCRT__locale_t); int __cdecl MSVCRT__tolower_l(int,MSVCRT__locale_t); +int __cdecl MSVCRT__towupper_l(MSVCRT_wint_t,MSVCRT__locale_t); +int __cdecl MSVCRT__towlower_l(MSVCRT_wint_t,MSVCRT__locale_t); int __cdecl MSVCRT__strnicmp(const char*, const char*, MSVCRT_size_t); int __cdecl MSVCRT__strnicoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t); int __cdecl MSVCRT__strncoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t); diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 2e5e102442e..b9511545d6b 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2543,7 +2543,7 @@ @ cdecl tmpnam_s(ptr long) MSVCRT_tmpnam_s @ cdecl tolower(long) MSVCRT_tolower @ cdecl toupper(long) MSVCRT_toupper -@ stub towctrans +@ cdecl towctrans(long long) MSVCR120_towctrans @ cdecl towlower(long) MSVCRT_towlower @ cdecl towupper(long) MSVCRT_towupper @ cdecl trunc(double) MSVCR120_trunc @@ -2593,7 +2593,7 @@ @ cdecl wctob(long) MSVCRT_wctob @ cdecl wctomb(ptr long) MSVCRT_wctomb @ cdecl wctomb_s(ptr ptr long long) MSVCRT_wctomb_s -@ stub wctrans +@ cdecl wctrans(str) MSVCR120_wctrans @ cdecl wctype(str) @ cdecl wmemcpy_s(ptr long ptr long) @ cdecl wmemmove_s(ptr long ptr long)