mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / msvcr120 / tests / msvcr120.c
blob151989f8f7458523fd781802e3b77782f853f931
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 double r;
152 double i;
153 } _Dcomplex;
155 typedef void (*vtable_ptr)(void);
157 typedef struct {
158 const vtable_ptr *vtable;
159 } Context;
161 typedef struct {
162 Context *ctx;
163 } _Context;
165 static char* (CDECL *p_setlocale)(int category, const char* locale);
166 static struct MSVCRT_lconv* (CDECL *p_localeconv)(void);
167 static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max);
168 static int (CDECL *p__dsign)(double);
169 static int (CDECL *p__fdsign)(float);
170 static int (__cdecl *p__dpcomp)(double x, double y);
171 static wchar_t** (CDECL *p____lc_locale_name_func)(void);
172 static unsigned int (CDECL *p__GetConcurrency)(void);
173 static void* (CDECL *p__W_Gettnames)(void);
174 static void* (CDECL *p__Gettnames)(void);
175 static void (CDECL *p_free)(void*);
176 static float (CDECL *p_strtof)(const char *, char **);
177 static int (CDECL *p__finite)(double);
178 static float (CDECL *p_wcstof)(const wchar_t*, wchar_t**);
179 static double (CDECL *p_remainder)(double, double);
180 static int* (CDECL *p_errno)(void);
181 static int (CDECL *p_fegetenv)(fenv_t*);
182 static int (CDECL *p_fesetenv)(const fenv_t*);
183 static int (CDECL *p_fegetround)(void);
184 static int (CDECL *p_fesetround)(int);
185 static int (CDECL *p_fegetexceptflag)(fexcept_t*,int);
186 static int (CDECL *p_fesetexceptflag)(const fexcept_t*,int);
187 static int (CDECL *p_fetestexcept)(int);
188 static int (CDECL *p_feclearexcept)(int);
189 static int (CDECL *p__clearfp)(void);
190 static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *);
191 static void (__cdecl *p_free_locale)(_locale_t);
192 static unsigned short (__cdecl *p_wctype)(const char*);
193 static int (__cdecl *p_vsscanf)(const char*, const char *, __ms_va_list valist);
194 static _Dcomplex* (__cdecl *p__Cbuild)(_Dcomplex*, double, double);
195 static double (__cdecl *p_creal)(_Dcomplex);
196 static double (__cdecl *p_nexttoward)(double, double);
197 static float (__cdecl *p_nexttowardf)(float, double);
198 static double (__cdecl *p_nexttowardl)(double, double);
199 static wctrans_t (__cdecl *p_wctrans)(const char*);
200 static wint_t (__cdecl *p_towctrans)(wint_t, wctrans_t);
202 /* make sure we use the correct errno */
203 #undef errno
204 #define errno (*p_errno())
206 static critical_section* (__thiscall *p_critical_section_ctor)(critical_section*);
207 static void (__thiscall *p_critical_section_dtor)(critical_section*);
208 static void (__thiscall *p_critical_section_lock)(critical_section*);
209 static void (__thiscall *p_critical_section_unlock)(critical_section*);
210 static critical_section* (__thiscall *p_critical_section_native_handle)(critical_section*);
211 static MSVCRT_bool (__thiscall *p_critical_section_try_lock)(critical_section*);
212 static MSVCRT_bool (__thiscall *p_critical_section_try_lock_for)(critical_section*, unsigned int);
213 static critical_section_scoped_lock* (__thiscall *p_critical_section_scoped_lock_ctor)
214 (critical_section_scoped_lock*, critical_section *);
215 static void (__thiscall *p_critical_section_scoped_lock_dtor)(critical_section_scoped_lock*);
217 static _Condition_variable* (__thiscall *p__Condition_variable_ctor)(_Condition_variable*);
218 static void (__thiscall *p__Condition_variable_dtor)(_Condition_variable*);
219 static void (__thiscall *p__Condition_variable_wait)(_Condition_variable*, critical_section*);
220 static MSVCRT_bool (__thiscall *p__Condition_variable_wait_for)(_Condition_variable*, critical_section*, unsigned int);
221 static void (__thiscall *p__Condition_variable_notify_one)(_Condition_variable*);
222 static void (__thiscall *p__Condition_variable_notify_all)(_Condition_variable*);
224 static Context* (__cdecl *p_Context_CurrentContext)(void);
225 static _Context* (__cdecl *p__Context__CurrentContext)(_Context*);
227 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y)
228 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
230 static BOOL init(void)
232 HMODULE module;
234 module = LoadLibraryA("msvcr120.dll");
235 if (!module)
237 win_skip("msvcr120.dll not installed\n");
238 return FALSE;
241 p_setlocale = (void*)GetProcAddress(module, "setlocale");
242 p_localeconv = (void*)GetProcAddress(module, "localeconv");
243 p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s");
244 p__dsign = (void*)GetProcAddress(module, "_dsign");
245 p__fdsign = (void*)GetProcAddress(module, "_fdsign");
246 p__dpcomp = (void*)GetProcAddress(module, "_dpcomp");
247 p____lc_locale_name_func = (void*)GetProcAddress(module, "___lc_locale_name_func");
248 p__GetConcurrency = (void*)GetProcAddress(module,"?_GetConcurrency@details@Concurrency@@YAIXZ");
249 p__W_Gettnames = (void*)GetProcAddress(module, "_W_Gettnames");
250 p__Gettnames = (void*)GetProcAddress(module, "_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");
264 SET(p_fegetexceptflag, "fegetexceptflag");
265 SET(p_fesetexceptflag, "fesetexceptflag");
266 SET(p_fetestexcept, "fetestexcept");
267 SET(p_feclearexcept, "feclearexcept");
269 SET(p__clearfp, "_clearfp");
270 SET(p_vsscanf, "vsscanf");
271 SET(p__Cbuild, "_Cbuild");
272 SET(p_creal, "creal");
273 SET(p_nexttoward, "nexttoward");
274 SET(p_nexttowardf, "nexttowardf");
275 SET(p_nexttowardl, "nexttowardl");
276 SET(p_wctrans, "wctrans");
277 SET(p_towctrans, "towctrans");
278 SET(p__Context__CurrentContext, "?_CurrentContext@_Context@details@Concurrency@@SA?AV123@XZ");
279 if(sizeof(void*) == 8) { /* 64-bit initialization */
280 SET(p_critical_section_ctor,
281 "??0critical_section@Concurrency@@QEAA@XZ");
282 SET(p_critical_section_dtor,
283 "??1critical_section@Concurrency@@QEAA@XZ");
284 SET(p_critical_section_lock,
285 "?lock@critical_section@Concurrency@@QEAAXXZ");
286 SET(p_critical_section_unlock,
287 "?unlock@critical_section@Concurrency@@QEAAXXZ");
288 SET(p_critical_section_native_handle,
289 "?native_handle@critical_section@Concurrency@@QEAAAEAV12@XZ");
290 SET(p_critical_section_try_lock,
291 "?try_lock@critical_section@Concurrency@@QEAA_NXZ");
292 SET(p_critical_section_try_lock_for,
293 "?try_lock_for@critical_section@Concurrency@@QEAA_NI@Z");
294 SET(p_critical_section_scoped_lock_ctor,
295 "??0scoped_lock@critical_section@Concurrency@@QEAA@AEAV12@@Z");
296 SET(p_critical_section_scoped_lock_dtor,
297 "??1scoped_lock@critical_section@Concurrency@@QEAA@XZ");
298 SET(p__Condition_variable_ctor,
299 "??0_Condition_variable@details@Concurrency@@QEAA@XZ");
300 SET(p__Condition_variable_dtor,
301 "??1_Condition_variable@details@Concurrency@@QEAA@XZ");
302 SET(p__Condition_variable_wait,
303 "?wait@_Condition_variable@details@Concurrency@@QEAAXAEAVcritical_section@3@@Z");
304 SET(p__Condition_variable_wait_for,
305 "?wait_for@_Condition_variable@details@Concurrency@@QEAA_NAEAVcritical_section@3@I@Z");
306 SET(p__Condition_variable_notify_one,
307 "?notify_one@_Condition_variable@details@Concurrency@@QEAAXXZ");
308 SET(p__Condition_variable_notify_all,
309 "?notify_all@_Condition_variable@details@Concurrency@@QEAAXXZ");
310 SET(p_Context_CurrentContext,
311 "?CurrentContext@Context@Concurrency@@SAPEAV12@XZ");
312 } else {
313 #ifdef __arm__
314 SET(p_critical_section_ctor,
315 "??0critical_section@Concurrency@@QAA@XZ");
316 SET(p_critical_section_dtor,
317 "??1critical_section@Concurrency@@QAA@XZ");
318 SET(p_critical_section_lock,
319 "?lock@critical_section@Concurrency@@QAAXXZ");
320 SET(p_critical_section_unlock,
321 "?unlock@critical_section@Concurrency@@QAAXXZ");
322 SET(p_critical_section_native_handle,
323 "?native_handle@critical_section@Concurrency@@QAAAAV12@XZ");
324 SET(p_critical_section_try_lock,
325 "?try_lock@critical_section@Concurrency@@QAA_NXZ");
326 SET(p_critical_section_try_lock_for,
327 "?try_lock_for@critical_section@Concurrency@@QAA_NI@Z");
328 SET(p_critical_section_scoped_lock_ctor,
329 "??0scoped_lock@critical_section@Concurrency@@QAA@AAV12@@Z");
330 SET(p_critical_section_scoped_lock_dtor,
331 "??1scoped_lock@critical_section@Concurrency@@QAA@XZ");
332 SET(p__Condition_variable_ctor,
333 "??0_Condition_variable@details@Concurrency@@QAA@XZ");
334 SET(p__Condition_variable_dtor,
335 "??1_Condition_variable@details@Concurrency@@QAA@XZ");
336 SET(p__Condition_variable_wait,
337 "?wait@_Condition_variable@details@Concurrency@@QAAXAAVcritical_section@3@@Z");
338 SET(p__Condition_variable_wait_for,
339 "?wait_for@_Condition_variable@details@Concurrency@@QAA_NAAVcritical_section@3@I@Z");
340 SET(p__Condition_variable_notify_one,
341 "?notify_one@_Condition_variable@details@Concurrency@@QAAXXZ");
342 SET(p__Condition_variable_notify_all,
343 "?notify_all@_Condition_variable@details@Concurrency@@QAAXXZ");
344 #else
345 SET(p_critical_section_ctor,
346 "??0critical_section@Concurrency@@QAE@XZ");
347 SET(p_critical_section_dtor,
348 "??1critical_section@Concurrency@@QAE@XZ");
349 SET(p_critical_section_lock,
350 "?lock@critical_section@Concurrency@@QAEXXZ");
351 SET(p_critical_section_unlock,
352 "?unlock@critical_section@Concurrency@@QAEXXZ");
353 SET(p_critical_section_native_handle,
354 "?native_handle@critical_section@Concurrency@@QAEAAV12@XZ");
355 SET(p_critical_section_try_lock,
356 "?try_lock@critical_section@Concurrency@@QAE_NXZ");
357 SET(p_critical_section_try_lock_for,
358 "?try_lock_for@critical_section@Concurrency@@QAE_NI@Z");
359 SET(p_critical_section_scoped_lock_ctor,
360 "??0scoped_lock@critical_section@Concurrency@@QAE@AAV12@@Z");
361 SET(p_critical_section_scoped_lock_dtor,
362 "??1scoped_lock@critical_section@Concurrency@@QAE@XZ");
363 SET(p__Condition_variable_ctor,
364 "??0_Condition_variable@details@Concurrency@@QAE@XZ");
365 SET(p__Condition_variable_dtor,
366 "??1_Condition_variable@details@Concurrency@@QAE@XZ");
367 SET(p__Condition_variable_wait,
368 "?wait@_Condition_variable@details@Concurrency@@QAEXAAVcritical_section@3@@Z");
369 SET(p__Condition_variable_wait_for,
370 "?wait_for@_Condition_variable@details@Concurrency@@QAE_NAAVcritical_section@3@I@Z");
371 SET(p__Condition_variable_notify_one,
372 "?notify_one@_Condition_variable@details@Concurrency@@QAEXXZ");
373 SET(p__Condition_variable_notify_all,
374 "?notify_all@_Condition_variable@details@Concurrency@@QAEXXZ");
375 #endif
376 SET(p_Context_CurrentContext,
377 "?CurrentContext@Context@Concurrency@@SAPAV12@XZ");
380 init_thiscall_thunk();
381 return TRUE;
384 static void test_lconv_helper(const char *locstr)
386 struct MSVCRT_lconv *lconv;
387 char mbs[256];
388 size_t i;
390 if(!p_setlocale(LC_ALL, locstr))
392 win_skip("locale %s not available\n", locstr);
393 return;
396 lconv = p_localeconv();
398 /* If multi-byte version available, asserts that wide char version also available.
399 * If wide char version can be converted to a multi-byte string , asserts that the
400 * conversion result is the same as the multi-byte version.
402 if(strlen(lconv->decimal_point) > 0)
403 ok(wcslen(lconv->_W_decimal_point) > 0, "%s: decimal_point\n", locstr);
404 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_decimal_point, 256) == 0)
405 ok(strcmp(mbs, lconv->decimal_point) == 0, "%s: decimal_point\n", locstr);
407 if(strlen(lconv->thousands_sep) > 0)
408 ok(wcslen(lconv->_W_thousands_sep) > 0, "%s: thousands_sep\n", locstr);
409 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_thousands_sep, 256) == 0)
410 ok(strcmp(mbs, lconv->thousands_sep) == 0, "%s: thousands_sep\n", locstr);
412 if(strlen(lconv->int_curr_symbol) > 0)
413 ok(wcslen(lconv->_W_int_curr_symbol) > 0, "%s: int_curr_symbol\n", locstr);
414 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_int_curr_symbol, 256) == 0)
415 ok(strcmp(mbs, lconv->int_curr_symbol) == 0, "%s: int_curr_symbol\n", locstr);
417 if(strlen(lconv->currency_symbol) > 0)
418 ok(wcslen(lconv->_W_currency_symbol) > 0, "%s: currency_symbol\n", locstr);
419 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_currency_symbol, 256) == 0)
420 ok(strcmp(mbs, lconv->currency_symbol) == 0, "%s: currency_symbol\n", locstr);
422 if(strlen(lconv->mon_decimal_point) > 0)
423 ok(wcslen(lconv->_W_mon_decimal_point) > 0, "%s: decimal_point\n", locstr);
424 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_mon_decimal_point, 256) == 0)
425 ok(strcmp(mbs, lconv->mon_decimal_point) == 0, "%s: decimal_point\n", locstr);
427 if(strlen(lconv->positive_sign) > 0)
428 ok(wcslen(lconv->_W_positive_sign) > 0, "%s: positive_sign\n", locstr);
429 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_positive_sign, 256) == 0)
430 ok(strcmp(mbs, lconv->positive_sign) == 0, "%s: positive_sign\n", locstr);
432 if(strlen(lconv->negative_sign) > 0)
433 ok(wcslen(lconv->_W_negative_sign) > 0, "%s: negative_sign\n", locstr);
434 if(p_wcstombs_s(&i, mbs, 256, lconv->_W_negative_sign, 256) == 0)
435 ok(strcmp(mbs, lconv->negative_sign) == 0, "%s: negative_sign\n", locstr);
438 static void test_lconv(void)
440 int i;
441 const char *locstrs[] =
443 "American", "Belgian", "Chinese",
444 "Dutch", "English", "French",
445 "German", "Hungarian", "Icelandic",
446 "Japanese", "Korean", "Spanish"
449 for(i = 0; i < ARRAY_SIZE(locstrs); i ++)
450 test_lconv_helper(locstrs[i]);
453 static void test__dsign(void)
455 int ret;
457 ret = p__dsign(1);
458 ok(ret == 0, "p_dsign(1) = %x\n", ret);
459 ret = p__dsign(0);
460 ok(ret == 0, "p_dsign(0) = %x\n", ret);
461 ret = p__dsign(-1);
462 ok(ret == 0x8000, "p_dsign(-1) = %x\n", ret);
464 ret = p__fdsign(1);
465 ok(ret == 0, "p_fdsign(1) = %x\n", ret);
466 ret = p__fdsign(0);
467 ok(ret == 0, "p_fdsign(0) = %x\n", ret);
468 ret = p__fdsign(-1);
469 ok(ret == 0x8000, "p_fdsign(-1) = %x\n", ret);
472 static void test__dpcomp(void)
474 struct {
475 double x, y;
476 int ret;
477 } tests[] = {
478 {0, 0, 2}, {1, 1, 2}, {-1, -1, 2},
479 {-2, -1, 1}, {-1, 1, 1}, {1, 2, 1},
480 {1, -1, 4}, {2, 1, 4}, {-1, -2, 4},
481 {NAN, NAN, 0}, {NAN, 1, 0}, {1, NAN, 0},
482 {INFINITY, INFINITY, 2}, {-1, INFINITY, 1}, {1, INFINITY, 1},
484 int i, ret;
486 for(i=0; i<ARRAY_SIZE(tests); i++) {
487 ret = p__dpcomp(tests[i].x, tests[i].y);
488 ok(ret == tests[i].ret, "%d) dpcomp(%f, %f) = %x\n", i, tests[i].x, tests[i].y, ret);
492 static void test____lc_locale_name_func(void)
494 struct {
495 const char *locale;
496 const WCHAR name[10];
497 const WCHAR broken_name[10];
498 } tests[] = {
499 { "American", {'e','n',0}, {'e','n','-','U','S',0} },
500 { "Belgian", {'n','l','-','B','E',0} },
501 { "Chinese", {'z','h',0}, {'z','h','-','C','N',0} },
502 { "Dutch", {'n','l',0}, {'n','l','-','N','L',0} },
503 { "English", {'e','n',0}, {'e','n','-','U','S',0} },
504 { "French", {'f','r',0}, {'f','r','-','F','R',0} },
505 { "German", {'d','e',0}, {'d','e','-','D','E',0} },
506 { "Hungarian", {'h','u',0}, {'h','u','-','H','U',0} },
507 { "Icelandic", {'i','s',0}, {'i','s','-','I','S',0} },
508 { "Japanese", {'j','a',0}, {'j','a','-','J','P',0} },
509 { "Korean", {'k','o',0}, {'k','o','-','K','R',0} }
511 int i, j;
512 wchar_t **lc_names;
514 for(i=0; i<ARRAY_SIZE(tests); i++) {
515 if(!p_setlocale(LC_ALL, tests[i].locale))
516 continue;
518 lc_names = p____lc_locale_name_func();
519 ok(lc_names[0] == NULL, "%d - lc_names[0] = %s\n", i, wine_dbgstr_w(lc_names[0]));
520 ok(!lstrcmpW(lc_names[1], tests[i].name) || broken(!lstrcmpW(lc_names[1], tests[i].broken_name)),
521 "%d - lc_names[1] = %s\n", i, wine_dbgstr_w(lc_names[1]));
523 for(j=LC_MIN+2; j<=LC_MAX; j++) {
524 ok(!lstrcmpW(lc_names[1], lc_names[j]), "%d - lc_names[%d] = %s, expected %s\n",
525 i, j, wine_dbgstr_w(lc_names[j]), wine_dbgstr_w(lc_names[1]));
529 p_setlocale(LC_ALL, "C");
530 lc_names = p____lc_locale_name_func();
531 ok(!lc_names[1], "___lc_locale_name_func()[1] = %s\n", wine_dbgstr_w(lc_names[1]));
534 static void test__GetConcurrency(void)
536 SYSTEM_INFO si;
537 unsigned int c;
539 GetSystemInfo(&si);
540 c = (*p__GetConcurrency)();
541 ok(c == si.dwNumberOfProcessors, "expected %u, got %u\n", si.dwNumberOfProcessors, c);
544 static void test_gettnames(void* (CDECL *p_gettnames)(void))
546 static const char *str[] = {
547 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
548 "Sunday", "Monday", "Tuesday", "Wednesday",
549 "Thursday", "Friday", "Saturday",
550 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
551 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
552 "January", "February", "March", "April", "May", "June", "July",
553 "August", "September", "October", "November", "December",
554 "AM", "PM", "M/d/yyyy"
557 struct {
558 char *str[43];
559 int unk[2];
560 wchar_t *wstr[43];
561 wchar_t *locname;
562 char data[1];
563 } *ret;
564 int i, size;
565 WCHAR buf[64];
567 if(!p_setlocale(LC_ALL, "english"))
568 return;
570 ret = p_gettnames();
571 size = ret->str[0]-(char*)ret;
572 if(sizeof(void*) == 8)
573 ok(size==0x2c0, "structure size: %x\n", size);
574 else
575 ok(size==0x164, "structure size: %x\n", size);
577 for(i=0; i<ARRAY_SIZE(str); i++) {
578 ok(!strcmp(ret->str[i], str[i]), "ret->str[%d] = %s, expected %s\n",
579 i, ret->str[i], str[i]);
581 MultiByteToWideChar(CP_ACP, 0, str[i], strlen(str[i])+1, buf, ARRAY_SIZE(buf));
582 ok(!lstrcmpW(ret->wstr[i], buf), "ret->wstr[%d] = %s, expected %s\n",
583 i, wine_dbgstr_w(ret->wstr[i]), wine_dbgstr_w(buf));
586 ok(ret->str[42] + strlen(ret->str[42]) + 1 == (char*)ret->wstr[0] ||
587 ret->str[42] + strlen(ret->str[42]) + 2 == (char*)ret->wstr[0],
588 "ret->str[42] = %p len = %d, ret->wstr[0] = %p\n",
589 ret->str[42], strlen(ret->str[42]), ret->wstr[0]);
590 p_free(ret);
592 p_setlocale(LC_ALL, "C");
595 static void test__strtof(void)
597 const char float1[] = "12.0";
598 const char float2[] = "3.402823466e+38"; /* FLT_MAX */
599 const char float3[] = "-3.402823466e+38";
600 const char float4[] = "1.7976931348623158e+308"; /* DBL_MAX */
602 char *end;
603 float f;
605 f = p_strtof(float1, &end);
606 ok(f == 12.0, "f = %lf\n", f);
607 ok(end == float1+4, "incorrect end (%d)\n", (int)(end-float1));
609 f = p_strtof(float2, &end);
610 ok(f == FLT_MAX, "f = %lf\n", f);
611 ok(end == float2+15, "incorrect end (%d)\n", (int)(end-float2));
613 f = p_strtof(float3, &end);
614 ok(f == -FLT_MAX, "f = %lf\n", f);
615 ok(end == float3+16, "incorrect end (%d)\n", (int)(end-float3));
617 f = p_strtof(float4, &end);
618 ok(!p__finite(f), "f = %lf\n", f);
619 ok(end == float4+23, "incorrect end (%d)\n", (int)(end-float4));
621 f = p_strtof("inf", NULL);
622 ok(f == 0, "f = %lf\n", f);
624 f = p_strtof("INF", NULL);
625 ok(f == 0, "f = %lf\n", f);
627 f = p_strtof("1.#inf", NULL);
628 ok(f == 1, "f = %lf\n", f);
630 f = p_strtof("INFINITY", NULL);
631 ok(f == 0, "f = %lf\n", f);
633 f = p_strtof("0x12", NULL);
634 ok(f == 0, "f = %lf\n", f);
636 f = p_wcstof(L"12.0", NULL);
637 ok(f == 12.0, "f = %lf\n", f);
639 f = p_wcstof(L"\x0662\x0663", NULL);
640 ok(f == 0, "f = %lf\n", f);
642 if(!p_setlocale(LC_ALL, "Arabic")) {
643 win_skip("Arabic locale not available\n");
644 return;
647 f = p_wcstof(L"12.0", NULL);
648 ok(f == 12.0, "f = %lf\n", f);
650 f = p_wcstof(L"\x0662\x0663", NULL);
651 ok(f == 0, "f = %lf\n", f);
653 p_setlocale(LC_ALL, "C");
656 static void test_remainder(void)
658 struct {
659 double x, y, r;
660 errno_t e;
661 } tests[] = {
662 { 3.0, 2.0, -1.0, -1 },
663 { 1.0, 1.0, 0.0, -1 },
664 { INFINITY, 0.0, NAN, EDOM },
665 { INFINITY, 42.0, NAN, EDOM },
666 { NAN, 0.0, NAN, EDOM },
667 { NAN, 42.0, NAN, EDOM },
668 { 0.0, INFINITY, 0.0, -1 },
669 { 42.0, INFINITY, 42.0, -1 },
670 { 0.0, NAN, NAN, EDOM },
671 { 42.0, NAN, NAN, EDOM },
672 { 1.0, 0.0, NAN, EDOM },
673 { INFINITY, INFINITY, NAN, EDOM },
675 errno_t e;
676 double r;
677 int i;
679 if(sizeof(void*) != 8) /* errno handling slightly different on 32-bit */
680 return;
682 for(i=0; i<ARRAY_SIZE(tests); i++) {
683 errno = -1;
684 r = p_remainder(tests[i].x, tests[i].y);
685 e = errno;
687 ok(tests[i].e == e, "expected errno %i, but got %i\n", tests[i].e, e);
688 if(_isnan(tests[i].r))
689 ok(_isnan(r), "expected NAN, but got %f\n", r);
690 else
691 ok(tests[i].r == r, "expected result %f, but got %f\n", tests[i].r, r);
695 static int enter_flag;
696 static critical_section cs;
697 static unsigned __stdcall test_critical_section_lock(void *arg)
699 critical_section *native_handle;
700 native_handle = (critical_section*)call_func1(p_critical_section_native_handle, &cs);
701 ok(native_handle == &cs, "native_handle = %p\n", native_handle);
702 call_func1(p_critical_section_lock, &cs);
703 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
704 call_func1(p_critical_section_unlock, &cs);
705 return 0;
708 static unsigned __stdcall test_critical_section_try_lock(void *arg)
710 ok(!(MSVCRT_bool)call_func1(p_critical_section_try_lock, &cs),
711 "critical_section_try_lock succeeded\n");
712 return 0;
715 static unsigned __stdcall test_critical_section_try_lock_for(void *arg)
717 ok((MSVCRT_bool)call_func2(p_critical_section_try_lock_for, &cs, 5000),
718 "critical_section_try_lock_for failed\n");
719 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
720 call_func1(p_critical_section_unlock, &cs);
721 return 0;
724 static unsigned __stdcall test_critical_section_scoped_lock(void *arg)
726 critical_section_scoped_lock counter_scope_lock;
728 call_func2(p_critical_section_scoped_lock_ctor, &counter_scope_lock, &cs);
729 ok(enter_flag == 1, "enter_flag = %d\n", enter_flag);
730 call_func1(p_critical_section_scoped_lock_dtor, &counter_scope_lock);
731 return 0;
734 static void test_critical_section(void)
736 HANDLE thread;
737 DWORD ret;
739 enter_flag = 0;
740 call_func1(p_critical_section_ctor, &cs);
741 call_func1(p_critical_section_lock, &cs);
742 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_lock, NULL, 0, NULL);
743 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
744 ret = WaitForSingleObject(thread, 100);
745 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d\n", ret);
746 enter_flag = 1;
747 call_func1(p_critical_section_unlock, &cs);
748 ret = WaitForSingleObject(thread, INFINITE);
749 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
750 ret = CloseHandle(thread);
751 ok(ret, "CloseHandle failed\n");
753 ok((MSVCRT_bool)call_func1(p_critical_section_try_lock, &cs),
754 "critical_section_try_lock failed\n");
755 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock, NULL, 0, NULL);
756 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
757 ret = WaitForSingleObject(thread, INFINITE);
758 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
759 ret = CloseHandle(thread);
760 ok(ret, "CloseHandle failed\n");
761 call_func1(p_critical_section_unlock, &cs);
763 enter_flag = 0;
764 ok((MSVCRT_bool)call_func2(p_critical_section_try_lock_for, &cs, 50),
765 "critical_section_try_lock_for failed\n");
766 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock, NULL, 0, NULL);
767 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
768 ret = WaitForSingleObject(thread, INFINITE);
769 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
770 ret = CloseHandle(thread);
771 ok(ret, "CloseHandle failed\n");
772 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_try_lock_for, NULL, 0, NULL);
773 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
774 enter_flag = 1;
775 Sleep(10);
776 call_func1(p_critical_section_unlock, &cs);
777 ret = WaitForSingleObject(thread, INFINITE);
778 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
779 ret = CloseHandle(thread);
780 ok(ret, "CloseHandle failed\n");
782 enter_flag = 0;
783 call_func1(p_critical_section_lock, &cs);
784 thread = (HANDLE)_beginthreadex(NULL, 0, test_critical_section_scoped_lock, NULL, 0, NULL);
785 ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
786 ret = WaitForSingleObject(thread, 100);
787 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %d\n", ret);
788 enter_flag = 1;
789 call_func1(p_critical_section_unlock, &cs);
790 ret = WaitForSingleObject(thread, INFINITE);
791 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
792 ret = CloseHandle(thread);
793 ok(ret, "CloseHandle failed\n");
794 call_func1(p_critical_section_dtor, &cs);
797 static void test_feenv(void)
799 static const int tests[] = {
801 FE_INEXACT,
802 FE_UNDERFLOW,
803 FE_OVERFLOW,
804 FE_DIVBYZERO,
805 FE_INVALID,
806 FE_ALL_EXCEPT,
808 static const struct {
809 fexcept_t except;
810 unsigned int flag;
811 unsigned int get;
812 fexcept_t expect;
813 } tests2[] = {
814 /* except flag get expect */
815 { 0, 0, 0, 0 },
816 { FE_ALL_EXCEPT, FE_INEXACT, 0, 0 },
817 { FE_ALL_EXCEPT, FE_INEXACT, FE_ALL_EXCEPT, FE_INEXACT },
818 { FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT, FE_INEXACT },
819 { FE_ALL_EXCEPT, FE_INEXACT, FE_OVERFLOW, 0 },
820 { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT },
821 { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT },
822 { FE_ALL_EXCEPT, FE_ALL_EXCEPT, 0, 0 },
823 { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~0, FE_ALL_EXCEPT },
824 { FE_ALL_EXCEPT, FE_ALL_EXCEPT, ~FE_ALL_EXCEPT, 0 },
825 { FE_INEXACT, FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_INEXACT },
826 { FE_INEXACT, FE_UNDERFLOW, FE_ALL_EXCEPT, 0 },
827 { FE_UNDERFLOW, FE_INEXACT, FE_ALL_EXCEPT, 0 },
828 { FE_INEXACT|FE_UNDERFLOW, FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW },
829 { FE_UNDERFLOW, FE_INEXACT|FE_UNDERFLOW, FE_ALL_EXCEPT, FE_UNDERFLOW },
831 fenv_t env, env2;
832 fexcept_t except;
833 int i, ret, flags;
835 p__clearfp();
837 ret = p_fegetenv(&env);
838 ok(!ret, "fegetenv returned %x\n", ret);
839 p_fesetround(FE_UPWARD);
840 ok(env._Fe_ctl == (_EM_INEXACT|_EM_UNDERFLOW|_EM_OVERFLOW|_EM_ZERODIVIDE|_EM_INVALID),
841 "env._Fe_ctl = %lx\n", env._Fe_ctl);
842 ok(!env._Fe_stat, "env._Fe_stat = %lx\n", env._Fe_stat);
843 ret = p_fegetenv(&env2);
844 ok(!ret, "fegetenv returned %x\n", ret);
845 ok(env2._Fe_ctl == (_EM_INEXACT|_EM_UNDERFLOW|_EM_OVERFLOW|_EM_ZERODIVIDE|_EM_INVALID | FE_UPWARD),
846 "env2._Fe_ctl = %lx\n", env2._Fe_ctl);
847 ret = p_fesetenv(&env);
848 ok(!ret, "fesetenv returned %x\n", ret);
849 ret = p_fegetround();
850 ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret);
852 if(0) { /* crash on windows */
853 p_fesetexceptflag(NULL, FE_ALL_EXCEPT);
854 p_fegetexceptflag(NULL, 0);
856 except = FE_ALL_EXCEPT;
857 ret = p_fesetexceptflag(&except, FE_INEXACT|FE_UNDERFLOW);
858 ok(!ret, "fesetexceptflag returned %x\n", ret);
859 except = p_fetestexcept(FE_ALL_EXCEPT);
860 ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
862 ret = p_feclearexcept(~FE_ALL_EXCEPT);
863 ok(!ret, "feclearexceptflag returned %x\n", ret);
864 except = p_fetestexcept(FE_ALL_EXCEPT);
865 ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
867 /* no crash, but no-op */
868 ret = p_fesetexceptflag(NULL, 0);
869 ok(!ret, "fesetexceptflag returned %x\n", ret);
870 except = p_fetestexcept(FE_ALL_EXCEPT);
871 ok(except == (FE_INEXACT|FE_UNDERFLOW), "expected %x, got %lx\n", FE_INEXACT|FE_UNDERFLOW, except);
873 /* zero clears all */
874 except = 0;
875 ret = p_fesetexceptflag(&except, FE_ALL_EXCEPT);
876 ok(!ret, "fesetexceptflag returned %x\n", ret);
877 except = p_fetestexcept(FE_ALL_EXCEPT);
878 ok(!except, "expected 0, got %lx\n", except);
880 ret = p_fetestexcept(FE_ALL_EXCEPT);
881 ok(!ret, "fetestexcept returned %x\n", ret);
883 flags = 0;
884 /* adding bits with flags */
885 for(i=0; i<ARRAY_SIZE(tests); i++) {
886 except = FE_ALL_EXCEPT;
887 ret = p_fesetexceptflag(&except, tests[i]);
888 ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
890 ret = p_fetestexcept(tests[i]);
891 ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
893 flags |= tests[i];
894 ret = p_fetestexcept(FE_ALL_EXCEPT);
895 ok(ret == flags, "Test %d: expected %x, got %x\n", i, flags, ret);
897 except = ~0;
898 ret = p_fegetexceptflag(&except, ~0);
899 ok(!ret, "Test %d: fegetexceptflag returned %x.\n", i, ret);
900 ok(except == flags, "Test %d: expected %x, got %lx\n", i, flags, except);
902 except = ~0;
903 ret = p_fegetexceptflag(&except, tests[i]);
904 ok(!ret, "Test %d: fegetexceptflag returned %x.\n", i, ret);
905 ok(except == tests[i], "Test %d: expected %x, got %lx\n", i, tests[i], except);
908 for(i=0; i<ARRAY_SIZE(tests); i++) {
909 ret = p_feclearexcept(tests[i]);
910 ok(!ret, "Test %d: feclearexceptflag returned %x\n", i, ret);
912 flags &= ~tests[i];
913 except = p_fetestexcept(tests[i]);
914 ok(!except, "Test %d: expected %x, got %lx\n", i, flags, except);
917 except = p_fetestexcept(FE_ALL_EXCEPT);
918 ok(!except, "expected 0, got %lx\n", except);
920 /* setting bits with except */
921 for(i=0; i<ARRAY_SIZE(tests); i++) {
922 except = tests[i];
923 ret = p_fesetexceptflag(&except, FE_ALL_EXCEPT);
924 ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
926 ret = p_fetestexcept(tests[i]);
927 ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
929 ret = p_fetestexcept(FE_ALL_EXCEPT);
930 ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret);
933 for(i=0; i<ARRAY_SIZE(tests2); i++) {
934 p__clearfp();
936 except = tests2[i].except;
937 ret = p_fesetexceptflag(&except, tests2[i].flag);
938 ok(!ret, "Test %d: fesetexceptflag returned %x\n", i, ret);
940 ret = p_fetestexcept(tests2[i].get);
941 ok(ret == tests2[i].expect, "Test %d: expected %lx, got %x\n", i, tests2[i].expect, ret);
944 ret = p_feclearexcept(FE_ALL_EXCEPT);
945 ok(!ret, "feclearexceptflag returned %x\n", ret);
946 except = p_fetestexcept(FE_ALL_EXCEPT);
947 ok(!except, "expected 0, got %lx\n", except);
950 static void test__wcreate_locale(void)
952 _locale_t lcl;
953 errno_t e;
955 /* simple success */
956 errno = -1;
957 lcl = p_wcreate_locale(LC_ALL, L"C");
958 e = errno;
959 ok(!!lcl, "expected success, but got NULL\n");
960 ok(errno == -1, "expected errno -1, but got %i\n", e);
961 p_free_locale(lcl);
963 errno = -1;
964 lcl = p_wcreate_locale(LC_ALL, L"");
965 e = errno;
966 ok(!!lcl, "expected success, but got NULL\n");
967 ok(errno == -1, "expected errno -1, but got %i\n", e);
968 p_free_locale(lcl);
970 /* bogus category */
971 errno = -1;
972 lcl = p_wcreate_locale(-1, L"C");
973 e = errno;
974 ok(!lcl, "expected failure, but got %p\n", lcl);
975 ok(errno == -1, "expected errno -1, but got %i\n", e);
977 /* bogus names */
978 errno = -1;
979 lcl = p_wcreate_locale(LC_ALL, L"bogus");
980 e = errno;
981 ok(!lcl, "expected failure, but got %p\n", lcl);
982 ok(errno == -1, "expected errno -1, but got %i\n", e);
984 errno = -1;
985 lcl = p_wcreate_locale(LC_ALL, NULL);
986 e = errno;
987 ok(!lcl, "expected failure, but got %p\n", lcl);
988 ok(errno == -1, "expected errno -1, but got %i\n", e);
991 struct wait_thread_arg
993 critical_section *cs;
994 _Condition_variable *cv;
995 HANDLE thread_initialized;
998 static DWORD WINAPI condition_variable_wait_thread(void *varg)
1000 struct wait_thread_arg *arg = varg;
1002 call_func1(p_critical_section_lock, arg->cs);
1003 SetEvent(arg->thread_initialized);
1004 call_func2(p__Condition_variable_wait, arg->cv, arg->cs);
1005 call_func1(p_critical_section_unlock, arg->cs);
1006 return 0;
1009 static void test__Condition_variable(void)
1011 critical_section cs;
1012 _Condition_variable cv;
1013 HANDLE thread_initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
1014 struct wait_thread_arg wait_thread_arg = { &cs, &cv, thread_initialized };
1015 HANDLE threads[2];
1016 DWORD ret;
1017 MSVCRT_bool b;
1019 ok(thread_initialized != NULL, "CreateEvent failed\n");
1021 call_func1(p_critical_section_ctor, &cs);
1022 call_func1(p__Condition_variable_ctor, &cv);
1024 call_func1(p__Condition_variable_notify_one, &cv);
1025 call_func1(p__Condition_variable_notify_all, &cv);
1027 threads[0] = CreateThread(0, 0, condition_variable_wait_thread,
1028 &wait_thread_arg, 0, 0);
1029 ok(threads[0] != NULL, "CreateThread failed\n");
1030 WaitForSingleObject(thread_initialized, INFINITE);
1031 call_func1(p_critical_section_lock, &cs);
1032 call_func1(p_critical_section_unlock, &cs);
1034 threads[1] = CreateThread(0, 0, condition_variable_wait_thread,
1035 &wait_thread_arg, 0, 0);
1036 ok(threads[1] != NULL, "CreateThread failed\n");
1037 WaitForSingleObject(thread_initialized, INFINITE);
1038 call_func1(p_critical_section_lock, &cs);
1039 call_func1(p_critical_section_unlock, &cs);
1041 call_func1(p__Condition_variable_notify_one, &cv);
1042 ret = WaitForSingleObject(threads[1], 500);
1043 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
1044 call_func1(p__Condition_variable_notify_one, &cv);
1045 ret = WaitForSingleObject(threads[0], 500);
1046 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", ret);
1048 CloseHandle(threads[0]);
1049 CloseHandle(threads[1]);
1051 call_func1(p_critical_section_lock, &cs);
1052 b = call_func3(p__Condition_variable_wait_for, &cv, &cs, 1);
1053 ok(!b, "_Condition_variable_wait_for returned TRUE\n");
1054 call_func1(p_critical_section_unlock, &cs);
1056 call_func1(p_critical_section_dtor, &cs);
1057 call_func1(p__Condition_variable_dtor, &cv);
1059 CloseHandle(thread_initialized);
1062 static void test_wctype(void)
1064 static const struct {
1065 const char *name;
1066 unsigned short mask;
1067 } properties[] = {
1068 { "alnum", 0x107 },
1069 { "alpha", 0x103 },
1070 { "cntrl", 0x020 },
1071 { "digit", 0x004 },
1072 { "graph", 0x117 },
1073 { "lower", 0x002 },
1074 { "print", 0x157 },
1075 { "punct", 0x010 },
1076 { "space", 0x008 },
1077 { "upper", 0x001 },
1078 { "xdigit", 0x080 },
1079 { "ALNUM", 0x000 },
1080 { "Alnum", 0x000 },
1081 { "", 0x000 }
1083 int i, ret;
1085 for(i=0; i<ARRAY_SIZE(properties); i++) {
1086 ret = p_wctype(properties[i].name);
1087 ok(properties[i].mask == ret, "%d - Expected %x, got %x\n", i, properties[i].mask, ret);
1091 static int WINAPIV _vsscanf_wrapper(const char *buffer, const char *format, ...)
1093 int ret;
1094 __ms_va_list valist;
1095 __ms_va_start(valist, format);
1096 ret = p_vsscanf(buffer, format, valist);
1097 __ms_va_end(valist);
1098 return ret;
1101 static void test_vsscanf(void)
1103 static const char *fmt = "%d";
1104 char buff[16];
1105 int ret, v;
1107 v = 0;
1108 strcpy(buff, "10");
1109 ret = _vsscanf_wrapper(buff, fmt, &v);
1110 ok(ret == 1, "Unexpected ret %d.\n", ret);
1111 ok(v == 10, "got %d.\n", v);
1114 static void test__Cbuild(void)
1116 _Dcomplex c;
1117 double d;
1119 memset(&c, 0, sizeof(c));
1120 p__Cbuild(&c, 1.0, 2.0);
1121 ok(c.r == 1.0, "c.r = %lf\n", c.r);
1122 ok(c.i == 2.0, "c.i = %lf\n", c.i);
1123 d = p_creal(c);
1124 ok(d == 1.0, "creal returned %lf\n", d);
1126 p__Cbuild(&c, 3.0, NAN);
1127 ok(c.r == 3.0, "c.r = %lf\n", c.r);
1128 ok(_isnan(c.i), "c.i = %lf\n", c.i);
1129 d = p_creal(c);
1130 ok(d == 3.0, "creal returned %lf\n", d);
1133 static void test_nexttoward(void)
1135 errno_t e;
1136 double d;
1137 float f;
1138 int i;
1140 struct
1142 double source;
1143 double dir;
1144 float f;
1145 double d;
1147 tests[] =
1149 {0.0, 0.0, 0.0f, 0.0},
1150 {0.0, 1.0, 1.0e-45f, 5.0e-324},
1151 {0.0, -1.0, -1.0e-45f, -5.0e-324},
1152 {2.2250738585072009e-308, 0.0, 0.0f, 2.2250738585072004e-308},
1153 {2.2250738585072009e-308, 2.2250738585072010e-308, 1.0e-45f, 2.2250738585072009e-308},
1154 {2.2250738585072009e-308, 1.0, 1.0e-45f, 2.2250738585072014e-308},
1155 {2.2250738585072014e-308, 0.0, 0.0f, 2.2250738585072009e-308},
1156 {2.2250738585072014e-308, 2.2250738585072014e-308, 1.0e-45f, 2.2250738585072014e-308},
1157 {2.2250738585072014e-308, 1.0, 1.0e-45f, 2.2250738585072019e-308},
1158 {1.0, 2.0, 1.00000012f, 1.0000000000000002},
1159 {1.0, 0.0, 0.99999994f, 0.9999999999999999},
1160 {1.0, 1.0, 1.0f, 1.0},
1161 {0.0, INFINITY, 1.0e-45f, 5.0e-324},
1162 {FLT_MAX, INFINITY, INFINITY, 3.402823466385289e+038},
1163 {DBL_MAX, INFINITY, INFINITY, INFINITY},
1164 {INFINITY, INFINITY, INFINITY, INFINITY},
1165 {INFINITY, 0, FLT_MAX, DBL_MAX},
1168 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1170 f = p_nexttowardf(tests[i].source, tests[i].dir);
1171 ok(f == tests[i].f, "Test %d: expected %0.8ef, got %0.8ef.\n", i, tests[i].f, f);
1173 errno = -1;
1174 d = p_nexttoward(tests[i].source, tests[i].dir);
1175 e = errno;
1176 ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
1177 if (!isnormal(d) && !isinf(tests[i].source))
1178 ok(e == ERANGE, "Test %d: expected ERANGE, got %d.\n", i, e);
1179 else
1180 ok(e == -1, "Test %d: expected no error, got %d.\n", i, e);
1182 d = p_nexttowardl(tests[i].source, tests[i].dir);
1183 ok(d == tests[i].d, "Test %d: expected %0.16e, got %0.16e.\n", i, tests[i].d, d);
1186 errno = -1;
1187 d = p_nexttoward(NAN, 0);
1188 e = errno;
1189 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1190 ok(e == -1, "Expected no error, got %d.\n", e);
1192 errno = -1;
1193 d = p_nexttoward(NAN, NAN);
1194 e = errno;
1195 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1196 ok(e == -1, "Expected no error, got %d.\n", e);
1198 errno = -1;
1199 d = p_nexttoward(0, NAN);
1200 e = errno;
1201 ok(_isnan(d), "Expected NAN, got %0.16e.\n", d);
1202 ok(e == -1, "Expected no error, got %d.\n", e);
1205 static void test_towctrans(void)
1207 wchar_t ret;
1209 ret = p_wctrans("tolower");
1210 ok(ret == 2, "wctrans returned %d, expected 2\n", ret);
1211 ret = p_wctrans("toupper");
1212 ok(ret == 1, "wctrans returned %d, expected 1\n", ret);
1213 ret = p_wctrans("toLower");
1214 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1215 ret = p_wctrans("");
1216 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1217 if(0) { /* crashes on windows */
1218 ret = p_wctrans(NULL);
1219 ok(ret == 0, "wctrans returned %d, expected 0\n", ret);
1222 ret = p_towctrans('t', 2);
1223 ok(ret == 't', "towctrans('t', 2) returned %c, expected t\n", ret);
1224 ret = p_towctrans('T', 2);
1225 ok(ret == 't', "towctrans('T', 2) returned %c, expected t\n", ret);
1226 ret = p_towctrans('T', 0);
1227 ok(ret == 't', "towctrans('T', 0) returned %c, expected t\n", ret);
1228 ret = p_towctrans('T', 3);
1229 ok(ret == 't', "towctrans('T', 3) returned %c, expected t\n", ret);
1230 ret = p_towctrans('t', 1);
1231 ok(ret == 'T', "towctrans('t', 1) returned %c, expected T\n", ret);
1232 ret = p_towctrans('T', 1);
1233 ok(ret == 'T', "towctrans('T', 1) returned %c, expected T\n", ret);
1236 static void test_CurrentContext(void)
1238 _Context _ctx, *ret;
1239 Context *ctx;
1241 ctx = p_Context_CurrentContext();
1242 ok(!!ctx, "got NULL\n");
1244 memset(&_ctx, 0xcc, sizeof(_ctx));
1245 ret = p__Context__CurrentContext(&_ctx);
1246 ok(_ctx.ctx == ctx, "expected %p, got %p\n", ctx, _ctx.ctx);
1247 ok(ret == &_ctx, "expected %p, got %p\n", &_ctx, ret);
1250 START_TEST(msvcr120)
1252 if (!init()) return;
1253 test_lconv();
1254 test__dsign();
1255 test__dpcomp();
1256 test____lc_locale_name_func();
1257 test__GetConcurrency();
1258 test_gettnames(p__W_Gettnames);
1259 test_gettnames(p__Gettnames);
1260 test__strtof();
1261 test_remainder();
1262 test_critical_section();
1263 test_feenv();
1264 test__wcreate_locale();
1265 test__Condition_variable();
1266 test_wctype();
1267 test_vsscanf();
1268 test__Cbuild();
1269 test_nexttoward();
1270 test_towctrans();
1271 test_CurrentContext();