Author: akhaldi
Date: Sat Sep 29 14:28:48 2012
New Revision: 57432
URL:
http://svn.reactos.org/svn/reactos?rev=57432&view=rev
Log:
[MSVCRT_WINETEST]: Sync to Wine 1.5.13.
CORE-6415
Modified:
trunk/rostests/winetests/msvcrt/cpp.c
trunk/rostests/winetests/msvcrt/file.c
trunk/rostests/winetests/msvcrt/locale.c
trunk/rostests/winetests/msvcrt/misc.c
trunk/rostests/winetests/msvcrt/printf.c
trunk/rostests/winetests/msvcrt/scanf.c
trunk/rostests/winetests/msvcrt/string.c
trunk/rostests/winetests/msvcrt/time.c
Modified: trunk/rostests/winetests/msvcrt/cpp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/cpp.c?re…
==============================================================================
--- trunk/rostests/winetests/msvcrt/cpp.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/cpp.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -15,42 +15,33 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * NOTES
- * This tests is only valid for ix86 platforms, on others it's a no-op.
- * Some tests cannot be checked with ok(), for example the dtors. We simply
- * call them to ensure we don't crash ;-)
- *
- * If we build this test with VC++ in debug mode, we will fail in _chkstk()
- * or at program exit malloc() checking if these methods haven't been
- * implemented correctly (they have).
- *
- * Tested with a range of native msvcrt's from v4 -> v7.
*/
#include "wine/test.h"
#include "winbase.h"
#include "winnt.h"
-#ifndef __i386__
-/* Skip these tests for non x86 platforms */
-START_TEST(cpp)
-{
-}
-#else
+typedef void (*vtable_ptr)(void);
typedef struct __exception
{
- void *vtable;
+ vtable_ptr *vtable;
char *name;
int do_free;
} exception;
typedef struct __type_info
{
- void *vtable;
+ vtable_ptr *vtable;
char *name;
char mangled[16];
} type_info;
+
+#undef __thiscall
+#ifdef __i386__
+#define __thiscall __stdcall
+#else
+#define __thiscall __cdecl
+#endif
/* Function pointers. We need to use these to call these funcs as __thiscall */
static HMODULE hMsvcrt;
@@ -61,56 +52,56 @@
static void (__cdecl *pfree)(void*);
/* exception */
-static void (WINAPI *pexception_ctor)(exception*,LPCSTR*);
-static void (WINAPI *pexception_copy_ctor)(exception*,exception*);
-static void (WINAPI *pexception_default_ctor)(exception*);
-static void (WINAPI *pexception_dtor)(exception*);
-static exception* (WINAPI *pexception_opequals)(exception*,exception*);
-static char* (WINAPI *pexception_what)(exception*);
-static void* (WINAPI *pexception_vtable)(exception*);
-static void (WINAPI *pexception_vector_dtor)(exception*,unsigned int);
-static void (WINAPI *pexception_scalar_dtor)(exception*,unsigned int);
+static void (__thiscall *pexception_ctor)(exception*,LPCSTR*);
+static void (__thiscall *pexception_copy_ctor)(exception*,exception*);
+static void (__thiscall *pexception_default_ctor)(exception*);
+static void (__thiscall *pexception_dtor)(exception*);
+static exception* (__thiscall *pexception_opequals)(exception*,exception*);
+static char* (__thiscall *pexception_what)(exception*);
+static vtable_ptr *pexception_vtable;
+static void (__thiscall *pexception_vector_dtor)(exception*,unsigned int);
+static void (__thiscall *pexception_scalar_dtor)(exception*,unsigned int);
/* bad_typeid */
-static void (WINAPI *pbad_typeid_ctor)(exception*,LPCSTR);
-static void (WINAPI *pbad_typeid_ctor_closure)(exception*);
-static void (WINAPI *pbad_typeid_copy_ctor)(exception*,exception*);
-static void (WINAPI *pbad_typeid_dtor)(exception*);
-static exception* (WINAPI *pbad_typeid_opequals)(exception*,exception*);
-static char* (WINAPI *pbad_typeid_what)(exception*);
-static void* (WINAPI *pbad_typeid_vtable)(exception*);
-static void (WINAPI *pbad_typeid_vector_dtor)(exception*,unsigned int);
-static void (WINAPI *pbad_typeid_scalar_dtor)(exception*,unsigned int);
+static void (__thiscall *pbad_typeid_ctor)(exception*,LPCSTR);
+static void (__thiscall *pbad_typeid_ctor_closure)(exception*);
+static void (__thiscall *pbad_typeid_copy_ctor)(exception*,exception*);
+static void (__thiscall *pbad_typeid_dtor)(exception*);
+static exception* (__thiscall *pbad_typeid_opequals)(exception*,exception*);
+static char* (__thiscall *pbad_typeid_what)(exception*);
+static vtable_ptr *pbad_typeid_vtable;
+static void (__thiscall *pbad_typeid_vector_dtor)(exception*,unsigned int);
+static void (__thiscall *pbad_typeid_scalar_dtor)(exception*,unsigned int);
/* bad_cast */
-static void (WINAPI *pbad_cast_ctor)(exception*,LPCSTR*);
-static void (WINAPI *pbad_cast_ctor2)(exception*,LPCSTR);
-static void (WINAPI *pbad_cast_ctor_closure)(exception*);
-static void (WINAPI *pbad_cast_copy_ctor)(exception*,exception*);
-static void (WINAPI *pbad_cast_dtor)(exception*);
-static exception* (WINAPI *pbad_cast_opequals)(exception*,exception*);
-static char* (WINAPI *pbad_cast_what)(exception*);
-static void* (WINAPI *pbad_cast_vtable)(exception*);
-static void (WINAPI *pbad_cast_vector_dtor)(exception*,unsigned int);
-static void (WINAPI *pbad_cast_scalar_dtor)(exception*,unsigned int);
+static void (__thiscall *pbad_cast_ctor)(exception*,LPCSTR*);
+static void (__thiscall *pbad_cast_ctor2)(exception*,LPCSTR);
+static void (__thiscall *pbad_cast_ctor_closure)(exception*);
+static void (__thiscall *pbad_cast_copy_ctor)(exception*,exception*);
+static void (__thiscall *pbad_cast_dtor)(exception*);
+static exception* (__thiscall *pbad_cast_opequals)(exception*,exception*);
+static char* (__thiscall *pbad_cast_what)(exception*);
+static vtable_ptr *pbad_cast_vtable;
+static void (__thiscall *pbad_cast_vector_dtor)(exception*,unsigned int);
+static void (__thiscall *pbad_cast_scalar_dtor)(exception*,unsigned int);
/* __non_rtti_object */
-static void (WINAPI *p__non_rtti_object_ctor)(exception*,LPCSTR);
-static void (WINAPI *p__non_rtti_object_copy_ctor)(exception*,exception*);
-static void (WINAPI *p__non_rtti_object_dtor)(exception*);
-static exception* (WINAPI *p__non_rtti_object_opequals)(exception*,exception*);
-static char* (WINAPI *p__non_rtti_object_what)(exception*);
-static void* (WINAPI *p__non_rtti_object_vtable)(exception*);
-static void (WINAPI *p__non_rtti_object_vector_dtor)(exception*,unsigned int);
-static void (WINAPI *p__non_rtti_object_scalar_dtor)(exception*,unsigned int);
+static void (__thiscall *p__non_rtti_object_ctor)(exception*,LPCSTR);
+static void (__thiscall *p__non_rtti_object_copy_ctor)(exception*,exception*);
+static void (__thiscall *p__non_rtti_object_dtor)(exception*);
+static exception* (__thiscall *p__non_rtti_object_opequals)(exception*,exception*);
+static char* (__thiscall *p__non_rtti_object_what)(exception*);
+static vtable_ptr *p__non_rtti_object_vtable;
+static void (__thiscall *p__non_rtti_object_vector_dtor)(exception*,unsigned int);
+static void (__thiscall *p__non_rtti_object_scalar_dtor)(exception*,unsigned int);
/* type_info */
-static void (WINAPI *ptype_info_dtor)(type_info*);
-static char* (WINAPI *ptype_info_raw_name)(type_info*);
-static char* (WINAPI *ptype_info_name)(type_info*);
-static int (WINAPI *ptype_info_before)(type_info*,type_info*);
-static int (WINAPI *ptype_info_opequals_equals)(type_info*,type_info*);
-static int (WINAPI *ptype_info_opnot_equals)(type_info*,type_info*);
+static void (__thiscall *ptype_info_dtor)(type_info*);
+static char* (__thiscall *ptype_info_raw_name)(type_info*);
+static char* (__thiscall *ptype_info_name)(type_info*);
+static int (__thiscall *ptype_info_before)(type_info*,type_info*);
+static int (__thiscall *ptype_info_opequals_equals)(type_info*,type_info*);
+static int (__thiscall *ptype_info_opnot_equals)(type_info*,type_info*);
/* RTTI */
static type_info* (__cdecl *p__RTtypeid)(void*);
@@ -125,147 +116,184 @@
static void* bAncientVersion;
/* Emulate a __thiscall */
-#ifdef _MSC_VER
-static inline void* do_call_func1(void *func, void *_this)
-{
- volatile void* retval = 0;
- __asm
- {
- push ecx
- mov ecx, _this
- call func
- mov retval, eax
- pop ecx
- }
- return (void*)retval;
-}
-
-static inline void* do_call_func2(void *func, void *_this, const void* arg)
-{
- volatile void* retval = 0;
- __asm
- {
- push ecx
- push arg
- mov ecx, _this
- call func
- mov retval, eax
- pop ecx
- }
- return (void*)retval;
-}
+#ifdef __i386__
+
+#include "pshpack1.h"
+struct thiscall_thunk
+{
+ BYTE pop_eax; /* popl %eax (ret addr) */
+ BYTE pop_edx; /* popl %edx (func) */
+ BYTE pop_ecx; /* popl %ecx (this) */
+ BYTE push_eax; /* pushl %eax */
+ WORD jmp_edx; /* jmp *%edx */
+};
+#include "poppack.h"
+
+static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
+static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
+
+static void init_thiscall_thunk(void)
+{
+ struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
+ MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ thunk->pop_eax = 0x58; /* popl %eax */
+ thunk->pop_edx = 0x5a; /* popl %edx */
+ thunk->pop_ecx = 0x59; /* popl %ecx */
+ thunk->push_eax = 0x50; /* pushl %eax */
+ thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
+ call_thiscall_func1 = (void *)thunk;
+ call_thiscall_func2 = (void *)thunk;
+}
+
+#define call_func1(func,_this) call_thiscall_func1(func,_this)
+#define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)a)
+
#else
-static void* do_call_func1(void *func, void *_this)
-{
- void *ret, *dummy;
- __asm__ __volatile__ ("call *%2"
- : "=a" (ret), "=c" (dummy)
- : "g" (func), "1" (_this)
- : "edx", "memory" );
- return ret;
-}
-static void* do_call_func2(void *func, void *_this, const void* arg)
-{
- void *ret, *dummy;
- __asm__ __volatile__ ("pushl %3\n\tcall *%2"
- : "=a" (ret), "=c" (dummy)
- : "r" (func), "r" (arg), "1"
(_this)
- : "edx", "memory" );
- return ret;
-}
-#endif
-
-#define call_func1(x,y) do_call_func1((void*)x,(void*)y)
-#define call_func2(x,y,z) do_call_func2((void*)x,(void*)y,(const void*)z)
+
+#define init_thiscall_thunk() do { } while(0)
+#define call_func1(func,_this) func(_this)
+#define call_func2(func,_this,a) func(_this,a)
+
+#endif /* __i386__ */
/* Some exports are only available in later versions */
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not
found\n", y); } while(0)
-static void InitFunctionPtrs(void)
-{
- hMsvcrt = GetModuleHandleA("msvcrt.dll");
- if (!hMsvcrt)
- hMsvcrt = GetModuleHandleA("msvcrtd.dll");
- ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
- if (hMsvcrt)
- {
- if (sizeof(void *) > sizeof(int)) /* 64-bit has different names */
+static BOOL InitFunctionPtrs(void)
+{
+ hMsvcrt = GetModuleHandleA("msvcrt.dll");
+ if (!hMsvcrt)
+ hMsvcrt = GetModuleHandleA("msvcrtd.dll");
+ ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
+ if (!hMsvcrt)
+ {
+ win_skip("Could not load msvcrt.dll\n");
+ return FALSE;
+ }
+
+ SET(pmalloc, "malloc");
+ SET(pfree, "free");
+
+ SET(pexception_vtable, "??_7exception@@6B@");
+ SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@");
+ SET(pbad_cast_vtable, "??_7bad_cast@@6B@");
+ SET(p__non_rtti_object_vtable, "??_7__non_rtti_object@@6B@");
+
+ SET(p__RTtypeid, "__RTtypeid");
+ SET(p__RTCastToVoid, "__RTCastToVoid");
+ SET(p__RTDynamicCast, "__RTDynamicCast");
+
+ SET(p__unDName,"__unDName");
+
+ /* Extremely early versions export logic_error, and crash in RTTI */
+ SETNOFAIL(bAncientVersion, "??0logic_error@@QAE@ABQBD@Z");
+ if (sizeof(void *) > sizeof(int)) /* 64-bit initialization */
{
SETNOFAIL(poperator_new, "??_U@YAPEAX_K@Z");
SETNOFAIL(poperator_delete, "??_V@YAXPEAX@Z");
+
+ SET(pexception_ctor, "??0exception@@QEAA@AEBQEBD@Z");
+ SET(pexception_copy_ctor, "??0exception@@QEAA@AEBV0@@Z");
+ SET(pexception_default_ctor, "??0exception@@QEAA@XZ");
+ SET(pexception_dtor, "??1exception@@UEAA@XZ");
+ SET(pexception_opequals, "??4exception@@QEAAAEAV0@AEBV0@@Z");
+ SET(pexception_what, "?what@exception@@UEBAPEBDXZ");
+ pexception_vector_dtor = (void*)pexception_vtable[0];
+ pexception_scalar_dtor = (void*)pexception_vtable[0];
+
+ SET(pbad_typeid_ctor, "??0bad_typeid@@QEAA@PEBD@Z");
+ SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QEAAXXZ");
+ SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QEAA@AEBV0@@Z");
+ SET(pbad_typeid_dtor, "??1bad_typeid@@UEAA@XZ");
+ SET(pbad_typeid_opequals, "??4bad_typeid@@QEAAAEAV0@AEBV0@@Z");
+ SET(pbad_typeid_what, "?what@exception@@UEBAPEBDXZ");
+ pbad_typeid_vector_dtor = (void*)pbad_typeid_vtable[0];
+ pbad_typeid_scalar_dtor = (void*)pbad_typeid_vtable[0];
+
+ SET(pbad_cast_ctor, "??0bad_cast@@QEAA@AEBQEBD@Z");
+ SET(pbad_cast_ctor2, "??0bad_cast@@QEAA@PEBD@Z");
+ SET(pbad_cast_ctor_closure, "??_Fbad_cast@@QEAAXXZ");
+ SET(pbad_cast_copy_ctor, "??0bad_cast@@QEAA@AEBV0@@Z");
+ SET(pbad_cast_dtor, "??1bad_cast@@UEAA@XZ");
+ SET(pbad_cast_opequals, "??4bad_cast@@QEAAAEAV0@AEBV0@@Z");
+ SET(pbad_cast_what, "?what@exception@@UEBAPEBDXZ");
+ pbad_cast_vector_dtor = (void*)pbad_cast_vtable[0];
+ pbad_cast_scalar_dtor = (void*)pbad_cast_vtable[0];
+
+ SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QEAA@PEBD@Z");
+ SET(p__non_rtti_object_copy_ctor,
"??0__non_rtti_object@@QEAA@AEBV0@@Z");
+ SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UEAA@XZ");
+ SET(p__non_rtti_object_opequals,
"??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z");
+ SET(p__non_rtti_object_what, "?what@exception@@UEBAPEBDXZ");
+ p__non_rtti_object_vector_dtor = (void*)p__non_rtti_object_vtable[0];
+ p__non_rtti_object_scalar_dtor = (void*)p__non_rtti_object_vtable[0];
+
+ SET(ptype_info_dtor, "??1type_info@@UEAA@XZ");
+ SET(ptype_info_raw_name, "?raw_name@type_info@@QEBAPEBDXZ");
+ SET(ptype_info_name, "?name@type_info@@QEBAPEBDXZ");
+ SET(ptype_info_before, "?before@type_info@@QEBAHAEBV1@@Z");
+ SET(ptype_info_opequals_equals, "??8type_info@@QEBAHAEBV0@@Z");
+ SET(ptype_info_opnot_equals, "??9type_info@@QEBAHAEBV0@@Z");
}
else
{
SETNOFAIL(poperator_new, "??_U@YAPAXI@Z");
SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z");
+
+ SET(pexception_ctor, "??0exception@@QAE@ABQBD@Z");
+ SET(pexception_copy_ctor, "??0exception@@QAE@ABV0@@Z");
+ SET(pexception_default_ctor, "??0exception@@QAE@XZ");
+ SET(pexception_dtor, "??1exception@@UAE@XZ");
+ SET(pexception_opequals, "??4exception@@QAEAAV0@ABV0@@Z");
+ SET(pexception_what, "?what@exception@@UBEPBDXZ");
+ SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");
+ SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");
+
+ SET(pbad_typeid_ctor, "??0bad_typeid@@QAE@PBD@Z");
+ SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAEXXZ");
+ SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAE@ABV0@@Z");
+ SET(pbad_typeid_dtor, "??1bad_typeid@@UAE@XZ");
+ SET(pbad_typeid_opequals, "??4bad_typeid@@QAEAAV0@ABV0@@Z");
+ SET(pbad_typeid_what, "?what@exception@@UBEPBDXZ");
+ SET(pbad_typeid_vector_dtor, "??_Ebad_typeid@@UAEPAXI@Z");
+ SET(pbad_typeid_scalar_dtor, "??_Gbad_typeid@@UAEPAXI@Z");
+
+ SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z");
+ if (!pbad_cast_ctor)
+ SET(pbad_cast_ctor, "??0bad_cast@@AAE@PBQBD@Z");
+ SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAE@PBD@Z");
+ SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAEXXZ");
+ SET(pbad_cast_copy_ctor, "??0bad_cast@@QAE@ABV0@@Z");
+ SET(pbad_cast_dtor, "??1bad_cast@@UAE@XZ");
+ SET(pbad_cast_opequals, "??4bad_cast@@QAEAAV0@ABV0@@Z");
+ SET(pbad_cast_what, "?what@exception@@UBEPBDXZ");
+ SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z");
+ SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z");
+
+ SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAE@PBD@Z");
+ SET(p__non_rtti_object_copy_ctor,
"??0__non_rtti_object@@QAE@ABV0@@Z");
+ SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAE@XZ");
+ SET(p__non_rtti_object_opequals,
"??4__non_rtti_object@@QAEAAV0@ABV0@@Z");
+ SET(p__non_rtti_object_what, "?what@exception@@UBEPBDXZ");
+ SET(p__non_rtti_object_vector_dtor,
"??_E__non_rtti_object@@UAEPAXI@Z");
+ SET(p__non_rtti_object_scalar_dtor,
"??_G__non_rtti_object@@UAEPAXI@Z");
+
+ SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
+ SET(ptype_info_raw_name, "?raw_name@type_info@@QBEPBDXZ");
+ SET(ptype_info_name, "?name@type_info@@QBEPBDXZ");
+ SET(ptype_info_before, "?before@type_info@@QBEHABV1@@Z");
+ SET(ptype_info_opequals_equals, "??8type_info@@QBEHABV0@@Z");
+ SET(ptype_info_opnot_equals, "??9type_info@@QBEHABV0@@Z");
}
- SET(pmalloc, "malloc");
- SET(pfree, "free");
if (!poperator_new)
- poperator_new = pmalloc;
+ poperator_new = pmalloc;
if (!poperator_delete)
- poperator_delete = pfree;
-
- SET(pexception_ctor, "??0exception@@QAE@ABQBD@Z");
- SET(pexception_copy_ctor, "??0exception@@QAE@ABV0@@Z");
- SET(pexception_default_ctor, "??0exception@@QAE@XZ");
- SET(pexception_dtor, "??1exception@@UAE@XZ");
- SET(pexception_opequals, "??4exception@@QAEAAV0@ABV0@@Z");
- SET(pexception_what, "?what@exception@@UBEPBDXZ");
- SET(pexception_vtable, "??_7exception@@6B@");
- SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");
- SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");
-
- SET(pbad_typeid_ctor, "??0bad_typeid@@QAE@PBD@Z");
- SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAEXXZ");
- SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAE@ABV0@@Z");
- SET(pbad_typeid_dtor, "??1bad_typeid@@UAE@XZ");
- SET(pbad_typeid_opequals, "??4bad_typeid@@QAEAAV0@ABV0@@Z");
- SET(pbad_typeid_what, "?what@exception@@UBEPBDXZ");
- SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@");
- SET(pbad_typeid_vector_dtor, "??_Ebad_typeid@@UAEPAXI@Z");
- SET(pbad_typeid_scalar_dtor, "??_Gbad_typeid@@UAEPAXI@Z");
-
- SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z");
- if (!pbad_cast_ctor)
- SET(pbad_cast_ctor, "??0bad_cast@@AAE@PBQBD@Z");
- SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAE@PBD@Z");
- SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAEXXZ");
- SET(pbad_cast_copy_ctor, "??0bad_cast@@QAE@ABV0@@Z");
- SET(pbad_cast_dtor, "??1bad_cast@@UAE@XZ");
- SET(pbad_cast_opequals, "??4bad_cast@@QAEAAV0@ABV0@@Z");
- SET(pbad_cast_what, "?what@exception@@UBEPBDXZ");
- SET(pbad_cast_vtable, "??_7bad_cast@@6B@");
- SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z");
- SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z");
-
- SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAE@PBD@Z");
- SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@@QAE@ABV0@@Z");
- SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAE@XZ");
- SET(p__non_rtti_object_opequals, "??4__non_rtti_object@@QAEAAV0@ABV0@@Z");
- SET(p__non_rtti_object_what, "?what@exception@@UBEPBDXZ");
- SET(p__non_rtti_object_vtable, "??_7__non_rtti_object@@6B@");
- SET(p__non_rtti_object_vector_dtor, "??_E__non_rtti_object@@UAEPAXI@Z");
- SET(p__non_rtti_object_scalar_dtor, "??_G__non_rtti_object@@UAEPAXI@Z");
-
- SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
- SET(ptype_info_raw_name, "?raw_name@type_info@@QBEPBDXZ");
- SET(ptype_info_name, "?name@type_info@@QBEPBDXZ");
- SET(ptype_info_before, "?before@type_info@@QBEHABV1@@Z");
- SET(ptype_info_opequals_equals, "??8type_info@@QBEHABV0@@Z");
- SET(ptype_info_opnot_equals, "??9type_info@@QBEHABV0@@Z");
-
- SET(p__RTtypeid, "__RTtypeid");
- SET(p__RTCastToVoid, "__RTCastToVoid");
- SET(p__RTDynamicCast, "__RTDynamicCast");
-
- SET(p__unDName,"__unDName");
-
- /* Extremely early versions export logic_error, and crash in RTTI */
- SETNOFAIL(bAncientVersion, "??0logic_error@@QAE@ABQBD@Z");
- }
+ poperator_delete = pfree;
+
+ init_thiscall_thunk();
+ return TRUE;
}
static void test_exception(void)
@@ -346,14 +374,14 @@
call_func2(pexception_vector_dtor, pe, 1); /* Should delete pe as single element*/
}
- pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(size_t));
ok(pe != NULL, "new() failed\n");
if (pe)
{
/* vector dtor, multiple elements */
char name[] = "a constant";
- *((int*)pe) = 3;
- pe = (exception*)((int*)pe + 1);
+ *((size_t*)pe) = 3;
+ pe = (exception*)((size_t*)pe + 1);
call_func2(pexception_ctor, &pe[0], &e_name);
call_func2(pexception_ctor, &pe[1], &e_name);
call_func2(pexception_ctor, &pe[2], &e_name);
@@ -471,13 +499,13 @@
call_func2(pbad_typeid_vector_dtor, pe, 1); /* Should delete pe as single element*/
}
- pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(size_t));
ok(pe != NULL, "new() failed\n");
if (pe)
{
/* vector dtor, multiple elements */
- *((int*)pe) = 3;
- pe = (exception*)((int*)pe + 1);
+ *((size_t*)pe) = 3;
+ pe = (exception*)((size_t*)pe + 1);
call_func2(pbad_typeid_ctor, &pe[0], e_name);
call_func2(pbad_typeid_ctor, &pe[1], e_name);
call_func2(pbad_typeid_ctor, &pe[2], e_name);
@@ -599,13 +627,13 @@
call_func2(pbad_cast_vector_dtor, pe, 1); /* Should delete pe as single element*/
}
- pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(size_t));
ok(pe != NULL, "new() failed\n");
if (pe)
{
/* vector dtor, multiple elements */
- *((int*)pe) = 3;
- pe = (exception*)((int*)pe + 1);
+ *((size_t*)pe) = 3;
+ pe = (exception*)((size_t*)pe + 1);
call_func2(pbad_cast_ctor, &pe[0], &e_name);
call_func2(pbad_cast_ctor, &pe[1], &e_name);
call_func2(pbad_cast_ctor, &pe[2], &e_name);
@@ -701,13 +729,13 @@
call_func2(p__non_rtti_object_vector_dtor, pe, 1); /* Should delete pe as single
element*/
}
- pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(size_t));
ok(pe != NULL, "new() failed\n");
if (pe)
{
/* vector dtor, multiple elements */
- *((int*)pe) = 3;
- pe = (exception*)((int*)pe + 1);
+ *((size_t*)pe) = 3;
+ pe = (exception*)((size_t*)pe + 1);
call_func2(p__non_rtti_object_ctor, &pe[0], e_name);
call_func2(p__non_rtti_object_ctor, &pe[1], e_name);
call_func2(p__non_rtti_object_ctor, &pe[2], e_name);
@@ -732,7 +760,6 @@
}
call_func2(p__non_rtti_object_vector_dtor, &e, 0); /* Should delete e.name, but not
e */
}
-
static void test_type_info(void)
{
@@ -801,13 +828,99 @@
ok(res == 1, "expected 1, got %d\n", res);
}
+static inline vtable_ptr *get_vtable( void *obj )
+{
+ return *(vtable_ptr **)obj;
+}
+
+static inline void/*rtti_object_locator*/ *get_obj_locator( void *cppobj )
+{
+ const vtable_ptr *vtable = get_vtable( cppobj );
+ return (void *)vtable[-1];
+}
+
+#ifndef __x86_64__
+#define DEFINE_RTTI_REF(type, name) type *name
+#define RTTI_REF(instance, name) &instance.name
+#define RTTI_REF_SIG0(instance, name, base) RTTI_REF(instance, name)
+#else
+#define DEFINE_RTTI_REF(type, name) unsigned name
+#define RTTI_REF(instance, name) FIELD_OFFSET(struct rtti_data, name)
+#define RTTI_REF_SIG0(instance, name, base) ((char*)&instance.name-base)
+#endif
/* Test RTTI functions */
static void test_rtti(void)
{
+ struct _object_locator
+ {
+ unsigned int signature;
+ int base_class_offset;
+ unsigned int flags;
+ DEFINE_RTTI_REF(type_info, type_descriptor);
+ DEFINE_RTTI_REF(struct _rtti_object_hierarchy, type_hierarchy);
+ DEFINE_RTTI_REF(void, object_locator);
+ } *obj_locator;
+
+ struct rtti_data
+ {
+ type_info type_info[4];
+
+ struct _rtti_base_descriptor
+ {
+ DEFINE_RTTI_REF(type_info, type_descriptor);
+ int num_base_classes;
+ struct {
+ int this_offset;
+ int vbase_descr;
+ int vbase_offset;
+ } this_ptr_offsets;
+ unsigned int attributes;
+ } base_descriptor[4];
+
+ struct _rtti_base_array {
+ DEFINE_RTTI_REF(struct _rtti_base_descriptor, bases[4]);
+ } base_array;
+
+ struct _rtti_object_hierarchy {
+ unsigned int signature;
+ unsigned int attributes;
+ int array_len;
+ DEFINE_RTTI_REF(struct _rtti_base_array, base_classes);
+ } object_hierarchy;
+
+ struct _object_locator object_locator;
+ } simple_class_rtti = {
+ { {NULL, NULL, "simple_class"} },
+ { {RTTI_REF(simple_class_rtti, type_info[0]), 0, {0, 0, 0}, 0} },
+ { {RTTI_REF(simple_class_rtti, base_descriptor[0])} },
+ {0, 0, 1, RTTI_REF(simple_class_rtti, base_array)},
+ {1, 0, 0, RTTI_REF(simple_class_rtti, type_info[0]), RTTI_REF(simple_class_rtti,
object_hierarchy), RTTI_REF(simple_class_rtti, object_locator)}
+ }, child_class_rtti = {
+ { {NULL, NULL, "simple_class"}, {NULL, NULL, "child_class"} },
+ { {RTTI_REF(child_class_rtti, type_info[1]), 0, {4, -1, 0}, 0},
{RTTI_REF(child_class_rtti, type_info[0]), 0, {8, -1, 0}, 0} },
+ { {RTTI_REF(child_class_rtti, base_descriptor[0]), RTTI_REF(child_class_rtti,
base_descriptor[1])} },
+ {0, 0, 2, RTTI_REF(child_class_rtti, base_array)},
+ {1, 0, 0, RTTI_REF(child_class_rtti, type_info[1]), RTTI_REF(child_class_rtti,
object_hierarchy), RTTI_REF(child_class_rtti, object_locator)}
+ };
+ static struct rtti_data simple_class_sig0_rtti, child_class_sig0_rtti;
+
+ void *simple_class_vtbl[2] = {&simple_class_rtti.object_locator};
+ void *simple_class = &simple_class_vtbl[1];
+ void *child_class_vtbl[2] = {&child_class_rtti.object_locator};
+ void *child_class = &child_class_vtbl[1];
+ void *simple_class_sig0_vtbl[2] = {&simple_class_sig0_rtti.object_locator};
+ void *simple_class_sig0 = &simple_class_sig0_vtbl[1];
+ void *child_class_sig0_vtbl[2] = {&child_class_sig0_rtti.object_locator};
+ void *child_class_sig0 = &child_class_sig0_vtbl[1];
+
static const char* e_name = "name";
type_info *ti,*bti;
exception e,b;
void *casted;
+ BOOL old_signature;
+#ifdef __x86_64__
+ char *base = (char*)GetModuleHandleW(NULL);
+#endif
if (bAncientVersion ||
!p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor
@@ -817,6 +930,12 @@
call_func2(pexception_ctor, &e, &e_name);
call_func2(pbad_typeid_ctor, &b, e_name);
+ obj_locator = get_obj_locator(&e);
+ if(obj_locator->signature!=1 && sizeof(void*)>sizeof(int))
+ old_signature = TRUE;
+ else
+ old_signature = FALSE;
+
/* dynamic_cast to void* */
casted = p__RTCastToVoid(&e);
ok (casted == (void*)&e, "failed cast to void\n");
@@ -838,6 +957,75 @@
call_func1(pexception_dtor, &e);
call_func1(pbad_typeid_dtor, &b);
+
+ memcpy(&simple_class_sig0_rtti, &simple_class_rtti, sizeof(struct rtti_data));
+ simple_class_sig0_rtti.object_locator.signature = 0;
+ simple_class_sig0_rtti.base_descriptor[0].type_descriptor =
RTTI_REF_SIG0(simple_class_sig0_rtti, type_info[0], base);
+ simple_class_sig0_rtti.base_array.bases[0] = RTTI_REF_SIG0(simple_class_sig0_rtti,
base_descriptor[0], base);
+ simple_class_sig0_rtti.object_hierarchy.base_classes =
RTTI_REF_SIG0(simple_class_sig0_rtti, base_array, base);
+ simple_class_sig0_rtti.object_locator.type_descriptor =
RTTI_REF_SIG0(simple_class_sig0_rtti, type_info[0], base);
+ simple_class_sig0_rtti.object_locator.type_hierarchy =
RTTI_REF_SIG0(simple_class_sig0_rtti, object_hierarchy, base);
+
+ memcpy(&child_class_sig0_rtti, &child_class_rtti, sizeof(struct rtti_data));
+ child_class_sig0_rtti.object_locator.signature = 0;
+ child_class_sig0_rtti.base_descriptor[0].type_descriptor =
RTTI_REF_SIG0(child_class_sig0_rtti, type_info[1], base);
+ child_class_sig0_rtti.base_descriptor[1].type_descriptor =
RTTI_REF_SIG0(child_class_sig0_rtti, type_info[0], base);
+ child_class_sig0_rtti.base_array.bases[0] = RTTI_REF_SIG0(child_class_sig0_rtti,
base_descriptor[0], base);
+ child_class_sig0_rtti.base_array.bases[1] = RTTI_REF_SIG0(child_class_sig0_rtti,
base_descriptor[1], base);
+ child_class_sig0_rtti.object_hierarchy.base_classes =
RTTI_REF_SIG0(child_class_sig0_rtti, base_array, base);
+ child_class_sig0_rtti.object_locator.type_descriptor =
RTTI_REF_SIG0(child_class_sig0_rtti, type_info[1], base);
+ child_class_sig0_rtti.object_locator.type_hierarchy =
RTTI_REF_SIG0(child_class_sig0_rtti, object_hierarchy, base);
+
+ ti = p__RTtypeid(&simple_class_sig0);
+ ok (ti && ti->mangled && !strcmp(ti->mangled,
"simple_class"),
+ "incorrect rtti data\n");
+
+ casted = p__RTCastToVoid(&simple_class_sig0);
+ ok (casted == (void*)&simple_class_sig0, "failed cast to void\n");
+
+ ti = p__RTtypeid(&child_class_sig0);
+ ok (ti && ti->mangled && !strcmp(ti->mangled,
"child_class"),
+ "incorrect rtti data\n");
+
+ casted = p__RTCastToVoid(&child_class_sig0);
+ ok (casted == (void*)&child_class_sig0, "failed cast to void\n");
+
+ casted = p__RTDynamicCast(&child_class_sig0, 0, NULL,
simple_class_sig0_rtti.type_info, 0);
+ if(casted)
+ {
+ ok (casted == (char*)&child_class_sig0+8, "failed cast to simple_class (%p
%p)\n", casted, &child_class_sig0);
+ }
+
+ casted = p__RTDynamicCast(&child_class_sig0, 0,
&child_class_sig0_rtti.type_info[0], &child_class_sig0_rtti.type_info[1], 0);
+ ok(casted == (char*)&child_class_sig0+4, "failed cast to child class (%p
%p)\n", casted, &child_class_sig0);
+
+ if(old_signature) {
+ skip("signature==1 is not supported\n");
+ return;
+ }
+
+ ti = p__RTtypeid(&simple_class);
+ ok (ti && ti->mangled && !strcmp(ti->mangled,
"simple_class"),
+ "incorrect rtti data\n");
+
+ casted = p__RTCastToVoid(&simple_class);
+ ok (casted == (void*)&simple_class, "failed cast to void\n");
+
+ ti = p__RTtypeid(&child_class);
+ ok (ti && ti->mangled && !strcmp(ti->mangled,
"child_class"),
+ "incorrect rtti data\n");
+
+ casted = p__RTCastToVoid(&child_class);
+ ok (casted == (void*)&child_class, "failed cast to void\n");
+
+ casted = p__RTDynamicCast(&child_class, 0, NULL, simple_class_rtti.type_info, 0);
+ if(casted)
+ {
+ ok (casted == (char*)&child_class+8, "failed cast to simple_class (%p
%p)\n", casted, &child_class);
+ }
+
+ casted = p__RTDynamicCast(&child_class, 0, &child_class_rtti.type_info[0],
&child_class_rtti.type_info[1], 0);
+ ok(casted == (char*)&child_class+4, "failed cast to child class (%p
%p)\n", casted, &child_class);
}
struct _demangle {
@@ -1081,7 +1269,8 @@
START_TEST(cpp)
{
- InitFunctionPtrs();
+ if (!InitFunctionPtrs())
+ return;
test_exception();
test_bad_typeid();
@@ -1092,4 +1281,3 @@
test_demangle_datatype();
test_demangle();
}
-#endif /* __i386__ */
Modified: trunk/rostests/winetests/msvcrt/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/file.c?r…
==============================================================================
--- trunk/rostests/winetests/msvcrt/file.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/file.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -434,6 +434,37 @@
unlink("ascii2.tst");
}
+static void test_filemodeT(void)
+{
+ char DATA [] = {26, 't', 'e', 's' ,'t'};
+ char DATA2 [100];
+ char temppath[MAX_PATH];
+ char tempfile[MAX_PATH];
+ FILE* f;
+ size_t bytesWritten;
+ size_t bytesRead;
+ WIN32_FIND_DATA findData;
+ HANDLE h;
+
+ GetTempPath (MAX_PATH, temppath);
+ GetTempFileName (temppath, "", 0, tempfile);
+
+ f = fopen(tempfile, "w+bDT");
+ bytesWritten = fwrite(DATA, 1, sizeof(DATA), f);
+ rewind(f);
+ bytesRead = fread(DATA2, 1, sizeof(DATA2), f);
+ fclose(f);
+
+ ok (bytesRead == bytesWritten && bytesRead == sizeof(DATA),
+ "fopen file mode 'T' wrongly interpreted as 't'\n" );
+
+ h = FindFirstFile(tempfile, &findData);
+
+ ok (h == INVALID_HANDLE_VALUE, "file wasn't deleted when closed.\n" );
+
+ if (h != INVALID_HANDLE_VALUE) FindClose(h);
+}
+
static WCHAR* AtoW( const char* p )
{
WCHAR* buffer;
@@ -544,10 +575,21 @@
bufmodes[bufmode], 0, ret);
ret = _flsbuf(0xff,tempfh);
ok(0xff == ret, "_flsbuf(0xff,tempfh) with bufmode %x expected %x got
%x\n",
- bufmodes[bufmode], 0, ret);
+ bufmodes[bufmode], 0xff, ret);
ret = _flsbuf(0xffffffff,tempfh);
ok(0xff == ret, "_flsbuf(0xffffffff,tempfh) with bufmode %x expected %x got
%x\n",
- bufmodes[bufmode], 0, ret);
+ bufmodes[bufmode], 0xff, ret);
+ if(tempfh->_base) {
+ fputc('x', tempfh);
+ tempfh->_cnt = -1;
+ tempfh->_base[1] = 'a';
+ ret = _flsbuf(0xab,tempfh);
+ ok(ret == 0xab, "_flsbuf(0xab,tempfh) with bufmode %x expected 0xab got
%x\n",
+ bufmodes[bufmode], ret);
+ ok(tempfh->_base[1] == 'a', "tempfh->_base[1] should not be
changed (%d)\n",
+ tempfh->_base[1]);
+ }
+
fclose(tempfh);
}
@@ -574,6 +616,58 @@
ok(c == 'Q', "first byte should be 'Q'\n");
c = fgetc(tempfh);
ok(c == EOF, "there should only be one byte\n");
+ fclose(tempfh);
+
+ unlink(tempf);
+ free(tempf);
+}
+
+static void test_fflush( void )
+{
+ static const char obuf[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ char buf1[16], buf2[24];
+ char *tempf;
+ FILE *tempfh;
+ int ret;
+
+ tempf=_tempnam(".","wne");
+
+ /* Prepare the file. */
+ tempfh = fopen(tempf,"wb");
+ ok(tempfh != NULL, "Can't open test file.\n");
+ fwrite(obuf, 1, sizeof(obuf), tempfh);
+ fclose(tempfh);
+
+ /* Open the file for input. */
+ tempfh = fopen(tempf,"rb");
+ ok(tempfh != NULL, "Can't open test file.\n");
+ fread(buf1, 1, sizeof(buf1), tempfh);
+
+ /* Using fflush() on input stream is undefined in ANSI.
+ * But MSDN says that it clears input buffer. */
+ _lseek(_fileno(tempfh), 0, SEEK_SET);
+ ret = fflush(tempfh);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+ memset(buf2, '?', sizeof(buf2));
+ fread(buf2, 1, sizeof(buf2), tempfh);
+ ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n",
buf2[0]);
+
+ /* fflush(NULL) doesn't clear input buffer. */
+ _lseek(_fileno(tempfh), 0, SEEK_SET);
+ ret = fflush(NULL);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+ memset(buf2, '?', sizeof(buf2));
+ fread(buf2, 1, sizeof(buf2), tempfh);
+ ok(memcmp(buf1, buf2, sizeof(buf1)) != 0, "Got unexpected data (%c)\n",
buf2[0]);
+
+ /* _flushall() clears input buffer. */
+ _lseek(_fileno(tempfh), 0, SEEK_SET);
+ ret = _flushall();
+ ok(ret >= 0, "unexpected ret %d\n", ret);
+ memset(buf2, '?', sizeof(buf2));
+ fread(buf2, 1, sizeof(buf2), tempfh);
+ ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n",
buf2[0]);
+
fclose(tempfh);
unlink(tempf);
@@ -1565,12 +1659,14 @@
test_fileops();
test_asciimode();
test_asciimode2();
+ test_filemodeT();
test_readmode(FALSE); /* binary mode */
test_readmode(TRUE); /* ascii mode */
test_readboundary();
test_fgetc();
test_fputc();
test_flsbuf();
+ test_fflush();
test_fgetwc();
test_ctrlz();
test_file_put_get();
Modified: trunk/rostests/winetests/msvcrt/locale.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/locale.c…
==============================================================================
--- trunk/rostests/winetests/msvcrt/locale.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/locale.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -25,6 +25,7 @@
static BOOL (__cdecl *p__crtGetStringTypeW)(DWORD, DWORD, const wchar_t*, int, WORD*);
static int (__cdecl *pmemcpy_s)(void *, size_t, void*, size_t);
+void* __cdecl _Gettnames(void);
static void init(void)
{
@@ -471,10 +472,11 @@
if(ret)
ok(!strcmp(ret, "Polish_Poland.1250"), "ret = %s\n", ret);
- ret = setlocale(LC_ALL, "portugese");
- ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
- if(ret)
- ok(!strcmp(ret, "Portuguese_Brazil.1252"), "ret = %s\n",
ret);
+ ret = setlocale(LC_ALL, "portuguese");
+ ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
+ if(ret)
+ ok(!strcmp(ret, "Portuguese_Brazil.1252")
+ || broken(!strcmp(ret, "Portuguese_Portugal.1252")) /* NT4 */,
"ret = %s\n", ret);
ret = setlocale(LC_ALL, "portuguese-brazil");
ok(ret != NULL || broken (ret == NULL), "ret == NULL\n");
@@ -616,10 +618,131 @@
ok(!ret, "ret == TRUE\n");
}
+static void test__Gettnames(void)
+{
+ struct {
+ char *str[43];
+ LCID lcid;
+ int unk[2];
+ wchar_t *wstr[43];
+ char data[1];
+ } *ret;
+ int size;
+
+ if(!setlocale(LC_ALL, "english"))
+ return;
+
+ ret = _Gettnames();
+ size = ret->data-(char*)ret;
+ /* Newer version of the structure stores both ascii and unicode strings.
+ * Unicode strings are only initialized on Windows 7
+ */
+ if(sizeof(void*) == 8)
+ ok(size==0x2c0 || broken(size==0x170), "strucure size: %x\n", size);
+ else
+ ok(size==0x164 || broken(size==0xb8), "strucure size: %x\n", size);
+
+ ok(!strcmp(ret->str[0], "Sun"), "ret->str[0] = %s\n",
ret->str[0]);
+ ok(!strcmp(ret->str[1], "Mon"), "ret->str[1] = %s\n",
ret->str[1]);
+ ok(!strcmp(ret->str[2], "Tue"), "ret->str[2] = %s\n",
ret->str[2]);
+ ok(!strcmp(ret->str[3], "Wed"), "ret->str[3] = %s\n",
ret->str[3]);
+ ok(!strcmp(ret->str[4], "Thu"), "ret->str[4] = %s\n",
ret->str[4]);
+ ok(!strcmp(ret->str[5], "Fri"), "ret->str[5] = %s\n",
ret->str[5]);
+ ok(!strcmp(ret->str[6], "Sat"), "ret->str[6] = %s\n",
ret->str[6]);
+ ok(!strcmp(ret->str[7], "Sunday"), "ret->str[7] = %s\n",
ret->str[7]);
+ ok(!strcmp(ret->str[8], "Monday"), "ret->str[8] = %s\n",
ret->str[8]);
+ ok(!strcmp(ret->str[9], "Tuesday"), "ret->str[9] = %s\n",
ret->str[9]);
+ ok(!strcmp(ret->str[10], "Wednesday"), "ret->str[10] =
%s\n", ret->str[10]);
+ ok(!strcmp(ret->str[11], "Thursday"), "ret->str[11] =
%s\n", ret->str[11]);
+ ok(!strcmp(ret->str[12], "Friday"), "ret->str[12] = %s\n",
ret->str[12]);
+ ok(!strcmp(ret->str[13], "Saturday"), "ret->str[13] =
%s\n", ret->str[13]);
+ ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n",
ret->str[14]);
+ ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n",
ret->str[15]);
+ ok(!strcmp(ret->str[16], "Mar"), "ret->str[16] = %s\n",
ret->str[16]);
+ ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n",
ret->str[17]);
+ ok(!strcmp(ret->str[18], "May"), "ret->str[18] = %s\n",
ret->str[18]);
+ ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n",
ret->str[19]);
+ ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n",
ret->str[20]);
+ ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n",
ret->str[21]);
+ ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n",
ret->str[22]);
+ ok(!strcmp(ret->str[23], "Oct"), "ret->str[23] = %s\n",
ret->str[23]);
+ ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n",
ret->str[24]);
+ ok(!strcmp(ret->str[25], "Dec"), "ret->str[25] = %s\n",
ret->str[25]);
+ ok(!strcmp(ret->str[26], "January"), "ret->str[26] = %s\n",
ret->str[26]);
+ ok(!strcmp(ret->str[27], "February"), "ret->str[27] =
%s\n", ret->str[27]);
+ ok(!strcmp(ret->str[28], "March"), "ret->str[28] = %s\n",
ret->str[28]);
+ ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n",
ret->str[29]);
+ ok(!strcmp(ret->str[30], "May"), "ret->str[30] = %s\n",
ret->str[30]);
+ ok(!strcmp(ret->str[31], "June"), "ret->str[31] = %s\n",
ret->str[31]);
+ ok(!strcmp(ret->str[32], "July"), "ret->str[32] = %s\n",
ret->str[32]);
+ ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n",
ret->str[33]);
+ ok(!strcmp(ret->str[34], "September"), "ret->str[34] =
%s\n", ret->str[34]);
+ ok(!strcmp(ret->str[35], "October"), "ret->str[35] = %s\n",
ret->str[35]);
+ ok(!strcmp(ret->str[36], "November"), "ret->str[36] =
%s\n", ret->str[36]);
+ ok(!strcmp(ret->str[37], "December"), "ret->str[37] =
%s\n", ret->str[37]);
+ ok(!strcmp(ret->str[38], "AM"), "ret->str[38] = %s\n",
ret->str[38]);
+ ok(!strcmp(ret->str[39], "PM"), "ret->str[39] = %s\n",
ret->str[39]);
+ ok(!strcmp(ret->str[40], "M/d/yyyy") || broken(!strcmp(ret->str[40],
"M/d/yy"))/*NT*/,
+ "ret->str[40] = %s\n", ret->str[40]);
+ ok(!strcmp(ret->str[41], "dddd, MMMM dd, yyyy"), "ret->str[41] =
%s\n", ret->str[41]);
+ free(ret);
+
+ if(!setlocale(LC_TIME, "german"))
+ return;
+
+ ret = _Gettnames();
+ ok(!strcmp(ret->str[0], "So"), "ret->str[0] = %s\n",
ret->str[0]);
+ ok(!strcmp(ret->str[1], "Mo"), "ret->str[1] = %s\n",
ret->str[1]);
+ ok(!strcmp(ret->str[2], "Di"), "ret->str[2] = %s\n",
ret->str[2]);
+ ok(!strcmp(ret->str[3], "Mi"), "ret->str[3] = %s\n",
ret->str[3]);
+ ok(!strcmp(ret->str[4], "Do"), "ret->str[4] = %s\n",
ret->str[4]);
+ ok(!strcmp(ret->str[5], "Fr"), "ret->str[5] = %s\n",
ret->str[5]);
+ ok(!strcmp(ret->str[6], "Sa"), "ret->str[6] = %s\n",
ret->str[6]);
+ ok(!strcmp(ret->str[7], "Sonntag"), "ret->str[7] = %s\n",
ret->str[7]);
+ ok(!strcmp(ret->str[8], "Montag"), "ret->str[8] = %s\n",
ret->str[8]);
+ ok(!strcmp(ret->str[9], "Dienstag"), "ret->str[9] = %s\n",
ret->str[9]);
+ ok(!strcmp(ret->str[10], "Mittwoch"), "ret->str[10] =
%s\n", ret->str[10]);
+ ok(!strcmp(ret->str[11], "Donnerstag"), "ret->str[11] =
%s\n", ret->str[11]);
+ ok(!strcmp(ret->str[12], "Freitag"), "ret->str[12] = %s\n",
ret->str[12]);
+ ok(!strcmp(ret->str[13], "Samstag"), "ret->str[13] = %s\n",
ret->str[13]);
+ ok(!strcmp(ret->str[14], "Jan"), "ret->str[14] = %s\n",
ret->str[14]);
+ ok(!strcmp(ret->str[15], "Feb"), "ret->str[15] = %s\n",
ret->str[15]);
+ ok(!strcmp(ret->str[16], "Mrz"), "ret->str[16] = %s\n",
ret->str[16]);
+ ok(!strcmp(ret->str[17], "Apr"), "ret->str[17] = %s\n",
ret->str[17]);
+ ok(!strcmp(ret->str[18], "Mai"), "ret->str[18] = %s\n",
ret->str[18]);
+ ok(!strcmp(ret->str[19], "Jun"), "ret->str[19] = %s\n",
ret->str[19]);
+ ok(!strcmp(ret->str[20], "Jul"), "ret->str[20] = %s\n",
ret->str[20]);
+ ok(!strcmp(ret->str[21], "Aug"), "ret->str[21] = %s\n",
ret->str[21]);
+ ok(!strcmp(ret->str[22], "Sep"), "ret->str[22] = %s\n",
ret->str[22]);
+ ok(!strcmp(ret->str[23], "Okt"), "ret->str[23] = %s\n",
ret->str[23]);
+ ok(!strcmp(ret->str[24], "Nov"), "ret->str[24] = %s\n",
ret->str[24]);
+ ok(!strcmp(ret->str[25], "Dez"), "ret->str[25] = %s\n",
ret->str[25]);
+ ok(!strcmp(ret->str[26], "Januar"), "ret->str[26] = %s\n",
ret->str[26]);
+ ok(!strcmp(ret->str[27], "Februar"), "ret->str[27] = %s\n",
ret->str[27]);
+ ok(!strcmp(ret->str[29], "April"), "ret->str[29] = %s\n",
ret->str[29]);
+ ok(!strcmp(ret->str[30], "Mai"), "ret->str[30] = %s\n",
ret->str[30]);
+ ok(!strcmp(ret->str[31], "Juni"), "ret->str[31] = %s\n",
ret->str[31]);
+ ok(!strcmp(ret->str[32], "Juli"), "ret->str[32] = %s\n",
ret->str[32]);
+ ok(!strcmp(ret->str[33], "August"), "ret->str[33] = %s\n",
ret->str[33]);
+ ok(!strcmp(ret->str[34], "September"), "ret->str[34] =
%s\n", ret->str[34]);
+ ok(!strcmp(ret->str[35], "Oktober"), "ret->str[35] = %s\n",
ret->str[35]);
+ ok(!strcmp(ret->str[36], "November"), "ret->str[36] =
%s\n", ret->str[36]);
+ ok(!strcmp(ret->str[37], "Dezember"), "ret->str[37] =
%s\n", ret->str[37]);
+ ok(!strcmp(ret->str[38], ""), "ret->str[38] = %s\n",
ret->str[38]);
+ ok(!strcmp(ret->str[39], ""), "ret->str[39] = %s\n",
ret->str[39]);
+ ok(!strcmp(ret->str[40], "dd.MM.yyyy") ||
broken(!strcmp(ret->str[40], "dd.MM.yy"))/*NT*/,
+ "ret->str[40] = %s\n", ret->str[40]);
+ ok(!strcmp(ret->str[41], "dddd, d. MMMM yyyy"), "ret->str[41] =
%s\n", ret->str[41]);
+ free(ret);
+
+ setlocale(LC_ALL, "C");
+}
+
START_TEST(locale)
{
init();
test_crtGetStringTypeW();
test_setlocale();
+ test__Gettnames();
}
Modified: trunk/rostests/winetests/msvcrt/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/misc.c?r…
==============================================================================
--- trunk/rostests/winetests/msvcrt/misc.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/misc.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -23,7 +23,6 @@
#include "msvcrt.h"
static int (__cdecl *prand_s)(unsigned int *);
-static int (__cdecl *pmemcpy_s)(void *, MSVCRT_size_t, void*, MSVCRT_size_t);
static int (__cdecl *pI10_OUTPUT)(long double, int, int, void*);
static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int);
static int (__cdecl *p_get_doserrno)(int *);
@@ -36,7 +35,6 @@
HMODULE hmod = GetModuleHandleA("msvcrt.dll");
prand_s = (void *)GetProcAddress(hmod, "rand_s");
- pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s");
pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT");
pstrerror_s = (void *)GetProcAddress(hmod, "strerror_s");
p_get_doserrno = (void *)GetProcAddress(hmod, "_get_doserrno");
@@ -63,57 +61,6 @@
ret = prand_s(&rand);
ok(ret == 0, "Expected rand_s to return 0, got %d\n", ret);
-}
-
-static void test_memcpy_s(void)
-{
- static char data[] = "data\0to\0be\0copied";
- static char dest[32];
- int ret;
-
- if(!pmemcpy_s)
- {
- win_skip("memcpy_s is not available\n");
- return;
- }
-
- errno = 0xdeadbeef;
- ret = pmemcpy_s(NULL, 0, NULL, 0);
- ok(ret == 0, "ret = %x\n", ret);
- ok(errno == 0xdeadbeef, "errno = %x\n", errno);
-
- errno = 0xdeadbeef;
- dest[0] = 'x';
- ret = pmemcpy_s(dest, 10, NULL, 0);
- ok(ret == 0, "ret = %x\n", ret);
- ok(errno == 0xdeadbeef, "errno = %x\n", errno);
- ok(dest[0] == 'x', "dest[0] != \'x\'\n");
-
- errno = 0xdeadbeef;
- ret = pmemcpy_s(NULL, 10, data, 10);
- ok(ret == EINVAL, "ret = %x\n", ret);
- ok(errno == EINVAL, "errno = %x\n", errno);
-
- errno = 0xdeadbeef;
- dest[7] = 'x';
- ret = pmemcpy_s(dest, 10, data, 5);
- ok(ret == 0, "ret = %x\n", ret);
- ok(errno == 0xdeadbeef, "errno = %x\n", errno);
- ok(memcmp(dest, data, 10), "All data copied\n");
- ok(!memcmp(dest, data, 5), "First five bytes are different\n");
-
- errno = 0xdeadbeef;
- ret = pmemcpy_s(data, 10, data, 10);
- ok(ret == 0, "ret = %x\n", ret);
- ok(errno == 0xdeadbeef, "errno = %x\n", errno);
- ok(!memcmp(dest, data, 5), "data was destroyed during overwriting\n");
-
- errno = 0xdeadbeef;
- dest[0] = 'x';
- ret = pmemcpy_s(dest, 5, data, 10);
- ok(ret == ERANGE, "ret = %x\n", ret);
- ok(errno == ERANGE, "errno = %x\n", errno);
- ok(dest[0] == '\0', "dest[0] != \'\\0\'\n");
}
typedef struct _I10_OUTPUT_data {
@@ -367,7 +314,6 @@
init();
test_rand_s();
- test_memcpy_s();
test_I10_OUTPUT();
test_strerror_s();
test__get_doserrno();
Modified: trunk/rostests/winetests/msvcrt/printf.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/printf.c…
==============================================================================
--- trunk/rostests/winetests/msvcrt/printf.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/printf.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -323,6 +323,22 @@
ok(!strcmp(buffer,"1 "),"Character zero-padded and/or not
left-adjusted \"%s\"\n",buffer);
ok( r==4, "return count wrong\n");
+ format = "%#012x";
+ r = sprintf(buffer,format,1);
+ ok(!strcmp(buffer,"0x0000000001"),"Hexadecimal zero-padded
\"%s\"\n",buffer);
+
+ format = "%#04.8x";
+ r = sprintf(buffer,format,1);
+ ok(!strcmp(buffer,"0x00000001"), "Hexadecimal zero-padded precision
\"%s\"\n",buffer);
+
+ format = "%#-08.2x";
+ r = sprintf(buffer,format,1);
+ ok(!strcmp(buffer,"0x01 "), "Hexadecimal zero-padded not
left-adjusted \"%s\"\n",buffer);
+
+ format = "%#08o";
+ r = sprintf(buffer,format,1);
+ ok(!strcmp(buffer,"00000001"), "Octal zero-padded
\"%s\"\n",buffer);
+
if (sizeof(void *) == 8)
{
format = "%p";
@@ -591,6 +607,16 @@
r = sprintf(buffer, format);
ok(!strcmp(buffer,"%0"), "failed: \"%s\"\n", buffer);
ok( r==2, "return count wrong\n");
+
+ format = "%hx";
+ r = sprintf(buffer, format, 0x12345);
+ ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer);
+
+ format = "%hhx";
+ r = sprintf(buffer, format, 0x123);
+ ok(!strcmp(buffer,"123"), "failed: \"%s\"\n", buffer);
+ r = sprintf(buffer, format, 0x12345);
+ ok(!strcmp(buffer,"2345"), "failed \"%s\"\n", buffer);
}
static void test_swprintf( void )
Modified: trunk/rostests/winetests/msvcrt/scanf.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/scanf.c?…
==============================================================================
--- trunk/rostests/winetests/msvcrt/scanf.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/scanf.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -27,6 +27,7 @@
char buffer[100], buffer1[100];
char format[20];
int result, ret;
+ LONGLONG result64;
char c;
void *ptr;
float res1= -82.6267f, res2= 27.76f, res11, res12;
@@ -125,6 +126,25 @@
ok(ret == 0 , "problem with format arg \"%%*c%%n\"\n");
ok(number_so_far == 1,"Read wrong arg for \"%%n\" %d instead of
2\n",number_so_far);
+ result = 0xdeadbeef;
+ strcpy(buffer,"12345678");
+ ret = sscanf(buffer, "%hd", &result);
+ ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+ ok(result == 0xdead614e, "Wrong number read (%x)\n", result);
+
+ result = 0xdeadbeef;
+ ret = sscanf(buffer, "%hhd", &result);
+ ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+ ok(result == 0xbc614e, "Wrong number read (%x)\n", result);
+
+ strcpy(buffer,"12345678901234");
+ ret = sscanf(buffer, "%lld", &result64);
+ ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+ ret = sprintf(buffer1, "%lld", result64);
+ ok(ret==14 || broken(ret==10), "sprintf retuned %d\n", ret);
+ if(ret == 14)
+ ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1,
buffer);
+
/* Check %i according to bug 1878 */
strcpy(buffer,"123");
ret = sscanf(buffer, "%i", &result);
@@ -243,8 +263,25 @@
ok(i==123, "i = %d\n", i);
}
+static void test_swscanf( void )
+{
+ wchar_t buffer[100];
+ int result, ret;
+ static const WCHAR formatd[] = {'%','d',0};
+
+ /* check WEOF */
+ /* WEOF is an unsigned short -1 but swscanf returns int
+ so it should be sign-extended */
+ buffer[0] = 0;
+ ret = swscanf(buffer, formatd, &result);
+ /* msvcrt returns 0 but should return -1 (later versions do) */
+ ok( ret == (short)WEOF || broken(ret == 0),
+ "swscanf returns %x instead of %x\n", ret, WEOF );
+}
+
START_TEST(scanf)
{
test_sscanf();
test_sscanf_s();
-}
+ test_swscanf();
+}
Modified: trunk/rostests/winetests/msvcrt/string.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/string.c…
==============================================================================
--- trunk/rostests/winetests/msvcrt/string.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/string.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -58,6 +58,8 @@
#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, "Binary
buffer mismatch - expected %s, got %s\n", buf_to_string((unsigned char *)value, len,
1), buf_to_string((buf), len, 0)); }
static void* (__cdecl *pmemcpy)(void *, const void *, size_t n);
+static int (__cdecl *p_memcpy_s)(void *, size_t, const void *, size_t);
+static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t);
static int* (__cdecl *pmemcmp)(void *, const void *, size_t n);
static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src);
static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src);
@@ -500,6 +502,148 @@
ok(ret == EINVAL, "Copying a big string a NULL dest returned %d, expected
EINVAL\n", ret);
}
+#define NUMELMS(array) (sizeof(array)/sizeof((array)[0]))
+
+#define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \
+ ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] ==
b3 && \
+ dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] ==
b7, \
+ "Bad result: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x
0x%02x\n",\
+ dst[0], dst[1], dst[2], dst[3], dst[4], dst[5], dst[6], dst[7])
+
+static void test_memcpy_s(void)
+{
+ static char dest[8];
+ static const char tiny[] = {'T',0,'I','N','Y',0};
+ static const char big[] =
{'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0};
+ int ret;
+ if (!p_memcpy_s) {
+ skip("memcpy_s not found\n");
+ return;
+ }
+
+ if (p_set_invalid_parameter_handler)
+ ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
+ "Invalid parameter handler was already set\n");
+
+ /* Normal */
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memcpy_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ok(ret == 0, "Copying a buffer into a big enough destination returned %d,
expected 0\n", ret);
+ okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X',
'X');
+
+ /* Vary source size */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memcpy_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d,
expected ERANGE\n", ret);
+ ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
+ okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ /* Replace source with NULL */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memcpy_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected
EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+ okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ /* Vary dest size */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memcpy_s(dest, 0, tiny, NUMELMS(tiny));
+ ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected
ERANGE\n", ret);
+ ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ /* Replace dest with NULL */
+ errno = 0xdeadbeef;
+ ret = p_memcpy_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d,
expected EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+
+ /* Combinations */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memcpy_s(dest, 0, NULL, NUMELMS(tiny));
+ ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned
%d, expected EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ if (p_set_invalid_parameter_handler)
+ ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
+ "Cannot reset invalid parameter handler\n");
+}
+
+static void test_memmove_s(void)
+{
+ static char dest[8];
+ static const char tiny[] = {'T',0,'I','N','Y',0};
+ static const char big[] =
{'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0};
+ int ret;
+ if (!p_memmove_s) {
+ skip("memmove_s not found\n");
+ return;
+ }
+
+ if (p_set_invalid_parameter_handler)
+ ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
+ "Invalid parameter handler was already set\n");
+
+ /* Normal */
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memmove_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ok(ret == 0, "Moving a buffer into a big enough destination returned %d,
expected 0\n", ret);
+ okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X',
'X');
+
+ /* Overlapping */
+ memcpy(dest, big, sizeof(dest));
+ ret = p_memmove_s(dest+1, NUMELMS(dest)-1, dest, NUMELMS(dest)-1);
+ ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n",
ret);
+ okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]);
+
+ /* Vary source size */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memmove_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d,
expected ERANGE\n", ret);
+ ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ /* Replace source with NULL */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memmove_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected
EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ /* Vary dest size */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memmove_s(dest, 0, tiny, NUMELMS(tiny));
+ ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected
ERANGE\n", ret);
+ ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ /* Replace dest with NULL */
+ errno = 0xdeadbeef;
+ ret = p_memmove_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d,
expected EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+
+ /* Combinations */
+ errno = 0xdeadbeef;
+ memset(dest, 'X', sizeof(dest));
+ ret = p_memmove_s(dest, 0, NULL, NUMELMS(tiny));
+ ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned
%d, expected EINVAL\n", ret);
+ ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
+ okchars(dest, 'X', 'X', 'X', 'X', 'X',
'X', 'X', 'X');
+
+ if (p_set_invalid_parameter_handler)
+ ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
+ "Cannot reset invalid parameter handler\n");
+}
+
static void test_strcat_s(void)
{
char dest[8];
@@ -685,6 +829,22 @@
ret = p_wcsncpy_s(szDestShort, 8, szLongText, sizeof(szLongText)/sizeof(WCHAR));
ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n",
ret);
ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
+
+ szDest[0] = 'A';
+ ret = p_wcsncpy_s(szDest, 5, szLongText, -1);
+ ok(ret == STRUNCATE, "expected STRUNCATE got %d\n", ret);
+ ok(szDest[4] == 0, "szDest[4] not 0\n");
+ ok(!memcmp(szDest, szLongText, 4*sizeof(WCHAR)), "szDest = %s\n",
wine_dbgstr_w(szDest));
+
+ ret = p_wcsncpy_s(NULL, 0, (void*)0xdeadbeef, 0);
+ ok(ret == 0, "ret = %d\n", ret);
+
+ szDestShort[0] = '1';
+ szDestShort[1] = 0;
+ ret = p_wcsncpy_s(szDestShort+1, 4, szDestShort, -1);
+ ok(ret == STRUNCATE, "expected ERROR_SUCCESS got %d\n", ret);
+ ok(szDestShort[0]=='1' && szDestShort[1]=='1' &&
szDestShort[2]=='1' && szDestShort[3]=='1',
+ "szDestShort = %s\n", wine_dbgstr_w(szDestShort));
}
static void test__wcsupr_s(void)
@@ -866,21 +1026,79 @@
/* List of value-pairs to test. The test assumes the last pair to be {0, ..} */
unsigned int jisjms[][2] = { {0x2020, 0}, {0x2021, 0}, {0x2120, 0}, {0x2121,
0x8140},
{0x7f7f, 0}, {0x7f7e, 0}, {0x7e7f, 0}, {0x7e7e,
0xeffc},
+ {0x255f, 0x837e}, {0x2560, 0x8380}, {0x2561, 0x8381},
{0x2121FFFF, 0}, {0x2223, 0x81a1}, {0x237e, 0x829e}, {0,
0}};
- unsigned int ret, exp, i;
-
- i = 0;
- do
+ int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
+ unsigned int i, j;
+ int prev_cp = _getmbcp();
+
+ for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
{
- ret = _mbcjistojms(jisjms[i][0]);
-
- if(_getmbcp() == 932) /* Japanese codepage? */
- exp = jisjms[i][1];
- else
- exp = jisjms[i][0]; /* If not, no conversion */
-
- ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
- } while(jisjms[i++][0] != 0);
+ _setmbcp(cp[i]);
+ for (j = 0; jisjms[j][0] != 0; j++)
+ {
+ unsigned int ret, exp;
+ ret = _mbcjistojms(jisjms[j][0]);
+ exp = (cp[i] == 932) ? jisjms[j][1] : jisjms[j][0];
+ ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n",
+ exp, ret, jisjms[j][0], cp[i]);
+ }
+ }
+ _setmbcp(prev_cp);
+}
+
+static void test_mbcjmsjis(void)
+{
+ /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */
+ unsigned int jmsjis[][2] = { {0x80fc, 0}, {0x813f, 0}, {0x8140, 0x2121},
+ {0x817e, 0x215f}, {0x817f, 0}, {0x8180, 0x2160},
+ {0x819e, 0x217e}, {0x819f, 0x2221}, {0x81fc, 0x227e},
+ {0x81fd, 0}, {0x9ffc, 0x5e7e}, {0x9ffd, 0},
+ {0xa040, 0}, {0xdffc, 0}, {0xe040, 0x5f21},
+ {0xeffc, 0x7e7e}, {0xf040, 0}, {0x21, 0}, {0, 0}};
+ int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
+ unsigned int i, j;
+ int prev_cp = _getmbcp();
+
+ for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ {
+ _setmbcp(cp[i]);
+ for (j = 0; jmsjis[j][0] != 0; j++)
+ {
+ unsigned int ret, exp;
+ ret = _mbcjmstojis(jmsjis[j][0]);
+ exp = (cp[i] == 932) ? jmsjis[j][1] : jmsjis[j][0];
+ ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n",
+ exp, ret, jmsjis[j][0], cp[i]);
+ }
+ }
+ _setmbcp(prev_cp);
+}
+
+static void test_mbbtombc(void)
+{
+ static const unsigned int mbbmbc[][2] = {
+ {0x1f, 0x1f}, {0x20, 0x8140}, {0x39, 0x8258}, {0x40, 0x8197},
+ {0x41, 0x8260}, {0x5e, 0x814f}, {0x7e, 0x8150}, {0x7f, 0x7f},
+ {0x80, 0x80}, {0x81, 0x81}, {0xa0, 0xa0}, {0xa7, 0x8340},
+ {0xb0, 0x815b}, {0xd1, 0x8380}, {0xff, 0xff}, {0,0}};
+ int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
+ int i, j;
+ int prev_cp = _getmbcp();
+
+ for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ {
+ _setmbcp(cp[i]);
+ for (j = 0; mbbmbc[j][0] != 0; j++)
+ {
+ unsigned int exp, ret;
+ ret = _mbbtombc(mbbmbc[j][0]);
+ exp = (cp[i] == 932) ? mbbmbc[j][1] : mbbmbc[j][0];
+ ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage %d)\n",
+ exp, ret, mbbmbc[j][0], cp[i]);
+ }
+ }
+ _setmbcp(prev_cp);
}
static void test_mbctombb(void)
@@ -1586,7 +1804,7 @@
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
- "Expected the output buffer to be \"gorrIsTeR\"\n");
+ "Expected the output buffer to be \"\\0oRrIsTeR\"\n");
strcpy(buffer, "GoRrIsTeR");
errno = EBADF;
@@ -1594,7 +1812,7 @@
ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
- "Expected the output buffer to be \"gorrIsTeR\"\n");
+ "Expected the output buffer to be \"\\0oRrIsTeR\"\n");
strcpy(buffer, "GoRrIsTeR");
ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR"));
@@ -2005,6 +2223,9 @@
ret = p_wctob(0x81);
ok(ret == (int)(char)0x81, "ret = %x\n", ret);
+ ret = p_wctob(0x9f);
+ ok(ret == (int)(char)0x9f, "ret = %x\n", ret);
+
ret = p_wctob(0xe0);
ok(ret == (int)(char)0xe0, "ret = %x\n", ret);
}
@@ -2055,6 +2276,8 @@
hMsvcrt = GetModuleHandleA("msvcrtd.dll");
ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
SET(pmemcpy,"memcpy");
+ p_memcpy_s = (void*)GetProcAddress( hMsvcrt, "memcpy_s" );
+ p_memmove_s = (void*)GetProcAddress( hMsvcrt, "memmove_s" );
SET(pmemcmp,"memcmp");
SET(p_mbctype,"_mbctype");
SET(p__mb_cur_max,"__mb_cur_max");
@@ -2102,9 +2325,13 @@
/* test _strdup */
test_strdup();
test_strcpy_s();
+ test_memcpy_s();
+ test_memmove_s();
test_strcat_s();
test__mbsnbcpy_s();
test_mbcjisjms();
+ test_mbcjmsjis();
+ test_mbbtombc();
test_mbctombb();
test_ismbclegal();
test_strtok();
Modified: trunk/rostests/winetests/msvcrt/time.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/msvcrt/time.c?r…
==============================================================================
--- trunk/rostests/winetests/msvcrt/time.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/msvcrt/time.c [iso-8859-1] Sat Sep 29 14:28:48 2012
@@ -25,6 +25,7 @@
#include <stdlib.h> /*setenv*/
#include <stdio.h> /*printf*/
+#include <locale.h>
#include <errno.h>
#define _MAX__TIME64_T (((__time64_t)0x00000007 << 32) | 0x93406FFF)
@@ -37,6 +38,7 @@
static __time32_t (__cdecl *p_mkgmtime32)(struct tm*);
static struct tm* (__cdecl *p_gmtime32)(__time32_t*);
+static struct tm* (__cdecl *p_gmtime)(time_t*);
static errno_t (__cdecl *p_gmtime32_s)(struct tm*, __time32_t*);
static errno_t (__cdecl *p_strtime_s)(char*,size_t);
static errno_t (__cdecl *p_strdate_s)(char*,size_t);
@@ -44,12 +46,16 @@
static errno_t (__cdecl *p_localtime64_s)(struct tm*, __time64_t*);
static int* (__cdecl *p__daylight)(void);
static int* (__cdecl *p___p__daylight)(void);
+static size_t (__cdecl *p_strftime)(char *, size_t, const char *, const struct tm
*);
+static size_t (__cdecl *p_wcsftime)(wchar_t *, size_t, const wchar_t *, const struct
tm *);
+static char* (__cdecl *p_asctime)(const struct tm *);
static void init(void)
{
- HMODULE hmod = GetModuleHandleA("msvcrt.dll");
+ HMODULE hmod = LoadLibrary("msvcrt.dll");
p_gmtime32 = (void*)GetProcAddress(hmod, "_gmtime32");
+ p_gmtime = (void*)GetProcAddress(hmod, "gmtime");
p_gmtime32_s = (void*)GetProcAddress(hmod, "_gmtime32_s");
p_mkgmtime32 = (void*)GetProcAddress(hmod, "_mkgmtime32");
p_strtime_s = (void*)GetProcAddress(hmod, "_strtime_s");
@@ -58,6 +64,9 @@
p_localtime64_s = (void*)GetProcAddress(hmod, "_localtime64_s");
p__daylight = (void*)GetProcAddress(hmod, "__daylight");
p___p__daylight = (void*)GetProcAddress(hmod, "__p__daylight");
+ p_strftime = (void*)GetProcAddress(hmod, "strftime");
+ p_wcsftime = (void*)GetProcAddress(hmod, "wcsftime");
+ p_asctime = (void*)GetProcAddress(hmod, "asctime");
}
static int get_test_year(time_t *start)
@@ -568,10 +577,238 @@
ok(ret1 && ret1 == ret2, "got %p\n", ret1);
}
+static void test_strftime(void)
+{
+ static const wchar_t cW[] = { '%','c',0 };
+ static const char expected[] = "01/01/70 00:00:00";
+ time_t gmt;
+ struct tm* gmt_tm;
+ char buf[256], bufA[256];
+ WCHAR bufW[256];
+ long retA, retW;
+
+ if (!p_strftime || !p_wcsftime || !p_gmtime)
+ {
+ win_skip("strftime, wcsftime or gmtime is not available\n");
+ return;
+ }
+
+ setlocale(LC_TIME, "C");
+
+ gmt = 0;
+ gmt_tm = p_gmtime(&gmt);
+ ok(gmt_tm != NULL, "gmtime failed\n");
+
+ errno = 0xdeadbeef;
+ retA = strftime(NULL, 0, "copy", gmt_tm);
+ ok(retA == 0, "expected 0, got %ld\n", retA);
+ ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
+
+ retA = strftime(bufA, 256, "copy", NULL);
+ ok(retA == 4, "expected 4, got %ld\n", retA);
+ ok(!strcmp(bufA, "copy"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "copy it", gmt_tm);
+ ok(retA == 7, "expected 7, got %ld\n", retA);
+ ok(!strcmp(bufA, "copy it"), "got %s\n", bufA);
+
+ errno = 0xdeadbeef;
+ retA = strftime(bufA, 2, "copy", gmt_tm);
+ ok(retA == 0, "expected 0, got %ld\n", retA);
+ ok(!strcmp(bufA, "") || broken(!strcmp(bufA, "copy it")),
"got %s\n", bufA);
+ ok(errno==ERANGE || errno==0xdeadbeef, "errno = %d\n", errno);
+
+ errno = 0xdeadbeef;
+ retA = strftime(bufA, 256, "a%e", gmt_tm);
+ ok(retA==0 || broken(retA==1), "expected 0, got %ld\n", retA);
+ ok(!strcmp(bufA, "") || broken(!strcmp(bufA, "a")), "got
%s\n", bufA);
+ ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
+
+ if(0) { /* crashes on Win2k */
+ errno = 0xdeadbeef;
+ retA = strftime(bufA, 256, "%c", NULL);
+ ok(retA == 0, "expected 0, got %ld\n", retA);
+ ok(!strcmp(bufA, ""), "got %s\n", bufA);
+ ok(errno == EINVAL, "errno = %d\n", errno);
+ }
+
+ retA = strftime(bufA, 256, "e%#%e", gmt_tm);
+ ok(retA == 3, "expected 3, got %ld\n", retA);
+ ok(!strcmp(bufA, "e%e"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%c", gmt_tm);
+ ok(retA == 17, "expected 17, got %ld\n", retA);
+ ok(strcmp(bufA, expected) == 0, "expected %s, got %s\n", expected, bufA);
+
+ retW = wcsftime(bufW, 256, cW, gmt_tm);
+ ok(retW == 17, "expected 17, got %ld\n", retW);
+ ok(retA == retW, "expected %ld, got %ld\n", retA, retW);
+ buf[0] = 0;
+ retA = WideCharToMultiByte(CP_ACP, 0, bufW, retW, buf, 256, NULL, NULL);
+ buf[retA] = 0;
+ ok(strcmp(bufA, buf) == 0, "expected %s, got %s\n", bufA, buf);
+
+ retA = strftime(bufA, 256, "%x", gmt_tm);
+ ok(retA == 8, "expected 8, got %ld\n", retA);
+ ok(!strcmp(bufA, "01/01/70"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%X", gmt_tm);
+ ok(retA == 8, "expected 8, got %ld\n", retA);
+ ok(!strcmp(bufA, "00:00:00"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%a", gmt_tm);
+ ok(retA == 3, "expected 3, got %ld\n", retA);
+ ok(!strcmp(bufA, "Thu"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%A", gmt_tm);
+ ok(retA == 8, "expected 8, got %ld\n", retA);
+ ok(!strcmp(bufA, "Thursday"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%b", gmt_tm);
+ ok(retA == 3, "expected 3, got %ld\n", retA);
+ ok(!strcmp(bufA, "Jan"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%B", gmt_tm);
+ ok(retA == 7, "expected 7, got %ld\n", retA);
+ ok(!strcmp(bufA, "January"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%d", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "01"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%#d", gmt_tm);
+ ok(retA == 1, "expected 1, got %ld\n", retA);
+ ok(!strcmp(bufA, "1"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%H", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "00"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%I", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "12"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%j", gmt_tm);
+ ok(retA == 3, "expected 3, got %ld\n", retA);
+ ok(!strcmp(bufA, "001"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%m", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "01"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%#M", gmt_tm);
+ ok(retA == 1, "expected 1, got %ld\n", retA);
+ ok(!strcmp(bufA, "0"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%p", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "AM"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%U", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "00"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%W", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "00"), "got %s\n", bufA);
+
+ gmt_tm->tm_wday = 0;
+ retA = strftime(bufA, 256, "%U", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "01"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%W", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "00"), "got %s\n", bufA);
+
+ gmt_tm->tm_yday = 365;
+ retA = strftime(bufA, 256, "%U", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "53"), "got %s\n", bufA);
+
+ retA = strftime(bufA, 256, "%W", gmt_tm);
+ ok(retA == 2, "expected 2, got %ld\n", retA);
+ ok(!strcmp(bufA, "52"), "got %s\n", bufA);
+
+ gmt_tm->tm_mon = 1;
+ gmt_tm->tm_mday = 30;
+ retA = strftime(bufA, 256, "%c", gmt_tm);
+ todo_wine {
+ ok(retA == 17, "expected 17, got %ld\n", retA);
+ ok(!strcmp(bufA, "02/30/70 00:00:00"), "got %s\n", bufA);
+ }
+}
+
+static void test_asctime(void)
+{
+ struct tm* gmt_tm;
+ time_t gmt;
+ char *ret;
+
+ if(!p_asctime || !p_gmtime)
+ {
+ win_skip("asctime or gmtime is not available\n");
+ return;
+ }
+
+ gmt = 0;
+ gmt_tm = p_gmtime(&gmt);
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Thu Jan 01 00:00:00 1970\n"), "asctime retunred
%s\n", ret);
+
+ gmt = 312433121;
+ gmt_tm = p_gmtime(&gmt);
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Mon Nov 26 02:58:41 1979\n"), "asctime retunred
%s\n", ret);
+
+ /* Week day is only checked if it's in 0..6 range */
+ gmt_tm->tm_wday = 3;
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Wed Nov 26 02:58:41 1979\n"), "asctime returned
%s\n", ret);
+
+ errno = 0xdeadbeef;
+ gmt_tm->tm_wday = 7;
+ ret = p_asctime(gmt_tm);
+ ok(!ret || broken(!ret[0]), "asctime returned %s\n", ret);
+ ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
+
+ /* Year day is ignored */
+ gmt_tm->tm_wday = 3;
+ gmt_tm->tm_yday = 1300;
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Wed Nov 26 02:58:41 1979\n"), "asctime returned
%s\n", ret);
+
+ /* Dates that can't be displayed using 26 characters are broken */
+ gmt_tm->tm_mday = 28;
+ gmt_tm->tm_year = 8100;
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Wed Nov 28 02:58:41 :000\n"), "asctime returned
%s\n", ret);
+
+ gmt_tm->tm_year = 264100;
+ ret = p_asctime(gmt_tm);
+ ok(!strcmp(ret, "Wed Nov 28 02:58:41 :000\n"), "asctime returned
%s\n", ret);
+
+ /* asctime works from year 1900 */
+ errno = 0xdeadbeef;
+ gmt_tm->tm_year = -1;
+ ret = p_asctime(gmt_tm);
+ ok(!ret || broken(!strcmp(ret, "Wed Nov 28 02:58:41 190/\n")),
"asctime returned %s\n", ret);
+ ok(errno==EINVAL || broken(errno == 0xdeadbeef), "errno = %d\n", errno);
+
+ errno = 0xdeadbeef;
+ gmt_tm->tm_mon = 1;
+ gmt_tm->tm_mday = 30;
+ gmt_tm->tm_year = 79;
+ ret = p_asctime(gmt_tm);
+ ok(!ret || broken(!strcmp(ret, "Wed Feb 30 02:58:41 1979\n")),
"asctime returned %s\n", ret);
+ ok(errno==EINVAL || broken(errno==0xdeadbeef), "errno = %d\n", errno);
+}
+
START_TEST(time)
{
init();
+ test_strftime();
test_ctime();
test_gmtime();
test_mktime();
@@ -583,4 +820,5 @@
test_localtime32_s();
test_localtime64_s();
test_daylight();
-}
+ test_asctime();
+}