From 50518766602f6c2ec3ed974af99d37bd0ec206d5 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 20 Dec 2011 15:57:08 +0100 Subject: [PATCH] msvcp90: Added collate::compare implementation. --- dlls/msvcp90/locale.c | 20 ++++++++++++++---- dlls/msvcp90/msvcp90.h | 1 + dlls/msvcp90/msvcp90.spec | 2 +- dlls/msvcp90/msvcp90_main.c | 1 + dlls/msvcp90/tests/misc.c | 41 +++++++++++++++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c index 0c441c9170b..ec2f5d58d79 100644 --- a/dlls/msvcp90/locale.c +++ b/dlls/msvcp90/locale.c @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msvcp90); @@ -742,14 +743,25 @@ MSVCP_size_t __cdecl collate_char__Getcat(const locale_facet **facet, const loca return LC_COLLATE; } +/* _Strcoll */ +int __cdecl _Strcoll(const char *first1, const char *last1, const char *first2, + const char *last2, const _Collvec *coll) +{ + TRACE("(%s %s)\n", debugstr_an(first1, last1-first1), debugstr_an(first2, last2-first2)); + return CompareStringA(coll->handle, 0, first1, last1-first1, first2, last2-first2)-2; +} + /* ?do_compare@?$collate@D@std@@MBEHPBD000@Z */ /* ?do_compare@?$collate@D@std@@MEBAHPEBD000@Z */ DEFINE_THISCALL_WRAPPER(collate_char_do_compare, 20) +#define call_collate_char_do_compare(this, first1, last1, first2, last2) CALL_VTBL_FUNC(this, 4, int, \ + (const collate*, const char*, const char*, const char*, const char*), \ + (this, first1, last1, first2, last2)) int __thiscall collate_char_do_compare(const collate *this, const char *first1, const char *last1, const char *first2, const char *last2) { - FIXME("(%p %p %p %p %p) stub\n", this, first1, last1, first2, last2); - return 0; + TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2); + return _Strcoll(first1, last1, first2, last2, &this->coll); } /* ?compare@?$collate@D@std@@QBEHPBD000@Z */ @@ -758,8 +770,8 @@ DEFINE_THISCALL_WRAPPER(collate_char_compare, 20) int __thiscall collate_char_compare(const collate *this, const char *first1, const char *last1, const char *first2, const char *last2) { - FIXME("(%p %p %p %p %p) stub\n", this, first1, last1, first2, last2); - return 0; + TRACE("(%p %p %p %p %p)\n", this, first1, last1, first2, last2); + return call_collate_char_do_compare(this, first1, last1, first2, last2); } /* ?do_hash@?$collate@D@std@@MBEJPBD0@Z */ diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index ee793b1330a..23254afddb1 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -135,6 +135,7 @@ const rtti_object_locator name ## _rtti = { \ #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args extern void *vtbl_wrapper_0; +extern void *vtbl_wrapper_4; #else diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec index d288bbcda49..3c62462c445 100644 --- a/dlls/msvcp90/msvcp90.spec +++ b/dlls/msvcp90/msvcp90.spec @@ -5796,7 +5796,7 @@ @ stub _Stoull @ stub _Stoullx @ stub _Stoulx -@ stub _Strcoll +@ cdecl _Strcoll(ptr ptr ptr ptr ptr) @ stub _Strxfrm @ stub _Tolower @ stub _Toupper diff --git a/dlls/msvcp90/msvcp90_main.c b/dlls/msvcp90/msvcp90_main.c index 3aacf6d34c4..f27ac0c0b4a 100644 --- a/dlls/msvcp90/msvcp90_main.c +++ b/dlls/msvcp90/msvcp90_main.c @@ -39,6 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcp90); "jmp *" #off "(%eax)\n\t") DEFINE_VTBL_WRAPPER(0); +DEFINE_VTBL_WRAPPER(4); #endif diff --git a/dlls/msvcp90/tests/misc.c b/dlls/msvcp90/tests/misc.c index 221edf100cc..8e77e958b68 100644 --- a/dlls/msvcp90/tests/misc.c +++ b/dlls/msvcp90/tests/misc.c @@ -60,6 +60,11 @@ static char* (__thiscall *p_char_allocate)(void*, size_t); static void (__thiscall *p_char_construct)(void*, char*, const char*); static size_t (__thiscall *p_char_max_size)(void*); +void* (__thiscall *p_collate_char_ctor_refs)(void*, size_t); +int (__thiscall *p_collate_char_compare)(const void*, const char*, + const char*, const char*, const char*); +void (__thiscall *p_collate_char_dtor)(void*); + static int invalid_parameter = 0; static void __cdecl test_invalid_parameter_handler(const wchar_t *expression, const wchar_t *function, const wchar_t *file, @@ -90,6 +95,8 @@ struct thiscall_thunk static void * (WINAPI *call_thiscall_func1)( void *func, void *this ); static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a ); static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void *a, const void *b ); +static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a, const void *b, + const void *c, const void *d ); static void init_thiscall_thunk(void) { @@ -103,11 +110,14 @@ static void init_thiscall_thunk(void) call_thiscall_func1 = (void *)thunk; call_thiscall_func2 = (void *)thunk; call_thiscall_func3 = (void *)thunk; + call_thiscall_func5 = (void *)thunk; } #define call_func1(func,_this) call_thiscall_func1(func,_this) -#define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)a) -#define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)a,(const void*)b) +#define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a)) +#define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b)) +#define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \ + (const void*)(c), (const void *)(d)) #else @@ -115,6 +125,7 @@ static void init_thiscall_thunk(void) #define call_func1(func,_this) func(_this) #define call_func2(func,_this,a) func(_this,a) #define call_func3(func,_this,a,b) func(_this,a,b) +#define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d) #endif /* __i386__ */ @@ -158,6 +169,10 @@ static BOOL init(void) SET(p_char_allocate, "?allocate@?$allocator@D@std@@QEAAPEAD_K@Z"); SET(p_char_construct, "?construct@?$allocator@D@std@@QEAAXPEADAEBD@Z"); SET(p_char_max_size, "?max_size@?$allocator@D@std@@QEBA_KXZ"); + + SET(p_collate_char_ctor_refs, "??0?$collate@D@std@@QEAA@_K@Z"); + SET(p_collate_char_compare, "?compare@?$collate@D@std@@QEBAHPEBD000@Z"); + SET(p_collate_char_dtor, "??1?$collate@D@std@@MEAA@XZ"); } else { SET(p_char_assign, "?assign@?$char_traits@D@std@@SAXAADABD@Z"); SET(p_wchar_assign, "?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z"); @@ -175,6 +190,10 @@ static BOOL init(void) SET(p_char_allocate, "?allocate@?$allocator@D@std@@QAEPADI@Z"); SET(p_char_construct, "?construct@?$allocator@D@std@@QAEXPADABD@Z"); SET(p_char_max_size, "?max_size@?$allocator@D@std@@QBEIXZ"); + + SET(p_collate_char_ctor_refs, "??0?$collate@D@std@@QAE@I@Z"); + SET(p_collate_char_compare, "?compare@?$collate@D@std@@QBEHPBD000@Z"); + SET(p_collate_char_dtor, "??1?$collate@D@std@@MAE@XZ"); } init_thiscall_thunk(); @@ -356,6 +375,23 @@ static void test_allocator_char(void) ok(size == (unsigned int)0xffffffff, "size = %x\n", size); } +static void test_virtual_call(void) +{ + BYTE collate_char[16]; + char str1[] = "test"; + char str2[] = "TEST"; + int ret; + + call_func2(p_collate_char_ctor_refs, collate_char, 0); + ret = (int)call_func5(p_collate_char_compare, collate_char, str1, str1+4, str1, str1+4); + ok(ret == 0, "collate::compare returned %d\n", ret); + ret = (int)call_func5(p_collate_char_compare, collate_char, str2, str2+4, str1, str1+4); + ok(ret == 1, "collate::compare returned %d\n", ret); + ret = (int)call_func5(p_collate_char_compare, collate_char, str1, str1+3, str1, str1+4); + ok(ret == -1, "collate::compare returned %d\n", ret); + call_func1(p_collate_char_dtor, collate_char); +} + START_TEST(misc) { if(!init()) @@ -366,6 +402,7 @@ START_TEST(misc) test_Copy_s(); test_wctype(); test__Getctype(); + test_virtual_call(); test_allocator_char();