msvcp90/tests: Fix basic_string<wchar_t>.size tests.
[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
53 #ifdef __i386__
54 static basic_string_char* (WINAPI *p_basic_string_char_ctor)(void);
55 static basic_string_char* (WINAPI *p_basic_string_char_copy_ctor)(basic_string_char*);
56 static basic_string_char* (WINAPI *p_basic_string_char_ctor_cstr)(const char*);
57 static void (WINAPI *p_basic_string_char_dtor)(void);
58 static basic_string_char* (WINAPI *p_basic_string_char_erase)(size_t, size_t);
59 static basic_string_char* (WINAPI *p_basic_string_char_assign_cstr_len)(const char*, size_t);
60 static const char* (WINAPI *p_basic_string_char_cstr)(void);
61 static const char* (WINAPI *p_basic_string_char_data)(void);
62 static size_t (WINAPI *p_basic_string_char_size)(void);
63
64 static basic_string_wchar* (WINAPI *p_basic_string_wchar_ctor)(void);
65 static basic_string_wchar* (WINAPI *p_basic_string_wchar_copy_ctor)(basic_string_wchar*);
66 static basic_string_wchar* (WINAPI *p_basic_string_wchar_ctor_cstr)(const wchar_t*);
67 static void (WINAPI *p_basic_string_wchar_dtor)(void);
68 static basic_string_wchar* (WINAPI *p_basic_string_wchar_erase)(size_t, size_t);
69 static basic_string_wchar* (WINAPI *p_basic_string_wchar_assign_cstr_len)(const wchar_t*, size_t);
70 static const wchar_t* (WINAPI *p_basic_string_wchar_cstr)(void);
71 static const wchar_t* (WINAPI *p_basic_string_wchar_data)(void);
72 static size_t (WINAPI *p_basic_string_wchar_size)(void);
73 #else
74 static basic_string_char* (__cdecl *p_basic_string_char_ctor)(basic_string_char*);
75 static basic_string_char* (__cdecl *p_basic_string_char_copy_ctor)(basic_string_char*, basic_string_char*);
76 static basic_string_char* (__cdecl *p_basic_string_char_ctor_cstr)(basic_string_char*, const char*);
77 static void (__cdecl *p_basic_string_char_dtor)(basic_string_char*);
78 static basic_string_char* (__cdecl *p_basic_string_char_erase)(basic_string_char*, size_t, size_t);
79 static basic_string_char* (__cdecl *p_basic_string_char_assign_cstr_len)(basic_string_char*, const char*, size_t);
80 static const char* (__cdecl *p_basic_string_char_cstr)(basic_string_char*);
81 static const char* (__cdecl *p_basic_string_char_data)(basic_string_char*);
82 static size_t (__cdecl *p_basic_string_char_size)(basic_string_char*);
83
84 static basic_string_wchar* (__cdecl *p_basic_string_wchar_ctor)(basic_string_wchar*);
85 static basic_string_wchar* (__cdecl *p_basic_string_wchar_copy_ctor)(basic_string_wchar*, basic_string_wchar*);
86 static basic_string_wchar* (__cdecl *p_basic_string_wchar_ctor_cstr)(basic_string_wchar*, const wchar_t*);
87 static void (__cdecl *p_basic_string_wchar_dtor)(basic_string_wchar*);
88 static basic_string_wchar* (__cdecl *p_basic_string_wchar_erase)(basic_string_wchar*, size_t, size_t);
89 static basic_string_wchar* (__cdecl *p_basic_string_wchar_assign_cstr_len)(basic_string_wchar*, const wchar_t*, size_t);
90 static const wchar_t* (__cdecl *p_basic_string_wchar_cstr)(basic_string_wchar*);
91 static const wchar_t* (__cdecl *p_basic_string_wchar_data)(basic_string_wchar*);
92 static size_t (__cdecl *p_basic_string_wchar_size)(basic_string_wchar*);
93 #endif
94
95 static int invalid_parameter = 0;
96 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
97         const wchar_t *function, const wchar_t *file,
98         unsigned line, uintptr_t arg)
99 {
100     ok(expression == NULL, "expression is not NULL\n");
101     ok(function == NULL, "function is not NULL\n");
102     ok(file == NULL, "file is not NULL\n");
103     ok(line == 0, "line = %u\n", line);
104     ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
105     invalid_parameter++;
106 }
107
108 /* Emulate a __thiscall */
109 #ifdef __i386__
110 #ifdef _MSC_VER
111 static inline void* do_call_func1(void *func, void *_this)
112 {
113     volatile void* retval = 0;
114     __asm
115     {
116         push ecx
117         mov ecx, _this
118         call func
119         mov retval, eax
120         pop ecx
121     }
122     return (void*)retval;
123 }
124
125 static inline void* do_call_func2(void *func, void *_this, const void *arg)
126 {
127     volatile void* retval = 0;
128     __asm
129     {
130         push ecx
131         push arg
132         mov ecx, _this
133         call func
134         mov retval, eax
135         pop ecx
136     }
137     return (void*)retval;
138 }
139
140 static inline void* do_call_func3(void *func, void *_this,
141         const void *arg1, const void *arg2)
142 {
143     volatile void* retval = 0;
144     __asm
145     {
146         push ecx
147         push arg1
148         push arg2
149         mov ecx, _this
150         call func
151         mov retval, eax
152         pop ecx
153     }
154     return (void*)retval;
155 }
156 #else
157 static void* do_call_func1(void *func, void *_this)
158 {
159     void *ret, *dummy;
160     __asm__ __volatile__ (
161             "call *%2"
162             : "=a" (ret), "=c" (dummy)
163             : "g" (func), "1" (_this)
164             : "edx", "memory"
165             );
166     return ret;
167 }
168
169 static void* do_call_func2(void *func, void *_this, const void *arg)
170 {
171     void *ret, *dummy;
172     __asm__ __volatile__ (
173             "pushl %3\n\tcall *%2"
174             : "=a" (ret), "=c" (dummy)
175             : "r" (func), "r" (arg), "1" (_this)
176             : "edx", "memory"
177             );
178     return ret;
179 }
180
181 static void* do_call_func3(void *func, void *_this,
182         const void *arg1, const void *arg2)
183 {
184     void *ret, *dummy;
185     __asm__ __volatile__ (
186             "pushl %4\n\tpushl %3\n\tcall *%2"
187             : "=a" (ret), "=c" (dummy)
188             : "r" (func), "r" (arg1), "r" (arg2), "1" (_this)
189             : "edx", "memory"
190             );
191     return ret;
192 }
193 #endif
194
195 #define call_func1(func,_this)   do_call_func1(func,_this)
196 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
197 #define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b)
198
199 #else
200
201 #define call_func1(func,_this) func(_this)
202 #define call_func2(func,_this,a) func(_this,a)
203 #define call_func3(func,_this,a,b) func(_this,a,b)
204
205 #endif /* __i386__ */
206
207 static BOOL init(void)
208 {
209     HMODULE msvcr = LoadLibraryA("msvcr90.dll");
210     HMODULE msvcp = LoadLibraryA("msvcp90.dll");
211     if(!msvcr || !msvcp) {
212         win_skip("msvcp90.dll or msvcrt90.dll not installed\n");
213         return FALSE;
214     }
215
216     p_set_invalid_parameter_handler = (void*)GetProcAddress(msvcr, "_set_invalid_parameter_handler");
217     if(!p_set_invalid_parameter_handler) {
218         win_skip("Error setting tests environment\n");
219         return FALSE;
220     }
221
222     p_set_invalid_parameter_handler(test_invalid_parameter_handler);
223
224     if(sizeof(void*) == 8) { /* 64-bit initialization */
225         p_basic_string_char_ctor = (void*)GetProcAddress(msvcp,
226                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ");
227         p_basic_string_char_copy_ctor = (void*)GetProcAddress(msvcp,
228                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV01@@Z");
229         p_basic_string_char_ctor_cstr = (void*)GetProcAddress(msvcp,
230                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z");
231         p_basic_string_char_dtor = (void*)GetProcAddress(msvcp,
232                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ");
233         p_basic_string_char_erase = (void*)GetProcAddress(msvcp,
234                 "?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z");
235         p_basic_string_char_assign_cstr_len = (void*)GetProcAddress(msvcp,
236                 "?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@PEBD_K@Z");
237         p_basic_string_char_cstr = (void*)GetProcAddress(msvcp,
238                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ");
239         p_basic_string_char_data = (void*)GetProcAddress(msvcp,
240                 "?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBAPEBDXZ");
241         p_basic_string_char_size = (void*)GetProcAddress(msvcp,
242                 "?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KXZ");
243
244         p_basic_string_wchar_ctor = (void*)GetProcAddress(msvcp,
245                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ");
246         p_basic_string_wchar_copy_ctor = (void*)GetProcAddress(msvcp,
247                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@AEBV01@@Z");
248         p_basic_string_wchar_ctor_cstr = (void*)GetProcAddress(msvcp,
249                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z");
250         p_basic_string_wchar_dtor = (void*)GetProcAddress(msvcp,
251                 "??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ");
252         p_basic_string_wchar_erase = (void*)GetProcAddress(msvcp,
253                 "?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@_K0@Z");
254         p_basic_string_wchar_assign_cstr_len = (void*)GetProcAddress(msvcp,
255                 "?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z");
256         p_basic_string_wchar_cstr = (void*)GetProcAddress(msvcp,
257                 "?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ");
258         p_basic_string_wchar_data = (void*)GetProcAddress(msvcp,
259                 "?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ");
260         p_basic_string_wchar_size = (void*)GetProcAddress(msvcp,
261                 "?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ");
262
263     } else {
264         p_basic_string_char_ctor = (void*)GetProcAddress(msvcp,
265                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
266         p_basic_string_char_copy_ctor = (void*)GetProcAddress(msvcp,
267                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z");
268         p_basic_string_char_ctor_cstr = (void*)GetProcAddress(msvcp,
269                 "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z");
270         p_basic_string_char_dtor = (void*)GetProcAddress(msvcp,
271                 "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ");
272         p_basic_string_char_erase = (void*)GetProcAddress(msvcp,
273                 "?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z");
274         p_basic_string_char_assign_cstr_len = (void*)GetProcAddress(msvcp,
275                 "?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z");
276         p_basic_string_char_cstr = (void*)GetProcAddress(msvcp,
277                 "?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ");
278         p_basic_string_char_data = (void*)GetProcAddress(msvcp,
279                 "?data@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ");
280         p_basic_string_char_size = (void*)GetProcAddress(msvcp,
281                 "?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ");
282
283         p_basic_string_wchar_ctor = (void*)GetProcAddress(msvcp,
284                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ");
285         p_basic_string_wchar_copy_ctor = (void*)GetProcAddress(msvcp,
286                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@ABV01@@Z");
287         p_basic_string_wchar_ctor_cstr = (void*)GetProcAddress(msvcp,
288                 "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@PB_W@Z");
289         p_basic_string_wchar_dtor = (void*)GetProcAddress(msvcp,
290                 "??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ");
291         p_basic_string_wchar_erase = (void*)GetProcAddress(msvcp,
292                 "?erase@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@II@Z");
293         p_basic_string_wchar_assign_cstr_len = (void*)GetProcAddress(msvcp,
294                 "?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@PB_WI@Z");
295         p_basic_string_wchar_cstr = (void*)GetProcAddress(msvcp,
296                 "?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ");
297         p_basic_string_wchar_data = (void*)GetProcAddress(msvcp,
298                 "?data@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEPB_WXZ");
299         p_basic_string_wchar_size = (void*)GetProcAddress(msvcp,
300                 "?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBEIXZ");
301     }
302
303     return TRUE;
304 }
305
306 static void test_basic_string_char(void) {
307     basic_string_char str1, str2, *pstr;
308     const char *str;
309     size_t size;
310
311     if(!p_basic_string_char_ctor || !p_basic_string_char_copy_ctor
312             || !p_basic_string_char_ctor_cstr || !p_basic_string_char_dtor
313             || !p_basic_string_char_erase || !p_basic_string_char_assign_cstr_len
314             || !p_basic_string_char_cstr || !p_basic_string_char_data
315             || !p_basic_string_char_size) {
316         win_skip("basic_string<char> unavailable\n");
317         return;
318     }
319
320     call_func1(p_basic_string_char_ctor, &str1);
321     str = NULL;
322     str = call_func1(p_basic_string_char_cstr, &str1);
323     ok(str != NULL, "str = NULL\n");
324     ok(*str == '\0', "*str = %c\n", *str);
325     str = call_func1(p_basic_string_char_data, &str1);
326     ok(str != NULL, "str = NULL\n");
327     ok(*str == '\0', "*str = %c\n", *str);
328     call_func1(p_basic_string_char_dtor, &str1);
329
330     pstr = call_func2(p_basic_string_char_ctor_cstr, &str1, "test");
331     ok(pstr == &str1, "pstr != &str1\n");
332     str = call_func1(p_basic_string_char_cstr, &str1);
333     ok(!memcmp(str, "test", 5), "str = %s\n", str);
334     str = call_func1(p_basic_string_char_data, &str1);
335     ok(!memcmp(str, "test", 5), "str = %s\n", str);
336     size = (size_t)call_func1(p_basic_string_char_size, &str1);
337     ok(size == 4, "size = %lu\n", (unsigned long)size);
338
339     pstr = call_func2(p_basic_string_char_copy_ctor, &str2, &str1);
340     ok(pstr == &str2, "pstr != &str2\n");
341     str = call_func1(p_basic_string_char_cstr, &str2);
342     ok(!memcmp(str, "test", 5), "str = %s\n", str);
343     str = call_func1(p_basic_string_char_data, &str2);
344     ok(!memcmp(str, "test", 5), "str = %s\n", str);
345
346     call_func3(p_basic_string_char_erase, &str2, 1, 2);
347     str = call_func1(p_basic_string_char_cstr, &str2);
348     ok(!memcmp(str, "tt", 3), "str = %s\n", str);
349     str = call_func1(p_basic_string_char_data, &str2);
350     ok(!memcmp(str, "tt", 3), "str = %s\n", str);
351     size = (size_t)call_func1(p_basic_string_char_size, &str1);
352     ok(size == 4, "size = %lu\n", (unsigned long)size);
353
354     call_func3(p_basic_string_char_erase, &str2, 1, 100);
355     str = call_func1(p_basic_string_char_cstr, &str2);
356     ok(!memcmp(str, "t", 2), "str = %s\n", str);
357     str = call_func1(p_basic_string_char_data, &str2);
358     ok(!memcmp(str, "t", 2), "str = %s\n", str);
359     size = (size_t)call_func1(p_basic_string_char_size, &str1);
360     ok(size == 4, "size = %lu\n", (unsigned long)size);
361
362     call_func3(p_basic_string_char_assign_cstr_len, &str2, "test", 4);
363     str = call_func1(p_basic_string_char_cstr, &str2);
364     ok(!memcmp(str, "test", 5), "str = %s\n", str);
365     str = call_func1(p_basic_string_char_data, &str2);
366     ok(!memcmp(str, "test", 5), "str = %s\n", str);
367
368     call_func3(p_basic_string_char_assign_cstr_len, &str2, (str+1), 2);
369     str = call_func1(p_basic_string_char_cstr, &str2);
370     ok(!memcmp(str, "es", 3), "str = %s\n", str);
371     str = call_func1(p_basic_string_char_data, &str2);
372     ok(!memcmp(str, "es", 3), "str = %s\n", str);
373
374     call_func1(p_basic_string_char_dtor, &str1);
375     call_func1(p_basic_string_char_dtor, &str2);
376 }
377
378 static void test_basic_string_wchar(void) {
379     static const wchar_t test[] = { 't','e','s','t',0 };
380
381     basic_string_wchar str1, str2, *pstr;
382     const wchar_t *str;
383     size_t size;
384
385     if(!p_basic_string_wchar_ctor || !p_basic_string_wchar_copy_ctor
386             || !p_basic_string_wchar_ctor_cstr || !p_basic_string_wchar_dtor
387             || !p_basic_string_wchar_erase || !p_basic_string_wchar_assign_cstr_len
388             || !p_basic_string_wchar_cstr || !p_basic_string_wchar_data
389             || !p_basic_string_wchar_size) {
390         win_skip("basic_string<wchar_t> unavailable\n");
391         return;
392     }
393
394     call_func1(p_basic_string_wchar_ctor, &str1);
395     str = NULL;
396     str = call_func1(p_basic_string_wchar_cstr, &str1);
397     ok(str != NULL, "str = NULL\n");
398     ok(*str == '\0', "*str = %c\n", *str);
399     str = call_func1(p_basic_string_wchar_data, &str1);
400     ok(str != NULL, "str = NULL\n");
401     ok(*str == '\0', "*str = %c\n", *str);
402     call_func1(p_basic_string_wchar_dtor, &str1);
403
404     pstr = call_func2(p_basic_string_wchar_ctor_cstr, &str1, test);
405     ok(pstr == &str1, "pstr != &str1\n");
406     str = call_func1(p_basic_string_wchar_cstr, &str1);
407     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
408     str = call_func1(p_basic_string_wchar_data, &str1);
409     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
410     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
411     ok(size == 4, "size = %lu\n", (unsigned long)size);
412
413     memset(&str2, 0, sizeof(basic_string_wchar));
414     pstr = call_func2(p_basic_string_wchar_copy_ctor, &str2, &str1);
415     ok(pstr == &str2, "pstr != &str2\n");
416     str = call_func1(p_basic_string_wchar_cstr, &str2);
417     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
418     str = call_func1(p_basic_string_wchar_data, &str2);
419     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
420
421     call_func3(p_basic_string_wchar_erase, &str2, 1, 2);
422     str = call_func1(p_basic_string_wchar_cstr, &str2);
423     ok(str[0]=='t' && str[1]=='t' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
424     str = call_func1(p_basic_string_wchar_data, &str2);
425     ok(str[0]=='t' && str[1]=='t' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
426     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
427     ok(size == 4, "size = %lu\n", (unsigned long)size);
428
429     call_func3(p_basic_string_wchar_erase, &str2, 1, 100);
430     str = call_func1(p_basic_string_wchar_cstr, &str2);
431     ok(str[0]=='t' && str[1]=='\0', "str = %s\n", wine_dbgstr_w(str));
432     str = call_func1(p_basic_string_wchar_data, &str2);
433     ok(str[0]=='t' && str[1]=='\0', "str = %s\n", wine_dbgstr_w(str));
434     size = (size_t)call_func1(p_basic_string_wchar_size, &str1);
435     ok(size == 4, "size = %lu\n", (unsigned long)size);
436
437     call_func3(p_basic_string_wchar_assign_cstr_len, &str2, test, 4);
438     str = call_func1(p_basic_string_wchar_cstr, &str2);
439     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
440     str = call_func1(p_basic_string_wchar_data, &str2);
441     ok(!memcmp(str, test, 5*sizeof(wchar_t)), "str = %s\n", wine_dbgstr_w(str));
442
443     call_func3(p_basic_string_wchar_assign_cstr_len, &str2, (str+1), 2);
444     str = call_func1(p_basic_string_wchar_cstr, &str2);
445     ok(str[0]=='e' && str[1]=='s' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
446     str = call_func1(p_basic_string_wchar_data, &str2);
447     ok(str[0]=='e' && str[1]=='s' && str[2]=='\0', "str = %s\n", wine_dbgstr_w(str));
448
449     call_func1(p_basic_string_wchar_dtor, &str1);
450     call_func1(p_basic_string_wchar_dtor, &str2);
451 }
452
453 START_TEST(string)
454 {
455     if(!init())
456         return;
457
458     test_basic_string_char();
459     test_basic_string_wchar();
460
461     ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n");
462 }