https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f446a50f76032af9b0e1f…
commit f446a50f76032af9b0e1fe3d66c2b9d087772a93
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Tue Jan 29 13:08:13 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)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();
}