2 * Copyright 2010 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
25 static void* (__cdecl
*p_set_invalid_parameter_handler
)(void*);
27 static void (__cdecl
*p_char_assign
)(void*, const void*);
28 static void (__cdecl
*p_wchar_assign
)(void*, const void*);
29 static void (__cdecl
*p_short_assign
)(void*, const void*);
31 static BYTE (__cdecl
*p_char_eq
)(const void*, const void*);
32 static BYTE (__cdecl
*p_wchar_eq
)(const void*, const void*);
33 static BYTE (__cdecl
*p_short_eq
)(const void*, const void*);
35 static char* (__cdecl
*p_Copy_s
)(char*, size_t, const char*, size_t);
38 static char* (WINAPI
*p_char_address
)(char*);
39 static void* (WINAPI
*p_char_ctor
)(void);
40 static void (WINAPI
*p_char_deallocate
)(char*, size_t);
41 static char* (WINAPI
*p_char_allocate
)(size_t);
42 static void (WINAPI
*p_char_construct
)(char*, const char*);
43 static size_t (WINAPI
*p_char_max_size
)(void);
45 static char* (__cdecl
*p_char_address
)(void*, char*);
46 static void* (__cdecl
*p_char_ctor
)(void*);
47 static void (__cdecl
*p_char_deallocate
)(void*, char*, size_t);
48 static char* (__cdecl
*p_char_allocate
)(void*, size_t);
49 static void (__cdecl
*p_char_construct
)(void*, char*, const char*);
50 static size_t (__cdecl
*p_char_max_size
)(void*);
53 static int invalid_parameter
= 0;
54 static void __cdecl
test_invalid_parameter_handler(const wchar_t *expression
,
55 const wchar_t *function
, const wchar_t *file
,
56 unsigned line
, uintptr_t arg
)
58 ok(expression
== NULL
, "expression is not NULL\n");
59 ok(function
== NULL
, "function is not NULL\n");
60 ok(file
== NULL
, "file is not NULL\n");
61 ok(line
== 0, "line = %u\n", line
);
62 ok(arg
== 0, "arg = %lx\n", (UINT_PTR
)arg
);
66 /* Emulate a __thiscall */
69 static inline void* do_call_func1(void *func
, void *_this
)
71 volatile void* retval
= 0;
83 static inline void* do_call_func2(void *func
, void *_this
, const void *arg
)
85 volatile void* retval
= 0;
98 static inline void* do_call_func3(void *func
, void *_this
,
99 const void *arg1
, const void *arg2
)
101 volatile void* retval
= 0;
112 return (void*)retval
;
115 static void* do_call_func1(void *func
, void *_this
)
118 __asm__
__volatile__ (
120 : "=a" (ret
), "=c" (dummy
)
121 : "g" (func
), "1" (_this
)
127 static void* do_call_func2(void *func
, void *_this
, const void *arg
)
130 __asm__
__volatile__ (
131 "pushl %3\n\tcall *%2"
132 : "=a" (ret
), "=c" (dummy
)
133 : "r" (func
), "r" (arg
), "1" (_this
)
139 static void* do_call_func3(void *func
, void *_this
,
140 const void *arg1
, const void *arg2
)
143 __asm__
__volatile__ (
144 "pushl %4\n\tpushl %3\n\tcall *%2"
145 : "=a" (ret
), "=c" (dummy
)
146 : "r" (func
), "r" (arg1
), "r" (arg2
), "1" (_this
)
153 #define call_func1(func,_this) do_call_func1(func,_this)
154 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
155 #define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b)
159 #define call_func1(func,_this) func(_this)
160 #define call_func2(func,_this,a) func(_this,a)
161 #define call_func3(func,_this,a,b) func(_this,a,b)
163 #endif /* __i386__ */
165 static BOOL
init(void)
167 HMODULE msvcr
= LoadLibraryA("msvcr90.dll");
168 HMODULE msvcp
= LoadLibraryA("msvcp90.dll");
169 if(!msvcr
|| !msvcp
) {
170 win_skip("msvcp90.dll or msvcrt90.dll not installed\n");
174 p_set_invalid_parameter_handler
= (void*)GetProcAddress(msvcr
, "_set_invalid_parameter_handler");
175 if(!p_set_invalid_parameter_handler
) {
176 win_skip("Error setting tests environment\n");
180 p_set_invalid_parameter_handler(test_invalid_parameter_handler
);
182 if(sizeof(void*) == 8) { /* 64-bit initialization */
183 p_char_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@D@std@@SAXAEADAEBD@Z");
184 p_wchar_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@_W@std@@SAXAEA_WAEB_W@Z");
185 p_short_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@G@std@@SAXAEAGAEBG@Z");
187 p_char_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@D@std@@SA_NAEBD0@Z");
188 p_wchar_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@_W@std@@SA_NAEB_W0@Z");
189 p_short_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@G@std@@SA_NAEBG0@Z");
191 p_Copy_s
= (void*)GetProcAddress(msvcp
, "?_Copy_s@?$char_traits@D@std@@SAPEADPEAD_KPEBD1@Z");
193 p_char_address
= (void*)GetProcAddress(msvcp
, "?address@?$allocator@D@std@@QEBAPEADAEAD@Z");
194 p_char_ctor
= (void*)GetProcAddress(msvcp
, "??0?$allocator@D@std@@QEAA@XZ");
195 p_char_deallocate
= (void*)GetProcAddress(msvcp
, "?deallocate@?$allocator@D@std@@QEAAXPEAD_K@Z");
196 p_char_allocate
= (void*)GetProcAddress(msvcp
, "?allocate@?$allocator@D@std@@QEAAPEAD_K@Z");
197 p_char_construct
= (void*)GetProcAddress(msvcp
, "?construct@?$allocator@D@std@@QEAAXPEADAEBD@Z");
198 p_char_max_size
= (void*)GetProcAddress(msvcp
, "?max_size@?$allocator@D@std@@QEBA_KXZ");
200 p_char_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@D@std@@SAXAADABD@Z");
201 p_wchar_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@_W@std@@SAXAA_WAB_W@Z");
202 p_short_assign
= (void*)GetProcAddress(msvcp
, "?assign@?$char_traits@G@std@@SAXAAGABG@Z");
204 p_char_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@D@std@@SA_NABD0@Z");
205 p_wchar_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@_W@std@@SA_NAB_W0@Z");
206 p_short_eq
= (void*)GetProcAddress(msvcp
, "?eq@?$char_traits@G@std@@SA_NABG0@Z");
208 p_Copy_s
= (void*)GetProcAddress(msvcp
, "?_Copy_s@?$char_traits@D@std@@SAPADPADIPBDI@Z");
210 p_char_address
= (void*)GetProcAddress(msvcp
, "?address@?$allocator@D@std@@QBEPADAAD@Z");
211 p_char_ctor
= (void*)GetProcAddress(msvcp
, "??0?$allocator@D@std@@QAE@XZ");
212 p_char_deallocate
= (void*)GetProcAddress(msvcp
, "?deallocate@?$allocator@D@std@@QAEXPADI@Z");
213 p_char_allocate
= (void*)GetProcAddress(msvcp
, "?allocate@?$allocator@D@std@@QAEPADI@Z");
214 p_char_construct
= (void*)GetProcAddress(msvcp
, "?construct@?$allocator@D@std@@QAEXPADABD@Z");
215 p_char_max_size
= (void*)GetProcAddress(msvcp
, "?max_size@?$allocator@D@std@@QBEIXZ");
221 static void test_assign(void)
223 const char in
[] = "abc";
226 if(!p_char_assign
|| !p_wchar_assign
|| !p_short_assign
) {
227 win_skip("assign tests skipped\n");
232 p_char_assign(out
, in
);
233 ok(out
[0] == in
[0], "out[0] = %c\n", out
[0]);
234 ok(out
[1] == '#', "out[1] = %c\n", out
[1]);
237 p_wchar_assign(out
, in
);
238 ok(*((char*)out
)==in
[0] && *((char*)out
+1)==in
[1],
239 "out[0] = %d, out[1] = %d\n", (int)out
[0], (int)out
[1]);
240 ok(out
[2] == '#', "out[2] = %c\n", out
[2]);
243 p_short_assign(out
, in
);
244 ok(*((char*)out
)==in
[0] && *((char*)out
+1)==in
[1],
245 "out[0] = %d, out[1] = %d\n", (int)out
[0], (int)out
[1]);
246 ok(out
[2] == '#', "out[2] = %c\n", out
[2]);
249 static void test_equal(void)
251 static const char in1
[] = "abc";
252 static const char in2
[] = "ab";
253 static const char in3
[] = "a";
254 static const char in4
[] = "b";
257 if(!p_char_eq
|| !p_wchar_eq
|| !p_short_eq
) {
258 win_skip("equal tests skipped\n");
262 ret
= p_char_eq(in1
, in2
);
263 ok(ret
== TRUE
, "ret = %d\n", (int)ret
);
264 ret
= p_char_eq(in1
, in3
);
265 ok(ret
== TRUE
, "ret = %d\n", (int)ret
);
266 ret
= p_char_eq(in1
, in4
);
267 ok(ret
== FALSE
, "ret = %d\n", (int)ret
);
269 ret
= p_wchar_eq(in1
, in2
);
270 ok(ret
== TRUE
, "ret = %d\n", (int)ret
);
271 ret
= p_wchar_eq(in1
, in3
);
272 ok(ret
== FALSE
, "ret = %d\n", (int)ret
);
273 ret
= p_wchar_eq(in1
, in4
);
274 ok(ret
== FALSE
, "ret = %d\n", (int)ret
);
276 ret
= p_short_eq(in1
, in2
);
277 ok(ret
== TRUE
, "ret = %d\n", (int)ret
);
278 ret
= p_short_eq(in1
, in3
);
279 ok(ret
== FALSE
, "ret = %d\n", (int)ret
);
280 ret
= p_short_eq(in1
, in4
);
281 ok(ret
== FALSE
, "ret = %d\n", (int)ret
);
284 static void test_Copy_s(void)
286 static const char src
[] = "abcd";
290 win_skip("Copy_s tests skipped\n");
296 ret
= p_Copy_s(dest
, 4, src
, 4);
297 ok(ret
== dest
, "ret != dest\n");
298 ok(dest
[4] == '#', "dest[4] != '#'\n");
299 ok(!memcmp(dest
, src
, sizeof(char[4])), "dest = %s\n", dest
);
301 ret
= p_Copy_s(dest
, 32, src
, 4);
302 ok(ret
== dest
, "ret != dest\n");
303 ok(dest
[4] == '#', "dest[4] != '#'\n");
304 ok(!memcmp(dest
, src
, sizeof(char[4])), "dest = %s\n", dest
);
308 ret
= p_Copy_s(dest
, 3, src
, 4);
309 ok(ret
== dest
, "ret != dest\n");
310 ok(dest
[0] == '\0', "dest[0] != 0\n");
311 ok(invalid_parameter
==1, "invalid_parameter = %d\n",
313 invalid_parameter
= 0;
314 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
317 p_Copy_s(NULL
, 32, src
, 4);
318 ok(invalid_parameter
==1, "invalid_parameter = %d\n",
320 invalid_parameter
= 0;
321 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
324 p_Copy_s(dest
, 32, NULL
, 4);
325 ok(invalid_parameter
==1, "invalid_parameter = %d\n",
327 invalid_parameter
= 0;
328 ok(errno
== 0xdeadbeef, "errno = %d\n", errno
);
331 static void test_allocator_char(void)
333 void *allocator
= (void*)0xdeadbeef;
338 if(!p_char_address
|| !p_char_ctor
|| !p_char_deallocate
|| !p_char_allocate
339 || !p_char_construct
|| !p_char_max_size
) {
340 win_skip("allocator<char> class not available\n");
344 allocator
= call_func1(p_char_ctor
, allocator
);
345 ok(allocator
== (void*)0xdeadbeef, "allocator = %p\n", allocator
);
347 ptr
= call_func2(p_char_address
, NULL
, (void*)0xdeadbeef);
348 ok(ptr
== (void*)0xdeadbeef, "incorrect address (%p)\n", ptr
);
351 ptr
= call_func2(p_char_allocate
, allocator
, 10);
352 ok(ptr
!= NULL
, "Memory allocation failed\n");
354 ptr
[0] = ptr
[1] = '#';
356 call_func3(p_char_construct
, allocator
, ptr
, &val
);
358 call_func3(p_char_construct
, allocator
, (ptr
+1), &val
);
359 ok(ptr
[0] == 'a', "ptr[0] = %c\n", ptr
[0]);
360 ok(ptr
[1] == 'b', "ptr[1] = %c\n", ptr
[1]);
362 call_func3(p_char_deallocate
, allocator
, ptr
, -1);
364 size
= (unsigned int)call_func1(p_char_max_size
, allocator
);
365 ok(size
== (unsigned int)0xffffffff, "size = %x\n", size
);
377 test_allocator_char();
379 ok(!invalid_parameter
, "invalid_parameter_handler was invoked too many times\n");