Piotr Caban : msvcp90/tests: Added allocator<char> tests.

Alexandre Julliard julliard at winehq.org
Wed Aug 18 12:09:56 CDT 2010


Module: wine
Branch: master
Commit: 51a55fc9e2a59a4f702ceb9528f84abdbc2e2648
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=51a55fc9e2a59a4f702ceb9528f84abdbc2e2648

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Aug 18 10:36:29 2010 +0200

msvcp90/tests: Added allocator<char> tests.

---

 dlls/msvcp90/tests/misc.c |  168 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/dlls/msvcp90/tests/misc.c b/dlls/msvcp90/tests/misc.c
index a3f7401..d052225 100644
--- a/dlls/msvcp90/tests/misc.c
+++ b/dlls/msvcp90/tests/misc.c
@@ -34,6 +34,22 @@ static BYTE (__cdecl *p_short_eq)(const void*, const void*);
 
 static char* (__cdecl *p_Copy_s)(char*, size_t, const char*, size_t);
 
+#ifdef __i386__
+static char* (WINAPI *p_char_address)(char*);
+static void* (WINAPI *p_char_ctor)(void);
+static void (WINAPI *p_char_deallocate)(char*, size_t);
+static char* (WINAPI *p_char_allocate)(size_t);
+static void (WINAPI *p_char_construct)(char*, const char*);
+static size_t (WINAPI *p_char_max_size)(void);
+#else
+static char* (__cdecl *p_char_address)(void*, char*);
+static void* (__cdecl *p_char_ctor)(void*);
+static void (__cdecl *p_char_deallocate)(void*, char*, size_t);
+static char* (__cdecl *p_char_allocate)(void*, size_t);
+static void (__cdecl *p_char_construct)(void*, char*, const char*);
+static size_t (__cdecl *p_char_max_size)(void*);
+#endif
+
 static int invalid_parameter = 0;
 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
         const wchar_t *function, const wchar_t *file,
@@ -47,6 +63,105 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
     invalid_parameter++;
 }
 
