msvcrt: Fix fscanf return when EOF is immediately after an end of line.
[wine.git] / dlls / msvcr90 / tests / msvcr90.c
blob050699e4857bef94dfc81de63ffc9e683f499f36
1 /*
2 * Copyright 2010 Detlef Riekenberg
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 <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <fcntl.h>
24 #include <share.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <locale.h>
28 #include <fpieee.h>
29 #include <excpt.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <errno.h>
34 #include "wine/test.h"
36 #define DEFINE_EXPECT(func) \
37 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39 #define SET_EXPECT(func) \
40 do { \
41 expect_ ## func = TRUE; \
42 errno = 0xdeadbeef; \
43 }while(0)
45 #define CHECK_EXPECT2(func) \
46 do { \
47 ok(expect_ ##func, "unexpected call " #func "\n"); \
48 called_ ## func = TRUE; \
49 }while(0)
51 #define CHECK_EXPECT(func) \
52 do { \
53 CHECK_EXPECT2(func); \
54 expect_ ## func = FALSE; \
55 }while(0)
57 #define CHECK_CALLED(func,error) \
58 do { \
59 ok(called_ ## func, "expected " #func "\n"); \
60 ok( errno == (error), "got errno %u instead of %u\n", errno, (error) ); \
61 expect_ ## func = called_ ## func = FALSE; \
62 }while(0)
64 DEFINE_EXPECT(invalid_parameter_handler);
66 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
67 typedef int (__cdecl *_INITTERM_E_FN)(void);
68 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
69 static void* (__cdecl *p_encode_pointer)(void *);
70 static void* (__cdecl *p_decode_pointer)(void *);
71 static void* (__cdecl *p_encoded_null)(void);
72 static int *p_sys_nerr;
73 static int* (__cdecl *p__sys_nerr)(void);
74 static char **p_sys_errlist;
75 static char** (__cdecl *p__sys_errlist)(void);
76 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
77 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
78 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
79 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
80 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
81 static void* (__cdecl *p_bsearch_s)(const void *, const void *, size_t, size_t,
82 int (__cdecl *compare)(void *, const void *, const void *), void *);
83 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
84 static int (__cdecl *p_tmpfile_s)(FILE**);
85 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
86 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
87 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
88 static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
89 static void* (__cdecl *p_realloc_crt)(void*, size_t);
90 static void* (__cdecl *p_malloc)(size_t);
91 static void (__cdecl *p_free)(void*);
92 static void* (__cdecl *p_getptd)(void);
93 static int* (__cdecl *p_errno)(void);
94 static __msvcrt_ulong* (__cdecl *p_doserrno)(void);
95 static void (__cdecl *p_srand)(unsigned int);
96 static char* (__cdecl *p_strtok)(char*, const char*);
97 static char* (__cdecl *p_strtok_s)(char*, const char*, char**);
98 static wchar_t* (__cdecl *p_wcstok)(wchar_t*, const wchar_t*);
99 static unsigned char* (__cdecl *p__mbstok)(unsigned char*, const unsigned char*);
100 static unsigned char* (__cdecl *p__mbstok_s)(unsigned char*, const unsigned char*, unsigned char**);
101 static char* (__cdecl *p_strerror)(int);
102 static wchar_t* (__cdecl *p_wcserror)(int);
103 static char* (__cdecl *p_tmpnam)(char*);
104 static wchar_t* (__cdecl *p_wtmpnam)(wchar_t*);
105 static char* (__cdecl *p_asctime)(struct tm*);
106 static wchar_t* (__cdecl *p_wasctime)(struct tm*);
107 static struct tm* (__cdecl *p_localtime64)(__time64_t*);
108 static char* (__cdecl *p_ecvt)(double, int, int*, int*);
109 static int* (__cdecl *p_fpecode)(void);
110 static int (__cdecl *p_configthreadlocale)(int);
111 static void* (__cdecl *p_get_terminate)(void);
112 static void* (__cdecl *p_get_unexpected)(void);
113 static int (__cdecl *p__vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
114 static int (__cdecl *p_vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
115 static FILE* (__cdecl *p_fopen)(const char*, const char*);
116 static int (__cdecl *p_fclose)(FILE*);
117 static int (__cdecl *p_unlink)(const char*);
118 static int (__cdecl *p_access_s)(const char*, int);
119 static void (__cdecl *p_lock_file)(FILE*);
120 static void (__cdecl *p_unlock_file)(FILE*);
121 static int (__cdecl *p_fileno)(FILE*);
122 static int (__cdecl *p_feof)(FILE*);
123 static int (__cdecl *p_ferror)(FILE*);
124 static int (__cdecl *p_flsbuf)(int, FILE*);
125 static int (__cdecl *p_filbuf)(FILE*);
126 static unsigned long (__cdecl *p_byteswap_ulong)(unsigned long);
127 static void** (__cdecl *p__pxcptinfoptrs)(void);
128 static void* (__cdecl *p__AdjustPointer)(void*, const void*);
129 static int (__cdecl *p_fflush_nolock)(FILE*);
130 static size_t (__cdecl *p_mbstowcs)(wchar_t*, const char*, size_t);
131 static size_t (__cdecl *p_wcstombs)(char*, const wchar_t*, size_t);
132 static char* (__cdecl *p_setlocale)(int, const char*);
133 static int (__cdecl *p__fpieee_flt)(ULONG, EXCEPTION_POINTERS*, int (__cdecl *handler)(_FPIEEE_RECORD*));
134 static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
135 static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
136 static int (__cdecl *p__vsnwprintf)(wchar_t *buffer,size_t count, const wchar_t *format, __ms_va_list valist);
137 static size_t (__cdecl *p___strncnt)(const char *str, size_t count);
138 static int (__cdecl *p_swscanf)(const wchar_t *str, const wchar_t* format, ...);
140 /* make sure we use the correct errno */
141 #undef errno
142 #define errno (*p_errno())
144 /* type info */
145 typedef struct __type_info
147 void *vtable;
148 char *name;
149 char mangled[16];
150 } type_info;
152 struct __type_info_node
154 void *memPtr;
155 struct __type_info_node* next;
158 static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *);
159 static void (WINAPI *ptype_info_dtor)(type_info*);
161 #define CXX_FRAME_MAGIC_VC6 0x19930520
162 #define CXX_EXCEPTION 0xe06d7363
164 /* offsets for computing the this pointer */
165 typedef struct
167 int this_offset; /* offset of base class this pointer from start of object */
168 int vbase_descr; /* offset of virtual base class descriptor */
169 int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */
170 } this_ptr_offsets;
172 typedef void (*cxx_copy_ctor)(void);
174 /* complete information about a C++ type */
175 #ifndef __x86_64__
176 typedef struct __cxx_type_info
178 UINT flags; /* flags (see CLASS_* flags below) */
179 const type_info *type_info; /* C++ type info */
180 this_ptr_offsets offsets; /* offsets for computing the this pointer */
181 unsigned int size; /* object size */
182 cxx_copy_ctor copy_ctor; /* copy constructor */
183 } cxx_type_info;
184 #else
185 typedef struct __cxx_type_info
187 UINT flags;
188 unsigned int type_info;
189 this_ptr_offsets offsets;
190 unsigned int size;
191 unsigned int copy_ctor;
192 } cxx_type_info;
193 #endif
195 /* table of C++ types that apply for a given object */
196 #ifndef __x86_64__
197 typedef struct __cxx_type_info_table
199 UINT count; /* number of types */
200 const cxx_type_info *info[3]; /* variable length, we declare it large enough for static RTTI */
201 } cxx_type_info_table;
202 #else
203 typedef struct __cxx_type_info_table
205 UINT count;
206 unsigned int info[3];
207 } cxx_type_info_table;
208 #endif
210 /* type information for an exception object */
211 #ifndef __x86_64__
212 typedef struct __cxx_exception_type
214 UINT flags; /* TYPE_FLAG flags */
215 void (*destructor)(void);/* exception object destructor */
216 void *custom_handler; /* custom handler for this exception */
217 const cxx_type_info_table *type_info_table; /* list of types for this exception object */
218 } cxx_exception_type;
219 #else
220 typedef struct
222 UINT flags;
223 unsigned int destructor;
224 unsigned int custom_handler;
225 unsigned int type_info_table;
226 } cxx_exception_type;
227 #endif
229 static int (__cdecl *p_is_exception_typeof)(const type_info*, EXCEPTION_POINTERS*);
231 static void* (WINAPI *pEncodePointer)(void *);
233 static int cb_called[4];
234 static int g_qsort_s_context_counter;
235 static int g_bsearch_s_context_counter;
237 static inline int almost_equal_f(float f1, float f2)
239 return f1-f2 > -1e-30 && f1-f2 < 1e-30;
242 /* ########## */
244 /* thiscall emulation */
245 /* Emulate a __thiscall */
246 #ifdef __i386__
247 #ifdef _MSC_VER
248 static inline void* do_call_func1(void *func, void *_this)
250 volatile void* retval = 0;
251 __asm
253 push ecx
254 mov ecx, _this
255 call func
256 mov retval, eax
257 pop ecx
259 return (void*)retval;
262 static inline void* do_call_func2(void *func, void *_this, const void* arg)
264 volatile void* retval = 0;
265 __asm
267 push ecx
268 push arg
269 mov ecx, _this
270 call func
271 mov retval, eax
272 pop ecx
274 return (void*)retval;
276 #else
277 static void* do_call_func1(void *func, void *_this)
279 void *ret, *dummy;
280 __asm__ __volatile__ ("call *%2"
281 : "=a" (ret), "=c" (dummy)
282 : "g" (func), "1" (_this)
283 : "edx", "memory" );
284 return ret;
287 static void* do_call_func2(void *func, void *_this, const void* arg)
289 void *ret, *dummy;
290 __asm__ __volatile__ ("pushl %3\n\tcall *%2"
291 : "=a" (ret), "=c" (dummy)
292 : "r" (func), "r" (arg), "1" (_this)
293 : "edx", "memory" );
294 return ret;
296 #endif
298 #define call_func1(func,_this) do_call_func1(func,_this)
299 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)(a))
301 #else
303 #define call_func1(func,_this) func(_this)
304 #define call_func2(func,_this,a) func(_this,a)
306 #endif /* __i386__ */
308 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
309 const wchar_t *function, const wchar_t *file,
310 unsigned line, uintptr_t arg)
312 CHECK_EXPECT(invalid_parameter_handler);
313 ok(expression == NULL, "expression is not NULL\n");
314 ok(function == NULL, "function is not NULL\n");
315 ok(file == NULL, "file is not NULL\n");
316 ok(line == 0, "line = %u\n", line);
317 ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
318 ok(errno != 0xdeadbeef, "errno not set\n");
321 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
322 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
323 static BOOL init(void)
325 HMODULE hcrt;
326 HMODULE hkernel32;
328 SetLastError(0xdeadbeef);
329 hcrt = LoadLibraryA("msvcr90.dll");
330 if (!hcrt) {
331 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
332 return FALSE;
335 SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
336 if(p_set_invalid_parameter_handler)
337 ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
338 "Invalid parameter handler was already set\n");
340 SET(p_initterm_e, "_initterm_e");
341 SET(p_encode_pointer, "_encode_pointer");
342 SET(p_decode_pointer, "_decode_pointer");
343 SET(p_encoded_null, "_encoded_null");
344 SET(p_sys_nerr, "_sys_nerr");
345 SET(p__sys_nerr, "__sys_nerr");
346 SET(p_sys_errlist, "_sys_errlist");
347 SET(p__sys_errlist, "__sys_errlist");
348 SET(p_strtoi64, "_strtoi64");
349 SET(p_strtoui64, "_strtoui64");
350 SET(p_itoa_s, "_itoa_s");
351 SET(p_wcsncat_s,"wcsncat_s" );
352 SET(p_qsort_s, "qsort_s");
353 SET(p_bsearch_s, "bsearch_s");
354 SET(p_controlfp_s, "_controlfp_s");
355 SET(p_tmpfile_s, "tmpfile_s");
356 SET(p_atoflt, "_atoflt");
357 SET(p_set_abort_behavior, "_set_abort_behavior");
358 SET(p_sopen_s, "_sopen_s");
359 SET(p_wsopen_s, "_wsopen_s");
360 SET(p_realloc_crt, "_realloc_crt");
361 SET(p_malloc, "malloc");
362 SET(p_free, "free");
363 SET(p_getptd, "_getptd");
364 SET(p_errno, "_errno");
365 SET(p_doserrno, "__doserrno");
366 SET(p_srand, "srand");
367 SET(p_strtok, "strtok");
368 SET(p_strtok_s, "strtok_s");
369 SET(p_wcstok, "wcstok");
370 SET(p__mbstok, "_mbstok");
371 SET(p__mbstok_s, "_mbstok_s");
372 SET(p_strerror, "strerror");
373 SET(p_wcserror, "_wcserror");
374 SET(p_tmpnam, "tmpnam");
375 SET(p_wtmpnam, "_wtmpnam");
376 SET(p_asctime, "asctime");
377 SET(p_wasctime, "_wasctime");
378 SET(p_localtime64, "_localtime64");
379 SET(p_ecvt, "_ecvt");
380 SET(p_fpecode, "__fpecode");
381 SET(p_configthreadlocale, "_configthreadlocale");
382 SET(p_get_terminate, "_get_terminate");
383 SET(p_get_unexpected, "_get_unexpected");
384 SET(p__vswprintf_l, "__vswprintf_l");
385 SET(p_vswprintf_l, "_vswprintf_l");
386 SET(p_fopen, "fopen");
387 SET(p_fclose, "fclose");
388 SET(p_unlink, "_unlink");
389 SET(p_access_s, "_access_s");
390 SET(p_lock_file, "_lock_file");
391 SET(p_unlock_file, "_unlock_file");
392 SET(p_fileno, "_fileno");
393 SET(p_feof, "feof");
394 SET(p_ferror, "ferror");
395 SET(p_flsbuf, "_flsbuf");
396 SET(p_filbuf, "_filbuf");
397 SET(p_byteswap_ulong, "_byteswap_ulong");
398 SET(p__pxcptinfoptrs, "__pxcptinfoptrs");
399 SET(p__AdjustPointer, "__AdjustPointer");
400 SET(p_fflush_nolock, "_fflush_nolock");
401 SET(p_mbstowcs, "mbstowcs");
402 SET(p_wcstombs, "wcstombs");
403 SET(p_setlocale, "setlocale");
404 SET(p__fpieee_flt, "_fpieee_flt");
405 SET(p__memicmp, "_memicmp");
406 SET(p__memicmp_l, "_memicmp_l");
407 SET(p__vsnwprintf, "_vsnwprintf");
408 SET(p___strncnt, "__strncnt");
409 SET(p_swscanf, "swscanf");
411 if (sizeof(void *) == 8)
413 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
414 SET(ptype_info_dtor, "??1type_info@@UEAA@XZ");
415 SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z");
417 else
419 #ifdef __arm__
420 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z");
421 SET(ptype_info_dtor, "??1type_info@@UAA@XZ");
422 #else
423 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
424 SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
425 #endif
426 SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z");
429 hkernel32 = GetModuleHandleA("kernel32.dll");
430 pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
431 return TRUE;
434 static int __cdecl initterm_cb0(void)
436 cb_called[0]++;
437 return 0;
440 static int __cdecl initterm_cb1(void)
442 cb_called[1]++;
443 return 1;
446 static int __cdecl initterm_cb2(void)
448 cb_called[2]++;
449 return 2;
453 static void test__initterm_e(void)
455 _INITTERM_E_FN table[4];
456 int res;
458 memset(table, 0, sizeof(table));
460 memset(cb_called, 0, sizeof(cb_called));
461 errno = 0xdeadbeef;
462 res = p_initterm_e(table, table);
463 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
464 "got %d with 0x%x {%d, %d, %d}\n",
465 res, errno, cb_called[0], cb_called[1], cb_called[2]);
467 memset(cb_called, 0, sizeof(cb_called));
468 errno = 0xdeadbeef;
469 res = p_initterm_e(table, NULL);
470 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
471 "got %d with 0x%x {%d, %d, %d}\n",
472 res, errno, cb_called[0], cb_called[1], cb_called[2]);
474 if (0) {
475 /* this crash on Windows */
476 errno = 0xdeadbeef;
477 res = p_initterm_e(NULL, table);
478 trace("got %d with 0x%x\n", res, errno);
481 table[0] = initterm_cb0;
482 memset(cb_called, 0, sizeof(cb_called));
483 errno = 0xdeadbeef;
484 res = p_initterm_e(table, &table[1]);
485 ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
486 "got %d with 0x%x {%d, %d, %d}\n",
487 res, errno, cb_called[0], cb_called[1], cb_called[2]);
490 /* init-function returning failure */
491 table[1] = initterm_cb1;
492 memset(cb_called, 0, sizeof(cb_called));
493 errno = 0xdeadbeef;
494 res = p_initterm_e(table, &table[3]);
495 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
496 "got %d with 0x%x {%d, %d, %d}\n",
497 res, errno, cb_called[0], cb_called[1], cb_called[2]);
499 /* init-function not called, when end < start */
500 memset(cb_called, 0, sizeof(cb_called));
501 errno = 0xdeadbeef;
502 res = p_initterm_e(&table[3], table);
503 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
504 "got %d with 0x%x {%d, %d, %d}\n",
505 res, errno, cb_called[0], cb_called[1], cb_called[2]);
507 /* initialization stop after first non-zero result */
508 table[2] = initterm_cb0;
509 memset(cb_called, 0, sizeof(cb_called));
510 errno = 0xdeadbeef;
511 res = p_initterm_e(table, &table[3]);
512 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
513 "got %d with 0x%x {%d, %d, %d}\n",
514 res, errno, cb_called[0], cb_called[1], cb_called[2]);
516 /* NULL pointer in the array are skipped */
517 table[1] = NULL;
518 table[2] = initterm_cb2;
519 memset(cb_called, 0, sizeof(cb_called));
520 errno = 0xdeadbeef;
521 res = p_initterm_e(table, &table[3]);
522 ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
523 "got %d with 0x%x {%d, %d, %d}\n",
524 res, errno, cb_called[0], cb_called[1], cb_called[2]);
528 /* Beware that _encode_pointer is a NOP before XP
529 (the parameter is returned unchanged) */
530 static void test__encode_pointer(void)
532 void *ptr, *res;
534 ptr = (void*)0xdeadbeef;
535 res = p_encode_pointer(ptr);
536 res = p_decode_pointer(res);
537 ok(res == ptr, "Pointers are different after encoding and decoding\n");
539 ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
541 ptr = p_encode_pointer(p_encode_pointer);
542 ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
544 /* Not present before XP */
545 if (!pEncodePointer) {
546 win_skip("EncodePointer not found\n");
547 return;
550 res = pEncodePointer(p_encode_pointer);
551 ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
555 static void test_error_messages(void)
557 int *size, size_copy;
559 size = p__sys_nerr();
560 size_copy = *size;
561 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
563 *size = 20;
564 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
566 *size = size_copy;
568 ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
571 static void test__strtoi64(void)
573 __int64 res;
574 unsigned __int64 ures;
576 SET_EXPECT(invalid_parameter_handler);
577 res = p_strtoi64(NULL, NULL, 10);
578 ok(res == 0, "res != 0\n");
579 CHECK_CALLED(invalid_parameter_handler, EINVAL);
581 SET_EXPECT(invalid_parameter_handler);
582 res = p_strtoi64("123", NULL, 1);
583 ok(res == 0, "res != 0\n");
584 CHECK_CALLED(invalid_parameter_handler, EINVAL);
586 SET_EXPECT(invalid_parameter_handler);
587 res = p_strtoi64("123", NULL, 37);
588 ok(res == 0, "res != 0\n");
589 CHECK_CALLED(invalid_parameter_handler, EINVAL);
591 SET_EXPECT(invalid_parameter_handler);
592 ures = p_strtoui64(NULL, NULL, 10);
593 ok(ures == 0, "res = %d\n", (int)ures);
594 CHECK_CALLED(invalid_parameter_handler, EINVAL);
596 SET_EXPECT(invalid_parameter_handler);
597 ures = p_strtoui64("123", NULL, 1);
598 ok(ures == 0, "res = %d\n", (int)ures);
599 CHECK_CALLED(invalid_parameter_handler, EINVAL);
601 SET_EXPECT(invalid_parameter_handler);
602 ures = p_strtoui64("123", NULL, 37);
603 ok(ures == 0, "res = %d\n", (int)ures);
604 CHECK_CALLED(invalid_parameter_handler, EINVAL);
607 static void test__itoa_s(void)
609 errno_t ret;
610 char buffer[33];
612 SET_EXPECT(invalid_parameter_handler);
613 ret = p_itoa_s(0, NULL, 0, 0);
614 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
615 CHECK_CALLED(invalid_parameter_handler, EINVAL);
617 memset(buffer, 'X', sizeof(buffer));
618 SET_EXPECT(invalid_parameter_handler);
619 ret = p_itoa_s(0, buffer, 0, 0);
620 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
621 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
622 CHECK_CALLED(invalid_parameter_handler, EINVAL);
624 memset(buffer, 'X', sizeof(buffer));
625 SET_EXPECT(invalid_parameter_handler);
626 ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
627 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
628 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
629 CHECK_CALLED(invalid_parameter_handler, EINVAL);
631 memset(buffer, 'X', sizeof(buffer));
632 SET_EXPECT(invalid_parameter_handler);
633 ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
634 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
635 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
636 CHECK_CALLED(invalid_parameter_handler, EINVAL);
638 memset(buffer, 'X', sizeof(buffer));
639 SET_EXPECT(invalid_parameter_handler);
640 ret = p_itoa_s(12345678, buffer, 4, 10);
641 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
642 ok(!memcmp(buffer, "\000765", 4),
643 "Expected the output buffer to be null terminated with truncated output\n");
644 CHECK_CALLED(invalid_parameter_handler, ERANGE);
646 memset(buffer, 'X', sizeof(buffer));
647 SET_EXPECT(invalid_parameter_handler);
648 ret = p_itoa_s(12345678, buffer, 8, 10);
649 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
650 ok(!memcmp(buffer, "\0007654321", 8),
651 "Expected the output buffer to be null terminated with truncated output\n");
652 CHECK_CALLED(invalid_parameter_handler, ERANGE);
654 memset(buffer, 'X', sizeof(buffer));
655 SET_EXPECT(invalid_parameter_handler);
656 ret = p_itoa_s(-12345678, buffer, 9, 10);
657 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
658 ok(!memcmp(buffer, "\00087654321", 9),
659 "Expected the output buffer to be null terminated with truncated output\n");
660 CHECK_CALLED(invalid_parameter_handler, ERANGE);
662 ret = p_itoa_s(12345678, buffer, 9, 10);
663 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
664 ok(!strcmp(buffer, "12345678"),
665 "Expected output buffer string to be \"12345678\", got \"%s\"\n",
666 buffer);
668 ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
669 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
670 ok(!strcmp(buffer, "1010101010101010"),
671 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
672 buffer);
674 ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
675 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
676 ok(!strcmp(buffer, "nell"),
677 "Expected output buffer string to be \"nell\", got \"%s\"\n",
678 buffer);
680 ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
681 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
682 ok(!strcmp(buffer, "hag"),
683 "Expected output buffer string to be \"hag\", got \"%s\"\n",
684 buffer);
686 ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
687 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
688 ok(!strcmp(buffer, "-12345678"),
689 "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
690 buffer);
693 static void test_wcsncat_s(void)
695 static wchar_t abcW[] = {'a','b','c',0};
696 int ret;
697 wchar_t dst[4];
698 wchar_t src[4];
700 memcpy(src, abcW, sizeof(abcW));
701 dst[0] = 0;
702 SET_EXPECT(invalid_parameter_handler);
703 ret = p_wcsncat_s(NULL, 4, src, 4);
704 ok(ret == EINVAL, "err = %d\n", ret);
705 CHECK_CALLED(invalid_parameter_handler, EINVAL);
707 SET_EXPECT(invalid_parameter_handler);
708 ret = p_wcsncat_s(dst, 0, src, 4);
709 ok(ret == EINVAL, "err = %d\n", ret);
710 CHECK_CALLED(invalid_parameter_handler, EINVAL);
712 SET_EXPECT(invalid_parameter_handler);
713 ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
714 ok(ret == EINVAL, "err = %d\n", ret);
715 CHECK_CALLED(invalid_parameter_handler, EINVAL);
717 ret = p_wcsncat_s(dst, 4, NULL, 0);
718 ok(ret == 0, "err = %d\n", ret);
720 dst[0] = 0;
721 SET_EXPECT(invalid_parameter_handler);
722 ret = p_wcsncat_s(dst, 2, src, 4);
723 ok(ret == ERANGE, "err = %d\n", ret);
724 CHECK_CALLED(invalid_parameter_handler, ERANGE);
726 dst[0] = 0;
727 ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
728 ok(ret == STRUNCATE, "err = %d\n", ret);
729 ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
731 memcpy(dst, abcW, sizeof(abcW));
732 dst[3] = 'd';
733 SET_EXPECT(invalid_parameter_handler);
734 ret = p_wcsncat_s(dst, 4, src, 4);
735 ok(ret == EINVAL, "err = %d\n", ret);
736 CHECK_CALLED(invalid_parameter_handler, EINVAL);
739 /* Based on dlls/ntdll/tests/string.c */
740 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
742 const int *p = a, *q = b;
744 ok (a != b, "must never get the same pointer\n");
745 ++*(int *) context;
747 return *p - *q;
750 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
752 const char *p = a, *q = b;
754 ok (a != b, "must never get the same pointer\n");
755 ++*(int *) context;
757 return *p - *q;
760 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
762 const char * const *p = a;
763 const char * const *q = b;
765 ok (a != b, "must never get the same pointer\n");
766 ++*(int *) context;
768 return lstrcmpA(*p, *q);
771 static void test_qsort_s(void)
773 int arr[5] = { 23, 42, 8, 4, 16 };
774 int arr2[5] = { 23, 42, 8, 4, 16 };
775 char carr[5] = { 42, 23, 4, 8, 16 };
776 const char *strarr[7] = {
777 "Hello",
778 "Wine",
779 "World",
780 "!",
781 "Hopefully",
782 "Sorted",
786 SET_EXPECT(invalid_parameter_handler);
787 p_qsort_s(NULL, 0, 0, NULL, NULL);
788 CHECK_CALLED(invalid_parameter_handler, EINVAL);
790 SET_EXPECT(invalid_parameter_handler);
791 p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
792 CHECK_CALLED(invalid_parameter_handler, EINVAL);
794 SET_EXPECT(invalid_parameter_handler);
795 p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
796 CHECK_CALLED(invalid_parameter_handler, EINVAL);
798 SET_EXPECT(invalid_parameter_handler);
799 p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
800 CHECK_CALLED(invalid_parameter_handler, EINVAL);
802 errno = 0xdeadbeef;
803 g_qsort_s_context_counter = 0;
804 p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
805 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
806 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
808 /* overflow without side effects, other overflow values crash */
809 errno = 0xdeadbeef;
810 g_qsort_s_context_counter = 0;
811 p_qsort_s((void*)arr2, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
812 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
813 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
814 ok(arr2[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2[0]);
815 ok(arr2[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2[1]);
816 ok(arr2[2] == 8, "should remain unsorted, arr2[2] is %d\n", arr2[2]);
817 ok(arr2[3] == 4, "should remain unsorted, arr2[3] is %d\n", arr2[3]);
819 errno = 0xdeadbeef;
820 g_qsort_s_context_counter = 0;
821 p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
822 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
823 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
824 ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
825 ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
826 ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
827 ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
828 ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
830 errno = 0xdeadbeef;
831 g_qsort_s_context_counter = 0;
832 p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
833 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
834 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
835 ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
836 ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
837 ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
838 ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
839 ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
841 SET_EXPECT(invalid_parameter_handler);
842 g_qsort_s_context_counter = 0;
843 p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
844 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
845 ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
846 ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
847 ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
848 ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
849 ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
850 CHECK_CALLED(invalid_parameter_handler, EINVAL);
852 g_qsort_s_context_counter = 0;
853 p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
854 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
855 ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
856 ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
857 ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
858 ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
859 ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
861 g_qsort_s_context_counter = 0;
862 p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
863 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
864 ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
865 ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
866 ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
867 ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
868 ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
870 g_qsort_s_context_counter = 0;
871 p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
872 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
873 ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
874 ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
875 ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
876 ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
877 ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
878 ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
879 ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
882 static void test_bsearch_s(void)
884 int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
885 int *x, l, i, j = 1;
887 SET_EXPECT(invalid_parameter_handler);
888 x = p_bsearch_s(NULL, NULL, 0, 0, NULL, NULL);
889 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
890 CHECK_CALLED(invalid_parameter_handler, EINVAL);
892 g_bsearch_s_context_counter = 0;
893 SET_EXPECT(invalid_parameter_handler);
894 x = p_bsearch_s(&l, arr, j, 0, intcomparefunc, &g_bsearch_s_context_counter);
895 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
896 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
897 CHECK_CALLED(invalid_parameter_handler, EINVAL);
899 g_bsearch_s_context_counter = 0;
900 SET_EXPECT(invalid_parameter_handler);
901 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), NULL, &g_bsearch_s_context_counter);
902 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
903 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
904 CHECK_CALLED(invalid_parameter_handler, EINVAL);
906 /* just try all array sizes */
907 for (j=1; j<ARRAY_SIZE(arr); j++) {
908 for (i=0;i<j;i++) {
909 l = arr[i];
910 g_bsearch_s_context_counter = 0;
911 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
912 ok (x == &arr[i], "bsearch_s did not find %d entry in loopsize %d.\n", i, j);
913 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
915 l = 4242;
916 g_bsearch_s_context_counter = 0;
917 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
918 ok (x == NULL, "bsearch_s did find 4242 entry in loopsize %d.\n", j);
919 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
923 static void test_controlfp_s(void)
925 unsigned int cur;
926 int ret;
928 SET_EXPECT(invalid_parameter_handler);
929 ret = p_controlfp_s( NULL, ~0, ~0 );
930 ok( ret == EINVAL, "wrong result %d\n", ret );
931 CHECK_CALLED(invalid_parameter_handler, EINVAL);
933 cur = 0xdeadbeef;
934 SET_EXPECT(invalid_parameter_handler);
935 ret = p_controlfp_s( &cur, ~0, ~0 );
936 ok( ret == EINVAL, "wrong result %d\n", ret );
937 ok( cur != 0xdeadbeef, "value not set\n" );
938 CHECK_CALLED(invalid_parameter_handler, EINVAL);
940 cur = 0xdeadbeef;
941 ret = p_controlfp_s( &cur, 0, 0 );
942 ok( !ret, "wrong result %d\n", ret );
943 ok( cur != 0xdeadbeef, "value not set\n" );
945 SET_EXPECT(invalid_parameter_handler);
946 cur = 0xdeadbeef;
947 ret = p_controlfp_s( &cur, 0x80000000, 0x80000000 );
948 ok( ret == EINVAL, "wrong result %d\n", ret );
949 ok( cur != 0xdeadbeef, "value not set\n" );
950 CHECK_CALLED(invalid_parameter_handler, EINVAL);
952 cur = 0xdeadbeef;
953 /* mask is only checked when setting invalid bits */
954 ret = p_controlfp_s( &cur, 0, 0x80000000 );
955 ok( !ret, "wrong result %d\n", ret );
956 ok( cur != 0xdeadbeef, "value not set\n" );
959 static void test_tmpfile_s( void )
961 int ret;
963 SET_EXPECT(invalid_parameter_handler);
964 ret = p_tmpfile_s(NULL);
965 ok(ret == EINVAL, "Expected tmpfile_s to return EINVAL, got %i\n", ret);
966 CHECK_CALLED(invalid_parameter_handler, EINVAL);
969 typedef struct
971 const char *str;
972 float flt;
973 int ret;
974 } _atoflt_test;
976 static const _atoflt_test _atoflt_testdata[] = {
977 { "12.1", 12.1, 0 },
978 { "-13.721", -13.721, 0 },
979 { "INF", 0.0, 0 },
980 { ".21e12", 0.21e12, 0 },
981 { "214353e-3", 214.353, 0 },
982 { "1d9999999999999999999", 0.0, _OVERFLOW },
983 { " d10", 0.0, 0 },
984 /* more significant digits */
985 { "1.23456789", 1.23456789, 0 },
986 { "1.23456789e1", 12.3456789, 0 },
987 { "1e39", 0.0, _OVERFLOW },
988 { "1e-39", 0.0, _UNDERFLOW },
989 { NULL }
992 static void test__atoflt(void)
994 _CRT_FLOAT flt;
995 int ret, i = 0;
997 if (0)
999 /* crashes on native */
1000 p_atoflt(NULL, NULL);
1001 p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
1002 p_atoflt(&flt, NULL);
1005 while (_atoflt_testdata[i].str)
1007 ret = p_atoflt(&flt, (char*)_atoflt_testdata[i].str);
1008 ok(ret == _atoflt_testdata[i].ret, "got ret %d, expected ret %d, for %s\n", ret,
1009 _atoflt_testdata[i].ret, _atoflt_testdata[i].str);
1011 if (ret == 0)
1012 ok(almost_equal_f(flt.f, _atoflt_testdata[i].flt), "got %f, expected %f, for %s\n", flt.f,
1013 _atoflt_testdata[i].flt, _atoflt_testdata[i].str);
1015 i++;
1019 static void test__set_abort_behavior(void)
1021 unsigned int res;
1023 /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
1024 res = p_set_abort_behavior(0, 0);
1025 ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
1026 "got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1028 /* no internal mask */
1029 p_set_abort_behavior(0xffffffff, 0xffffffff);
1030 res = p_set_abort_behavior(0, 0);
1031 ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
1033 /* set to default value */
1034 p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
1037 static void test__sopen_s(void)
1039 int ret, fd;
1041 SET_EXPECT(invalid_parameter_handler);
1042 ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
1043 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
1044 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1046 fd = 0xdead;
1047 ret = p_sopen_s(&fd, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
1048 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
1049 ok(fd == -1, "got %d\n", fd);
1052 static void test__wsopen_s(void)
1054 wchar_t testW[] = {'t','e','s','t',0};
1055 int ret, fd;
1057 SET_EXPECT(invalid_parameter_handler);
1058 ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
1059 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
1060 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1062 fd = 0xdead;
1063 ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
1064 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
1065 ok(fd == -1, "got %d\n", fd);
1068 static void test__realloc_crt(void)
1070 void *mem;
1072 if (0)
1074 /* crashes on some systems starting Vista */
1075 p_realloc_crt(NULL, 10);
1078 mem = p_malloc(10);
1079 ok(mem != NULL, "memory not allocated\n");
1081 mem = p_realloc_crt(mem, 20);
1082 ok(mem != NULL, "memory not reallocated\n");
1084 mem = p_realloc_crt(mem, 0);
1085 ok(mem == NULL, "memory not freed\n");
1087 mem = p_realloc_crt(NULL, 0);
1088 ok(mem != NULL, "memory not (re)allocated for size 0\n");
1089 p_free(mem);
1092 static void test_typeinfo(void)
1094 static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
1095 struct __type_info_node node;
1096 char *name;
1098 /* name */
1099 t1.name = NULL;
1100 node.memPtr = NULL;
1101 node.next = NULL;
1102 name = call_func2(p_type_info_name_internal_method, &t1, &node);
1103 ok(name != NULL, "got %p\n", name);
1104 ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
1106 ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
1107 call_func1(ptype_info_dtor, &t1);
1110 /* Keep in sync with msvcrt/msvcrt.h */
1111 struct __thread_data {
1112 DWORD tid;
1113 HANDLE handle;
1114 int thread_errno;
1115 __msvcrt_ulong thread_doserrno;
1116 int unk1;
1117 unsigned int random_seed;
1118 char *strtok_next;
1119 wchar_t *wcstok_next;
1120 unsigned char *mbstok_next;
1121 char *strerror_buffer;
1122 wchar_t *wcserror_buffer;
1123 char *tmpnam_buffer;
1124 wchar_t *wtmpnam_buffer;
1125 void *unk2[2];
1126 char *asctime_buffer;
1127 wchar_t *wasctime_buffer;
1128 struct tm *time_buffer;
1129 char *efcvt_buffer;
1130 int unk3[2];
1131 void *unk4[3];
1132 EXCEPTION_POINTERS *xcptinfo;
1133 int fpecode;
1134 pthreadmbcinfo mbcinfo;
1135 pthreadlocinfo locinfo;
1136 BOOL have_locale;
1137 int unk5[1];
1138 void* terminate_handler;
1139 void* unexpected_handler;
1140 void* se_translator;
1141 void *unk6[3];
1142 int unk7;
1143 EXCEPTION_RECORD *exc_record;
1146 static void test_getptd(void)
1148 struct __thread_data *ptd = p_getptd();
1149 DWORD tid = GetCurrentThreadId();
1150 wchar_t testW[] = {'t','e','s','t',0}, tW[] = {'t',0}, *wp;
1151 char test[] = "test", *p;
1152 unsigned char mbstok_test[] = "test", *up;
1153 struct tm time;
1154 __time64_t secs = 0;
1155 int dec, sign;
1156 void *mbcinfo, *locinfo;
1158 ok(ptd->tid == tid, "ptd->tid = %x, expected %x\n", ptd->tid, tid);
1159 ok(ptd->handle == INVALID_HANDLE_VALUE, "ptd->handle = %p\n", ptd->handle);
1160 ok(p_errno() == &ptd->thread_errno, "ptd->thread_errno is different then _errno()\n");
1161 ok(p_doserrno() == &ptd->thread_doserrno, "ptd->thread_doserrno is different then __doserrno()\n");
1162 p_srand(1234);
1163 ok(ptd->random_seed == 1234, "ptd->random_seed = %d\n", ptd->random_seed);
1164 p = p_strtok(test, "t");
1165 ok(ptd->strtok_next == p+3, "ptd->strtok_next is incorrect\n");
1166 wp = p_wcstok(testW, tW);
1167 ok(ptd->wcstok_next == wp+3, "ptd->wcstok_next is incorrect\n");
1168 up = p__mbstok(mbstok_test, (unsigned char*)"t");
1169 ok(ptd->mbstok_next == up+3, "ptd->mbstok_next is incorrect\n");
1170 ok(p_strerror(0) == ptd->strerror_buffer, "ptd->strerror_buffer is incorrect\n");
1171 ok(p_wcserror(0) == ptd->wcserror_buffer, "ptd->wcserror_buffer is incorrect\n");
1172 ok(p_tmpnam(NULL) == ptd->tmpnam_buffer, "ptd->tmpnam_buffer is incorrect\n");
1173 ok(p_wtmpnam(NULL) == ptd->wtmpnam_buffer, "ptd->wtmpnam_buffer is incorrect\n");
1174 memset(&time, 0, sizeof(time));
1175 time.tm_mday = 1;
1176 ok(p_asctime(&time) == ptd->asctime_buffer, "ptd->asctime_buffer is incorrect\n");
1177 ok(p_wasctime(&time) == ptd->wasctime_buffer, "ptd->wasctime_buffer is incorrect\n");
1178 ok(p_localtime64(&secs) == ptd->time_buffer, "ptd->time_buffer is incorrect\n");
1179 ok(p_ecvt(3.12, 1, &dec, &sign) == ptd->efcvt_buffer, "ptd->efcvt_buffer is incorrect\n");
1180 ok(p__pxcptinfoptrs() == (void**)&ptd->xcptinfo, "ptd->xcptinfo is incorrect\n");
1181 ok(p_fpecode() == &ptd->fpecode, "ptd->fpecode is incorrect\n");
1182 mbcinfo = ptd->mbcinfo;
1183 locinfo = ptd->locinfo;
1184 todo_wine ok(ptd->have_locale == 1, "ptd->have_locale = %x\n", ptd->have_locale);
1185 p_configthreadlocale(1);
1186 todo_wine ok(mbcinfo == ptd->mbcinfo, "ptd->mbcinfo != mbcinfo\n");
1187 todo_wine ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n");
1188 todo_wine ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale);
1189 ok(p_get_terminate() == ptd->terminate_handler, "ptd->terminate_handler != _get_terminate()\n");
1190 ok(p_get_unexpected() == ptd->unexpected_handler, "ptd->unexpected_handler != _get_unexpected()\n");
1193 static int WINAPIV __vswprintf_l_wrapper(wchar_t *buf,
1194 const wchar_t *format, _locale_t locale, ...)
1196 int ret;
1197 __ms_va_list valist;
1198 __ms_va_start(valist, locale);
1199 ret = p__vswprintf_l(buf, format, locale, valist);
1200 __ms_va_end(valist);
1201 return ret;
1204 static int WINAPIV _vswprintf_l_wrapper(wchar_t *buf,
1205 const wchar_t *format, _locale_t locale, ...)
1207 int ret;
1208 __ms_va_list valist;
1209 __ms_va_start(valist, locale);
1210 ret = p_vswprintf_l(buf, format, locale, valist);
1211 __ms_va_end(valist);
1212 return ret;
1215 static void test__vswprintf_l(void)
1217 static const wchar_t format[] = {'t','e','s','t',0};
1219 wchar_t buf[32];
1220 int ret;
1222 ret = __vswprintf_l_wrapper(buf, format, NULL);
1223 ok(ret == 4, "ret = %d\n", ret);
1224 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1225 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1227 ret = _vswprintf_l_wrapper(buf, format, NULL);
1228 ok(ret == 4, "ret = %d\n", ret);
1229 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1230 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1233 struct block_file_arg
1235 FILE *read;
1236 FILE *write;
1237 HANDLE init;
1238 HANDLE finish;
1239 int deadlock_test;
1242 static DWORD WINAPI block_file(void *arg)
1244 struct block_file_arg *files = arg;
1245 int deadlock_test;
1247 p_lock_file(files->read);
1248 p_lock_file(files->write);
1249 SetEvent(files->init);
1251 WaitForSingleObject(files->finish, INFINITE);
1252 Sleep(200);
1253 deadlock_test = InterlockedIncrement(&files->deadlock_test);
1254 ok(deadlock_test == 1, "deadlock_test = %d\n", deadlock_test);
1255 p_unlock_file(files->read);
1256 p_unlock_file(files->write);
1257 return 0;
1260 static void test_nonblocking_file_access(void)
1262 HANDLE thread;
1263 struct block_file_arg arg;
1264 FILE *filer, *filew;
1265 int ret;
1267 if(!p_lock_file || !p_unlock_file) {
1268 win_skip("_lock_file not available\n");
1269 return;
1272 filew = p_fopen("test_file", "w");
1273 ok(filew != NULL, "unable to create test file\n");
1274 if(!filew)
1275 return;
1276 filer = p_fopen("test_file", "r");
1277 ok(filer != NULL, "unable to open test file\n");
1278 if(!filer) {
1279 p_fclose(filew);
1280 p_unlink("test_file");
1281 return;
1284 arg.read = filer;
1285 arg.write = filew;
1286 arg.init = CreateEventW(NULL, FALSE, FALSE, NULL);
1287 arg.finish = CreateEventW(NULL, FALSE, FALSE, NULL);
1288 arg.deadlock_test = 0;
1289 ok(arg.init != NULL, "CreateEventW failed\n");
1290 ok(arg.finish != NULL, "CreateEventW failed\n");
1291 thread = CreateThread(NULL, 0, block_file, (void*)&arg, 0, NULL);
1292 ok(thread != NULL, "CreateThread failed\n");
1293 WaitForSingleObject(arg.init, INFINITE);
1295 ret = p_fileno(filer);
1296 ok(ret, "_fileno(filer) returned %d\n", ret);
1297 ret = p_fileno(filew);
1298 ok(ret, "_fileno(filew) returned %d\n", ret);
1300 ret = p_feof(filer);
1301 ok(ret==0, "feof(filer) returned %d\n", ret);
1302 ret = p_feof(filew);
1303 ok(ret==0, "feof(filew) returned %d\n", ret);
1305 ret = p_ferror(filer);
1306 ok(ret==0, "ferror(filer) returned %d\n", ret);
1307 ret = p_ferror(filew);
1308 ok(ret==0, "ferror(filew) returned %d\n", ret);
1310 ret = p_flsbuf('a', filer);
1311 ok(ret==-1, "_flsbuf(filer) returned %d\n", ret);
1312 ret = p_flsbuf('a', filew);
1313 ok(ret=='a', "_flsbuf(filew) returned %d\n", ret);
1315 ret = p_filbuf(filer);
1316 ok(ret==-1, "_filbuf(filer) returned %d\n", ret);
1317 ret = p_filbuf(filew);
1318 ok(ret==-1, "_filbuf(filew) returned %d\n", ret);
1320 ret = p_fflush_nolock(filer);
1321 ok(ret==0, "_fflush_nolock(filer) returned %d\n", ret);
1322 ret = p_fflush_nolock(filew);
1323 ok(ret==0, "_fflush_nolock(filew) returned %d\n", ret);
1325 SetEvent(arg.finish);
1327 ret = p_fflush_nolock(NULL);
1328 ok(ret==0, "_fflush_nolock(NULL) returned %d\n", ret);
1329 ret = InterlockedIncrement(&arg.deadlock_test);
1330 ok(ret==2, "InterlockedIncrement returned %d\n", ret);
1332 WaitForSingleObject(thread, INFINITE);
1333 CloseHandle(arg.init);
1334 CloseHandle(arg.finish);
1335 CloseHandle(thread);
1336 p_fclose(filer);
1337 p_fclose(filew);
1338 p_unlink("test_file");
1341 static void test_byteswap(void)
1343 unsigned long ret;
1345 ret = p_byteswap_ulong(0x12345678);
1346 ok(ret == 0x78563412, "ret = %lx\n", ret);
1348 ret = p_byteswap_ulong(0);
1349 ok(ret == 0, "ret = %lx\n", ret);
1352 static void test_access_s(void)
1354 FILE *f;
1355 int res;
1357 f = p_fopen("test_file", "w");
1358 ok(f != NULL, "unable to create test file\n");
1359 if(!f)
1360 return;
1362 p_fclose(f);
1364 errno = 0xdeadbeef;
1365 res = p_access_s("test_file", 0);
1366 ok(res == 0, "got %x\n", res);
1367 ok(errno == 0xdeadbeef, "got %x\n", res);
1369 errno = 0xdeadbeef;
1370 res = p_access_s("test_file", 2);
1371 ok(res == 0, "got %x\n", res);
1372 ok(errno == 0xdeadbeef, "got %x\n", res);
1374 errno = 0xdeadbeef;
1375 res = p_access_s("test_file", 4);
1376 ok(res == 0, "got %x\n", res);
1377 ok(errno == 0xdeadbeef, "got %x\n", res);
1379 errno = 0xdeadbeef;
1380 res = p_access_s("test_file", 6);
1381 ok(res == 0, "got %x\n", res);
1382 ok(errno == 0xdeadbeef, "got %x\n", res);
1384 SetFileAttributesA("test_file", FILE_ATTRIBUTE_READONLY);
1386 errno = 0xdeadbeef;
1387 res = p_access_s("test_file", 0);
1388 ok(res == 0, "got %x\n", res);
1389 ok(errno == 0xdeadbeef, "got %x\n", res);
1391 errno = 0xdeadbeef;
1392 res = p_access_s("test_file", 2);
1393 ok(res == EACCES, "got %x\n", res);
1394 ok(errno == EACCES, "got %x\n", res);
1396 errno = 0xdeadbeef;
1397 res = p_access_s("test_file", 4);
1398 ok(res == 0, "got %x\n", res);
1399 ok(errno == 0xdeadbeef, "got %x\n", res);
1401 errno = 0xdeadbeef;
1402 res = p_access_s("test_file", 6);
1403 ok(res == EACCES, "got %x\n", res);
1404 ok(errno == EACCES, "got %x\n", res);
1406 SetFileAttributesA("test_file", FILE_ATTRIBUTE_NORMAL);
1408 p_unlink("test_file");
1410 errno = 0xdeadbeef;
1411 res = p_access_s("test_file", 0);
1412 ok(res == ENOENT, "got %x\n", res);
1413 ok(errno == ENOENT, "got %x\n", res);
1415 errno = 0xdeadbeef;
1416 res = p_access_s("test_file", 2);
1417 ok(res == ENOENT, "got %x\n", res);
1418 ok(errno == ENOENT, "got %x\n", res);
1420 errno = 0xdeadbeef;
1421 res = p_access_s("test_file", 4);
1422 ok(res == ENOENT, "got %x\n", res);
1423 ok(errno == ENOENT, "got %x\n", res);
1425 errno = 0xdeadbeef;
1426 res = p_access_s("test_file", 6);
1427 ok(res == ENOENT, "got %x\n", res);
1428 ok(errno == ENOENT, "got %x\n", res);
1431 #ifndef __x86_64__
1432 #define EXCEPTION_REF(instance, name) &instance.name
1433 #else
1434 #define EXCEPTION_REF(instance, name) FIELD_OFFSET(struct _exception_data, name)
1435 #endif
1436 static void test_is_exception_typeof(void)
1438 const type_info ti1 = {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}};
1439 const type_info ti2 = {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}};
1440 const type_info ti3 = {NULL, NULL, {'.','?','A','V','t','e','s','t','3','@','@',0}};
1442 const struct _exception_data {
1443 type_info ti1;
1444 type_info ti2;
1445 cxx_type_info cti1;
1446 cxx_type_info cti2;
1447 cxx_type_info_table tit;
1448 cxx_exception_type et;
1449 } exception_data = {
1450 {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}},
1451 {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}},
1452 {0, EXCEPTION_REF(exception_data, ti1)},
1453 {0, EXCEPTION_REF(exception_data, ti2)},
1454 {2, {EXCEPTION_REF(exception_data, cti1), EXCEPTION_REF(exception_data, cti2)}},
1455 {0, 0, 0, EXCEPTION_REF(exception_data, tit)}
1458 EXCEPTION_RECORD rec = {CXX_EXCEPTION, 0, NULL, NULL, 3, {CXX_FRAME_MAGIC_VC6, 0, (ULONG_PTR)&exception_data.et}};
1459 EXCEPTION_POINTERS except_ptrs = {&rec, NULL};
1461 int ret;
1463 #ifdef __x86_64__
1464 rec.NumberParameters = 4;
1465 rec.ExceptionInformation[3] = (ULONG_PTR)&exception_data;
1466 #endif
1468 ret = p_is_exception_typeof(&ti1, &except_ptrs);
1469 ok(ret == 1, "_is_exception_typeof returned %d\n", ret);
1470 ret = p_is_exception_typeof(&ti2, &except_ptrs);
1471 ok(ret == 1, "_is_exception_typeof returned %d\n", ret);
1472 ret = p_is_exception_typeof(&ti3, &except_ptrs);
1473 ok(ret == 0, "_is_exception_typeof returned %d\n", ret);
1476 static void test__AdjustPointer(void)
1478 int off = 0xf0;
1479 void *obj1 = &off;
1480 void *obj2 = (char*)&off - 2;
1481 struct test_data {
1482 void *ptr;
1483 void *ret;
1484 struct {
1485 int this_offset;
1486 int vbase_descr;
1487 int vbase_offset;
1488 } this_ptr_offsets;
1489 } data[] = {
1490 {NULL, NULL, {0, -1, 0}},
1491 {(void*)0xbeef, (void*)0xbef0, {1, -1, 1}},
1492 {(void*)0xbeef, (void*)0xbeee, {-1, -1, 0}},
1493 {&obj1, (char*)&obj1 + off, {0, 0, 0}},
1494 {(char*)&obj1 - 5, (char*)&obj1 + off, {0, 5, 0}},
1495 {(char*)&obj1 - 3, (char*)&obj1 + off + 24, {24, 3, 0}},
1496 {(char*)&obj2 - 17, (char*)&obj2 + off + 4, {4, 17, 2}}
1498 void *ret;
1499 int i;
1501 for(i=0; i<ARRAY_SIZE(data); i++) {
1502 ret = p__AdjustPointer(data[i].ptr, &data[i].this_ptr_offsets);
1503 ok(ret == data[i].ret, "%d) __AdjustPointer returned %p, expected %p\n", i, ret, data[i].ret);
1507 static void test_mbstowcs(void)
1509 wchar_t bufw[16];
1510 char buf[16];
1511 size_t ret;
1513 buf[0] = 'a';
1514 buf[1] = 0;
1515 memset(bufw, 'x', sizeof(bufw));
1516 ret = p_mbstowcs(bufw, buf, -1);
1517 ok(ret == 1, "ret = %d\n", (int)ret);
1518 ok(bufw[0] == 'a', "bufw[0] = '%c'\n", bufw[0]);
1519 ok(bufw[1] == 0, "bufw[1] = '%c'\n", bufw[1]);
1521 memset(bufw, 'x', sizeof(bufw));
1522 ret = p_mbstowcs(bufw, buf, -1000);
1523 ok(ret == 1, "ret = %d\n", (int)ret);
1524 ok(bufw[0] == 'a', "bufw[0] = '%c'\n", bufw[0]);
1525 ok(bufw[1] == 0, "bufw[1] = '%c'\n", bufw[1]);
1527 memset(buf, 'x', sizeof(buf));
1528 ret = p_wcstombs(buf, bufw, -1);
1529 ok(ret == 1, "ret = %d\n", (int)ret);
1530 ok(buf[0] == 'a', "buf[0] = '%c'\n", buf[0]);
1531 ok(buf[1] == 0, "buf[1] = '%c'\n", buf[1]);
1533 memset(buf, 'x', sizeof(buf));
1534 ret = p_wcstombs(buf, bufw, -1000);
1535 ok(ret == 1, "ret = %d\n", (int)ret);
1536 ok(buf[0] == 'a', "buf[0] = '%c'\n", buf[0]);
1537 ok(buf[1] == 0, "buf[1] = '%c'\n", buf[1]);
1539 if(!p_setlocale(LC_ALL, "English")) {
1540 win_skip("English locale not available\n");
1541 return;
1544 buf[0] = 'a';
1545 buf[1] = 0;
1546 memset(bufw, 'x', sizeof(bufw));
1547 ret = p_mbstowcs(bufw, buf, -1);
1548 ok(ret == -1, "ret = %d\n", (int)ret);
1549 ok(bufw[0] == 0, "bufw[0] = '%c'\n", bufw[0]);
1551 memset(bufw, 'x', sizeof(bufw));
1552 ret = p_mbstowcs(bufw, buf, -1000);
1553 ok(ret == -1, "ret = %d\n", (int)ret);
1554 ok(bufw[0] == 0, "bufw[0] = '%c'\n", bufw[0]);
1556 memset(buf, 'x', sizeof(buf));
1557 ret = p_wcstombs(buf, bufw, -1);
1558 ok(ret == 0, "ret = %d\n", (int)ret);
1559 ok(buf[0] == 0, "buf[0] = '%c'\n", buf[0]);
1561 memset(buf, 'x', sizeof(buf));
1562 ret = p_wcstombs(buf, bufw, -1000);
1563 ok(ret == 0, "ret = %d\n", (int)ret);
1564 ok(buf[0] == 0, "buf[0] = '%c'\n", buf[0]);
1566 p_setlocale(LC_ALL, "C");
1569 static void test_strtok_s(void)
1571 char test[] = "a/b";
1572 char empty[] = "";
1573 char space[] = " ";
1574 char delim[] = "/";
1575 char *strret;
1576 char *context;
1578 context = (char*)0xdeadbeef;
1579 strret = p_strtok_s( test, delim, &context);
1580 ok(strret == test, "Expected test, got %p.\n", strret);
1581 ok(context == test+2, "Expected test+2, got %p.\n", context);
1583 strret = p_strtok_s( NULL, delim, &context);
1584 ok(strret == test+2, "Expected test+2, got %p.\n", strret);
1585 ok(context == test+3, "Expected test+3, got %p.\n", context);
1587 strret = p_strtok_s( NULL, delim, &context);
1588 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1589 ok(context == test+3, "Expected test+3, got %p.\n", context);
1591 context = NULL;
1592 strret = p_strtok_s( empty, delim, &context);
1593 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1594 ok(context == empty, "Expected empty, got %p.\n", context);
1596 strret = p_strtok_s( NULL, delim, &context);
1597 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1598 ok(context == empty, "Expected empty, got %p.\n", context);
1600 context = NULL;
1601 strret = p_strtok_s( space, delim, &context);
1602 ok(strret == space, "Expected space, got %p.\n", strret);
1603 ok(context == space+1, "Expected space+1, got %p.\n", context);
1605 strret = p_strtok_s( NULL, delim, &context);
1606 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1607 ok(context == space+1, "Expected space+1, got %p.\n", context);
1610 static void test__mbstok_s(void)
1612 unsigned char test[] = "a/b";
1613 unsigned char empty[] = "";
1614 unsigned char space[] = " ";
1615 unsigned char delim[] = "/";
1616 unsigned char *strret;
1617 unsigned char *context;
1619 context = (unsigned char*)0xdeadbeef;
1620 strret = p__mbstok_s( test, delim, &context);
1621 ok(strret == test, "Expected test, got %p.\n", strret);
1622 ok(context == test+2, "Expected test+2, got %p.\n", context);
1624 strret = p__mbstok_s( NULL, delim, &context);
1625 ok(strret == test+2, "Expected test+2, got %p.\n", strret);
1626 ok(context == test+3, "Expected test+3, got %p.\n", context);
1628 strret = p__mbstok_s( NULL, delim, &context);
1629 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1630 ok(context == test+3, "Expected test+3, got %p.\n", context);
1632 context = NULL;
1633 strret = p__mbstok_s( empty, delim, &context);
1634 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1635 ok(context == empty, "Expected empty, got %p.\n", context);
1637 strret = p__mbstok_s( NULL, delim, &context);
1638 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1639 ok(context == empty, "Expected empty, got %p.\n", context);
1641 context = NULL;
1642 strret = p__mbstok_s( space, delim, &context);
1643 ok(strret == space, "Expected space, got %p.\n", strret);
1644 ok(context == space+1, "Expected space+1, got %p.\n", context);
1646 strret = p__mbstok_s( NULL, delim, &context);
1647 ok(strret == NULL, "Expected NULL, got %p.\n", strret);
1648 ok(context == space+1, "Expected space+1, got %p.\n", context);
1651 #ifdef __i386__
1652 static _FPIEEE_RECORD fpieee_record;
1653 static int handler_called;
1654 static int __cdecl fpieee_handler(_FPIEEE_RECORD *rec)
1656 handler_called++;
1657 fpieee_record = *rec;
1658 return EXCEPTION_CONTINUE_EXECUTION;
1661 static void test__fpieee_flt(void)
1663 double argd = 1.5;
1664 struct {
1665 DWORD exception_code;
1666 WORD opcode;
1667 DWORD data_offset;
1668 DWORD control_word;
1669 DWORD status_word;
1670 _FPIEEE_RECORD rec;
1671 int ret;
1672 } test_data[] = {
1673 { STATUS_FLOAT_DIVIDE_BY_ZERO, 0x35dc, (DWORD)&argd, 0, 0,
1674 {0, 2, _FpCodeDivide,
1675 {0}, {1, 1, 1, 1, 1}, {0},
1676 {{0}, 1, _FpFormatFp80},
1677 {{0}, 1, _FpFormatFp64},
1678 {{0}, 0, _FpFormatFp80}},
1679 EXCEPTION_CONTINUE_EXECUTION },
1680 { STATUS_FLOAT_INEXACT_RESULT, 0x35dc, (DWORD)&argd, 0, 0,
1681 {0, 2, _FpCodeDivide,
1682 {0}, {1, 1, 1, 1, 1}, {0},
1683 {{0}, 0, _FpFormatFp80},
1684 {{0}, 1, _FpFormatFp64},
1685 {{0}, 1, _FpFormatFp80}},
1686 EXCEPTION_CONTINUE_EXECUTION },
1687 { STATUS_FLOAT_INVALID_OPERATION, 0x35dc, (DWORD)&argd, 0, 0,
1688 {0, 2, _FpCodeDivide,
1689 {0}, {1, 1, 1, 1, 1}, {0},
1690 {{0}, 1, _FpFormatFp80},
1691 {{0}, 1, _FpFormatFp64},
1692 {{0}, 0, _FpFormatFp80}},
1693 EXCEPTION_CONTINUE_EXECUTION },
1694 { STATUS_FLOAT_OVERFLOW, 0x35dc, (DWORD)&argd, 0, 0,
1695 {0, 2, _FpCodeDivide,
1696 {0}, {1, 1, 1, 1, 1}, {0},
1697 {{0}, 0, _FpFormatFp80},
1698 {{0}, 1, _FpFormatFp64},
1699 {{0}, 1, _FpFormatFp80}},
1700 EXCEPTION_CONTINUE_EXECUTION },
1701 { STATUS_FLOAT_UNDERFLOW, 0x35dc, (DWORD)&argd, 0, 0,
1702 {0, 2, _FpCodeDivide,
1703 {0}, {1, 1, 1, 1, 1}, {0},
1704 {{0}, 0, _FpFormatFp80},
1705 {{0}, 1, _FpFormatFp64},
1706 {{0}, 1, _FpFormatFp80}},
1707 EXCEPTION_CONTINUE_EXECUTION },
1708 { STATUS_FLOAT_DIVIDE_BY_ZERO, 0x35dc, (DWORD)&argd, 0, 0xffffffff,
1709 {0, 2, _FpCodeDivide,
1710 {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1},
1711 {{0}, 1, _FpFormatFp80},
1712 {{0}, 1, _FpFormatFp64},
1713 {{0}, 0, _FpFormatFp80}},
1714 EXCEPTION_CONTINUE_EXECUTION },
1715 { STATUS_FLOAT_DIVIDE_BY_ZERO, 0x35dc, (DWORD)&argd, 0xffffffff, 0xffffffff,
1716 {3, 0, _FpCodeDivide,
1717 {0}, {0}, {1, 1, 1, 1, 1},
1718 {{0}, 1, _FpFormatFp80},
1719 {{0}, 1, _FpFormatFp64},
1720 {{0}, 0, _FpFormatFp80}},
1721 EXCEPTION_CONTINUE_EXECUTION },
1723 EXCEPTION_POINTERS ep;
1724 EXCEPTION_RECORD rec;
1725 CONTEXT ctx;
1726 int i, ret;
1728 if(!p__fpieee_flt) {
1729 win_skip("_fpieee_flt not available\n");
1730 return;
1733 ep.ExceptionRecord = &rec;
1734 ep.ContextRecord = &ctx;
1735 memset(&rec, 0, sizeof(rec));
1736 memset(&ctx, 0, sizeof(ctx));
1737 ret = p__fpieee_flt(1, &ep, fpieee_handler);
1738 ok(ret == EXCEPTION_CONTINUE_SEARCH, "_fpieee_flt returned %d\n", ret);
1739 ok(handler_called == 0, "handler_called = %d\n", handler_called);
1741 for(i=0; i<ARRAY_SIZE(test_data); i++) {
1742 ep.ExceptionRecord = &rec;
1743 ep.ContextRecord = &ctx;
1744 memset(&rec, 0, sizeof(rec));
1745 memset(&ctx, 0, sizeof(ctx));
1747 ctx.FloatSave.ErrorOffset = (DWORD)&test_data[i].opcode;
1748 ctx.FloatSave.DataOffset = test_data[i].data_offset;
1749 ctx.FloatSave.ControlWord = test_data[i].control_word;
1750 ctx.FloatSave.StatusWord = test_data[i].status_word;
1752 handler_called = 0;
1753 ret = p__fpieee_flt(test_data[i].exception_code, &ep, fpieee_handler);
1754 ok(ret == test_data[i].ret, "%d) _fpieee_flt returned %d\n", i, ret);
1755 ok(handler_called == 1, "%d) handler_called = %d\n", i, handler_called);
1757 ok(fpieee_record.RoundingMode == test_data[i].rec.RoundingMode,
1758 "%d) RoundingMode = %x\n", i, fpieee_record.RoundingMode);
1759 ok(fpieee_record.Precision == test_data[i].rec.Precision,
1760 "%d) Precision = %x\n", i, fpieee_record.Precision);
1761 ok(fpieee_record.Operation == test_data[i].rec.Operation,
1762 "%d) Operation = %x\n", i, fpieee_record.Operation);
1763 ok(fpieee_record.Cause.Inexact == test_data[i].rec.Cause.Inexact,
1764 "%d) Cause.Inexact = %x\n", i, fpieee_record.Cause.Inexact);
1765 ok(fpieee_record.Cause.Underflow == test_data[i].rec.Cause.Underflow,
1766 "%d) Cause.Underflow = %x\n", i, fpieee_record.Cause.Underflow);
1767 ok(fpieee_record.Cause.Overflow == test_data[i].rec.Cause.Overflow,
1768 "%d) Cause.Overflow = %x\n", i, fpieee_record.Cause.Overflow);
1769 ok(fpieee_record.Cause.ZeroDivide == test_data[i].rec.Cause.ZeroDivide,
1770 "%d) Cause.ZeroDivide = %x\n", i, fpieee_record.Cause.ZeroDivide);
1771 ok(fpieee_record.Cause.InvalidOperation == test_data[i].rec.Cause.InvalidOperation,
1772 "%d) Cause.InvalidOperation = %x\n", i, fpieee_record.Cause.InvalidOperation);
1773 ok(fpieee_record.Enable.Inexact == test_data[i].rec.Enable.Inexact,
1774 "%d) Enable.Inexact = %x\n", i, fpieee_record.Enable.Inexact);
1775 ok(fpieee_record.Enable.Underflow == test_data[i].rec.Enable.Underflow,
1776 "%d) Enable.Underflow = %x\n", i, fpieee_record.Enable.Underflow);
1777 ok(fpieee_record.Enable.Overflow == test_data[i].rec.Enable.Overflow,
1778 "%d) Enable.Overflow = %x\n", i, fpieee_record.Enable.Overflow);
1779 ok(fpieee_record.Enable.ZeroDivide == test_data[i].rec.Enable.ZeroDivide,
1780 "%d) Enable.ZeroDivide = %x\n", i, fpieee_record.Enable.ZeroDivide);
1781 ok(fpieee_record.Enable.InvalidOperation == test_data[i].rec.Enable.InvalidOperation,
1782 "%d) Enable.InvalidOperation = %x\n", i, fpieee_record.Enable.InvalidOperation);
1783 ok(fpieee_record.Status.Inexact == test_data[i].rec.Status.Inexact,
1784 "%d) Status.Inexact = %x\n", i, fpieee_record.Status.Inexact);
1785 ok(fpieee_record.Status.Underflow == test_data[i].rec.Status.Underflow,
1786 "%d) Status.Underflow = %x\n", i, fpieee_record.Status.Underflow);
1787 ok(fpieee_record.Status.Overflow == test_data[i].rec.Status.Overflow,
1788 "%d) Status.Overflow = %x\n", i, fpieee_record.Status.Overflow);
1789 ok(fpieee_record.Status.ZeroDivide == test_data[i].rec.Status.ZeroDivide,
1790 "%d) Status.ZeroDivide = %x\n", i, fpieee_record.Status.ZeroDivide);
1791 ok(fpieee_record.Status.InvalidOperation == test_data[i].rec.Status.InvalidOperation,
1792 "%d) Status.InvalidOperation = %x\n", i, fpieee_record.Status.InvalidOperation);
1793 ok(fpieee_record.Operand1.OperandValid == test_data[i].rec.Operand1.OperandValid,
1794 "%d) Operand1.OperandValid = %x\n", i, fpieee_record.Operand1.OperandValid);
1795 if(fpieee_record.Operand1.OperandValid) {
1796 ok(fpieee_record.Operand1.Format == test_data[i].rec.Operand1.Format,
1797 "%d) Operand1.Format = %x\n", i, fpieee_record.Operand1.Format);
1799 ok(fpieee_record.Operand2.OperandValid == test_data[i].rec.Operand2.OperandValid,
1800 "%d) Operand2.OperandValid = %x\n", i, fpieee_record.Operand2.OperandValid);
1801 ok(fpieee_record.Operand2.Format == test_data[i].rec.Operand2.Format,
1802 "%d) Operand2.Format = %x\n", i, fpieee_record.Operand2.Format);
1803 ok(fpieee_record.Result.OperandValid == test_data[i].rec.Result.OperandValid,
1804 "%d) Result.OperandValid = %x\n", i, fpieee_record.Result.OperandValid);
1805 ok(fpieee_record.Result.Format == test_data[i].rec.Result.Format,
1806 "%d) Result.Format = %x\n", i, fpieee_record.Result.Format);
1809 #endif
1811 static void test__memicmp(void)
1813 static const char *s1 = "abc";
1814 static const char *s2 = "aBd";
1815 int ret;
1817 ret = p__memicmp(NULL, NULL, 0);
1818 ok(!ret, "got %d\n", ret);
1820 SET_EXPECT(invalid_parameter_handler);
1821 ret = p__memicmp(NULL, NULL, 1);
1822 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1823 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1825 SET_EXPECT(invalid_parameter_handler);
1826 ret = p__memicmp(s1, NULL, 1);
1827 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1828 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1830 SET_EXPECT(invalid_parameter_handler);
1831 ret = p__memicmp(NULL, s2, 1);
1832 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1833 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1835 ret = p__memicmp(s1, s2, 2);
1836 ok(!ret, "got %d\n", ret);
1838 ret = p__memicmp(s1, s2, 3);
1839 ok(ret == -1, "got %d\n", ret);
1842 static void test__memicmp_l(void)
1844 static const char *s1 = "abc";
1845 static const char *s2 = "aBd";
1846 int ret;
1848 ret = p__memicmp_l(NULL, NULL, 0, NULL);
1849 ok(!ret, "got %d\n", ret);
1851 SET_EXPECT(invalid_parameter_handler);
1852 ret = p__memicmp_l(NULL, NULL, 1, NULL);
1853 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1854 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1856 SET_EXPECT(invalid_parameter_handler);
1857 ret = p__memicmp_l(s1, NULL, 1, NULL);
1858 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1859 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1861 SET_EXPECT(invalid_parameter_handler);
1862 ret = p__memicmp_l(NULL, s2, 1, NULL);
1863 ok(ret == _NLSCMPERROR, "got %d\n", ret);
1864 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1866 ret = p__memicmp_l(s1, s2, 2, NULL);
1867 ok(!ret, "got %d\n", ret);
1869 ret = p__memicmp_l(s1, s2, 3, NULL);
1870 ok(ret == -1, "got %d\n", ret);
1873 static int WINAPIV _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...)
1875 int ret;
1876 __ms_va_list valist;
1877 __ms_va_start(valist, format);
1878 ret = p__vsnwprintf(str, len, format, valist);
1879 __ms_va_end(valist);
1880 return ret;
1883 static void test__vsnwprintf(void)
1885 int ret;
1886 WCHAR str[2] = {0};
1888 _invalid_parameter_handler old_handler = p_set_invalid_parameter_handler(test_invalid_parameter_handler);
1890 SET_EXPECT(invalid_parameter_handler);
1891 errno = 0xdeadbeef;
1892 str[0] = 'x';
1893 ret = _vsnwprintf_wrapper(str, 0, NULL);
1894 ok(ret == -1, "got %d, expected -1\n", ret);
1895 ok(str[0] == 'x', "Expected string to be unchanged.\n");
1896 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1898 ok(p_set_invalid_parameter_handler(old_handler) == test_invalid_parameter_handler, "Cannot reset invalid parameter handler\n");
1901 static void test___strncnt(void)
1903 static const struct
1905 const char *str;
1906 size_t size;
1907 size_t ret;
1909 strncnt_tests[] =
1911 { NULL, 0, 0 },
1912 { "a", 0, 0 },
1913 { "a", 1, 1 },
1914 { "a", 10, 1 },
1915 { "abc", 1, 1 },
1917 unsigned int i;
1918 size_t ret;
1920 if (0)
1921 ret = p___strncnt(NULL, 1);
1923 for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
1925 ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
1926 ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
1930 static void test_swscanf(void)
1933 wchar_t buffer[100];
1934 int ret;
1936 /* check WEOF */
1937 ret = p_swscanf(L" \t\n\n", L"%s", buffer);
1938 ok( ret == (short)WEOF, "ret = %d\n", ret );
1941 START_TEST(msvcr90)
1943 if(!init())
1944 return;
1946 test__initterm_e();
1947 test__encode_pointer();
1948 test_error_messages();
1949 test__strtoi64();
1950 test__itoa_s();
1951 test_wcsncat_s();
1952 test_qsort_s();
1953 test_bsearch_s();
1954 test_controlfp_s();
1955 test_tmpfile_s();
1956 test__atoflt();
1957 test__set_abort_behavior();
1958 test__sopen_s();
1959 test__wsopen_s();
1960 test__realloc_crt();
1961 test_typeinfo();
1962 test_getptd();
1963 test__vswprintf_l();
1964 test_nonblocking_file_access();
1965 test_byteswap();
1966 test_access_s();
1967 test_is_exception_typeof();
1968 test__AdjustPointer();
1969 test_mbstowcs();
1970 test_strtok_s();
1971 test__mbstok_s();
1972 test__memicmp();
1973 test__memicmp_l();
1974 test__vsnwprintf();
1975 #ifdef __i386__
1976 test__fpieee_flt();
1977 #endif
1978 test___strncnt();
1979 test_swscanf();