msvcrt: Implement _memicmp_l().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Nikolay Sivov 2017-11-08 10:26:16 +01:00 committed by Alexandre Julliard
parent f94f169518
commit d045a5ea29
16 changed files with 425 additions and 19 deletions

View File

@ -37,7 +37,7 @@
@ cdecl _isxdigit_l(long ptr) ucrtbase._isxdigit_l
@ cdecl _memccpy(ptr ptr long long) ucrtbase._memccpy
@ cdecl _memicmp(str str long) ucrtbase._memicmp
@ stub _memicmp_l
@ cdecl _memicmp_l(str str long ptr) ucrtbase._memicmp_l
@ cdecl _strcoll_l(str str ptr) ucrtbase._strcoll_l
@ cdecl _strdup(str) ucrtbase._strdup
@ cdecl _stricmp(str str) ucrtbase._stricmp

View File

@ -1205,8 +1205,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64

View File

@ -229,6 +229,9 @@ static Scheduler* (__cdecl *p_CurrentScheduler_Get)(void);
static void (__cdecl *p_CurrentScheduler_Detach)(void);
static unsigned int (__cdecl *p_CurrentScheduler_Id)(void);
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);
/* make sure we use the correct errno */
#undef errno
#define errno (*p_errno())
@ -260,6 +263,8 @@ static BOOL init(void)
SET(p__aligned_free, "_aligned_free");
SET(p__aligned_msize, "_aligned_msize");
SET(p_atoi, "atoi");
SET(p__memicmp, "_memicmp");
SET(p__memicmp_l, "_memicmp_l");
SET(p_Context_Id, "?Id@Context@Concurrency@@SAIXZ");
SET(p_CurrentScheduler_Detach, "?Detach@CurrentScheduler@Concurrency@@SAXXZ");
@ -966,6 +971,86 @@ static void test_Scheduler(void)
call_func1(p_SchedulerPolicy_dtor, &policy);
}
static void test__memicmp(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
ret = p__memicmp(NULL, NULL, 0);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(NULL, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(s1, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(NULL, s2, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ret = p__memicmp(s1, s2, 2);
ok(!ret, "got %d\n", ret);
ret = p__memicmp(s1, s2, 3);
ok(ret == -1, "got %d\n", ret);
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
static void test__memicmp_l(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
ret = p__memicmp_l(NULL, NULL, 0, NULL);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(NULL, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(s1, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(NULL, s2, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ret = p__memicmp_l(s1, s2, 2, NULL);
ok(!ret, "got %d\n", ret);
ret = p__memicmp_l(s1, s2, 3, NULL);
ok(ret == -1, "got %d\n", ret);
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
START_TEST(msvcr100)
{
if (!init())
@ -982,4 +1067,6 @@ START_TEST(msvcr100)
test_reader_writer_lock();
test__ReentrantBlockingLock();
test_event();
test__memicmp();
test__memicmp_l();
}

View File

@ -1562,8 +1562,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64

View File

@ -1572,8 +1572,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64

View File

@ -1310,7 +1310,7 @@
@ cdecl _mbtowc_l(ptr str long ptr) msvcr120._mbtowc_l
@ cdecl _memccpy(ptr ptr long long) msvcr120._memccpy
@ cdecl _memicmp(str str long) msvcr120._memicmp
@ stub _memicmp_l
@ cdecl _memicmp_l(str str long ptr) msvcr120._memicmp_l
@ cdecl _mkdir(str) msvcr120._mkdir
@ cdecl _mkgmtime32(ptr) msvcr120._mkgmtime32
@ cdecl _mkgmtime64(ptr) msvcr120._mkgmtime64

View File

@ -472,7 +472,7 @@
@ cdecl _mbstrlen(str)
@ cdecl _mbsupr(str)
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mktemp(str) MSVCRT__mktemp
@ cdecl _mktime64(ptr) MSVCRT__mktime64

View File

@ -467,7 +467,7 @@
@ cdecl _mbstrlen(str)
@ cdecl _mbsupr(str)
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mktemp(str) MSVCRT__mktemp
@ cdecl _mktime64(ptr) MSVCRT__mktime64

View File

@ -877,8 +877,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64

View File

@ -855,8 +855,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64

View File

@ -131,6 +131,8 @@ static size_t (__cdecl *p_mbstowcs)(wchar_t*, const char*, size_t);
static size_t (__cdecl *p_wcstombs)(char*, const wchar_t*, size_t);
static char* (__cdecl *p_setlocale)(int, const char*);
static int (__cdecl *p__fpieee_flt)(ULONG, EXCEPTION_POINTERS*, int (__cdecl *handler)(_FPIEEE_RECORD*));
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);
/* make sure we use the correct errno */
#undef errno
@ -397,6 +399,9 @@ static BOOL init(void)
SET(p_wcstombs, "wcstombs");
SET(p_setlocale, "setlocale");
SET(p__fpieee_flt, "_fpieee_flt");
SET(p__memicmp, "_memicmp");
SET(p__memicmp_l, "_memicmp_l");
if (sizeof(void *) == 8)
{
SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
@ -1797,6 +1802,68 @@ static void test__fpieee_flt(void)
}
#endif
static void test__memicmp(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ret = p__memicmp(NULL, NULL, 0);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(NULL, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(s1, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp(NULL, s2, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
ret = p__memicmp(s1, s2, 2);
ok(!ret, "got %d\n", ret);
ret = p__memicmp(s1, s2, 3);
ok(ret == -1, "got %d\n", ret);
}
static void test__memicmp_l(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ret = p__memicmp_l(NULL, NULL, 0, NULL);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(NULL, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(s1, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
SET_EXPECT(invalid_parameter_handler);
ret = p__memicmp_l(NULL, s2, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler, EINVAL);
ret = p__memicmp_l(s1, s2, 2, NULL);
ok(!ret, "got %d\n", ret);
ret = p__memicmp_l(s1, s2, 3, NULL);
ok(ret == -1, "got %d\n", ret);
}
START_TEST(msvcr90)
{
if(!init())
@ -1828,6 +1895,8 @@ START_TEST(msvcr90)
test_mbstowcs();
test_strtok_s();
test__mbstok_s();
test__memicmp();
test__memicmp_l();
#ifdef __i386__
test__fpieee_flt();
#endif

View File

@ -824,8 +824,8 @@
# stub _mbsupr_s_l(str long ptr)
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
# stub _memicmp_l(str str long ptr)
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime(ptr) MSVCRT__mkgmtime
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32

View File

@ -1940,3 +1940,37 @@ char* __cdecl MSVCRT_strstr(const char *haystack, const char *needle)
{
return strstr(haystack, needle);
}
/*********************************************************************
* _memicmp_l (MSVCRT.@)
*/
int __cdecl MSVCRT__memicmp_l(const char *s1, const char *s2, MSVCRT_size_t len, MSVCRT__locale_t locale)
{
int ret = 0;
#if _MSVCR_VER == 0 || _MSVCR_VER >= 80
if (!s1 || !s2)
{
if (len)
MSVCRT_INVALID_PMT(NULL, EINVAL);
return len ? MSVCRT__NLSCMPERROR : 0;
}
#endif
while (len--)
{
if ((ret = MSVCRT__tolower_l(*s1, locale) - MSVCRT__tolower_l(*s2, locale)))
break;
s1++;
s2++;
}
return ret;
}
/*********************************************************************
* _memicmp (MSVCRT.@)
*/
int __cdecl MSVCRT__memicmp(const char *s1, const char *s2, MSVCRT_size_t len)
{
return MSVCRT__memicmp_l(s1, s2, len, NULL);
}

View File

@ -98,6 +98,8 @@ static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t);
static int (__cdecl *p__wcsset_s)(wchar_t*,size_t,wchar_t);
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);
#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)
@ -3266,6 +3268,84 @@ static void test__ismbclx(void)
_setmbcp(cp);
}
static void test__memicmp(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ret = p__memicmp(NULL, NULL, 0);
ok(!ret, "got %d\n", ret);
ret = p__memicmp(s1, s2, 2);
ok(!ret, "got %d\n", ret);
ret = p__memicmp(s1, s2, 3);
ok(ret == -1, "got %d\n", ret);
if (!p__memicmp_l)
return;
/* Following calls crash on WinXP/W2k3. */
errno = 0xdeadbeef;
ret = p__memicmp(NULL, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp(s1, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp(NULL, s2, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
}
static void test__memicmp_l(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
if (!p__memicmp_l)
{
win_skip("_memicmp_l not found.\n");
return;
}
errno = 0xdeadbeef;
ret = p__memicmp_l(NULL, NULL, 0, NULL);
ok(!ret, "got %d\n", ret);
ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp_l(NULL, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp_l(s1, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp_l(NULL, s2, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp_l(s1, s2, 2, NULL);
ok(!ret, "got %d\n", ret);
ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
errno = 0xdeadbeef;
ret = p__memicmp_l(s1, s2, 3, NULL);
ok(ret == -1, "got %d\n", ret);
ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
}
START_TEST(string)
{
char mem[100];
@ -3322,6 +3402,8 @@ START_TEST(string)
p__wcsset_s = (void*)GetProcAddress(hMsvcrt, "_wcsset_s");
p__mbsnlen = (void*)GetProcAddress(hMsvcrt, "_mbsnlen");
p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s");
p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp");
p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l");
/* MSVCRT memcpy behaves like memmove for overlapping moves,
MFC42 CString::Insert seems to rely on that behaviour */
@ -3384,4 +3466,6 @@ START_TEST(string)
test__wcsset_s();
test__mbscmp();
test__ismbclx();
test__memicmp();
test__memicmp_l();
}

View File

@ -28,6 +28,34 @@
#include <math.h>
#define DEFINE_EXPECT(func) \
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
#define SET_EXPECT(func) \
expect_ ## func = TRUE
#define CHECK_EXPECT2(func) \
do { \
ok(expect_ ##func, "unexpected call &quot; #func &quot;\n"); \
called_ ## func = TRUE; \
}while(0)
#define CHECK_EXPECT(func) \
do { \
CHECK_EXPECT2(func); \
expect_ ## func = FALSE; \
}while(0)
#define CHECK_CALLED(func) \
do { \
ok(called_ ## func, "expected &quot; #func &quot;\n"); \
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT(invalid_parameter_handler);
static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
#ifndef INFINITY
static inline float __port_infinity(void)
{
@ -46,7 +74,21 @@ static inline float __port_nan(void)
#define NAN __port_nan()
#endif
static double (CDECL *p_strtod)(const char*, char** end);
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
const wchar_t *function, const wchar_t *file,
unsigned line, uintptr_t arg)
{
CHECK_EXPECT(invalid_parameter_handler);
ok(expression == NULL, "expression is not NULL\n");
ok(function == NULL, "function is not NULL\n");
ok(file == NULL, "file is not NULL\n");
ok(line == 0, "line = %u\n", line);
ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
}
static double (__cdecl *p_strtod)(const char*, char** end);
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 BOOL init(void)
{
@ -59,7 +101,10 @@ static BOOL init(void)
return FALSE;
}
p_set_invalid_parameter_handler = (void*)GetProcAddress(module, "_set_invalid_parameter_handler");
p_strtod = (void*)GetProcAddress(module, "strtod");
p__memicmp = (void*)GetProcAddress(module, "_memicmp");
p__memicmp_l = (void*)GetProcAddress(module, "_memicmp_l");
return TRUE;
}
@ -114,8 +159,95 @@ static void test_strtod(void)
test_strtod_str("0x1p1a", 2, 5);
}
static void test__memicmp(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
ret = p__memicmp(NULL, NULL, 0);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp(NULL, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp(s1, NULL, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp(NULL, s2, 1);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ret = p__memicmp(s1, s2, 2);
ok(!ret, "got %d\n", ret);
ret = p__memicmp(s1, s2, 3);
ok(ret == -1, "got %d\n", ret);
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
static void test__memicmp_l(void)
{
static const char *s1 = "abc";
static const char *s2 = "aBd";
int ret;
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
ret = p__memicmp_l(NULL, NULL, 0, NULL);
ok(!ret, "got %d\n", ret);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp_l(NULL, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp_l(s1, NULL, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
SET_EXPECT(invalid_parameter_handler);
errno = 0xdeadbeef;
ret = p__memicmp_l(NULL, s2, 1, NULL);
ok(ret == _NLSCMPERROR, "got %d\n", ret);
ok(errno == 0xdeadbeef, "Unexpected errno = %d\n", errno);
CHECK_CALLED(invalid_parameter_handler);
ret = p__memicmp_l(s1, s2, 2, NULL);
ok(!ret, "got %d\n", ret);
ret = p__memicmp_l(s1, s2, 3, NULL);
ok(ret == -1, "got %d\n", ret);
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
START_TEST(string)
{
if (!init()) return;
test_strtod();
test__memicmp();
test__memicmp_l();
}

View File

@ -718,8 +718,8 @@
@ stub _mbsupr_s_l
@ cdecl _mbtowc_l(ptr str long ptr) MSVCRT_mbtowc_l
@ cdecl _memccpy(ptr ptr long long) ntdll._memccpy
@ cdecl _memicmp(str str long) ntdll._memicmp
@ stub _memicmp_l
@ cdecl _memicmp(str str long) MSVCRT__memicmp
@ cdecl _memicmp_l(str str long ptr) MSVCRT__memicmp_l
@ cdecl _mkdir(str) MSVCRT__mkdir
@ cdecl _mkgmtime32(ptr) MSVCRT__mkgmtime32
@ cdecl _mkgmtime64(ptr) MSVCRT__mkgmtime64