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>
This commit is contained in:
parent
f94f169518
commit
d045a5ea29
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 " #func "\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 " #func "\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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue