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?rev... ============================================================================== --- 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?re... ============================================================================== --- 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?re... ============================================================================== --- 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?r... ============================================================================== --- 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?re... ============================================================================== --- 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(); +}