mmdevapi/tests: Add tests for IAudioClient::GetCurrentPadding.
[wine] / dlls / msvcp90 / tests / string.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <stdio.h>
20
21 #include <windef.h>
22 #include <winbase.h>
23 #include "wine/test.h"
24
25 /* basic_string<char, char_traits<char>, allocator<char>> */
26 #define BUF_SIZE_CHAR 16
27 typedef struct _basic_string_char
28 {
29     void *allocator;
30     union {
31         char buf[BUF_SIZE_CHAR];
32         char *ptr;
33     } data;
34     size_t size;
35     size_t res;
36 } basic_string_char;
37
38 /* basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>> */
39 #define BUF_SIZE_WCHAR 8
40 typedef struct _basic_string_wchar
41 {
42     void *allocator;
43     union {
44         wchar_t buf[BUF_SIZE_WCHAR];
45         wchar_t *ptr;
46     } data;
47     size_t size;
48     size_t res;
49 } basic_string_wchar;
50
51 static void* (__cdecl *p_set_invalid_parameter_handler)(void*);
52 static basic_string_char* (WINAPI *p_basic_string_char_concatenate)(basic_string_char*, const basic_string_char*, const basic_string_char*);
53 static basic_string_char* (WINAPI *p_basic_string_char_concatenate_cstr)(basic_string_char*, const basic_string_char*, const char*);
54
55 #ifdef __i386__
56 static basic_string_char* (WINAPI *p_basic_string_char_ctor)(void);
57 static basic_string_char* (WINAPI *p_basic_string_char_copy_ctor)(basic_string_char*);
58 static basic_string_char* (WINAPI *p_basic_string_char_ctor_cstr)(const char*);
59 static void (WINAPI *p_basic_string_char_dtor)(void);
60 static basic_string_char* (WINAPI *p_basic_string_char_erase)(size_t, size_t);
61 static basic_string_char* (WINAPI *p_basic_string_char_assign_cstr_len)(const char*, size_t);
62 static const char* (WINAPI *p_basic_string_char_cstr)(void);
63 static const char* (WINAPI *p_basic_string_char_data)(void);
64 static size_t (WINAPI *p_basic_string_char_size)(void);
65 static size_t (WINAPI *p_basic_string_char_capacity)(void);
66 static void (WINAPI *p_basic_string_char_swap)(basic_string_char*);
67 static basic_string_char* (WINAPI *p_basic_string_char_append)(basic_string_char*);
68 static basic_string_char* (WINAPI *p_basic_string_char_append_substr)(basic_string_char*, size_t, size_t);
69 static int (WINAPI *p_basic_string_char_compare_substr_substr)(size_t, size_t, basic_string_char*, size_t, size_t);
70 static int (WINAPI *p_basic_string_char_compare_substr_cstr_len)(size_t, size_t, const char*, size_t);
71
72 static basic_string_wchar* (WINAPI *p_basic_string_wchar_ctor)(void);
73 static basic_string_wchar* (WINAPI *p_basic_string_wchar_copy_ctor)(basic_string_wchar*);
74 static basic_string_wchar* (WINAPI *p_basic_string_wchar_ctor_cstr)(const wchar_t*);
75 static void (WINAPI *p_basic_string_wchar_dtor)(void);
76 static basic_string_wchar* (WINAPI *p_basic_string_wchar_erase)(size_t, size_t);
77 static basic_string_wchar* (WINAPI *p_basic_string_wchar_assign_cstr_len)(const wchar_t*, size_t);
78 static const wchar_t* (WINAPI *p_basic_string_wchar_cstr)(void);
79 static const wchar_t* (WINAPI *p_basic_string_wchar_data)(void);
80 static size_t (WINAPI *p_basic_string_wchar_size)(void);
81 static size_t (WINAPI *p_basic_string_wchar_capacity)(void);
82 static void (WINAPI *p_basic_string_wchar_swap)(basic_string_wchar*);
83 #else
84 static basic_string_char* (__cdecl *p_basic_string_char_ctor)(basic_string_char*);
85 static basic_string_char* (__cdecl *p_basic_string_char_copy_ctor)(basic_string_char*, basic_string_char*);
86 static basic_string_char* (__cdecl *p_basic_string_char_ctor_cstr)(basic_string_char*, const char*);
87 static void (__cdecl *p_basic_string_char_dtor)(basic_string_char*);
88 static basic_string_char* (__cdecl *p_basic_string_char_erase)(basic_string_char*, size_t, size_t);
89 static basic_string_char* (__cdecl *p_basic_string_char_assign_cstr_len)(basic_string_char*, const char*, size_t);
90 static const char* (__cdecl *p_basic_string_char_cstr)(basic_string_char*);
91 static const char* (__cdecl *p_basic_string_char_data)(basic_string_char*);
92 static size_t (__cdecl *p_basic_string_char_size)(basic_string_char*);
93 static size_t (__cdecl *p_basic_string_char_capacity)(basic_string_char*);
94 static void (__cdecl *p_basic_string_char_swap)(basic_string_char*, basic_string_char*);
95 static basic_string_char* (WINAPI *p_basic_string_char_append)(basic_string_char*, basic_string_char*);
96 static basic_string_char* (WINAPI *p_basic_string_char_append_substr)(basic_string_char*, basic_string_char*, size_t, size_t);
97 static int (WINAPI *p_basic_string_char_compare_substr_substr)(basic_string_char*, size_t, size_t, basic_string_char*, size_t, size_t);
98 static int (WINAPI *p_basic_string_char_compare_substr_cstr_len)(basic_string_char*, size_t, size_t, const char*, size_t);
99
100 static basic_string_wchar* (__cdecl *p_basic_string_wchar_ctor)(basic_string_wchar*);
101 static basic_string_wchar* (__cdecl *p_basic_string_wchar_copy_ctor)(basic_string_wchar*, basic_string_wchar*);
102 static basic_string_wchar* (__cdecl *p_basic_string_wchar_ctor_cstr)(basic_string_wchar*, const wchar_t*);
103 static void (__cdecl *p_basic_string_wchar_dtor)(basic_string_wchar*);
104 static basic_string_wchar* (__cdecl *p_basic_string_wchar_erase)(basic_string_wchar*, size_t, size_t);
105 static basic_string_wchar* (__cdecl *p_basic_string_wchar_assign_cstr_len)(basic_string_wchar*, const wchar_t*, size_t);
106 static const wchar_t* (__cdecl *p_basic_string_wchar_cstr)(basic_string_wchar*);
107 static const wchar_t* (__cdecl *p_basic_string_wchar_data)(basic_string_wchar*);
108 static size_t (__cdecl *p_basic_string_wchar_size)(basic_string_wchar*);
109 static size_t (__cdecl *p_basic_string_wchar_capacity)(basic_string_wchar*);
110 static void (__cdecl *p_basic_string_wchar_swap)(basic_string_wchar*, basic_string_wchar*);
111 #endif
112
113 static int invalid_parameter = 0;
114 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
115         const wchar_t *function, const wchar_t *file,
116         unsigned line, uintptr_t arg)
117 {
118     ok(expression == NULL, "expression is not NULL\n");
119     ok(function == NULL, "function is not NULL\n");
120     ok(file == NULL, "file is not NULL\n");
121     ok(line == 0, "line = %u\n", line);
122     ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
123     invalid_parameter++;
124 }
125
126 /* Emulate a __thiscall */
127 #ifdef __i386__
128 #ifdef _MSC_VER
129 static inline void* do_call_func1(void *func, void *_this)
130 {
131     volatile void* retval = 0;
132     __asm
133     {
134         push ecx
135         mov ecx, _this
136         call func
137         mov retval, eax
138         pop ecx
139     }
140     return (void*)retval;
141 }
142
143 static inline void* do_call_func2(void *func, void *_this, const void *arg)
144 {
145     volatile void* retval = 0;
146     __asm
147     {
148         push ecx
149         push arg
150         mov ecx, _this
151         call func
152         mov retval, eax
153         pop ecx
154     }
155     return (void*)retval;
156 }
157
158 static inline void* do_call_func3(void *func, void *_this,
159         const void *arg1, const void *arg2)
160 {
161     volatile void* retval = 0;
162     __asm
163     {
164         push ecx
165         push arg1
166         push arg2
167         mov ecx, _this
168         call func
169         mov retval, eax
170         pop ecx
171     }
172     return (void*)retval;
173 }
174
175 static inline void* do_call_func4(void *func, void *_this,
176         const void *arg1, const void *arg2, const void *arg3)
177 {
178     volatile void* retval = 0;
179     __asm
180     {
181         push ecx
182         push arg1
183         push arg2
184         push arg3
185         mov ecx, _this
186         call func
187         mov retval, eax
188         pop ecx
189     }
190     return (void*)retval;
191 }
192
193 static inline void* do_call_func5(void *func, void *_this,
194         const void *arg1, const void *arg2, const void *arg3, const void *arg4)
195 {
196     volatile void* retval = 0;
197     __asm
198     {
199         push ecx
200         push arg1
201         push arg2
202         push arg3
203         push arg4
204         mov ecx, _this
205         call func
206         mov retval, eax
207         pop ecx
208     }
209     return (void*)retval;
210 }
211
212 static inline void* do_call_func6(void *func, void *_this,
213         const void *arg1, const void *arg2, const void *arg3,
214         const void *arg4, const void *arg5)
215 {
216     volatile void* retval = 0;
217     __asm
218     {
219         push ecx
220         push arg1
221         push arg2
222         push arg3
223         push arg4
224         push arg5
225         mov ecx, _this
226         call func
227         mov retval, eax
228         pop ecx
229     }
230     return (void*)retval;
231 }
232 #else
233 static void* do_call_func1(void *func, void *_this)
234 {
235     void *ret, *dummy;
236     __asm__ __volatile__ (
237             "call *%2"
238             : "=a" (ret), "=c" (dummy)
239             : "g" (func), "1" (_this)
240             : "edx", "memory"
241             );
242     return ret;
243 }
244
245 static void* do_call_func2(void *func, void *_this, const void *arg)
246 {
247     void *ret, *dummy;
248     __asm__ __volatile__ (
249             "pushl %3\n\tcall *%2"
250             : "=a" (ret), "=c" (dummy)
251             : "r" (func), "r" (arg), "1" (_this)
252             : "edx", "memory"
253             );
254     return ret;
255 }
256
257 static void* do_call_func3(void *func, void *_this,
258         const void *arg1, const void *arg2)
259 {
260     void *ret, *dummy;
261     __asm__ __volatile__ (
262             "pushl %4\n\tpushl %3\n\tcall *%2"
263             : "=a" (ret), "=c" (dummy)
264             : "r" (func), "r" (arg1), "r" (arg2), "1" (_this)
265             : "edx", "memory"
266             );
267     return ret;
268 }
269
270 static void* do_call_func4(void *func, void *_this,
271         const void *arg1, const void *arg2, const void *arg3)
272 {
273     void *ret, *dummy;
274     __asm__ __volatile__ (
275             "pushl %5\n\tpushl %4\n\tpushl %3\n\tcall *%2"
276             : "=a" (ret), "=c" (dummy)
277             : "r" (func), "r" (arg1), "r" (arg2), "m" (arg3), "1" (_this)
278             : "edx", "memory"
279             );
280     return ret;
281 }
282
283 static void* do_call_func5(void *func, void *_this,
284         const void *arg1, const void *arg2, const void *arg3, const void *arg4)
285 {
286     void *ret, *dummy;
287     __asm__ __volatile__ (
288             "pushl %6\n\tpushl %5\n\tpushl %4\n\tpushl %3\n\tcall *%2"
289             : "=a" (ret), "=c" (dummy)
290             : "r" (func), "r" (arg1), "r" (arg2), "m" (arg3), "m" (arg4), "1" (_this)
291             : "edx", "memory"
292             );
293     return ret;
294 }
295
296 static void* do_call_func6(void *func, void *_this,
297         const void *arg1, const void *arg2, const void *arg3,
298         const void *arg4, const void *arg5)
299 {
300     void *ret, *dummy;
301     __asm__ __volatile__ (
302             "pushl %7\n\tpushl %6\n\tpushl %5\n\tpushl %4\n\tpushl %3\n\tcall *%2"
303             : "=a" (ret), "=c" (dummy)
304             : "r" (func), "r" (arg1), "r" (arg2), "m" (arg3), "m" (arg4), "m" (arg5), "1" (_this)
305             : "edx", "memory"
306             );
307     return ret;
308 }
309 #endif
310
311 #define call_func1(func,_this)   do_call_func1(func,_this)
312 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
313 #define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b)
314 #define call_func4(func,_this,a,b,c) do_call_func4(func,_this,(const void*)a,\
315         (const void*)b,(const void*)c)
316 #define call_func5(func,_this,a,b,c,d) do_call_func5(func,_this,(const void*)a,\
317         (const void*)b,(const void*)c,(const void*)d)
318 #define call_func6(func,_this,a,b,c,d,e) do_call_func6(func,_this,(const void*)a,\
319         (const void*)b,(const void*)c,(const void*)d,(const void*)e)
320
321 #else
322
323 #define call_func1(func,_this) func(_this)
324 #define call_func2(func,_this,a) func(_this,a)
325 #define call_func3(func,_this,a,b) func(_this,a,b)
326 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
327 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
328 #define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
329
330 #endif /* __i386__ */
331
332 static BOOL init(void)
333 {
334     HMODULE msvcr = LoadLibraryA("msvcr90.dll");
335     HMODULE msvcp = LoadLibraryA("msvcp90.dll");
336     if(!msvcr || !msvcp) {
337         win_skip("msvcp90.dll or msvcrt90.dll not installed\n");
338         return FALSE;
339     }
340
341     p_set_invalid_parameter_handler = (void*)GetProcAddress(msvcr, "_set_invalid_parameter_handler");
342     if(!p_set_invalid_parameter_handler) {
343         win_skip("Error setting tests environment\n");
344         return FALSE;
345     }
346
347     p_set_invalid_parameter_handler(test_invalid_parameter_handler);
348
349     if(sizeof(void*) == 8) { /* 64-bit initialization */
350         p_basic_string_char_ctor = (void*)GetProcAddress(msvcp,
351                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ");
352         p_basic_string_char_copy_ctor = (void*)GetProcAddress(msvcp,
353                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@@Z");
354         p_basic_string_char_ctor_cstr = (void*)GetProcAddress(msvcp,
355                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z");
356         p_basic_string_char_dtor = (void*)GetProcAddress(msvcp,
357                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ");
358         p_basic_string_char_erase = (void*)GetProcAddress(msvcp,
359                 "?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z");
360         p_basic_string_char_assign_cstr_len = (void*)GetProcAddress(msvcp,
361                 "?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z");
362         p_basic_string_char_cstr = (void*)GetProcAddress(msvcp,
363                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ");
364         p_basic_string_char_data = (void*)GetProcAddress(msvcp,
365                 "?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ");
366         p_basic_string_char_size = (void*)GetProcAddress(msvcp,
367                 "?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ");
368         p_basic_string_char_capacity = (void*)GetProcAddress(msvcp,
369                 "?capacity@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ");
370         p_basic_string_char_swap = (void*)GetProcAddress(msvcp,
371                 "?swap@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXAEAV12@@Z");
372         p_basic_string_char_append = (void*)GetProcAddress(msvcp,
373                 "?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@@Z");
374         p_basic_string_char_append_substr = (void*)GetProcAddress(msvcp,
375                 "?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z");
376         p_basic_string_char_compare_substr_substr = (void*)GetProcAddress(msvcp,
377                 "?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0AEBV12@00@Z");
378         p_basic_string_char_compare_substr_cstr_len = (void*)GetProcAddress(msvcp,
379                 "?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAH_K0PEBD0@Z");
380         p_basic_string_char_concatenate = (void*)GetProcAddress(msvcp,
381                 "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@AEBV10@0@Z");
382         p_basic_string_char_concatenate_cstr = (void*)GetProcAddress(msvcp,
383                 "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@AEBV10@PEBD@Z");
384
385         p_basic_string_wchar_ctor = (void*)GetProcAddress(msvcp,
386                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ");
387         p_basic_string_wchar_copy_ctor = (void*)GetProcAddress(msvcp,
388                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@AEBV01@@Z");
389         p_basic_string_wchar_ctor_cstr = (void*)GetProcAddress(msvcp,
390                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z");
391         p_basic_string_wchar_dtor = (void*)GetProcAddress(msvcp,
392                 "??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ");
393         p_basic_string_wchar_erase = (void*)GetProcAddress(msvcp,
394                 "?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K0@Z");
395         p_basic_string_wchar_assign_cstr_len = (void*)GetProcAddress(msvcp,
396                 "?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z");
397         p_basic_string_wchar_cstr = (void*)GetProcAddress(msvcp,
398                 "?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ");
399         p_basic_string_wchar_data = (void*)GetProcAddress(msvcp,
400                 "?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ");
401         p_basic_string_wchar_size = (void*)GetProcAddress(msvcp,
402                 "?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ");
403         p_basic_string_wchar_capacity = (void*)GetProcAddress(msvcp,
404                 "?capacity@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ");
405         p_basic_string_wchar_swap = (void*)GetProcAddress(msvcp,
406                 "?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAXAEAV12@@Z");
407     } else {
408         p_basic_string_char_ctor = (void*)GetProcAddress(msvcp,
409                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
410         p_basic_string_char_copy_ctor = (void*)GetProcAddress(msvcp,
411                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z");
412         p_basic_string_char_ctor_cstr = (void*)GetProcAddress(msvcp,
413                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z");
414         p_basic_string_char_dtor = (void*)GetProcAddress(msvcp,
415                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
416         p_basic_string_char_erase = (void*)GetProcAddress(msvcp,
417                 "?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z");
418         p_basic_string_char_assign_cstr_len = (void*)GetProcAddress(msvcp,
419                 "?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z");
420         p_basic_string_char_cstr = (void*)GetProcAddress(msvcp,
421                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ");
422         p_basic_string_char_data = (void*)GetProcAddress(msvcp,
423                 "?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ");
424         p_basic_string_char_size = (void*)GetProcAddress(msvcp,
425                 "?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ");
426         p_basic_string_char_capacity = (void*)GetProcAddress(msvcp,
427                 "?capacity@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ");
428         p_basic_string_char_swap = (void*)GetProcAddress(msvcp,
429                 "?swap@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXAAV12@@Z");
430         p_basic_string_char_append = (void*)GetProcAddress(msvcp,
431                 "?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@@Z");
432         p_basic_string_char_append_substr = (void*)GetProcAddress(msvcp,
433                 "?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z");
434         p_basic_string_char_compare_substr_substr = (void*)GetProcAddress(msvcp,
435                 "?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIABV12@II@Z");
436         p_basic_string_char_compare_substr_cstr_len = (void*)GetProcAddress(msvcp,
437                 "?compare@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHIIPBDI@Z");
438         p_basic_string_char_concatenate = (void*)GetProcAddress(msvcp,
439                 "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z");
440         p_basic_string_char_concatenate_cstr = (void*)GetProcAddress(msvcp,
441                 "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z");
442
443         p_basic_string_wchar_ctor = (void*)GetProcAddress(msvcp,
444                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ");
445         p_basic_string_wchar_copy_ctor = (void*)GetProcAddress(msvcp,
446                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@ABV01@@Z");
447         p_basic_string_wchar_ctor_cstr = (void*)GetProcAddress(msvcp,
448                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_W@Z");
449         p_basic_string_wchar_dtor = (void*)GetProcAddress(msvcp,
450                 "??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ");
451         p_basic_string_wchar_erase = (void*)GetProcAddress(msvcp,
452                 "?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@II@Z");
453         p_basic_string_wchar_assign_cstr_len = (void*)GetProcAddress(msvcp,
454                 "?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z");
455         p_basic_string_wchar_cstr = (void*)GetProcAddress(msvcp,
456                 "?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ");
457         p_basic_string_wchar_data = (void*)GetProcAddress(msvcp,
458                 "?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ");
459         p_basic_string_wchar_size = (void*)GetProcAddress(msvcp,
460                 "?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ");
461         p_basic_string_wchar_capacity = (void*)GetProcAddress(msvcp,
462                 "?capacity@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ");
463         p_basic_string_wchar_swap = (void*)GetProcAddress(msvcp,
464                 "?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXAAV12@@Z");
465     }
466
467     return TRUE;
468 }
469
470 static void test_basic_string_char(void) {
471     basic_string_char str1, str2, *pstr;
472     const char *str;
473     size_t size, capacity;
474
475     if(!p_basic_string_char_ctor || !p_basic_string_char_copy_ctor
476             || !p_basic_string_char_ctor_cstr || !p_basic_string_char_dtor
477             || !p_basic_string_char_erase || !p_basic_string_char_assign_cstr_len
478             || !p_basic_string_char_cstr || !p_basic_string_char_data
479             || !p_basic_string_char_size || !p_basic_string_char_capacity) {
480         win_skip("basic_string<char> unavailable\n");
481         return;
482     }
483
484     call_func1(p_basic_string_char_ctor, &str1);
485     str = NULL;
486     str = call_func1(p_basic_string_char_cstr, &str1);
487     ok(str != NULL, "str = NULL\n");
488     ok(*str == '\0', "*str = %c\n", *str);
489     str = call_func1(p_basic_string_char_data, &str1);
490     ok(str != NULL, "str = NULL\n");
491     ok(*str == '\0', "*str = %c\n", *str);
492     call_func1(p_basic_string_char_dtor, &str1);
493
494     pstr = call_func2(p_basic_string_char_ctor_cstr, &str1, "test");
495     ok(pstr == &str1, "pstr != &str1\n");
496     str = call_func1(p_basic_string_char_cstr, &str1);
497     ok(!memcmp(str, "test", 5), "str = %s\n", str);
498     str = call_func1(p_basic_string_char_data, &str1);
499     ok(!memcmp(str, "test", 5), "str = %s\n", str);
500     size = (size_t)call_func1(p_basic_string_char_size, &str1);
501     ok(size == 4, "size = %lu\n", (unsigned long)size);
502     capacity = (size_t)call_func1(p_basic_string_char_capacity, &str1);
503     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
504
505     pstr = call_func2(p_basic_string_char_copy_ctor, &str2, &str1);
506     ok(pstr == &str2, "pstr != &str2\n");
507     str = call_func1(p_basic_string_char_cstr, &str2);
508     ok(!memcmp(str, "test", 5), "str = %s\n", str);
509     str = call_func1(p_basic_string_char_data, &str2);
510     ok(!memcmp(str, "test", 5), "str = %s\n", str);
511
512     call_func3(p_basic_string_char_erase, &str2, 1, 2);
513     str = call_func1(p_basic_string_char_cstr, &str2);
514     ok(!memcmp(str, "tt", 3), "str = %s\n", str);
515     str = call_func1(p_basic_string_char_data, &str2);
516     ok(!memcmp(str, "tt", 3), "str = %s\n", str);
517     size = (size_t)call_func1(p_basic_string_char_size, &str1);
518     ok(size == 4, "size = %lu\n", (unsigned long)size);
519     capacity = (size_t)call_func1(p_basic_string_char_capacity, &str1);
520     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
521
522     call_func3(p_basic_string_char_erase, &str2, 1, 100);
523     str = call_func1(p_basic_string_char_cstr, &str2);
524     ok(!memcmp(str, "t", 2), "str = %s\n", str);
525     str = call_func1(p_basic_string_char_data, &str2);
526     ok(!memcmp(str, "t", 2), "str = %s\n", str);
527     size = (size_t)call_func1(p_basic_string_char_size, &str1);
528     ok(size == 4, "size = %lu\n", (unsigned long)size);
529     capacity = (size_t)call_func1(p_basic_string_char_capacity, &str1);
530     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
531
532     call_func3(p_basic_string_char_assign_cstr_len, &str2, "test", 4);
533     str = call_func1(p_basic_string_char_cstr, &str2);
534     ok(!memcmp(str, "test", 5), "str = %s\n", str);
535     str = call_func1(p_basic_string_char_data, &str2);
536     ok(!memcmp(str, "test", 5), "str = %s\n", str);
537
538     call_func3(p_basic_string_char_assign_cstr_len, &str2, (str+1), 2);
539     str = call_func1(p_basic_string_char_cstr, &str2);
540     ok(!memcmp(str, "es", 3), "str = %s\n", str);
541     str = call_func1(p_basic_string_char_data, &str2);
542     ok(!memcmp(str, "es", 3), "str = %s\n", str);
543
544     call_func1(p_basic_string_char_dtor, &str1);
545     call_func1(p_basic_string_char_dtor, &str2);
546 }
547
548 static void test_basic_string_char_swap(void) {
549     basic_string_char str1, str2;
550     char atmp1[32], atmp2[32];
551
552     if(!p_basic_string_char_ctor_cstr || !p_basic_string_char_dtor ||
553             !p_basic_string_char_swap || !p_basic_string_char_cstr) {
554         win_skip("basic_string<char> unavailable\n");
555         return;
556     }
557
558     /* Swap self, local */
559     strcpy(atmp1, "qwerty");
560     call_func2(p_basic_string_char_ctor_cstr, &str1, atmp1);
561     call_func2(p_basic_string_char_swap, &str1, &str1);
562     ok(strcmp(atmp1, (const char *) call_func1(p_basic_string_char_cstr, &str1)) == 0, "Invalid value of str1\n");
563     call_func2(p_basic_string_char_swap, &str1, &str1);
564     ok(strcmp(atmp1, (const char *) call_func1(p_basic_string_char_cstr, &str1)) == 0, "Invalid value of str1\n");
565     call_func1(p_basic_string_char_dtor, &str1);
566
567     /* str1 allocated, str2 local */
568     strcpy(atmp1, "qwerty12345678901234567890");
569     strcpy(atmp2, "asd");
570     call_func2(p_basic_string_char_ctor_cstr, &str1, atmp1);
571     call_func2(p_basic_string_char_ctor_cstr, &str2, atmp2);
572     call_func2(p_basic_string_char_swap, &str1, &str2);
573     ok(strcmp(atmp2, (const char *) call_func1(p_basic_string_char_cstr, &str1)) == 0, "Invalid value of str1\n");
574     ok(strcmp(atmp1, (const char *) call_func1(p_basic_string_char_cstr, &str2)) == 0, "Invalid value of str2\n");
575     call_func2(p_basic_string_char_swap, &str1, &str2);
576     ok(strcmp(atmp1, (const char *) call_func1(p_basic_string_char_cstr, &str1)) == 0, "Invalid value of str1\n");
577     ok(strcmp(atmp2, (const char *) call_func1(p_basic_string_char_cstr, &str2)) == 0, "Invalid value of str2\n");
578     call_func1(p_basic_string_char_dtor, &str1);
579     call_func1(p_basic_string_char_dtor, &str2);
580 }
581
582 static void test_basic_string_char_append(void) {
583     basic_string_char str1, str2;
584     const char *str;
585
586     if(!p_basic_string_char_ctor_cstr || !p_basic_string_char_dtor
587             || !p_basic_string_char_append || !p_basic_string_char_append_substr
588             || !p_basic_string_char_cstr) {
589         win_skip("basic_string<char> unavailable\n");
590         return;
591     }
592
593     call_func2(p_basic_string_char_ctor_cstr, &str1, "");
594     call_func2(p_basic_string_char_ctor_cstr, &str2, "append");
595
596     call_func2(p_basic_string_char_append, &str1, &str2);
597     str = call_func1(p_basic_string_char_cstr, &str1);
598     ok(!memcmp(str, "append", 7), "str = %s\n", str);
599
600     call_func4(p_basic_string_char_append_substr, &str1, &str2, 3, 1);
601     str = call_func1(p_basic_string_char_cstr, &str1);
602     ok(!memcmp(str, "appende", 8), "str = %s\n", str);
603
604     call_func4(p_basic_string_char_append_substr, &str1, &str2, 5, 100);
605     str = call_func1(p_basic_string_char_cstr, &str1);
606     ok(!memcmp(str, "appended", 9), "str = %s\n", str);
607
608     call_func4(p_basic_string_char_append_substr, &str1, &str2, 6, 100);
609     str = call_func1(p_basic_string_char_cstr, &str1);
610     ok(!memcmp(str, "appended", 9), "str = %s\n", str);
611
612     call_func1(p_basic_string_char_dtor, &str1);
613     call_func1(p_basic_string_char_dtor, &str2);
614 }
615
616 static void test_basic_string_char_compare(void) {
617     basic_string_char str1, str2;
618     int ret;
619
620     if(!p_basic_string_char_ctor_cstr || !p_basic_string_char_dtor
621             || !p_basic_string_char_compare_substr_substr
622             || !p_basic_string_char_compare_substr_cstr_len) {
623         win_skip("basic_string<char> unavailable\n");
624         return;
625     }
626
627     call_func2(p_basic_string_char_ctor_cstr, &str1, "str1str");
628     call_func2(p_basic_string_char_ctor_cstr, &str2, "str9str");
629
630     ret = (int)call_func6(p_basic_string_char_compare_substr_substr,
631             &str1, 0, 3, &str2, 0, 3);
632     ok(ret == 0, "ret = %d\n", ret);
633     ret = (int)call_func6(p_basic_string_char_compare_substr_substr,
634             &str1, 4, 3, &str2, 4, 10);
635     ok(ret == 0, "ret = %d\n", ret);
636     ret = (int)call_func6(p_basic_string_char_compare_substr_substr,
637             &str1, 1, 3, &str2, 1, 4);
638     ok(ret == -1, "ret = %d\n", ret);
639
640     ret = (int)call_func5(p_basic_string_char_compare_substr_cstr_len,
641             &str1, 0, 1000, "str1str", 7);
642     ok(ret == 0, "ret = %d\n", ret);
643     ret = (int)call_func5(p_basic_string_char_compare_substr_cstr_len,
644             &str1, 1, 2, "tr", 2);
645     ok(ret == 0, "ret = %d\n", ret);
646     ret = (int)call_func5(p_basic_string_char_compare_substr_cstr_len,
647             &str1, 1, 0, "aaa", 0);
648     ok(ret == 0, "ret = %d\n", ret);
649     ret = (int)call_func5(p_basic_string_char_compare_substr_cstr_len,
650             &str1, 1, 0, "aaa", 1);
651     ok(ret == -1, "ret = %d\n", ret);
652
653     call_func1(p_basic_string_char_dtor, &str1);
654     call_func1(p_basic_string_char_dtor, &str2);
655 }
656
657 static void test_basic_string_char_concatenate(void) {
658     basic_string_char str, ret;
659     const char *cstr;
660
661     if(!p_basic_string_char_ctor_cstr || !p_basic_string_char_concatenate
662             || !p_basic_string_char_concatenate_cstr || !p_basic_string_char_cstr
663             || !p_basic_string_char_dtor) {
664         win_skip("basic_string<wchar> unavailable\n");
665         return;
666     }
667
668     call_func2(p_basic_string_char_ctor_cstr, &str, "test ");
669     /* CDECL calling convention with return bigger than 8 bytes */
670     p_basic_string_char_concatenate(&ret, &str, &str);
671     cstr = call_func1(p_basic_string_char_cstr, &ret);
672     ok(cstr != NULL, "cstr = NULL\n");
673     ok(!strcmp(cstr, "test test "), "cstr = %s\n", cstr);
674     call_func1(p_basic_string_char_dtor, &ret);
675
676     p_basic_string_char_concatenate_cstr(&ret, &str, "passed");
677     cstr = call_func1(p_basic_string_char_cstr, &ret);
678     ok(cstr != NULL, "cstr = NULL\n");
679     ok(!strcmp(cstr, "test passed"), "cstr = %s\n", cstr);
680     call_func1(p_basic_string_char_dtor, &ret);
681
682     call_func1(p_basic_string_char_dtor, &str);
683 }
684
685 static void test_basic_string_wchar(void) {
686     static const wchar_t test[] = { 't','e','s','t',0 };
687
688     basic_string_wchar str1, str2, *pstr;
689     const wchar_t *str;
690     size_t size, capacity;
691
692     if(!p_basic_string_wchar_ctor || !p_basic_string_wchar_copy_ctor
693             || !p_basic_string_wchar_ctor_cstr || !p_basic_string_wchar_dtor
694             || !p_basic_string_wchar_erase || !p_basic_string_wchar_assign_cstr_len
695             || !p_basic_string_wchar_cstr || !p_basic_string_wchar_data
696             || !p_basic_string_wchar_size || !p_basic_string_wchar_capacity) {
697         win_skip("basic_string<wchar_t> unavailable\n");
698         return;
699     }
700
701     call_func1(p_basic_string_wchar_ctor, &str1);
702     str = NULL;
703     str = call_func1(p_basic_string_wchar_cstr, &str1);
704     ok(str != NULL, "str = NULL\n");
705     ok(*str == '\0', "*str = %c\n", *str);
706     str = call_func1(p_basic_string_wchar_data, &str1);
707     ok(str != NULL, "str = NULL\n");
708     ok(*str == '\0', "*str = %c\n", *str);
709     call_func1(p_basic_string_wchar_dtor, &str1);
710
711     pstr = call_func2(p_basic_string_wchar_ctor_cstr, &str1, test);
712     ok(pstr == &str1, "pstr != &str1\n");
713     str = call_func1(p_basic_string_wchar_cstr, &str1);
714     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
715     str = call_func1(p_basic_string_wchar_data, &str1);
716     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
717     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
718     ok(size == 4, "size = %lu\n", (unsigned long)size);
719     capacity = (size_t)call_func1(p_basic_string_wchar_capacity, &str1);
720     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
721
722     memset(&str2, 0, sizeof(basic_string_wchar));
723     pstr = call_func2(p_basic_string_wchar_copy_ctor, &str2, &str1);
724     ok(pstr == &str2, "pstr != &str2\n");
725     str = call_func1(p_basic_string_wchar_cstr, &str2);
726     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
727     str = call_func1(p_basic_string_wchar_data, &str2);
728     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
729
730     call_func3(p_basic_string_wchar_erase, &str2, 1, 2);
731     str = call_func1(p_basic_string_wchar_cstr, &str2);
732     ok(str[0]=='t' && str[1]=='t' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
733     str = call_func1(p_basic_string_wchar_data, &str2);
734     ok(str[0]=='t' && str[1]=='t' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
735     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
736     ok(size == 4, "size = %lu\n", (unsigned long)size);
737     capacity = (size_t)call_func1(p_basic_string_wchar_capacity, &str1);
738     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
739
740     call_func3(p_basic_string_wchar_erase, &str2, 1, 100);
741     str = call_func1(p_basic_string_wchar_cstr, &str2);
742     ok(str[0]=='t' && str[1]=='\0', "str = %s\n", wine_dbgstr_w(str));
743     str = call_func1(p_basic_string_wchar_data, &str2);
744     ok(str[0]=='t' && str[1]=='\0', "str = %s\n", wine_dbgstr_w(str));
745     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
746     ok(size == 4, "size = %lu\n", (unsigned long)size);
747     capacity = (size_t)call_func1(p_basic_string_wchar_capacity, &str1);
748     ok(capacity >= size, "capacity = %lu < size = %lu\n", (unsigned long)capacity, (unsigned long)size);
749
750     call_func3(p_basic_string_wchar_assign_cstr_len, &str2, test, 4);
751     str = call_func1(p_basic_string_wchar_cstr, &str2);
752     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
753     str = call_func1(p_basic_string_wchar_data, &str2);
754     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
755
756     call_func3(p_basic_string_wchar_assign_cstr_len, &str2, (str+1), 2);
757     str = call_func1(p_basic_string_wchar_cstr, &str2);
758     ok(str[0]=='e' && str[1]=='s' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
759     str = call_func1(p_basic_string_wchar_data, &str2);
760     ok(str[0]=='e' && str[1]=='s' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
761
762     call_func1(p_basic_string_wchar_dtor, &str1);
763     call_func1(p_basic_string_wchar_dtor, &str2);
764 }
765
766 static void test_basic_string_wchar_swap(void) {
767     basic_string_wchar str1, str2;
768     wchar_t wtmp1[32], wtmp2[32];
769
770     if(!p_basic_string_wchar_ctor_cstr || !p_basic_string_wchar_dtor ||
771             !p_basic_string_wchar_swap || !p_basic_string_wchar_cstr) {
772         win_skip("basic_string<wchar_t> unavailable\n");
773         return;
774     }
775
776     /* Swap self, local */
777     mbstowcs(wtmp1, "qwerty", 32);
778     call_func2(p_basic_string_wchar_ctor_cstr, &str1, wtmp1);
779     call_func2(p_basic_string_wchar_swap, &str1, &str1);
780     ok(wcscmp(wtmp1, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str1)) == 0, "Invalid value of str1\n");
781     call_func2(p_basic_string_wchar_swap, &str1, &str1);
782     ok(wcscmp(wtmp1, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str1)) == 0, "Invalid value of str1\n");
783     call_func1(p_basic_string_wchar_dtor, &str1);
784
785     /* str1 allocated, str2 local */
786     mbstowcs(wtmp1, "qwerty12345678901234567890", 32);
787     mbstowcs(wtmp2, "asd", 32);
788     call_func2(p_basic_string_wchar_ctor_cstr, &str1, wtmp1);
789     call_func2(p_basic_string_wchar_ctor_cstr, &str2, wtmp2);
790     call_func2(p_basic_string_wchar_swap, &str1, &str2);
791     ok(wcscmp(wtmp2, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str1)) == 0, "Invalid value of str1\n");
792     ok(wcscmp(wtmp1, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str2)) == 0, "Invalid value of str2\n");
793     call_func2(p_basic_string_wchar_swap, &str1, &str2);
794     ok(wcscmp(wtmp1, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str1)) == 0, "Invalid value of str1\n");
795     ok(wcscmp(wtmp2, (const wchar_t *) call_func1(p_basic_string_wchar_cstr, &str2)) == 0, "Invalid value of str2\n");
796     call_func1(p_basic_string_wchar_dtor, &str1);
797     call_func1(p_basic_string_wchar_dtor, &str2);
798 }
799
800 START_TEST(string)
801 {
802     if(!init())
803         return;
804
805     test_basic_string_char();
806     test_basic_string_char_swap();
807     test_basic_string_char_append();
808     test_basic_string_char_compare();
809     test_basic_string_char_concatenate();
810     test_basic_string_wchar();
811     test_basic_string_wchar_swap();
812
813     ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n");
814 }