https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f446a50f76032af9b0e1fe...
commit f446a50f76032af9b0e1fe3d66c2b9d087772a93 Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Tue Jan 29 13:08:13 2019 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Tue Jan 29 13:08:13 2019 +0100
[MSVCRT_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/msvcrt/cpp.c | 6 +- modules/rostests/winetests/msvcrt/dir.c | 16 +- modules/rostests/winetests/msvcrt/file.c | 23 +- modules/rostests/winetests/msvcrt/locale.c | 17 +- modules/rostests/winetests/msvcrt/misc.c | 4 +- modules/rostests/winetests/msvcrt/printf.c | 4 +- modules/rostests/winetests/msvcrt/scanf.c | 9 +- modules/rostests/winetests/msvcrt/string.c | 422 ++++++++++++++++++++++++++--- 8 files changed, 426 insertions(+), 75 deletions(-)
diff --git a/modules/rostests/winetests/msvcrt/cpp.c b/modules/rostests/winetests/msvcrt/cpp.c index cf5e4c7d60..07b49ae755 100644 --- a/modules/rostests/winetests/msvcrt/cpp.c +++ b/modules/rostests/winetests/msvcrt/cpp.c @@ -1108,8 +1108,8 @@ static void test_demangle_datatype(void) { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE}, /* { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@",FALSE}, */ }; - int i, num_test = (sizeof(demangle)/sizeof(struct _demangle)); - + int i, num_test = ARRAY_SIZE(demangle); + for (i = 0; i < num_test; i++) { name = p__unDName(0, demangle[i].mangled, 0, pmalloc, pfree, 0x2800); @@ -1326,7 +1326,7 @@ static void test_demangle(void) /* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", "public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"}, }; - int i, num_test = (sizeof(test)/sizeof(test[0])); + int i, num_test = ARRAY_SIZE(test); char* name;
for (i = 0; i < num_test; i++) diff --git a/modules/rostests/winetests/msvcrt/dir.c b/modules/rostests/winetests/msvcrt/dir.c index a29d32b9d3..210cf3983c 100644 --- a/modules/rostests/winetests/msvcrt/dir.c +++ b/modules/rostests/winetests/msvcrt/dir.c @@ -97,7 +97,7 @@ static void test_makepath(void)
unsigned int i, n;
- for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); ++i) + for (i = 0; i < ARRAY_SIZE(makepath_cases); ++i) { const makepath_case* p = &makepath_cases[i];
@@ -253,7 +253,7 @@ static void test_makepath_s(void) ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
/* Test with the normal _makepath cases. */ - for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); i++) + for (i = 0; i < ARRAY_SIZE(makepath_cases); i++) { const makepath_case *p = makepath_cases + i;
@@ -296,7 +296,7 @@ static void test_makepath_s(void) }
/* Try insufficient length cases. */ - for (i = 0; i < sizeof(makepath_s_cases)/sizeof(makepath_s_cases[0]); i++) + for (i = 0; i < ARRAY_SIZE(makepath_s_cases); i++) { const makepath_s_case *p = makepath_s_cases + i;
@@ -457,12 +457,12 @@ static void test_searchenv(void) ok(path_len, "GetTempPath failed\n"); memcpy(path, tmppath, path_len);
- for(i=0; i<sizeof(dirs)/sizeof(*dirs); i++) { + for (i=0; i<ARRAY_SIZE(dirs); i++) { strcpy(path+path_len, dirs[i]); ok(!mkdir(path), "mkdir failed (dir = %s)\n", path); }
- for(i=0; i<sizeof(files)/sizeof(*files); i++) { + for (i=0; i<ARRAY_SIZE(files); i++) { strcpy(path+path_len, files[i]); tmp_file = fopen(path, "wb"); ok(tmp_file != NULL, "fopen failed (file = %s)\n", path); @@ -471,7 +471,7 @@ static void test_searchenv(void)
strcpy(env1, "TEST_PATH="); strcpy(env2, "TEST_PATH=;"); - for(i=1; i<sizeof(dirs)/sizeof(*dirs); i++) { + for (i=1; i<ARRAY_SIZE(dirs); i++) { strcat(env1, tmppath); strcat(env1, dirs[i]); strcat(env1, ";"); @@ -599,12 +599,12 @@ static void test_searchenv(void)
putenv("TEST_PATH=");
- for(i=sizeof(files)/sizeof(*files)-1; i>=0; i--) { + for (i=ARRAY_SIZE(files)-1; i>=0; i--) { strcpy(path+path_len, files[i]); ok(!remove(path), "remove failed (file = %s)\n", path); }
- for(i=sizeof(dirs)/sizeof(*dirs)-1; i>=0; i--) { + for (i=ARRAY_SIZE(dirs)-1; i>=0; i--) { strcpy(path+path_len, dirs[i]); ok(!rmdir(path), "rmdir failed (dir = %s)\n", path); } diff --git a/modules/rostests/winetests/msvcrt/file.c b/modules/rostests/winetests/msvcrt/file.c index 136ee1563e..fe62d5c385 100644 --- a/modules/rostests/winetests/msvcrt/file.c +++ b/modules/rostests/winetests/msvcrt/file.c @@ -144,7 +144,7 @@ static void test_fileops( void ) write (fd, outbuffer, sizeof (outbuffer)); close (fd);
- for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++) + for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++) { fd = open ("fdopen.tst", O_RDONLY | O_BINARY); file = fdopen (fd, "rb"); @@ -195,13 +195,13 @@ static void test_fileops( void ) } fd = open ("fdopen.tst", O_RDONLY | O_TEXT); file = fdopen (fd, "rt"); /* open in TEXT mode */ - ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n"); - ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n"); + ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) !=0,"fgetws failed unexpected\n"); + ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) ==0,"fgetws didn't signal EOF\n"); ok(feof(file) !=0,"feof doesn't signal EOF\n"); rewind(file); ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n"); ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n"); - ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n"); + ok(fgetws(wbuffer,ARRAY_SIZE(outbuffer),file) !=0,"fgets failed unexpected\n"); ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n"); fclose (file);
@@ -624,7 +624,7 @@ static void test_flsbuf( void ) static const int bufmodes[] = {_IOFBF,_IONBF};
tempf=_tempnam(".","wne"); - for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++) + for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++) { tempfh = fopen(tempf,"wb"); setvbuf(tempfh,NULL,bufmodes[bufmode],2048); @@ -878,8 +878,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag { /* mbstowcs rejects invalid multibyte sequence, so we use MultiByteToWideChar here. */ - ret = MultiByteToWideChar(codepage, 0, text, -1, - wtextW, sizeof(wtextW)/sizeof(wtextW[0])); + ret = MultiByteToWideChar(codepage, 0, text, -1, wtextW, ARRAY_SIZE(wtextW)); ok(ret > 0, "MultiByteToWideChar failed\n"); } else @@ -910,7 +909,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag
tempfh = fopen(tempfile, "rb"); ok(tempfh != NULL, "can't open tempfile\n"); - for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) + for (i = 0; i < ARRAY_SIZE(wchar_text); i++) { ch = fgetwc(tempfh); ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i); @@ -946,7 +945,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt,ccs=unicode"); ok(tempfh != NULL, "can't open tempfile\n"); - for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) { ch = fgetwc(tempfh); ok(ch == wchar_text[i], @@ -958,7 +957,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "wb"); ok(tempfh != NULL, "can't open tempfile\n"); - ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]), + ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, ARRAY_SIZE(wchar_text), utf8_text, sizeof(utf8_text), NULL, NULL); ok(ret > 0, "utf-8 conversion failed\n"); fwrite(utf8_text, sizeof(char), ret, tempfh); @@ -966,7 +965,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt, ccs=UTF-8"); ok(tempfh != NULL, "can't open tempfile\n"); - for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++) + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) { ch = fgetwc(tempfh); ok(ch == wchar_text[i], @@ -2659,5 +2658,5 @@ START_TEST(file) /* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report * file contains lines in the correct order */ - WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000); + WaitForMultipleObjects(ARRAY_SIZE(proc_handles), proc_handles, TRUE, 5000); } diff --git a/modules/rostests/winetests/msvcrt/locale.c b/modules/rostests/winetests/msvcrt/locale.c index f87a7914d0..ff777599aa 100644 --- a/modules/rostests/winetests/msvcrt/locale.c +++ b/modules/rostests/winetests/msvcrt/locale.c @@ -144,12 +144,10 @@ static void test_setlocale(void) || broken(!strcmp(ret, "Chinese_Taiwan.950")), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "Chinese_China.936"); -todo_wine ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) { trace("Chinese_China.936=%s\n", ret); -todo_wine ok(!strcmp(ret, "Chinese (Simplified)_People's Republic of China.936") /* Vista - Win7 */ || !strcmp(ret, "Chinese (Simplified)_China.936") /* Win8 - Win10 */ || broken(!strcmp(ret, "Chinese_People's Republic of China.936")), "ret = %s\n", ret); @@ -158,12 +156,14 @@ todo_wine ret = setlocale(LC_ALL, "csy"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Czech_Czech Republic.1250"), "ret = %s\n", ret); + ok(!strcmp(ret, "Czech_Czech Republic.1250") + || !strcmp(ret, "Czech_Czechia.1250"), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "czech"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Czech_Czech Republic.1250"), "ret = %s\n", ret); + ok(!strcmp(ret, "Czech_Czech Republic.1250") + || !strcmp(ret, "Czech_Czechia.1250"), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "dan"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); @@ -614,6 +614,9 @@ todo_wine
ret = setlocale(LC_ALL, "English_United States.UTF8"); ok(ret == NULL, "ret != NULL\n"); + + ret = setlocale(LC_ALL, "en-US"); + ok(ret == NULL || broken (ret != NULL), "ret != NULL\n"); /* XP & 2003 */ }
static void test_crtGetStringTypeW(void) @@ -640,7 +643,7 @@ static void test_crtGetStringTypeW(void) return; }
- for(i=0; i<sizeof(str)/sizeof(*str); i++) { + for(i=0; i<ARRAY_SIZE(str); i++) { ret_crt = p__crtGetStringTypeW(0, CT_CTYPE1, str[i], 1, &out_crt); ret = GetStringTypeW(CT_CTYPE1, str[i], 1, &out); ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt); @@ -705,7 +708,7 @@ static void test__Gettnames(void) else ok(size==0x164 || broken(size==0xb8), "structure size: %x\n", size);
- for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++) + for (i = 0; i < ARRAY_SIZE(time_data); i++) { size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); @@ -719,7 +722,7 @@ static void test__Gettnames(void) return;
ret = _Gettnames(); - for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++) + for (i = 0; i < ARRAY_SIZE(time_data); i++) { size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); diff --git a/modules/rostests/winetests/msvcrt/misc.c b/modules/rostests/winetests/msvcrt/misc.c index 20253342d9..4a0330a2e2 100644 --- a/modules/rostests/winetests/msvcrt/misc.c +++ b/modules/rostests/winetests/msvcrt/misc.c @@ -170,7 +170,7 @@ static void test_I10_OUTPUT(void) if (j != 12) trace("sizeof(long double) = %d on this machine\n", j);
- for(i=0; i<sizeof(I10_OUTPUT_tests)/sizeof(I10_OUTPUT_test); i++) { + for(i=0; i<ARRAY_SIZE(I10_OUTPUT_tests); i++) { memset(out.str, '#', sizeof(out.str));
if (sizeof(long double) == 12) @@ -627,7 +627,7 @@ static void test__lfind_s(void) }
key = 1234; - num = sizeof(tests)/sizeof(tests[0]); + num = ARRAY_SIZE(tests);
errno = 0xdeadbeef; found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL); diff --git a/modules/rostests/winetests/msvcrt/printf.c b/modules/rostests/winetests/msvcrt/printf.c index 64658ce25f..80180ff8b2 100644 --- a/modules/rostests/winetests/msvcrt/printf.c +++ b/modules/rostests/winetests/msvcrt/printf.c @@ -841,7 +841,7 @@ static void test_snprintf (void) const int bufsiz = sizeof buffer; unsigned int i;
- for (i = 0; i < sizeof tests / sizeof tests[0]; i++) { + for (i = 0; i < ARRAY_SIZE(tests); i++) { const char *fmt = tests[i].format; const int expect = tests[i].expected; const int n = _snprintf (buffer, bufsiz, fmt); @@ -1215,7 +1215,7 @@ static void test_vsnwprintf(void) wchar_t str[32]; char buf[32];
- ret = _vsnwprintf_wrapper( str, sizeof(str)/sizeof(str[0]), format, one, two, three ); + ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), format, one, two, three );
ok( ret == 11, "got %d expected 11\n", ret ); WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL ); diff --git a/modules/rostests/winetests/msvcrt/scanf.c b/modules/rostests/winetests/msvcrt/scanf.c index 359b07937a..b7244835ac 100644 --- a/modules/rostests/winetests/msvcrt/scanf.c +++ b/modules/rostests/winetests/msvcrt/scanf.c @@ -282,10 +282,17 @@ static void test_sscanf_s(void) ok(ret == 0, "Wrong number of arguments read: %d\n", ret); ok(buf[0]=='\0', "buf = %s\n", buf);
- buf[0] = 'a'; + memset(buf, 'a', sizeof(buf)); ret = psscanf_s("123", "%3c", buf, 2); ok(ret == 0, "Wrong number of arguments read: %d\n", ret); ok(buf[0]=='\0', "buf = %s\n", buf); + ok(buf[1]=='2', "buf[1] = %d\n", buf[1]); + ok(buf[2]=='a', "buf[2] = %d\n", buf[2]); + + buf[3] = 'a'; + buf[4] = 0; + ret = psscanf_s("123", "%3c", buf, 3); + ok(!strcmp("123a", buf), "buf = %s\n", buf);
i = 1; ret = psscanf_s("123 123", "%s %d", buf, 2, &i); diff --git a/modules/rostests/winetests/msvcrt/string.c b/modules/rostests/winetests/msvcrt/string.c index b270366599..e80a51824b 100644 --- a/modules/rostests/winetests/msvcrt/string.c +++ b/modules/rostests/winetests/msvcrt/string.c @@ -89,6 +89,12 @@ static errno_t (__cdecl *p_mbslwr_s)(unsigned char *str, size_t numberOfElements static int (__cdecl *p_wctob)(wint_t); static size_t (__cdecl *p_wcrtomb)(char*, wchar_t, mbstate_t*); static int (__cdecl *p_tolower)(int); +static int (__cdecl *p_towlower)(wint_t); +static int (__cdecl *p__towlower_l)(wint_t, _locale_t); +static int (__cdecl *p_towupper)(wint_t); +static int (__cdecl *p__towupper_l)(wint_t, _locale_t); +static _locale_t(__cdecl *p__create_locale)(int, const char*); +static void(__cdecl *p__free_locale)(_locale_t); static size_t (__cdecl *p_mbrlen)(const char*, size_t, mbstate_t*); static size_t (__cdecl *p_mbrtowc)(wchar_t*, const char*, size_t, mbstate_t*); static int (__cdecl *p__atodbl_l)(_CRT_DOUBLE*,char*,_locale_t); @@ -100,6 +106,7 @@ static size_t (__cdecl *p__mbsnlen)(const unsigned char*, size_t); static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned char*); 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);
#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) @@ -607,8 +614,6 @@ static void test_strcpy_s(void) dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); }
-#define NUMELMS(array) (sizeof(array)/sizeof((array)[0])) - #define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \ ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] == b3 && \ dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] == b7, \ @@ -617,7 +622,7 @@ static void test_strcpy_s(void)
static void test_memcpy_s(void) { - static char dest[8]; + static char dest[8], buf[32]; static const char tiny[] = {'T',0,'I','N','Y',0}; static const char big[] = {'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0}; int ret; @@ -628,14 +633,14 @@ static void test_memcpy_s(void)
/* Normal */ memset(dest, 'X', sizeof(dest)); - ret = p_memcpy_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny)); + ret = p_memcpy_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); ok(ret == 0, "Copying a buffer into a big enough destination returned %d, expected 0\n", ret); okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Vary source size */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memcpy_s(dest, NUMELMS(dest), big, NUMELMS(big)); + ret = p_memcpy_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big)); ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d, expected ERANGE\n", ret); ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0); @@ -643,7 +648,7 @@ static void test_memcpy_s(void) /* Replace source with NULL */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memcpy_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny)); + ret = p_memcpy_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0); @@ -651,24 +656,36 @@ static void test_memcpy_s(void) /* Vary dest size */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memcpy_s(dest, 0, tiny, NUMELMS(tiny)); + ret = p_memcpy_s(dest, 0, tiny, ARRAY_SIZE(tiny)); ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected ERANGE\n", ret); ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */ errno = 0xdeadbeef; - ret = p_memcpy_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny)); + ret = p_memcpy_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memcpy_s(dest, 0, NULL, NUMELMS(tiny)); + ret = p_memcpy_s(dest, 0, NULL, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); + + ret = p_memcpy_s(buf, ARRAY_SIZE(buf), big, ARRAY_SIZE(big)); + ok(!ret, "memcpy_s returned %d\n", ret); + ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n"); + + ret = p_memcpy_s(buf + 1, ARRAY_SIZE(buf) - 1, buf, ARRAY_SIZE(big)); + ok(!ret, "memcpy_s returned %d\n", ret); + ok(!memcmp(buf + 1, big, sizeof(big)), "unexpected buf\n"); + + ret = p_memcpy_s(buf, ARRAY_SIZE(buf), buf + 1, ARRAY_SIZE(big)); + ok(!ret, "memcpy_s returned %d\n", ret); + ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n"); }
static void test_memmove_s(void) @@ -684,20 +701,20 @@ static void test_memmove_s(void)
/* Normal */ memset(dest, 'X', sizeof(dest)); - ret = p_memmove_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny)); + ret = p_memmove_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); ok(ret == 0, "Moving a buffer into a big enough destination returned %d, expected 0\n", ret); okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Overlapping */ memcpy(dest, big, sizeof(dest)); - ret = p_memmove_s(dest+1, NUMELMS(dest)-1, dest, NUMELMS(dest)-1); + ret = p_memmove_s(dest+1, ARRAY_SIZE(dest)-1, dest, ARRAY_SIZE(dest)-1); ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n", ret); okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]);
/* Vary source size */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memmove_s(dest, NUMELMS(dest), big, NUMELMS(big)); + ret = p_memmove_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big)); ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d, expected ERANGE\n", ret); ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); @@ -705,7 +722,7 @@ static void test_memmove_s(void) /* Replace source with NULL */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memmove_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny)); + ret = p_memmove_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); @@ -713,21 +730,21 @@ static void test_memmove_s(void) /* Vary dest size */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memmove_s(dest, 0, tiny, NUMELMS(tiny)); + ret = p_memmove_s(dest, 0, tiny, ARRAY_SIZE(tiny)); ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected ERANGE\n", ret); ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */ errno = 0xdeadbeef; - ret = p_memmove_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny)); + ret = p_memmove_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */ errno = 0xdeadbeef; memset(dest, 'X', sizeof(dest)); - ret = p_memmove_s(dest, 0, NULL, NUMELMS(tiny)); + ret = p_memmove_s(dest, 0, NULL, ARRAY_SIZE(tiny)); ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret); ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno); okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'); @@ -1016,7 +1033,7 @@ static void test_wcscpy_s(void) return; }
- ret = p_wcsncpy_s(NULL, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR)); + ret = p_wcsncpy_s(NULL, 18, szLongText, ARRAY_SIZE(szLongText)); ok(ret == EINVAL, "p_wcsncpy_s expect EINVAL got %d\n", ret);
szDest[0] = 'A'; @@ -1030,16 +1047,16 @@ static void test_wcscpy_s(void) ok(szDest[0] == 0, "szDest[0] not 0\n");
szDest[0] = 'A'; - ret = p_wcsncpy_s(szDest, 0, szLongText, sizeof(szLongText)/sizeof(WCHAR)); + ret = p_wcsncpy_s(szDest, 0, szLongText, ARRAY_SIZE(szLongText)); ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n");
- ret = p_wcsncpy_s(szDest, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR)); + ret = p_wcsncpy_s(szDest, 18, szLongText, ARRAY_SIZE(szLongText)); ok(ret == 0, "expected 0 got %d\n", ret); ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n");
szDest[0] = 'A'; - ret = p_wcsncpy_s(szDestShort, 8, szLongText, sizeof(szLongText)/sizeof(WCHAR)); + ret = p_wcsncpy_s(szDestShort, 8, szLongText, ARRAY_SIZE(szLongText)); ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret); ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
@@ -1067,7 +1084,7 @@ static void test__wcsupr_s(void) static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O', 'W', 'E', 'R', 'U', 'P', 'P', 'E', 'R', 0}; - WCHAR testBuffer[2*sizeof(mixedString)/sizeof(WCHAR)]; + WCHAR testBuffer[2*ARRAY_SIZE(mixedString)]; int ret;
if (!p_wcsupr_s) @@ -1084,7 +1101,7 @@ static void test__wcsupr_s(void)
/* Test NULL input string and valid size. */ errno = EBADF; - ret = p_wcsupr_s(NULL, sizeof(testBuffer)/sizeof(WCHAR)); + ret = p_wcsupr_s(NULL, ARRAY_SIZE(testBuffer)); ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
@@ -1128,21 +1145,21 @@ static void test__wcsupr_s(void)
/* Test normal string uppercasing. */ wcscpy(testBuffer, mixedString); - ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR)); + ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString)); ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
/* Test uppercasing with a shorter buffer size count. */ wcscpy(testBuffer, mixedString); errno = EBADF; - ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR) - 1); + ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString) - 1); ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret); ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
/* Test uppercasing with a longer buffer size count. */ wcscpy(testBuffer, mixedString); - ret = p_wcsupr_s(testBuffer, sizeof(testBuffer)/sizeof(WCHAR)); + ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(testBuffer)); ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret); ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n"); } @@ -1154,7 +1171,7 @@ static void test__wcslwr_s(void) static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o', 'w', 'e', 'r', 'u', 'p', 'p', 'e', 'r', 0}; - WCHAR buffer[2*sizeof(mixedString)/sizeof(WCHAR)]; + WCHAR buffer[2*ARRAY_SIZE(mixedString)]; int ret;
if (!p_wcslwr_s) @@ -1171,7 +1188,7 @@ static void test__wcslwr_s(void)
/* Test NULL input string and valid size. */ errno = EBADF; - ret = p_wcslwr_s(NULL, sizeof(buffer)/sizeof(buffer[0])); + ret = p_wcslwr_s(NULL, ARRAY_SIZE(buffer)); ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
@@ -1215,21 +1232,21 @@ static void test__wcslwr_s(void)
/* Test normal string uppercasing. */ wcscpy(buffer, mixedString); - ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR)); + ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString)); ok(ret == 0, "expected 0, got %d\n", ret); ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
/* Test uppercasing with a shorter buffer size count. */ wcscpy(buffer, mixedString); errno = EBADF; - ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR) - 1); + ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString) - 1); ok(ret == EINVAL, "expected EINVAL, got %d\n", ret); ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno); ok(buffer[0] == '\0', "expected empty string\n");
/* Test uppercasing with a longer buffer size count. */ wcscpy(buffer, mixedString); - ret = p_wcslwr_s(buffer, sizeof(buffer)/sizeof(WCHAR)); + ret = p_wcslwr_s(buffer, ARRAY_SIZE(buffer)); ok(ret == 0, "expected 0, got %d\n", ret); ok(!wcscmp(buffer, expectedString), "expected lowercase\n"); } @@ -1245,7 +1262,7 @@ static void test_mbcjisjms(void) unsigned int i, j; int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++) + for (i = 0; i < ARRAY_SIZE(cp); i++) { _setmbcp(cp[i]); for (j = 0; jisjms[j][0] != 0; j++) @@ -1273,7 +1290,7 @@ static void test_mbcjmsjis(void) unsigned int i, j; int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++) + for (i = 0; i < ARRAY_SIZE(cp); i++) { _setmbcp(cp[i]); for (j = 0; jmsjis[j][0] != 0; j++) @@ -1300,7 +1317,7 @@ static void test_mbctohira(void) unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS); - for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++) + for (i = 0; i < ARRAY_SIZE(mbchira_932); i++) { int ret, exp = mbchira_932[i][0]; ret = _mbctohira(mbchira_932[i][0]); @@ -1308,7 +1325,7 @@ static void test_mbctohira(void) }
_setmbcp(932); - for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++) + for (i = 0; i < ARRAY_SIZE(mbchira_932); i++) { unsigned int ret, exp; ret = _mbctohira(mbchira_932[i][0]); @@ -1329,7 +1346,7 @@ static void test_mbctokata(void) unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS); - for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++) + for (i = 0; i < ARRAY_SIZE(mbckata_932); i++) { int ret, exp = mbckata_932[i][0]; ret = _mbctokata(mbckata_932[i][0]); @@ -1337,7 +1354,7 @@ static void test_mbctokata(void) }
_setmbcp(932); - for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++) + for (i = 0; i < ARRAY_SIZE(mbckata_932); i++) { unsigned int ret, exp; ret = _mbctokata(mbckata_932[i][0]); @@ -1358,7 +1375,7 @@ static void test_mbbtombc(void) int i, j; int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++) + for (i = 0; i < ARRAY_SIZE(cp); i++) { _setmbcp(cp[i]); for (j = 0; mbbmbc[j][0] != 0; j++) @@ -1411,13 +1428,13 @@ static void test_ismbckata(void) { unsigned int i;
_setmbcp(_MB_CP_SBCS); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(tests); i++) { ret = _ismbckata(tests[i].c); ok(!ret, "expected 0, got %d for %04x\n", ret, tests[i].c); }
_setmbcp(932); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(tests); i++) { ret = _ismbckata(tests[i].c); ok(!!ret == tests[i].exp, "expected %d, got %d for %04x\n", tests[i].exp, !!ret, tests[i].c); @@ -2995,7 +3012,7 @@ static void test__wcstoi64(void) ok(ures == 071, "ures != 071\n");
/* Test various unicode digits */ - for (i = 0; i < sizeof(zeros) / sizeof(zeros[0]); ++i) { + for (i = 0; i < ARRAY_SIZE(zeros); ++i) { WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0}; res = p_wcstoi64(tmp, NULL, 0); ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res); @@ -3346,6 +3363,319 @@ static void test__memicmp_l(void) ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno); }
+static void test__strupr(void) +{ + const char str[] = "123"; + char str2[4]; + char *mem, *p; + DWORD prot; + + mem = VirtualAlloc(NULL, sizeof(str), MEM_COMMIT, PAGE_READWRITE); + ok(mem != NULL, "VirtualAlloc failed\n"); + memcpy(mem, str, sizeof(str)); + ok(VirtualProtect(mem, sizeof(str), PAGE_READONLY, &prot), "VirtualProtect failed\n"); + + strcpy(str2, "aBc"); + p = _strupr(str2); + ok(p == str2, "_strupr returned %p\n", p); + ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2); + + p = _strupr(mem); + ok(p == mem, "_strupr returned %p\n", p); + ok(!strcmp(mem, "123"), "mem = %s\n", mem); + + if(!setlocale(LC_ALL, "english")) { + VirtualFree(mem, sizeof(str), MEM_RELEASE); + win_skip("English locale _strupr tests\n"); + return; + } + + strcpy(str2, "aBc"); + p = _strupr(str2); + ok(p == str2, "_strupr returned %p\n", p); + ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2); + + if (0) /* crashes on Windows */ + { + p = _strupr(mem); + ok(p == mem, "_strupr returned %p\n", p); + ok(!strcmp(mem, "123"), "mem = %s\n", mem); + } + + setlocale(LC_ALL, "C"); + VirtualFree(mem, sizeof(str), MEM_RELEASE); +} + +static void test__tcsncoll(void) +{ + struct test { + const char *locale; + const char *str1; + const char *str2; + size_t count; + int exp; + }; + static const struct test tests[] = { + { "English", "ABCD", "ABCD", 4, 0 }, + { "English", "ABCD", "ABCD", 10, 0 }, + + { "English", "ABC", "ABCD", 3, 0 }, + { "English", "ABC", "ABCD", 4, -1 }, + { "English", "ABC", "ABCD", 10, -1 }, + + { "English", "ABCD", "ABC", 3, 0 }, + { "English", "ABCD", "ABC", 4, 1 }, + { "English", "ABCD", "ABC", 10, 1 }, + + { "English", "ABCe", "ABCf", 3, 0 }, + { "English", "abcd", "ABCD", 10, -1 }, + + { "C", "ABCD", "ABCD", 4, 0 }, + { "C", "ABCD", "ABCD", 10, 0 }, + + { "C", "ABC", "ABCD", 3, 0 }, + { "C", "ABC", "ABCD", 10, -1 }, + + { "C", "ABCD", "ABC", 3, 0 }, + { "C", "ABCD", "ABC", 10, 1 }, + + { "C", "ABCe", "ABCf", 3, 0 }, + { "C", "abcd", "ABCD", 10, 1 }, + }; + WCHAR str1W[16]; + WCHAR str2W[16]; + char str1[16]; + char str2[16]; + size_t len; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + if (!setlocale(LC_ALL, tests[i].locale)) + { + win_skip("%s locale _tcsncoll tests\n", tests[i].locale); + for (; i+1 < ARRAY_SIZE(tests); i++) + if (strcmp(tests[i].locale, tests[i+1].locale)) break; + continue; + } + + memset(str1, 0xee, sizeof(str1)); + strcpy(str1, tests[i].str1); + + memset(str2, 0xff, sizeof(str2)); + strcpy(str2, tests[i].str2); + + ret = _strncoll(str1, str2, tests[i].count); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + + memset(str1W, 0xee, sizeof(str1W)); + len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); + str1W[len] = 0; + + memset(str2W, 0xff, sizeof(str2W)); + len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W)); + str2W[len] = 0; + + ret = _wcsncoll(str1W, str2W, tests[i].count); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + } +} + +static void test__tcsnicoll(void) +{ + struct test { + const char *locale; + const char *str1; + const char *str2; + size_t count; + int exp; + }; + static const struct test tests[] = { + { "English", "abcd", "ABCD", 4, 0 }, + { "English", "abcd", "ABCD", 10, 0 }, + + { "English", "abc", "ABCD", 3, 0 }, + { "English", "abc", "ABCD", 4, -1 }, + { "English", "abc", "ABCD", 10, -1 }, + + { "English", "abcd", "ABC", 3, 0 }, + { "English", "abcd", "ABC", 4, 1 }, + { "English", "abcd", "ABC", 10, 1 }, + + { "English", "abcE", "ABCF", 3, 0 }, + + { "C", "abcd", "ABCD", 4, 0 }, + { "C", "abcd", "ABCD", 10, 0 }, + + { "C", "abc", "ABCD", 3, 0 }, + { "C", "abc", "ABCD", 10, -1 }, + + { "C", "abcd", "ABC", 3, 0 }, + { "C", "abcd", "ABC", 10, 1 }, + + { "C", "abce", "ABCf", 3, 0 }, + }; + WCHAR str1W[16]; + WCHAR str2W[16]; + char str1[16]; + char str2[16]; + size_t len; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + if (!setlocale(LC_ALL, tests[i].locale)) + { + win_skip("%s locale _tcsnicoll tests\n", tests[i].locale); + for (; i+1 < ARRAY_SIZE(tests); i++) + if (strcmp(tests[i].locale, tests[i+1].locale)) break; + continue; + } + + memset(str1, 0xee, sizeof(str1)); + strcpy(str1, tests[i].str1); + + memset(str2, 0xff, sizeof(str2)); + strcpy(str2, tests[i].str2); + + ret = _strnicoll(str1, str2, tests[i].count); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + + memset(str1W, 0xee, sizeof(str1W)); + len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); + str1W[len] = 0; + + memset(str2W, 0xff, sizeof(str2W)); + len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W)); + str2W[len] = 0; + + ret = _wcsnicoll(str1W, str2W, tests[i].count); + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + } +} + +static void test___strncnt(void) +{ + static const struct + { + const char *str; + size_t size; + size_t ret; + } + strncnt_tests[] = + { + { NULL, 0, 0 }, + { "a", 0, 0 }, + { "a", 1, 1 }, + { "a", 10, 1 }, + { "abc", 1, 1 }, + }; + unsigned int i; + size_t ret; + + if (!p___strncnt) + { + win_skip("__strncnt() is not available.\n"); + return; + } + + if (0) /* crashes */ + ret = p___strncnt(NULL, 1); + + for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i) + { + ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size); + ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret); + } +} + +static void test_C_locale(void) +{ + int i, j; + wint_t ret, exp; + _locale_t locale; + static const char *locales[] = { NULL, "C" }; + + /* C locale only converts case for [a-zA-Z] */ + setlocale(LC_ALL, "C"); + for (i = 0; i <= 0xffff; i++) + { + ret = p_towlower(i); + if (i >= 'A' && i <= 'Z') + { + exp = i + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + todo_wine_if(ret != i) + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + + ret = p_towupper(i); + if (i >= 'a' && i <= 'z') + { + exp = i + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + todo_wine_if(ret != i) + ok(ret == i, "expected self %x, got %x for C locale\n", i, ret); + } + + if (!p__towlower_l || !p__towupper_l || !p__create_locale) + { + win_skip("_towlower_l/_towupper_l/_create_locale not available\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(locales); i++) { + locale = locales[i] ? p__create_locale(LC_ALL, locales[i]) : NULL; + + for (j = 0; j <= 0xffff; j++) { + ret = p__towlower_l(j, locale); + if (j >= 'A' && j <= 'Z') + { + exp = j + 'a' - 'A'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + todo_wine_if(ret != j) + ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); + + ret = p__towupper_l(j, locale); + if (j >= 'a' && j <= 'z') + { + exp = j + 'A' - 'a'; + ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret); + } + else + todo_wine_if(ret != j) + ok(ret == j, "expected self %x, got %x for C locale\n", j, ret); + } + + p__free_locale(locale); + } +} + START_TEST(string) { char mem[100]; @@ -3391,6 +3721,12 @@ START_TEST(string) p_wctob = (void*)GetProcAddress(hMsvcrt, "wctob"); p_wcrtomb = (void*)GetProcAddress(hMsvcrt, "wcrtomb"); p_tolower = (void*)GetProcAddress(hMsvcrt, "tolower"); + p_towlower = (void*)GetProcAddress(hMsvcrt, "towlower"); + p__towlower_l = (void*)GetProcAddress(hMsvcrt, "_towlower_l"); + p_towupper = (void*)GetProcAddress(hMsvcrt, "towupper"); + p__towupper_l = (void*)GetProcAddress(hMsvcrt, "_towupper_l"); + p__create_locale = (void*)GetProcAddress(hMsvcrt, "_create_locale"); + p__free_locale = (void*)GetProcAddress(hMsvcrt, "_free_locale"); p_mbrlen = (void*)GetProcAddress(hMsvcrt, "mbrlen"); p_mbrtowc = (void*)GetProcAddress(hMsvcrt, "mbrtowc"); p_mbsrtowcs = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs"); @@ -3404,6 +3740,7 @@ START_TEST(string) p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s"); p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp"); p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l"); + p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt");
/* MSVCRT memcpy behaves like memmove for overlapping moves, MFC42 CString::Insert seems to rely on that behaviour */ @@ -3468,4 +3805,9 @@ START_TEST(string) test__ismbclx(); test__memicmp(); test__memicmp_l(); + test__strupr(); + test__tcsncoll(); + test__tcsnicoll(); + test___strncnt(); + test_C_locale(); }