+/* Emulate a __thiscall */
+#ifdef __i386__
+#ifdef _MSC_VER
+static inline void* do_call_func1(void *func, void *_this)
+{
+    volatile void* retval = 0;
+    __asm
+    {
+        push ecx
+            mov ecx, _this
+            call func
+            mov retval, eax
+            pop ecx
+    }
+    return (void*)retval;
+}
+
+static inline void* do_call_func2(void *func, void *_this, const void *arg)
+{
+    volatile void* retval = 0;
+    __asm
+    {
+        push ecx
+        push arg
+        mov ecx, _this
+        call func
+        mov retval, eax
+        pop ecx
+    }
+    return (void*)retval;
+}
+
+static inline void* do_call_func3(void *func, void *_this,
+        const void *arg1, const void *arg2)
+{
+    volatile void* retval = 0;
+    __asm
+    {
+        push ecx
+        push arg1
+        push arg2
+        mov ecx, _this
+        call func
+        mov retval, eax
+        pop ecx
+    }
+    return (void*)retval;
+}
+#else
+static void* do_call_func1(void *func, void *_this)
+{
+        void *ret, *dummy;
+        __asm__ __volatile__ (
+                "call *%2"
+                : "=a" (ret), "=c" (dummy)
+                : "g" (func), "1" (_this)
+                : "edx", "memory"
+                );
+        return ret;
+}
+
+static void* do_call_func2(void *func, void *_this, const void *arg)
+{
+    void *ret, *dummy;
+    __asm__ __volatile__ (
+            "pushl %3\n\tcall *%2"
+            : "=a" (ret), "=c" (dummy)
+            : "r" (func), "r" (arg), "1" (_this)
+            : "edx", "memory"
+            );
+    return ret;
+}
+
+static void* do_call_func3(void *func, void *_this,
+        const void *arg1, const void *arg2)
+{
+    void *ret, *dummy;
+    __asm__ __volatile__ (
+            "pushl %4\n\tpushl %3\n\tcall *%2"
+            : "=a" (ret), "=c" (dummy)
+            : "r" (func), "r" (arg1), "r" (arg2), "1" (_this)
+            : "edx", "memory"
+            );
+    return ret;
+}
+#endif
+
+#define call_func1(func,_this)   do_call_func1(func,_this)
+#define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
+#define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b)
+
+#else
+
+#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)
+
+#endif /* __i386__ */
+
 static BOOL init(void)
 {
     HMODULE msvcr = LoadLibraryA("msvcr90.dll");
@@ -74,6 +189,13 @@ static BOOL init(void)
         p_short_eq = (void*)GetProcAddress(msvcp, "?eq@?$char_traits at G@std@@SA_NAEBG0 at Z");
 
         p_Copy_s = (void*)GetProcAddress(msvcp, "?_Copy_s@?$char_traits at D@std@@SAPEADPEAD_KPEBD1 at Z");
+
+        p_char_address = (void*)GetProcAddress(msvcp, "?address@?$allocator at D@std@@QEBAPEADAEAD at Z");
+        p_char_ctor = (void*)GetProcAddress(msvcp, "??0?$allocator at D@std@@QEAA at XZ");
+        p_char_deallocate = (void*)GetProcAddress(msvcp, "?deallocate@?$allocator at D@std@@QEAAXPEAD_K at Z");
+        p_char_allocate = (void*)GetProcAddress(msvcp, "?allocate@?$allocator at D@std@@QEAAPEAD_K at Z");
+        p_char_construct = (void*)GetProcAddress(msvcp, "?construct@?$allocator at D@std@@QEAAXPEADAEBD at Z");
+        p_char_max_size = (void*)GetProcAddress(msvcp, "?max_size@?$allocator at D@std@@QEBA_KXZ");
     } else {
         p_char_assign = (void*)GetProcAddress(msvcp, "?assign@?$char_traits at D@std@@SAXAADABD at Z");
         p_wchar_assign = (void*)GetProcAddress(msvcp, "?assign@?$char_traits at _W@std@@SAXAA_WAB_W at Z");
@@ -84,6 +206,13 @@ static BOOL init(void)
         p_short_eq = (void*)GetProcAddress(msvcp, "?eq@?$char_traits at G@std@@SA_NABG0 at Z");
 
         p_Copy_s = (void*)GetProcAddress(msvcp, "?_Copy_s@?$char_traits at D@std@@SAPADPADIPBDI at Z");
+
+        p_char_address = (void*)GetProcAddress(msvcp, "?address@?$allocator at D@std@@QBEPADAAD at Z");
+        p_char_ctor = (void*)GetProcAddress(msvcp, "??0?$allocator at D@std@@QAE at XZ");
+        p_char_deallocate = (void*)GetProcAddress(msvcp, "?deallocate@?$allocator at D@std@@QAEXPADI at Z");
+        p_char_allocate = (void*)GetProcAddress(msvcp, "?allocate@?$allocator at D@std@@QAEPADI at Z");
+        p_char_construct = (void*)GetProcAddress(msvcp, "?construct@?$allocator at D@std@@QAEXPADABD at Z");
+        p_char_max_size = (void*)GetProcAddress(msvcp, "?max_size@?$allocator at D@std@@QBEIXZ");
     }
 
     return TRUE;
@@ -199,6 +328,43 @@ static void test_Copy_s(void)
     ok(errno == 0xdeadbeef, "errno = %d\n", errno);
 }
 
+static void test_allocator_char(void)
+{
+    void *allocator = (void*)0xdeadbeef;
+    char *ptr;
+    char val;
+    unsigned int size;
+
+    if(!p_char_address || !p_char_ctor || !p_char_deallocate || !p_char_allocate
+            || !p_char_construct || !p_char_max_size) {
+        win_skip("allocator<char> class not available\n");
+        return;
+    }
+
+    allocator = call_func1(p_char_ctor, allocator);
+    ok(allocator == (void*)0xdeadbeef, "allocator = %p\n", allocator);
+
+    ptr = call_func2(p_char_address, NULL, (void*)0xdeadbeef);
+    ok(ptr == (void*)0xdeadbeef, "incorrect address (%p)\n", ptr);
+
+    ptr = NULL;
+    ptr = call_func2(p_char_allocate, allocator, 10);
+    ok(ptr != NULL, "Memory allocation failed\n");
+
+    ptr[0] = ptr[1] = '#';
+    val = 'a';
+    call_func3(p_char_construct, allocator, ptr, &val);
+    val = 'b';
+    call_func3(p_char_construct, allocator, (ptr+1), &val);
+    ok(ptr[0] == 'a', "ptr[0] = %c\n", ptr[0]);
+    ok(ptr[1] == 'b', "ptr[1] = %c\n", ptr[1]);
+
+    call_func3(p_char_deallocate, allocator, ptr, -1);
+
+    size = (unsigned int)call_func1(p_char_max_size, allocator);
+    ok(size == (unsigned int)0xffffffff, "size = %x\n", size);
+}
+
 START_TEST(misc)
 {
     if(!init())
@@ -208,5 +374,7 @@ START_TEST(misc)
     test_equal();
     test_Copy_s();
 
+    test_allocator_char();
+
     ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n");
 }




More information about the wine-cvs mailing list