msvcrt: Save and restore rounding mode in fegetenv() / fesetenv().
[wine.git] / dlls / msvcr120 / tests / msvcr120.c
blob8663fc81ee8e26cd9c933a0baa5c6619c7dccaed
1 /*
2 * Copyright 2014 Yifu Wang for ESRI
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
19 #include <errno.h>
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <wchar.h>
23 #include <stdio.h>
24 #include <float.h>
25 #include <math.h>
26 #include <fenv.h>
27 #include <limits.h>
28 #include <wctype.h>
30 #include <windef.h>
31 #include <winbase.h>
32 #include <winnls.h>
33 #include "wine/test.h"
34 #include <process.h>
36 #include <locale.h>
38 #ifdef __i386__
39 #include "pshpack1.h"
40 struct thiscall_thunk
42 BYTE pop_eax; /* popl %eax (ret addr) */
43 BYTE pop_edx; /* popl %edx (func) */
44 BYTE pop_ecx; /* popl %ecx (this) */
45 BYTE push_eax; /* pushl %eax */
46 WORD jmp_edx; /* jmp *%edx */
48 #include "poppack.h"
50 static ULONG_PTR (WINAPI *call_thiscall_func1)( void *func, void *this );
51 static ULONG_PTR (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
52 static ULONG_PTR (WINAPI *call_thiscall_func3)( void *func,
53 void *this, const void *a, const void *b );
55 static void init_thiscall_thunk(void)
57 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
58 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
59 thunk->pop_eax = 0x58; /* popl %eax */
60 thunk->pop_edx = 0x5a; /* popl %edx */
61 thunk->pop_ecx = 0x59; /* popl %ecx */
62 thunk->push_eax = 0x50; /* pushl %eax */
63 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
64 call_thiscall_func1 = (void *)thunk;
65 call_thiscall_func2 = (void *)thunk;
66 call_thiscall_func3 = (void *)thunk;
69 #define call_func1(func,_this) call_thiscall_func1(func,_this)
70 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
71 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
73 #else
75 #define init_thiscall_thunk()
76 #define call_func1(func,_this) func(_this)
77 #define call_func2(func,_this,a) func(_this,a)
78 #define call_func3(func,_this,a,b) func(_this,a,b)
80 #endif /* __i386__ */
82 #undef __thiscall
83 #ifdef __i386__
84 #define __thiscall __stdcall
85 #else
86 #define __thiscall __cdecl
87 #endif
89 typedef unsigned char MSVCRT_bool;
91 typedef struct cs_queue
93 struct cs_queue *next;
94 BOOL free;
95 int unknown;
96 } cs_queue;
98 typedef struct
100 ULONG_PTR unk_thread_id;
101 cs_queue unk_active;
102 void *unknown[2];
103 cs_queue *head;
104 void *tail;
105 } critical_section;
107 typedef struct
109 critical_section *cs;
110 void *unknown[4];
111 int unknown2[2];
112 } critical_section_scoped_lock;
114 typedef struct {
115 void *chain;
116 critical_section lock;
117 } _Condition_variable;
119 struct MSVCRT_lconv
121 char* decimal_point;
122 char* thousands_sep;
123 char* grouping;
124 char* int_curr_symbol;
125 char* currency_symbol;
126 char* mon_decimal_point;
127 char* mon_thousands_sep;
128 char* mon_grouping;
129 char* positive_sign;
130 char* negative_sign;
131 char int_frac_digits;
132 char frac_digits;
133 char p_cs_precedes;
134 char p_sep_by_space;
135 char n_cs_precedes;
136 char n_sep_by_space;
137 char p_sign_posn;
138 char n_sign_posn;
139 wchar_t* _W_decimal_point;
140 wchar_t* _W_thousands_sep;
141 wchar_t* _W_int_curr_symbol;
142 wchar_t* _W_currency_symbol;
143 wchar_t* _W_mon_decimal_point;
144 wchar_t* _W_mon_thousands_sep;
145 wchar_t* _W_positive_sign;
146 wchar_t* _W_negative_sign;
149 typedef struct
151 unsigned int control;
152 unsigned int status;
153 } fenv_t;
155 typedef struct
157 double r;
158 double i;
159 } _Dcomplex;
161 typedef void (*vtable_ptr)(void);
163 typedef struct {
164 const vtable_ptr *vtable;
165 } Context;
167 typedef struct {
168 Context *ctx;
169 } _Context;
171 static char* (CDECL *p_setlocale)(int category, const char* locale);
172 static struct MSVCRT_lconv* (CDECL *p_localeconv)(void);
173 static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max);
174 static int (CDECL *p__dsign)(double);
175 static int (CDECL *p__fdsign)(float);
176 static int (__cdecl *p__dpcomp)(double x, double y);
177 static wchar_t** (CDECL *p____lc_locale_name_func)(void);
178 static unsigned int (CDECL *p__GetConcurrency)(void);
179 static void* (CDECL *p__W_Gettnames)(void);
180 static void (CDECL *p_free)(void*);
181 static float (CDECL *p_strtof)(const char *, char **);
182 static int (CDECL *p__finite)(double);
183 static float (CDECL *p_wcstof)(const wchar_t*, wchar_t**);
184 static double (CDECL *p_remainder)(double, double);
185 static int* (CDECL *p_errno)(void);
186 static int (CDECL *p_fegetenv)(fenv_t*);
187 static int (CDECL *p_fesetenv)(const fenv_t*);
188 static int (CDECL *p_fegetround)(void);
189 static int (CDECL *p_fesetround)(int);
190 static int (CDECL *p__clearfp)(void);
191 static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *);
192 static void (__cdecl *p_free_locale)(_locale_t);
193 static unsigned short (__cdecl *p_wctype)(const char*);
194 static int (__cdecl *p_vsscanf)(const char*, const char *, __ms_va_list valist);
195 static _Dcomplex* (__cdecl *p__Cbuild)(_Dcomplex*, double, double);
196 static double (__cdecl *p_creal)(_Dcomplex);
197 static double (__cdecl *p_nexttoward)(double, double);
198 static float (__cdecl *p_nexttowardf)(float, double);
199 static double (__cdecl *p_nexttowardl)(double, double);
200 static wctrans_t (__cdecl *p_wctrans)(const char*);
201 static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t);
203 /* make sure we use the correct errno */
204 #undef errno
205 #define errno (*p_errno())
207 static critical_section* (__thiscall *p_critical_section_ctor)(critical_section*);
208 static void (__thiscall *p_critical_section_dtor)(critical_section*);
209 static void (__thiscall *p_critical_section_lock)(critical_section*);
210 static void (__thiscall *p_critical_section_unlock)(critical_section*);
211 static critical_section* (__thiscall *p_critical_section_native_handle)(critical_section*);
212 static MSVCRT_bool (__thiscall *p_critical_section_try_lock)(critical_section*);
213 static MSVCRT_bool (__thiscall *p_critical_section_try_lock_for)(critical_section*, unsigned int);
214 static critical_section_scoped_lock* (__thiscall *p_critical_section_scoped_lock_ctor)
215 (critical_section_scoped_lock*, critical_section *);
216 static void (__thiscall *p_critical_section_scoped_lock_dtor)(critical_section_scoped_lock*);
218 static _Condition_variable* (__thiscall *p__Condition_variable_ctor)(_Condition_variable*);
219 static void (__thiscall *p__Condition_variable_dtor)(_Condition_variable*);
220 static void (__thiscall *p__Condition_variable_wait)(_Condition_variable*, critical_section*);
221 static MSVCRT_bool (__thiscall *p__Condition_variable_wait_for)(_Condition_variable*, critical_section*, unsigned int);
222 static void (__thiscall *p__Condition_variable_notify_one)(_Condition_variable*);
223 static void (__thiscall *p__Condition_variable_notify_all)(_Condition_variable*);
225 static Context* (__cdecl *p_Context_CurrentContext)(void);
226 static _Context* (__cdecl *p__Context__CurrentContext)(_Context*);
228 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y)
229 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
231 static BOOL init(void)
233 HMODULE module;
235 module = LoadLibraryA("msvcr120.dll");
236 if (!module)
238 win_skip("msvcr120.dll not installed\n");
239 return FALSE;
242 p_setlocale = (void*)GetProcAddress(module, "setlocale");
243 p_localeconv = (void*)GetProcAddress(module, "localeconv");
244 p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s");
245 p__dsign = (void*)GetProcAddress(module, "_dsign");
246 p__fdsign = (void*)GetProcAddress(module, "_fdsign");
247 p__dpcomp = (void*)GetProcAddress(module, "_dpcomp");
248 p____lc_locale_name_func = (void*)GetProcAddress(module, "___lc_locale_name_func");
249 p__GetConcurrency = (void*)GetProcAddress(module,"?_GetConcurrency@details@Concurrency@@YAIXZ");
250 p__W_Gettnames = (void*)GetProcAddress(module, "_W_Gettnames");
251 p_free = (void*)GetProcAddress(module, "free");
252 p_strtof = (void*)GetProcAddress(module, "strtof");
253 p__finite = (void*)GetProcAddress(module, "_finite");
254 p_wcstof = (void*)GetProcAddress(module, "wcstof");
255 p_remainder = (void*)GetProcAddress(module, "remainder");
256 p_errno = (void*)GetProcAddress(module, "_errno");
257 p_wcreate_locale = (void*)GetProcAddress(module, "_wcreate_locale");
258 p_free_locale = (void*)GetProcAddress(module, "_free_locale");
259 SET(p_wctype, "wctype");
260 SET(p_fegetenv, "fegetenv");
261 SET(p_fesetenv, "fesetenv");
262 SET(p_fegetround, "fegetround");
263 SET(p_fesetround, "fesetround");
265 SET(p__clearfp, "_clearfp");
266 SET(p_vsscanf, "vsscanf");
267 SET(p__Cbuild, "_Cbuild");
268 SET(p_creal, "creal");
269 SET(p_nexttoward, "nexttoward");
270 SET(p_nexttowardf, "nexttowardf");
271 SET(p_nexttowardl, "nexttowardl");
272 SET(p_wctrans, "wctrans");
273 SET(p_towctrans, "towctrans");
274 SET(p__Context__CurrentContext, "?_CurrentContext@_Context@details@Concurrency@@SA?AV123@XZ");
275 if(sizeof(void*) == 8) { /* 64-bit initialization */
276 SET(p_critical_section_ctor,
277 "??0critical_section@Concurrency@@QEAA@XZ");
278 SET(p_critical_section_dtor,
279 "??1critical_section@Concurrency@@QEAA@XZ");
280 SET(p_critical_section_lock,
281 "?lock@critical_section@Concurrency@@QEAAXXZ");
282 SET(p_critical_section_unlock,
283 "?unlock@critical_section@Concurrency@@QEAAXXZ");
284 SET(p_critical_section_native_handle,
285 "?native_handle@critical_section@Concurrency@@QEAAAEAV12@XZ");
286 SET(p_critical_section_try_lock,
287 "?try_lock@critical_section@Concurrency@@QEAA_NXZ");
288 SET(p_critical_section_try_lock_for,
289 "?try_lock_for@critical_section@Concurrency@@QEAA_NI@Z");
290 SET(p_critical_section_scoped_lock_ctor,
291 "??0scoped_lock@critical_section@Concurrency@@QEAA@AEAV12@@Z");
292 SET(p_critical_section_scoped_lock_dtor,
293 "??1scoped_lock@critical_section@Concurrency@@QEAA@XZ");
294 SET(p__Condition_variable_ctor,
295 "??0_Condition_variable@details@Concurrency@@QEAA@XZ");
296 SET(p__Condition_variable_dtor,
297 "??1_Condition_variable@details@Concurrency@@QEAA@XZ");
298 SET(p__Condition_variable_wait,
299 "?wait@_Condition_variable@details@Concurrency@@QEAAXAEAVcritical_section@3@@Z");
300 SET(p__Condition_variable_wait_for,
301 "?wait_for@_Condition_variable@details@Concurrency@@QEAA_NAEAVcritical_section@3@I@Z");
302 SET(p__Condition_variable_notify_one,
303 "?notify_one@_Condition_variable@details@Concurrency@@QEAAXXZ");
304 SET(p__Condition_variable_notify_all,
305 "?notify_all@_Condition_variable@details@Concurrency@@QEAAXXZ");
306 SET(p_Context_CurrentContext,
307 "?CurrentContext@Context@Concurrency@@SAPEAV12@XZ");
308 } else {
309 #ifdef __arm__
310 SET(p_critical_section_ctor,
311 "??0critical_section@Concurrency@@QAA@XZ");
312 SET(p_critical_section_dtor,
313 "??1critical_section@Concurrency@@QAA@XZ");
314 SET(p_critical_section_lock,
315 "?lock@critical_section@Concurrency@@QAAXXZ");
316 SET(p_critical_section_unlock,
317 "?unlock@critical_section@Concurrency@@QAAXXZ");
318 SET(p_critical_section_native_handle,
319 "?native_handle@critical_section@Concurrency@@QAAAAV12@XZ");
320 SET(p_critical_section_try_lock,
321 "?try_lock@critical_section@Concurrency@@QAA_NXZ");
322 SET(p_critical_section_try_lock_for,
323 "?try_lock_for@critical_section@Concurrency@@QAA_NI@Z");
324 SET(p_critical_section_scoped_lock_ctor,
325 "??0scoped_lock@critical_section@Concurrency@@QAA@AAV12@@Z");
326 SET(p_critical_section_scoped_lock_dtor,
327 "??1scoped_lock@critical_section@Concurrency@@QAA@XZ");
328 SET(p__Condition_variable_ctor,
329 "??0_Condition_variable@details@Concurrency@@QAA@XZ");
330 SET(p__Condition_variable_dtor,
331 "??1_Condition_variable@details@Concurrency@@QAA@XZ");
332 SET(p__Condition_variable_wait,
333 "?wait@_Condition_variable@details@Concurrency@@QAAXAAVcritical_section@3@@Z");
334 SET(p__Condition_variable_wait_for,
335 "?wait_for@_Condition_variable@details@Concurrency@@QAA_NAAVcritical_section@3@I@Z");
336 SET(p__Condition_variable_notify_one,
337 "?notify_one@_Condition_variable@details@Concurrency@@QAAXXZ");
338 SET(p__Condition_variable_notify_all,
339 "?notify_all@_Condition_variable@details@Concurrency@@QAAXXZ");
340 #else
341 SET(p_critical_section_ctor,
342 "??0critical_section@Concurrency@@QAE@XZ");
343 SET(p_critical_section_dtor,
344 "??1critical_section@Concurrency@@QAE@XZ");
345 SET(p_critical_section_lock,
346 "?lock@critical_section@Concurrency@@QAEXXZ");
347 SET(p_critical_section_unlock,
348 "?unlock@critical_section@Concurrency@@QAEXXZ");
349 SET(p_critical_section_native_handle,
350 "?native_handle@critical_section@Concurrency@@QAEAAV12@XZ");
351 SET(p_critical_section_try_lock,
352 "?try_lock@critical_section@Concurrency@@QAE_NXZ");
353 SET(p_critical_section_try_lock_for,
354 "?try_lock_for@critical_section@Concurrency@@QAE_NI@Z");
355 SET(p_critical_section_scoped_lock_ctor,
356 "??0scoped_lock@critical_section@Concurrency@@QAE@AAV12@@Z");
357 SET(p_critical_section_scoped_lock_dtor,
358 "??1scoped_lock@critical_section@Concurrency@@QAE@XZ");
359 SET(p__Condition_variable_ctor,
360 "??0_Condition_variable@details@Concurrency@@QAE@XZ");
361 SET(p__Condition_variable_dtor,
362 "??1_Condition_variable@details@Concurrency@@QAE@XZ");
363 SET(p__Condition_variable_wait,
364 "?wait@_Condition_variable@details@Concurrency@@QAEXAAVcritical_section@3@@Z");
365 SET(p__Condition_variable_wait_for,
366 "?wait_for@_Condition_variable@details@Concurrency@@QAE_NAAVcritical_section@3@I@Z");
367 SET(p__Condition_variable_notify_one,
368 "?notify_one@_Condition_variable@details@Concurrency@@QAEXXZ");
369 SET(p__Condition_variable_notify_all,
370 "?notify_all@_Condition_variable@details@Concurrency@@QAEXXZ");
371 #endif
372 SET(p_Context_CurrentContext,
373 "?CurrentContext@Context@Concurrency@@SAPAV12@XZ");
376 init_thiscall_thunk();
377 return TRUE;
380 static void test_lconv_helper(const char *locstr)
382 struct MSVCRT_lconv *lconv;
383 char mbs[256];
384 size_t i;
386 if(!p_setlocale(LC_ALL, locstr))
388 win_skip("locale %s not available\n", locstr);
389 return;
392 lconv = p_localeconv();
394 /* If multi-byte version available, asserts that wide char version also available.
395 * If wide char version can be converted to a multi-byte string , asserts that the
396 * conversion result is the same as the multi-byte version.
398 if(strlen(lconv->decimal_point) > 0)
399 ok(wcslen(lconv->_W_decimal_point) > 0, "%s: decimal_point\n", locstr);
400 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_decimal_point, 256) == 0)
401 ok(strcmp(mbs, lconv->decimal_point) == 0, "%s: decimal_point\n", locstr);
403 if(strlen(lconv->thousands_sep) > 0)
404 ok(wcslen(lconv->_W_thousands_sep) > 0, "%s: thousands_sep\n", locstr);
405 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_thousands_sep, 256) == 0)
406 ok(strcmp(mbs, lconv->thousands_sep) == 0, "%s: thousands_sep\n", locstr);
408 if(strlen(lconv->int_curr_symbol) > 0)
409 ok(wcslen(lconv->_W_int_curr_symbol) > 0, "%s: int_curr_symbol\n", locstr);
410 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_int_curr_symbol, 256) == 0)
411 ok(strcmp(mbs, lconv->int_curr_symbol) == 0, "%s: int_curr_symbol\n", locstr);
413 if(strlen(lconv->currency_symbol) > 0)
414 ok(wcslen(lconv->_W_currency_symbol) > 0, "%s: currency_symbol\n", locstr);
415 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_currency_symbol, 256) == 0)
416 ok(strcmp(mbs, lconv->currency_symbol) == 0, "%s: currency_symbol\n", locstr);
418 if(strlen(lconv->mon_decimal_point) > 0)
419 ok(wcslen(lconv->_W_mon_decimal_point) > 0, "%s: decimal_point\n", locstr);
420 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_mon_decimal_point, 256) == 0)
421 ok(strcmp(mbs, lconv->mon_decimal_point) == 0, "%s: decimal_point\n", locstr);
423 if(strlen(lconv->positive_sign) > 0)
424 ok(wcslen(lconv->_W_positive_sign) > 0, "%s: positive_sign\n", locstr);
425 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_positive_sign, 256) == 0)
426 ok(strcmp(mbs, lconv->positive_sign) == 0, "%s: positive_sign\n", locstr);
428 if(strlen(lconv->negative_sign) > 0)
429 ok(wcslen(lconv->_W_negative_sign) > 0, "%s: negative_sign\n", locstr);
430 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_negative_sign, 256) == 0)
431 ok(strcmp(mbs, lconv->negative_sign) == 0, "%s: negative_sign\n", locstr);
434 static void test_lconv(void)
436 int i;
437 const char *locstrs[] =
439 "American", "Belgian", "Chinese",
440 "Dutch", "English", "French",
441 "German", "Hungarian", "Icelandic",
442 "Japanese", "Korean", "Spanish"
445 for(i = 0; i < ARRAY_SIZE(locstrs); i ++)
446 test_lconv_helper(locstrs[i]);
449 static void test__dsign(void)
451 int ret;
453 ret = p__dsign(1);
454 ok(ret == 0, "p_dsign(1) = %x\n", ret);
455 ret = p__dsign(0);
456 ok(ret == 0, "p_dsign(0) = %x\n", ret);
457 ret = p__dsign(-1);
458 ok(ret == 0x8000, "p_dsign(-1) = %x\n", ret);
460 ret = p__fdsign(1);
461 ok(ret == 0, "p_fdsign(1) = %x\n", ret);
462 ret = p__fdsign(0);
463 ok(ret == 0, "p_fdsign(0) = %x\n", ret);
464 ret = p__fdsign(-1);
465 ok(ret == 0x8000, "p_fdsign(-1) = %x\n", ret);
468 static void test__dpcomp(void)
470 struct {
471 double x, y;
472 int ret;
473 } tests[] = {
474 {0, 0, 2}, {1, 1, 2}, {-1, -1, 2},
475 {-2, -1, 1}, {-1, 1, 1}, {1, 2, 1},
476 {1, -1, 4}, {2, 1, 4}, {-1, -2, 4},
477 {NAN, NAN, 0}, {NAN, 1, 0}, {1, NAN, 0},
478 {INFINITY, INFINITY, 2}, {-1, INFINITY, 1}, {1, INFINITY, 1},
480 int i, ret;
482 for(i=0; i<ARRAY_SIZE(tests); i++) {
483 ret = p__dpcomp(tests[i].x, tests[i].y);
484 ok(ret == tests[i].ret, "%d) dpcomp(%f, %f) = %x\n", i, tests[i].x, tests[i].y, ret);
488 static void test____lc_locale_name_func(void)
490 struct {
491 const char *locale;
492 const WCHAR name[10];
493 const WCHAR broken_name[10];
494 } tests[] = {
495 { "American", {'e','n',0}, {'e','n','-','U','S',0} },
496 { "Belgian", {'n','l','-','B','E',0} },
497 { "Chinese", {'z','h',0}, {'z','h','-','C','N',0} },
498 { "Dutch", {'n','l',0}, {'n','l','-','N','L',0} },
499 { "English", {'e','n',0}, {'e','n','-','U','S',0} },
500 { "French", {'f','r',0}, {'f','r','-','F','R',0} },
501 { "German", {'d','e',0}, {'d','e','-','D','E',0} },
502 { "Hungarian", {'h','u',0}, {'h','u','-','H','U',0} },
503 { "Icelandic", {'i','s',0}, {'i','s','-','I','S',0} },
504 { "Japanese", {'j','a',0}, {'j','a','-','J','P',0} },
505 { "Korean", {'k','o',0}, {'k','o','-','K','R',0} }
507 int i, j;
508 wchar_t **lc_names;
510 for(i=0; i<ARRAY_SIZE(tests); i++) {
511 if(!p_setlocale(LC_ALL, tests[i].locale))
512 continue;
514 lc_names = p____lc_locale_name_func();
515 ok(lc_names[0] == NULL, "%d - lc_names[0] = %s\n", i, wine_dbgstr_w(lc_names[0]));
516 ok(!lstrcmpW(lc_names[1], tests[i].name) || broken(!lstrcmpW(lc_names[1], tests[i].broken_name)),
517 "%d - lc_names[1] = %s\n", i, wine_dbgstr_w(lc_names[1]));
519 for(j=LC_MIN+2; j<=LC_MAX; j++) {
520 ok(!lstrcmpW(lc_names[1], lc_names[j]), "%d - lc_names[%d] = %s, expected %s\n",
521 i, j, wine_dbgstr_w(lc_names[j]), wine_dbgstr_w(lc_names[1]));
525 p_setlocale(LC_ALL, "C");
526 lc_names = p____lc_locale_name_func();
527 ok(!lc_names[1], "___lc_locale_name_func()[1] = %s\n", wine_dbgstr_w(lc_names[1]));
530 static void test__GetConcurrency(void)
532 SYSTEM_INFO si;
533 unsigned int c;
535 GetSystemInfo(&si);
536 c = (*p__GetConcurrency)();
537 ok(c == si.dwNumberOfProcessors, "expected %u, got %u\n", si.dwNumberOfProcessors, c);
540 static void test__W_Gettnames(void)
542 static const char *str[] = {
543 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
544 "Sunday", "Monday", "Tuesday", "Wednesday",
545 "Thursday", "Friday", "Saturday",
546 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
547 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
548 "January", "February", "March", "April", "May", "June", "July",
549 "August", "September", "October", "November", "December",
550 "AM", "PM", "M/d/yyyy"
553 struct {
554 char *str[43];
555 int unk[2];
556 wchar_t *wstr[43];
557 wchar_t *locname;
558 char data[1];
559 } *ret;
560 int i, size;
561 WCHAR buf[64];
563 if(!p_setlocale(LC_ALL, "english"))
564 return;
566 ret = p__W_Gettnames();
567 size = ret->str[0]-(char*)ret;
568 if(sizeof(void*) == 8)
569 ok(size==0x2c0, "structure size: %x\n", size);
570 else
571 ok(size==0x164, "structure size: %x\n", size);
573 for(i=0; i<ARRAY_SIZE(str); i++) {
574 ok(!strcmp(ret->str[i], str[i]), "ret->str[%d] = %s, expected %s\n",
575 i, ret->str[i], str[i]);
577 MultiByteToWideChar(CP_ACP, 0, str[i], strlen(str[i])+1, buf, ARRAY_SIZE(buf));
578 ok(!lstrcmpW(ret->wstr[i], buf), "ret->wstr[%d] = %s, expected %s\n",
579 i, wine_dbgstr_w(ret->wstr[i]), wine_dbgstr_w(buf));
581 p_free(ret);
583 p_setlocale(LC_ALL, "C");
586 static void test__strtof(void)
588 const char float1[] = "12.0";
589 const char float2[] = "3.402823466e+38"; /* FLT_MAX */
590 const char float3[] = "-3.402823466e+38";
591 const char float4[] = "1.7976931348623158e+308"; /* DBL_MAX */
593 const WCHAR twelve[] = {'1','2','.','0',0};
594 const WCHAR arabic23[] = { 0x662, 0x663, 0};
596 char *end;
597 float f;
599 f = p_strtof(float1, &end);
600 ok(f == 12.0, "f = %lf\n", f);
601 ok(end == float1+4, "incorrect end (%d)\n", (int)(end-float1));
603 f = p_strtof(float2, &end);
604 ok(f == FLT_MAX, "f = %lf\n", f);
605 ok(end == float2+15, "incorrect end (%d)\n", (int)(end-float2));
607 f = p_strtof(float3, &end);
608 ok(f == -FLT_MAX, "f = %lf\n", f);
609 ok(end == float3+16, "incorrect end (%d)\n", (int)(end-float3));
611 f = p_strtof(float4, &end);
612 ok(!p__finite(f), "f = %lf\n", f);
613 ok(end == float4+23, "incorrect end (%d)\n", (int)(end-float4));
615 f = p_strtof("inf", NULL);
616 ok(f == 0, "f = %lf\n", f);
618 f = p_strtof("INF", NULL);
619 ok(f == 0, "f = %lf\n", f);
621 f = p_strtof("1.#inf", NULL);
622 ok(f == 1, "f = %lf\n", f);
624 f = p_strtof("INFINITY", NULL);
625 ok(f == 0, "f = %lf\n", f);
627 f = p_strtof("0x12", NULL);
628 ok(f == 0, "f = %lf\n", f);
630 f = p_wcstof(twelve, NULL);
631 ok(f == 12.0, "f = %lf\n", f);
633 f = p_wcstof(arabic23, NULL);
634 ok(f == 0, "f = %lf\n", f);
636 if(!p_setlocale(LC_ALL, "Arabic")) {
637 win_skip("Arabic locale not available\n");
638 return;
641 f = p_wcstof(twelve, NULL);
642 ok(f == 12.0, "f = %lf\n", f);
644 f = p_wcstof(arabic23, NULL);
645 ok(f == 0, "f = %lf\n", f);
647 p_setlocale(LC_ALL, "C");
650 static void test_remainder(void)
652 struct {
653 double x, y, r;
654 errno_t e;
655 } tests[] = {
656 { 3.0, 2.0, -1.0, -1 },
657 { 1.0, 1.0, 0.0, -1 },
658 { INFINITY, 0.0, NAN, EDOM },
659 { INFINITY, 42.0, NAN, EDOM },
660 { NAN, 0.0, NAN, EDOM },
661 { NAN, 42.0, NAN, EDOM },
662 { 0.0, INFINITY, 0.0, -1 },
663 { 42.0, INFINITY, 42.0, -1 },
664 { 0.0, NAN, NAN, EDOM },
665 { 42.0, NAN, NAN, EDOM },
666 { 1.0, 0.0, NAN, EDOM },
667 { INFINITY, INFINITY, NAN, EDOM },
669 errno_t e;
670 double r;
671 int i;
673 if(sizeof(void*) != 8) /* errno handling slightly different on 32-bit */
674 return;
676 for(i=0; i<ARRAY_SIZE(tests); i++) {
677 errno = -1;
678 r = p_remainder(tests[i].x, tests[i].y);
679 e = errno;
681 ok(tests[i].e == e, "expected errno %i, but got %i\n", tests[i].e, e);
682 if(_isnan(tests[i].r))
683 ok(_isnan(r), "expected NAN, but got %f\n", r);
684 else
685 ok(tests[i].r == r, "expected result %f, but got %f\n", tests[i].r, r);
689 static int enter_flag;
690 static critical_section cs;
691 static unsigned __stdcall test_critical_section_lock(void *arg)
693 critical_section *native_handle;
694 native_handle = (critical_section*)call_func1(p_critical_section_native_handle, &cs);
695 ok(native_handle == &cs, "native_handle = %p\n", native_handle);
696 call_func1(p_critical_section_lock, &cs);
697 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
698 call_func1(p_critical_section_unlock, &cs);
699 return 0;
702 static unsigned __stdcall test_critical_section_try_lock(void *arg)
704 ok(!(MSVCRT_bool)call_func1(p_critical_section_try_lock, &cs),
705 "critical_section_try_lock succeeded\n");
706 return 0;
709 static unsigned __stdcall test_critical_section_try_lock_for(void *arg)
711 ok((MSVCRT_bool)call_func2(p_critical_section_try_lock_for, &cs, 5000),
712 "critical_section_try_lock_for failed\n");
713 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
714 call_func1(p_critical_section_unlock, &cs);
715 return 0;
718 static unsigned __stdcall test_critical_section_scoped_lock(void *arg)
720 critical_section_scoped_lock counter_scope_lock;
722 call_func2(p_critical_section_scoped_lock_ctor, &counter_scope_lock, &cs);
723 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
724 call_func1(p_critical_section_scoped_lock_dtor, &counter_scope_lock);
725 return 0;
728 static void test_critical_section(void)
730 HANDLE thread;
731 DWORD ret;
733 enter_flag = 0;
734 call_func1(p_critical_section_ctor, &cs);
735 call_func1(p_critical_section_lock, &cs);
736 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_lock, NULL, 0, NULL);
737 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
738 ret = WaitForSingleObject(thread, 100);
739 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d\n", ret);
740 enter_flag = 1;
741 call_func1(p_critical_section_unlock, &cs);
742 ret = WaitForSingleObject(thread, INFINITE);
743 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
744 ret = CloseHandle(thread);
745 ok(ret, "CloseHandle failed\n");
747 ok((MSVCRT_bool)call_func1(p_critical_section_try_lock, &cs),
748 "critical_section_try_lock failed\n");
749 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock, NULL, 0, NULL);
750 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
751 ret = WaitForSingleObject(thread, INFINITE);
752 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
753 ret = CloseHandle(thread);
754 ok(ret, "CloseHandle failed\n");
755 call_func1(p_critical_section_unlock, &cs);
757 enter_flag = 0;
758 ok((MSVCRT_bool)call_func2(p_critical_section_try_lock_for, &cs, 50),
759 "critical_section_try_lock_for failed\n");
760 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock, NULL, 0, NULL);
761 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
762 ret = WaitForSingleObject(thread, INFINITE);
763 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
764 ret = CloseHandle(thread);
765 ok(ret, "CloseHandle failed\n");
766 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock_for, NULL, 0, NULL);
767 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
768 enter_flag = 1;
769 Sleep(10);
770 call_func1(p_critical_section_unlock, &cs);
771 ret = WaitForSingleObject(thread, INFINITE);
772 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
773 ret = CloseHandle(thread);
774 ok(ret, "CloseHandle failed\n");
776 enter_flag = 0;
777 call_func1(p_critical_section_lock, &cs);
778 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_scoped_lock, NULL, 0, NULL);
779 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
780 ret = WaitForSingleObject(thread, 100);
781 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d\n", ret);
782 enter_flag = 1;
783 call_func1(p_critical_section_unlock, &cs);
784 ret = WaitForSingleObject(thread, INFINITE);
785 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
786 ret = CloseHandle(thread);
787 ok(ret, "CloseHandle failed\n");
788 call_func1(p_critical_section_dtor, &cs);
791 static void test_feenv(void)
793 fenv_t env, env2;
794 int ret;
796 p__clearfp();
798 ret = p_fegetenv(&env);
799 ok(!ret, "fegetenv returned %x\n", ret);
800 p_fesetround(FE_UPWARD);
801 ok(env.control == (_EM_INEXACT|_EM_UNDERFLOW|_EM_OVERFLOW|_EM_ZERODIVIDE|_EM_INVALID),
802 "env.control = %x\n", env.control);
803 ok(!env.status, "env.status = %x\n", env.status);
804 ret = p_fegetenv(&env2);
805 ok(!ret, "fegetenv returned %x\n", ret);
806 ok(env2.control == (_EM_INEXACT|_EM_UNDERFLOW|_EM_OVERFLOW|_EM_ZERODIVIDE|_EM_INVALID | FE_UPWARD),
807 "env2.control = %x\n", env2.control);
808 ret = p_fesetenv(&env);
809 ok(!ret, "fesetenv returned %x\n", ret);
810 ret = p_fegetround();
811 ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret);
814 static void test__wcreate_locale(void)
816 static const wchar_t c_locale[] = {'C',0};
817 static const wchar_t bogus[] = {'b','o','g','u','s',0};
818 static const wchar_t empty[] = {0};
819 _locale_t lcl;
820 errno_t e;
822 /* simple success */
823 errno = -1;
824 lcl = p_wcreate_locale(LC_ALL, c_locale);
825 e = errno;
826 ok(!!lcl, "expected success, but got NULL\n");
827 ok(errno == -1, "expected errno -1, but got %i\n", e);
828 p_free_locale(lcl);
830 errno = -1;
831 lcl = p_wcreate_locale(LC_ALL, empty);
832 e = errno;
833 ok(!!lcl, "expected success, but got NULL\n");
834 ok(errno == -1, "expected errno -1, but got %i\n", e);
835 p_free_locale(lcl);
837 /* bogus category */
838 errno = -1;
839 lcl = p_wcreate_locale(-1, c_locale);
840 e = errno;
841 ok(!lcl, "expected failure, but got %p\n", lcl);
842 ok(errno == -1, "expected errno -1, but got %i\n", e);
844 /* bogus names */
845 errno = -1;
846 lcl = p_wcreate_locale(LC_ALL, bogus);
847 e = errno;
848 ok(!lcl, "expected failure, but got %p\n", lcl);
849 ok(errno == -1, "expected errno -1, but got %i\n", e);
851 errno = -1;
852 lcl = p_wcreate_locale(LC_ALL, NULL);
853 e = errno;
854 ok(!lcl, "expected failure, but got %p\n", lcl);
855 ok(errno == -1, "expected errno -1, but got %i\n", e);
858 struct wait_thread_arg
860 critical_section *cs;
861 _Condition_variable *cv;
862 HANDLE thread_initialized;
865 static DWORD WINAPI condition_variable_wait_thread(void *varg)
867 struct wait_thread_arg *arg = varg;
869 call_func1(p_critical_section_lock, arg->cs);
870 SetEvent(arg->thread_initialized);
871 call_func2(p__Condition_variable_wait, arg->cv, arg->cs);
872 call_func1(p_critical_section_unlock, arg->cs);
873 return 0;
876 static void test__Condition_variable(void)
878 critical_section cs;
879 _Condition_variable cv;
880 HANDLE thread_initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
881 struct wait_thread_arg wait_thread_arg = { &cs, &cv, thread_initialized };
882 HANDLE threads[2];
883 DWORD ret;
884 MSVCRT_bool b;
886 ok(thread_initialized != NULL, "CreateEvent failed\n");
888 call_func1(p_critical_section_ctor, &cs);
889 call_func1(p__Condition_variable_ctor, &cv);
891 call_func1(p__Condition_variable_notify_one, &cv);
892 call_func1(p__Condition_variable_notify_all, &cv);
894 threads[0] = CreateThread(0, 0, condition_variable_wait_thread,
895 &wait_thread_arg, 0, 0);
896 ok(threads[0] != NULL, "CreateThread failed\n");
897 WaitForSingleObject(thread_initialized, INFINITE);
898 call_func1(p_critical_section_lock, &cs);
899 call_func1(p_critical_section_unlock, &cs);
901 threads[1] = CreateThread(0, 0, condition_variable_wait_thread,
902 &wait_thread_arg, 0, 0);
903 ok(threads[1] != NULL, "CreateThread failed\n");
904 WaitForSingleObject(thread_initialized, INFINITE);
905 call_func1(p_critical_section_lock, &cs);
906 call_func1(p_critical_section_unlock, &cs);
908 call_func1(p__Condition_variable_notify_one, &cv);
909 ret = WaitForSingleObject(threads[1], 500);
910 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
911 call_func1(p__Condition_variable_notify_one, &cv);
912 ret = WaitForSingleObject(threads[0], 500);
913 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
915 CloseHandle(threads[0]);
916 CloseHandle(threads[1]);
918 call_func1(p_critical_section_lock, &cs);
919 b = call_func3(p__Condition_variable_wait_for, &cv, &cs, 1);
920 ok(!b, "_Condition_variable_wait_for returned TRUE\n");
921 call_func1(p_critical_section_unlock, &cs);
923 call_func1(p_critical_section_dtor, &cs);
924 call_func1(p__Condition_variable_dtor, &cv);
926 CloseHandle(thread_initialized);
929 static void test_wctype(void)
931 static const struct {
932 const char *name;
933 unsigned short mask;
934 } properties[] = {
935 { "alnum", 0x107 },
936 { "alpha", 0x103 },
937 { "cntrl", 0x020 },
938 { "digit", 0x004 },
939 { "graph", 0x117 },
940 { "lower", 0x002 },
941 { "print", 0x157 },
942 { "punct", 0x010 },
943 { "space", 0x008 },
944 { "upper", 0x001 },
945 { "xdigit", 0x080 },
946 { "ALNUM", 0x000 },
947 { "Alnum", 0x000 },
948 { "", 0x000 }
950 int i, ret;
952 for(i=0; i<ARRAY_SIZE(properties); i++) {
953 ret = p_wctype(properties[i].name);
954 ok(properties[i].mask == ret, "%d - Expected %x, got %x\n", i, properties[i].mask, ret);
958 static int WINAPIV _vsscanf_wrapper(const char *buffer, const char *format, ...)
960 int ret;
961 __ms_va_list valist;
962 __ms_va_start(valist, format);
963 ret = p_vsscanf(buffer, format, valist);
964 __ms_va_end(valist);
965 return ret;
968 static void test_vsscanf(void)
970 static const char *fmt = "%d";
971 char buff[16];
972 int ret, v;
974 v = 0;
975 strcpy(buff, "10");
976 ret = _vsscanf_wrapper(buff, fmt, &v);
977 ok(ret == 1, "Unexpected ret %d.\n", ret);
978 ok(v == 10, "got %d.\n", v);
981 static void test__Cbuild(void)
983 _Dcomplex c;
984 double d;
986 memset(&c, 0, sizeof(c));
987 p__Cbuild(&c, 1.0, 2.0);
988 ok(c.r == 1.0, "c.r = %lf\n", c.r);
989 ok(c.i == 2.0, "c.i = %lf\n", c.i);
990 d = p_creal(c);
991 ok(d == 1.0, "creal returned %lf\n", d);
993 p__Cbuild(&c, 3.0, NAN);
994 ok(c.r == 3.0, "c.r = %lf\n", c.r);
995 ok(_isnan(c.i), "c.i = %lf\n", c.i);
996 d = p_creal(c);
997 ok(d == 3.0, "creal returned %lf\n", d);
1000 static void test_nexttoward(void)
1002 errno_t e;
1003 double d;
1004 float f;
1005 int i;
1007 struct
1009 double source;
1010 double dir;
1011 float f;
1012 double d;
1014 tests[] =
1016 {0.0, 0.0, 0.0f, 0.0},
1017 {0.0, 1.0, 1.0e-45f, 5.0e-324},
1018 {0.0, -1.0, -1.0e-45f, -5.0e-324},
1019 {2.2250738585072009e-308, 0.0, 0.0f, 2.2250738585072004e-308},
1020 {2.2250738585072009e-308, 2.2250738585072010e-308, 1.0e-45f, 2.2250738585072009e-308},
1021 {2.2250738585072009e-308, 1.0, 1.0e-45f, 2.2250738585072014e-308},
1022 {2.2250738585072014e-308, 0.0, 0.0f, 2.2250738585072009e-308},
1023 {2.2250738585072014e-308, 2.2250738585072014e-308, 1.0e-45f, 2.2250738585072014e-308},
1024 {2.2250738585072014e-308, 1.0, 1.0e-45f, 2.2250738585072019e-308},
1025 {1.0, 2.0, 1.00000012f, 1.0000000000000002},
1026 {1.0, 0.0, 0.99999994f, 0.9999999999999999},
1027 {1.0, 1.0, 1.0f, 1.0},
1028 {0.0, INFINITY, 1.0e-45f, 5.0e-324},
1029 {FLT_MAX, INFINITY, INFINITY, 3.402823466385289e+038},
1030 {DBL_MAX, INFINITY, INFINITY, INFINITY},
1031 {INFINITY, INFINITY, INFINITY, INFINITY},
1032 {INFINITY, 0, FLT_MAX, DBL_MAX},
1035 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1037 f = p_nexttowardf(tests[i].source, tests[i].dir);
1038 ok(f == tests[i].f, "Test %d: expected %0.8ef, got %0.8ef.\n", i, tests[i].f, f);
1040 errno = -1;
1041 d = p_nexttoward(tests[i].source, tests[i].dir);
1042 e = errno;
1043 ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
1044 if (!isnormal(d) && !isinf(tests[i].source))
1045 ok(e == ERANGE, "Test %d: expected ERANGE, got %d.\n", i, e);
1046 else
1047 ok(e == -1, "Test %d: expected no error, got %d.\n", i, e);
1049 d = p_nexttowardl(tests[i].source, tests[i].dir);
1050 ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
1053 errno = -1;
1054 d = p_nexttoward(NAN, 0);
1055 e = errno;
1056 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1057 ok(e == -1, "Expected no error, got %d.\n", e);
1059 errno = -1;
1060 d = p_nexttoward(NAN, NAN);
1061 e = errno;
1062 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1063 ok(e == -1, "Expected no error, got %d.\n", e);
1065 errno = -1;
1066 d = p_nexttoward(0, NAN);
1067 e = errno;
1068 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1069 ok(e == -1, "Expected no error, got %d.\n", e);
1072 static void test_towctrans(void)
1074 wchar_t ret;
1076 ret = p_wctrans("tolower");
1077 ok(ret == 2, "wctrans returned %d, expected 2\n", ret);
1078 ret = p_wctrans("toupper");
1079 ok(ret == 1, "wctrans returned %d, expected 1\n", ret);
1080 ret = p_wctrans("toLower");
1081 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1082 ret = p_wctrans("");
1083 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1084 if(0) { /* crashes on windows */
1085 ret = p_wctrans(NULL);
1086 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1089 ret = p_towctrans('t', 2);
1090 ok(ret == 't', "towctrans('t', 2) returned %c, expected t\n", ret);
1091 ret = p_towctrans('T', 2);
1092 ok(ret == 't', "towctrans('T', 2) returned %c, expected t\n", ret);
1093 ret = p_towctrans('T', 0);
1094 ok(ret == 't', "towctrans('T', 0) returned %c, expected t\n", ret);
1095 ret = p_towctrans('T', 3);
1096 ok(ret == 't', "towctrans('T', 3) returned %c, expected t\n", ret);
1097 ret = p_towctrans('t', 1);
1098 ok(ret == 'T', "towctrans('t', 1) returned %c, expected T\n", ret);
1099 ret = p_towctrans('T', 1);
1100 ok(ret == 'T', "towctrans('T', 1) returned %c, expected T\n", ret);
1103 static void test_CurrentContext(void)
1105 _Context _ctx, *ret;
1106 Context *ctx;
1108 ctx = p_Context_CurrentContext();
1109 ok(!!ctx, "got NULL\n");
1111 memset(&_ctx, 0xcc, sizeof(_ctx));
1112 ret = p__Context__CurrentContext(&_ctx);
1113 ok(_ctx.ctx == ctx, "expected %p, got %p\n", ctx, _ctx.ctx);
1114 ok(ret == &_ctx, "expected %p, got %p\n", &_ctx, ret);
1117 START_TEST(msvcr120)
1119 if (!init()) return;
1120 test__strtof();
1121 test_lconv();
1122 test__dsign();
1123 test__dpcomp();
1124 test____lc_locale_name_func();
1125 test__GetConcurrency();
1126 test__W_Gettnames();
1127 test__strtof();
1128 test_remainder();
1129 test_critical_section();
1130 test_feenv();
1131 test__wcreate_locale();
1132 test__Condition_variable();
1133 test_wctype();
1134 test_vsscanf();
1135 test__Cbuild();
1136 test_nexttoward();
1137 test_towctrans();
1138 test_CurrentContext();