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
33 #include "wine/test.h"
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 */
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))
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)
84 #define __thiscall __stdcall
86 #define __thiscall __cdecl
89 typedef unsigned char MSVCRT_bool
;
91 typedef struct cs_queue
93 struct cs_queue
*next
;
100 ULONG_PTR unk_thread_id
;
109 critical_section
*cs
;
112 } critical_section_scoped_lock
;
116 critical_section lock
;
117 } _Condition_variable
;
124 char* int_curr_symbol
;
125 char* currency_symbol
;
126 char* mon_decimal_point
;
127 char* mon_thousands_sep
;
131 char int_frac_digits
;
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
;
155 typedef void (*vtable_ptr
)(void);
158 const vtable_ptr
*vtable
;
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 */
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)
234 module
= LoadLibraryA("msvcr120.dll");
237 win_skip("msvcr120.dll not installed\n");
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");
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");
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");
376 SET(p_Context_CurrentContext
,
377 "?CurrentContext@Context@Concurrency@@SAPAV12@XZ");
380 init_thiscall_thunk();
384 static void test_lconv_helper(const char *locstr
)
386 struct MSVCRT_lconv
*lconv
;
390 if(!p_setlocale(LC_ALL
, locstr
))
392 win_skip("locale %s not available\n", locstr
);
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)
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)
458 ok(ret
== 0, "p_dsign(1) = %x\n", ret
);
460 ok(ret
== 0, "p_dsign(0) = %x\n", ret
);
462 ok(ret
== 0x8000, "p_dsign(-1) = %x\n", ret
);
465 ok(ret
== 0, "p_fdsign(1) = %x\n", ret
);
467 ok(ret
== 0, "p_fdsign(0) = %x\n", ret
);
469 ok(ret
== 0x8000, "p_fdsign(-1) = %x\n", ret
);
472 static void test__dpcomp(void)
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},
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)
496 const WCHAR name
[10];
497 const WCHAR broken_name
[10];
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} }
514 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
515 if(!p_setlocale(LC_ALL
, tests
[i
].locale
))
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)
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"
567 if(!p_setlocale(LC_ALL
, "english"))
571 size
= ret
->str
[0]-(char*)ret
;
572 if(sizeof(void*) == 8)
573 ok(size
==0x2c0, "structure size: %x\n", size
);
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]);
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 */
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");
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)
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
},
679 if(sizeof(void*) != 8) /* errno handling slightly different on 32-bit */
682 for(i
=0; i
<ARRAY_SIZE(tests
); i
++) {
684 r
= p_remainder(tests
[i
].x
, tests
[i
].y
);
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
);
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
);
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");
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
);
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
);
734 static void test_critical_section(void)
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
);
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
);
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
);
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");
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
);
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
[] = {
808 static const struct {
814 /* except flag get expect */
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
},
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 */
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
);
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
);
894 ret
= p_fetestexcept(FE_ALL_EXCEPT
);
895 ok(ret
== flags
, "Test %d: expected %x, got %x\n", i
, flags
, ret
);
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
);
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
);
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
++) {
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
++) {
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)
957 lcl
= p_wcreate_locale(LC_ALL
, L
"C");
959 ok(!!lcl
, "expected success, but got NULL\n");
960 ok(errno
== -1, "expected errno -1, but got %i\n", e
);
964 lcl
= p_wcreate_locale(LC_ALL
, L
"");
966 ok(!!lcl
, "expected success, but got NULL\n");
967 ok(errno
== -1, "expected errno -1, but got %i\n", e
);
972 lcl
= p_wcreate_locale(-1, L
"C");
974 ok(!lcl
, "expected failure, but got %p\n", lcl
);
975 ok(errno
== -1, "expected errno -1, but got %i\n", e
);
979 lcl
= p_wcreate_locale(LC_ALL
, L
"bogus");
981 ok(!lcl
, "expected failure, but got %p\n", lcl
);
982 ok(errno
== -1, "expected errno -1, but got %i\n", e
);
985 lcl
= p_wcreate_locale(LC_ALL
, NULL
);
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
);
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
};
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 {
1066 unsigned short mask
;
1078 { "xdigit", 0x080 },
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
, ...)
1094 __ms_va_list valist
;
1095 __ms_va_start(valist
, format
);
1096 ret
= p_vsscanf(buffer
, format
, valist
);
1097 __ms_va_end(valist
);
1101 static void test_vsscanf(void)
1103 static const char *fmt
= "%d";
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)
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
);
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
);
1130 ok(d
== 3.0, "creal returned %lf\n", d
);
1133 static void test_nexttoward(void)
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
);
1174 d
= p_nexttoward(tests
[i
].source
, tests
[i
].dir
);
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
);
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
);
1187 d
= p_nexttoward(NAN
, 0);
1189 ok(_isnan(d
), "Expected NAN, got %0.16e.\n", d
);
1190 ok(e
== -1, "Expected no error, got %d.\n", e
);
1193 d
= p_nexttoward(NAN
, NAN
);
1195 ok(_isnan(d
), "Expected NAN, got %0.16e.\n", d
);
1196 ok(e
== -1, "Expected no error, got %d.\n", e
);
1199 d
= p_nexttoward(0, NAN
);
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)
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
;
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;
1256 test____lc_locale_name_func();
1257 test__GetConcurrency();
1258 test_gettnames(p__W_Gettnames
);
1259 test_gettnames(p__Gettnames
);
1262 test_critical_section();
1264 test__wcreate_locale();
1265 test__Condition_variable();
1271 test_CurrentContext();