https://git.reactos.org/?p=reactos.git;a=commitdiff;h=063c818c729bd2eeb560c6...
commit 063c818c729bd2eeb560c691fdbf1297c94a4d24 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Thu Jan 30 12:42:59 2025 +0200 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Wed Feb 12 16:54:45 2025 +0200
[MSVCRT_WINETEST] Sync to wine-10.0 --- modules/rostests/winetests/msvcrt/CMakeLists.txt | 17 +- modules/rostests/winetests/msvcrt/cpp.c | 279 ++-- modules/rostests/winetests/msvcrt/data.c | 22 +- modules/rostests/winetests/msvcrt/dir.c | 118 +- modules/rostests/winetests/msvcrt/environ.c | 386 ++++-- modules/rostests/winetests/msvcrt/file.c | 694 +++++++++- modules/rostests/winetests/msvcrt/heap.c | 103 +- modules/rostests/winetests/msvcrt/locale.c | 227 ++- modules/rostests/winetests/msvcrt/misc.c | 151 +- modules/rostests/winetests/msvcrt/printf.c | 1191 ++++++---------- modules/rostests/winetests/msvcrt/scanf.c | 111 +- modules/rostests/winetests/msvcrt/string.c | 1599 +++++++++++++++++++--- modules/rostests/winetests/msvcrt/time.c | 455 +++--- 13 files changed, 3694 insertions(+), 1659 deletions(-)
diff --git a/modules/rostests/winetests/msvcrt/CMakeLists.txt b/modules/rostests/winetests/msvcrt/CMakeLists.txt index 53cb3a0067c..8ee88854dc9 100644 --- a/modules/rostests/winetests/msvcrt/CMakeLists.txt +++ b/modules/rostests/winetests/msvcrt/CMakeLists.txt @@ -1,4 +1,6 @@
+remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) + list(APPEND SOURCE cpp.c data.c @@ -15,7 +17,7 @@ list(APPEND SOURCE time.c)
list(APPEND PCH_SKIP_SOURCE - printf.c # _CRT_NON_CONFORMING_SWPRINTFS + printf.c testlist.c)
add_executable(msvcrt_winetest @@ -25,6 +27,8 @@ add_executable(msvcrt_winetest target_compile_definitions(msvcrt_winetest PRIVATE WINETEST_USE_DBGSTR_LONGLONG _CRT_NONSTDC_NO_DEPRECATE + _USE_MATH_DEFINES + WIN32_NO_STATUS= __msvcrt_ulong=ULONG)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") @@ -34,13 +38,14 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") endif() endif()
-set_module_type(msvcrt_winetest win32cui) -add_importlibs(msvcrt_winetest advapi32 msvcrt kernel32) -target_link_libraries(msvcrt_winetest oldnames) - if(MSVC) - add_importlibs(msvcrt_winetest ntdll) + # 'swscanf' : unknown type field character '\xe1' in format specifier + target_compile_options(msvcrt_winetest PRIVATE /wd4476) endif()
+set_module_type(msvcrt_winetest win32cui) +add_importlibs(msvcrt_winetest advapi32 msvcrt kernel32 ntdll) +target_link_libraries(msvcrt_winetest oldnames) + add_pch(msvcrt_winetest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET msvcrt_winetest) diff --git a/modules/rostests/winetests/msvcrt/cpp.c b/modules/rostests/winetests/msvcrt/cpp.c index 07b49ae755d..bfc092e0591 100644 --- a/modules/rostests/winetests/msvcrt/cpp.c +++ b/modules/rostests/winetests/msvcrt/cpp.c @@ -44,12 +44,8 @@ typedef struct __type_info #endif
/* Function pointers. We need to use these to call these funcs as __thiscall */ -static HMODULE hMsvcrt; - -static void* (__cdecl *poperator_new)(unsigned int); +static void* (__cdecl *poperator_new)(size_t); static void (__cdecl *poperator_delete)(void*); -static void* (__cdecl *pmalloc)(unsigned int); -static void (__cdecl *pfree)(void*);
/* exception */ static void (__thiscall *pexception_ctor)(exception*,LPCSTR*); @@ -112,9 +108,6 @@ static void* (__cdecl *p__RTDynamicCast)(void*,int,void*,void*,int); static char* (__cdecl *p__unDName)(char*,const char*,int,void*,void*,unsigned short int);
-/* _very_ early native versions have serious RTTI bugs, so we check */ -static void* bAncientVersion; - /* Emulate a __thiscall */ #ifdef __i386__
@@ -157,23 +150,12 @@ static void init_thiscall_thunk(void) #endif /* __i386__ */
/* Some exports are only available in later versions */ -#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) +#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 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"); + HMODULE hmsvcrt = GetModuleHandleA("msvcrt.dll");
SET(pexception_vtable, "??_7exception@@6B@"); SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@"); @@ -187,7 +169,6 @@ static BOOL InitFunctionPtrs(void) 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"); @@ -242,50 +223,50 @@ static BOOL InitFunctionPtrs(void) SETNOFAIL(poperator_new, "??_U@YAPAXI@Z"); SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z");
- SET(pexception_ctor, "??0exception@std@@QAA@ABQBD@Z"); - SET(pexception_copy_ctor, "??0exception@std@@QAA@ABV01@@Z"); - SET(pexception_default_ctor, "??0exception@std@@QAA@XZ"); - SET(pexception_dtor, "??1exception@std@@UAA@XZ"); - SET(pexception_opequals, "??4exception@std@@QAAAAV01@ABV01@@Z"); - SET(pexception_what, "?what@exception@std@@UBAPBDXZ"); - SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");/**/ - SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");/**/ - - SET(pbad_typeid_ctor, "??0bad_typeid@std@@QAA@PBD@Z"); - SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@std@@QAAXXZ"); - SET(pbad_typeid_copy_ctor, "??0bad_typeid@std@@QAA@ABV01@@Z"); - SET(pbad_typeid_dtor, "??1bad_typeid@std@@UAA@XZ"); - SET(pbad_typeid_opequals, "??4bad_typeid@std@@QAAAAV01@ABV01@@Z"); - SET(pbad_typeid_what, "?what@exception@std@@UBAPBDXZ"); - SET(pbad_typeid_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z"); - SET(pbad_typeid_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z"); + SET(pexception_ctor, "??0exception@@QAA@ABQBD@Z"); + SET(pexception_copy_ctor, "??0exception@@QAA@ABV0@@Z"); + SET(pexception_default_ctor, "??0exception@@QAA@XZ"); + SET(pexception_dtor, "??1exception@@UAA@XZ"); + SET(pexception_opequals, "??4exception@@QAAAAV0@ABV0@@Z"); + SET(pexception_what, "?what@exception@@UBAPBDXZ"); + pexception_vector_dtor = (void*)pexception_vtable[0]; + pexception_scalar_dtor = (void*)pexception_vtable[0]; + + SET(pbad_typeid_ctor, "??0bad_typeid@@QAA@PBD@Z"); + SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAAXXZ"); + SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAA@ABV0@@Z"); + SET(pbad_typeid_dtor, "??1bad_typeid@@UAA@XZ"); + SET(pbad_typeid_opequals, "??4bad_typeid@@QAAAAV0@ABV0@@Z"); + SET(pbad_typeid_what, "?what@exception@@UBAPBDXZ"); + pbad_typeid_vector_dtor = (void*)pbad_typeid_vtable[0]; + pbad_typeid_scalar_dtor = (void*)pbad_typeid_vtable[0];
SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z"); if (!pbad_cast_ctor) - SET(pbad_cast_ctor, "??0bad_cast@std@@AAA@PBQBD@Z"); - SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@std@@QAA@PBD@Z"); - SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@std@@QAAXXZ"); - /* FIXME: No ARM equivalent for "??0bad_cast@@QAE@ABV0@@Z" */ - SET(pbad_cast_dtor, "??1bad_cast@std@@UAA@XZ"); - SET(pbad_cast_opequals, "??4bad_cast@std@@QAAAAV01@ABV01@@Z"); - SET(pbad_cast_what, "?what@exception@std@@UBAPBDXZ"); - SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z"); - SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z"); + SET(pbad_cast_ctor, "??0bad_cast@@AAA@PBQBD@Z"); + SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAA@PBD@Z"); + SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAAXXZ"); + SET(pbad_cast_copy_ctor, "??0bad_cast@@QAA@ABV0@@Z"); + SET(pbad_cast_dtor, "??1bad_cast@@UAA@XZ"); + SET(pbad_cast_opequals, "??4bad_cast@@QAAAAV0@ABV0@@Z"); + SET(pbad_cast_what, "?what@exception@@UBAPBDXZ"); + 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@std@@QAA@PBD@Z"); - SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@std@@QAA@ABV01@@Z"); - SET(p__non_rtti_object_dtor, "??1__non_rtti_object@std@@UAA@XZ"); - SET(p__non_rtti_object_opequals, "??4__non_rtti_object@std@@QAAAAV01@ABV01@@Z"); - SET(p__non_rtti_object_what, "?what@exception@std@@UBAPBDXZ"); - 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(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAA@PBD@Z"); + SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@@QAA@ABV0@@Z"); + SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAA@XZ"); + SET(p__non_rtti_object_opequals, "??4__non_rtti_object@@QAAAAV0@ABV0@@Z"); + SET(p__non_rtti_object_what, "?what@exception@@UBAPBDXZ"); + 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@@UAA@XZ"); SET(ptype_info_raw_name, "?raw_name@type_info@@QBAPBDXZ"); - SET(ptype_info_name, "?name@type_info@@QBEPBDXZ"); - SET(ptype_info_before, "?before@type_info@@QBA_NABV1@@Z"); - SET(ptype_info_opequals_equals, "??8type_info@@QBA_NABV0@@Z"); - SET(ptype_info_opnot_equals, "??9type_info@@QBA_NABV0@@Z"); + SET(ptype_info_name, "?name@type_info@@QBAPBDXZ"); + SET(ptype_info_before, "?before@type_info@@QBAHABV1@@Z"); + SET(ptype_info_opequals_equals, "??8type_info@@QBAHABV0@@Z"); + SET(ptype_info_opnot_equals, "??9type_info@@QBAHABV0@@Z"); #else SETNOFAIL(poperator_new, "??_U@YAPAXI@Z"); SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z"); @@ -338,9 +319,9 @@ static BOOL InitFunctionPtrs(void) }
if (!poperator_new) - poperator_new = pmalloc; + poperator_new = malloc; if (!poperator_delete) - poperator_delete = pfree; + poperator_delete = free;
init_thiscall_thunk(); return TRUE; @@ -448,7 +429,7 @@ static void test_exception(void) name = call_func1(pexception_what, &e); ok(e.name == name, "Bad exception name from vtable e::what()\n");
- if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -571,7 +552,7 @@ static void test_bad_typeid(void) name = call_func1(pbad_typeid_what, &e); ok(e.name == name, "Bad bad_typeid name from vtable e::what()\n");
- if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -699,7 +680,7 @@ static void test_bad_cast(void) name = call_func1(pbad_cast_what, &e); ok(e.name == name, "Bad bad_cast name from vtable e::what()\n");
- if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -801,7 +782,7 @@ static void test___non_rtti_object(void) name = call_func1(p__non_rtti_object_what, &e); ok(e.name == name, "Bad __non_rtti_object name from vtable e::what()\n");
- if (p__RTtypeid && !bAncientVersion) + if (p__RTtypeid) { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); @@ -818,14 +799,14 @@ static void test_type_info(void) char* name; int res;
- if (!pmalloc || !pfree || !ptype_info_dtor || !ptype_info_raw_name || + if (!ptype_info_dtor || !ptype_info_raw_name || !ptype_info_name || !ptype_info_before || !ptype_info_opequals_equals || !ptype_info_opnot_equals) return;
/* Test calling the dtors */ call_func1(ptype_info_dtor, &t1); /* No effect, since name is NULL */ - t1.name = pmalloc(64); + t1.name = malloc(64); strcpy(t1.name, "foo"); call_func1(ptype_info_dtor, &t1); /* Frees t1.name using 'free' */
@@ -888,7 +869,7 @@ static inline void/*rtti_object_locator*/ *get_obj_locator( void *cppobj ) return (void *)vtable[-1]; }
-#ifndef __x86_64__ +#ifdef __i386__ #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) @@ -910,33 +891,36 @@ static void test_rtti(void) DEFINE_RTTI_REF(void, object_locator); } *obj_locator;
+ 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; + }; + + struct _rtti_base_array { + DEFINE_RTTI_REF(struct _rtti_base_descriptor, bases[4]); + }; + + struct _rtti_object_hierarchy { + unsigned int signature; + unsigned int attributes; + int array_len; + DEFINE_RTTI_REF(struct _rtti_base_array, base_classes); + }; + 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 _rtti_base_descriptor base_descriptor[4]; + struct _rtti_base_array base_array; + struct _rtti_object_hierarchy object_hierarchy; struct _object_locator object_locator; } simple_class_rtti = { { {NULL, NULL, "simple_class"} }, @@ -962,11 +946,17 @@ static void test_rtti(void) 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]; + struct { + void *vtbl; + char data[4]; + } 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]; + struct { + void *vtbl; + char data[4]; + } child_class_sig0 = { &child_class_sig0_vtbl[1] }; void *virtual_base_class_vtbl[2] = {&virtual_base_class_rtti.object_locator}; int virtual_base_class_vbtbl[2] = {0, 0x100}; struct { @@ -980,12 +970,11 @@ static void test_rtti(void) exception e,b; void *casted; BOOL old_signature; -#ifdef __x86_64__ +#ifndef __i386__ char *base = (char*)GetModuleHandleW(NULL); #endif
- if (bAncientVersion || - !p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor + if (!p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor || !p__RTDynamicCast || !pexception_dtor || !pbad_typeid_dtor) return;
@@ -1099,46 +1088,32 @@ static void test_demangle_datatype(void) { char * name; struct _demangle demangle[]={ -/* { "BlaBla"," ?? ::Bla", FALSE}, */ - { "ABVVec4@ref2@dice@@","class dice::ref2::Vec4 const &",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0H@@@", "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,7>", TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HO@@@", "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,126>",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOA@@@", "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,2016>",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOAA@@@", "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,32256>",TRUE}, - { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE}, -/* { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$011@@@",FALSE}, */ + { "BlaBla"," ?? ::Bla", FALSE}, + { "ABVVec4@ref2@dice@@", "class dice::ref2::Vec4 const &", TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0H@@@", + "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,7>", TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HO@@@", + "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,126>",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOA@@@", + "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,2016>",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$0HOAA@@@", + "class CDB_GEN_BIG_ENUM_FLAG<enum CDB_WYSIWYG_BITS_ENUM,32256>",TRUE}, + { "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", + "?AV?$CDB_GEN_BIG_ENUM_FLAG@W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE}, + { "P8test@@AACXZ", "signed char (__cdecl test::*)(void)", TRUE}, + { "P8test@@BACXZ", "signed char (__cdecl test::*)(void)const ", TRUE}, }; int i, num_test = ARRAY_SIZE(demangle);
for (i = 0; i < num_test; i++) { - name = p__unDName(0, demangle[i].mangled, 0, pmalloc, pfree, 0x2800); + name = p__unDName(0, demangle[i].mangled, 0, malloc, free, 0x2800); todo_wine_if (!demangle[i].test_in_wine) ok(name != NULL && !strcmp(name,demangle[i].result), "Got name "%s" for %d\n", name, i); - if(name) - pfree(name); + free(name); } }
-/* Compare two strings treating multiple spaces (' ', ascii 0x20) in s2 - as single space. Needed for test_demangle as __unDName() returns sometimes - two spaces instead of one in some older native msvcrt dlls. */ -static int strcmp_space(const char *s1, const char *s2) -{ - const char* s2start = s2; - do { - while (*s1 == *s2 && *s1) { - s1++; - s2++; - } - if (*s2 == ' ' && s2 > s2start && *(s2 - 1) == ' ') - s2++; - else - break; - } while (*s1 && *s2); - return *s1 - *s2; -} - static void test_demangle(void) { static struct {const char* in; const char* out; const char *broken; unsigned int flags;} test[] = { @@ -1202,7 +1177,7 @@ static void test_demangle(void) /* 23 */ {"??0streambuf@@QAE@ABV0@@Z", "public: __thiscall streambuf::streambuf(class streambuf const &)"}, /* 24 */ {"??0strstreambuf@@QAE@ABV0@@Z", "public: __thiscall strstreambuf::strstreambuf(class strstreambuf const &)"}, /* 25 */ {"??0strstreambuf@@QAE@H@Z", "public: __thiscall strstreambuf::strstreambuf(int)"}, -/* 26 */ {"??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*)(long),void (__cdecl*)(void *))"}, +/* 26 */ {"??0strstreambuf@@QAE@Q6APAXJ@ZS6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*const)(long),void (__cdecl*const volatile)(void *))"}, /* 27 */ {"??0strstreambuf@@QAE@PADH0@Z", "public: __thiscall strstreambuf::strstreambuf(char *,int,char *)"}, /* 28 */ {"??0strstreambuf@@QAE@PAEH0@Z", "public: __thiscall strstreambuf::strstreambuf(unsigned char *,int,unsigned char *)"}, /* 29 */ {"??0strstreambuf@@QAE@XZ", "public: __thiscall strstreambuf::strstreambuf(void)"}, @@ -1237,7 +1212,7 @@ static void test_demangle(void) /* 58 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_trai [...] /* 59 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_trai [...] /* 60 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_trai [...] -/* 61 */ {"?_query_new_handler@@YAP6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, +/* 61 */ {"?_query_new_handler@@YAR6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, /* 62 */ {"?register_callback@ios_base@std@@QAEXP6AXW4event@12@AAV12@H@ZH@Z", "public: void __thiscall std::ios_base::register_callback(void (__cdecl*)(enum std::ios_base::event,class std::ios_base &,int),int)"}, /* 63 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JW4seekdir@ios_base@2@@Z", "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(long,enum std::ios_base::seekdir)"}, /* 64 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@V?$fpos@H@2@@Z", "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(class std::fpos<int>)"}, @@ -1325,22 +1300,54 @@ static void test_demangle(void) "??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z"}, /* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", "public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"}, +/* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, +/* 132 */ {"??$meth@FD@DD@CC@@QAE_NK@Z", "public: bool __thiscall CC::DD::meth<short,char>(unsigned long)"}, +/* 133 */ {"?func@@YAXPIFAH@Z", "void __cdecl func(int __unaligned * __restrict)"}, +/* 135 */ {"?x@@3PAY02HA", "int (* x)[3]"}, +/* 136 */ {"?Qux@Bar@@0PAPAP6AHPAV1@AAH1PAH@ZA", + "private: static int (__cdecl** * Bar::Qux)(class Bar *,int &,int &,int *)"}, /* variation of 105: note white space handling! */ +/* 137 */ {"?x@@3PAW4myenum@@A", "enum myenum * x"}, +/* 138 */ {"?pfunc@@3PAY0E@P6AXF@ZA", "void (__cdecl*(* pfunc)[4])(short)"}, +/* 139 */ {"??$?0AEAVzzz@BB4@AA@@AEAV012@$0A@@?$pair@Vzzz@BB4@AA@@V123@@std@@QEAA@AEAVzzz@BB4@AA@@0@Z", + "public: __cdecl std::pair<class AA::BB4::zzz,class AA::BB4::zzz>::pair<class AA::BB4::zzz,class AA::BB4::zzz><class AA::BB4::zzz & __ptr64,class AA::BB4::zzz & __ptr64,0>(class AA::BB4::zzz & __ptr64,class AA::BB4::zzz & __ptr64) __ptr64"}, +/* 140 */ {"??$?BH@?$foo@N@@QEAAHXZ", "public: __cdecl foo<double>::operator<int> int(void) __ptr64"}, +/* 141 */ {"??Bcastop@@QAEHXZ", "public: __thiscall castop::operator int(void)"}, +/* 142 */ {"??Bcastop@@QAE?BHXZ", "public: __thiscall castop::operator int const (void)"}, +/* 143 */ {"?pfield@@3PTAA@@DT1@", "char const volatile AA::* const volatile pfield"}, +/* 144 */ {"?ptititi1@@3PEQtititi@@IEQ1@", "unsigned int tititi::* __ptr64 __ptr64 ptititi1"}, +/* 145 */ {"?ptititi2@@3PERtititi@@IER1@", "unsigned int const tititi::* __ptr64 const __ptr64 ptititi2"}, +/* 146 */ {"?ptititi3@@3PEStititi@@IES1@", "unsigned int volatile tititi::* __ptr64 volatile __ptr64 ptititi3"}, +/* 147 */ {"?ptititi4@@3PETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4"}, +/* 148 */ {"?ptititi4v@@3RETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4v"}, +/* 149 */ {"?meth@AAA@@QFCEXXZ", "public: void __thiscall AAA::meth(void)volatile __unaligned "}, +/* 150 */ {"?RegisterModuleUninitializer@<CrtImplementationDetails>@@YAXP$AAVEventHandler@System@@@Z", + "void __cdecl <CrtImplementationDetails>::RegisterModuleUninitializer(class System::EventHandler ^)"}, +/* 151 */ {"?RegisterModuleUninitializer@<CrtImplementationDetails>@@YAXBE$AAVEventHandler@System@@@Z", + "void __cdecl <CrtImplementationDetails>::RegisterModuleUninitializer(class System::EventHandler % __ptr64 volatile)"}, +/* 152 */ {"??$forward@AEAUFFIValue@?1??call@FFIFunctionBinder@@CAHPEAUlua_State@@@Z@@std@@YAAEAUFFIValue@?1??call@" + "FFIFunctionBinder@@CAHPEAUxlua_State@@@Z@AEAU1?1??23@CAH0@Z@@Z", + "struct `private: static int __cdecl FFIFunctionBinder::call(struct xlua_State * __ptr64)'::`2'::FFIValue & " + "__ptr64 __cdecl std::forward<struct `private: static int __cdecl FFIFunctionBinder::call(struct lua_State " + "* __ptr64)'::`2'::FFIValue & __ptr64>(struct `private: static int __cdecl FFIFunctionBinder::call(struct " + "xlua_State * __ptr64)'::`2'::FFIValue & __ptr64)"}, +/* 153 */ {"?$AAA@XX", "AAA<void,void>"}, +/* 154 */ {"?$AAA@", "AAA<>"}, }; - int i, num_test = ARRAY_SIZE(test); + int i; char* name;
- for (i = 0; i < num_test; i++) + for (i = 0; i < ARRAY_SIZE(test); i++) { - name = p__unDName(0, test[i].in, 0, pmalloc, pfree, test[i].flags); + name = p__unDName(0, test[i].in, 0, malloc, free, test[i].flags); ok(name != NULL, "%u: unDName failed\n", i); if (!name) continue; - ok( !strcmp_space(test[i].out, name) || - broken(test[i].broken && !strcmp_space(test[i].broken, name)), + ok( !strcmp(test[i].out, name) || + broken(test[i].broken && !strcmp(test[i].broken, name)), "%u: Got name "%s"\n", i, name ); - ok( !strcmp_space(test[i].out, name) || - broken(test[i].broken && !strcmp_space(test[i].broken, name)), + ok( !strcmp(test[i].out, name) || + broken(test[i].broken && !strcmp(test[i].broken, name)), "%u: Expected "%s"\n", i, test[i].out ); - pfree(name); + free(name); } }
diff --git a/modules/rostests/winetests/msvcrt/data.c b/modules/rostests/winetests/msvcrt/data.c index b0acc60b20b..b78bc4f7029 100644 --- a/modules/rostests/winetests/msvcrt/data.c +++ b/modules/rostests/winetests/msvcrt/data.c @@ -32,7 +32,11 @@ #include <errno.h> #include <direct.h>
-void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +#ifdef __REACTOS__ +_CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +_CRTIMP void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); +#endif + static int* (__cdecl *p___p___argc)(void); static char*** (__cdecl *p___p___argv)(void);
@@ -92,12 +96,12 @@ static void test_initvar( HMODULE hmsvcrt ) winminor = *pp_winminor; winmajor = *pp_winmajor; GetVersionExA( &osvi); - ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02x\n", + ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02lx\n", winminor, osvi.dwMinorVersion); - ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02x\n", + ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02lx\n", winmajor, osvi.dwMajorVersion); ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion), - "Wrong value for _winver %02x expected %02x\n", + "Wrong value for _winver %02x expected %02lx\n", winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion)); if( !pp_osver || !pp_osplatform ) { win_skip("_osver variables are not available\n"); @@ -108,10 +112,10 @@ static void test_initvar( HMODULE hmsvcrt ) ok( osver == (osvi.dwBuildNumber & 0xffff) || ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion && ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */ - "Wrong value for _osver %04x expected %04x\n", + "Wrong value for _osver %04x expected %04lx\n", osver, osvi.dwBuildNumber); ok(osplatform == osvi.dwPlatformId, - "Wrong value for _osplatform %x expected %x\n", + "Wrong value for _osplatform %x expected %lx\n", osplatform, osvi.dwPlatformId); }
@@ -133,7 +137,7 @@ static void test___getmainargs(void) { int argc, new_argc, mode; char **argv, **new_argv, **envp; - char tmppath[MAX_PATH], filepath[MAX_PATH]; + char tmppath[MAX_PATH], filepath[MAX_PATH + 14]; FILE *f;
ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); @@ -194,7 +198,7 @@ static void test___getmainargs(void) static void test___getmainargs_parent(char *name) { char cmdline[3*MAX_PATH]; - char tmppath[MAX_PATH], filepath[MAX_PATH]; + char tmppath[MAX_PATH], filepath[MAX_PATH + 14]; STARTUPINFOA startup; PROCESS_INFORMATION proc; FILE *f; @@ -218,7 +222,7 @@ static void test___getmainargs_parent(char *name) memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); - winetest_wait_child_process(proc.hProcess); + wait_child_process(proc.hProcess);
_unlink(filepath); sprintf(filepath, "%swine_test\a", tmppath); diff --git a/modules/rostests/winetests/msvcrt/dir.c b/modules/rostests/winetests/msvcrt/dir.c index 210cf3983cd..a2a704d85d3 100644 --- a/modules/rostests/winetests/msvcrt/dir.c +++ b/modules/rostests/winetests/msvcrt/dir.c @@ -138,36 +138,6 @@ static void test_makepath(void) } }
-static const WCHAR expected0[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected1[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected2[] = {'\0',':','X','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected3[] = {'\0',':','d','X','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected4[] = {'\0',':','d','\','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected5[] = {'\0',':','d','\','f','X','X','X','X','X','X','X','X'}; -static const WCHAR expected6[] = {'\0',':','d','\','f','i','X','X','X','X','X','X','X'}; -static const WCHAR expected7[] = {'\0',':','d','\','f','i','l','X','X','X','X','X','X'}; -static const WCHAR expected8[] = {'\0',':','d','\','f','i','l','e','X','X','X','X','X'}; -static const WCHAR expected9[] = {'\0',':','d','\','f','i','l','e','.','X','X','X','X'}; -static const WCHAR expected10[] = {'\0',':','d','\','f','i','l','e','.','e','X','X','X'}; -static const WCHAR expected11[] = {'\0',':','d','\','f','i','l','e','.','e','x','X','X'}; - -static const WCHAR expected12[] = {'\0',':','X','X','X','X','X','X','X','X'}; -static const WCHAR expected13[] = {'\0',':','d','X','X','X','X','X','X','X'}; -static const WCHAR expected14[] = {'\0',':','d','i','X','X','X','X','X','X'}; -static const WCHAR expected15[] = {'\0',':','d','i','r','X','X','X','X','X'}; -static const WCHAR expected16[] = {'\0',':','d','i','r','\','X','X','X','X'}; - -static const WCHAR expected17[] = {'\0','o','o'}; -static const WCHAR expected18[] = {'\0','o','o','\0','X'}; -static const WCHAR expected19[] = {'\0','o','o','\0'}; -static const WCHAR expected20[] = {'\0','o','o','\0','X','X','X','X','X'}; -static const WCHAR expected21[] = {'\0','o','o','\','f','i','l','X','X'}; -static const WCHAR expected22[] = {'\0','o','o','\0','X','X','X','X','X','X','X','X','X'}; -static const WCHAR expected23[] = {'\0','o','o','\','f','i','l','X','X','X','X','X','X'}; -static const WCHAR expected24[] = {'\0','o','o','\','f','i','l','e','.','e','x','X','X'}; -static const WCHAR expected25[] = {'\0','o','o','\0','X','X','X','X'}; -static const WCHAR expected26[] = {'\0','o','o','.','e','x','X','X'}; - typedef struct { const char* buffer; @@ -184,35 +154,35 @@ typedef struct static const makepath_s_case makepath_s_cases[] = { /* Behavior with directory parameter containing backslash. */ - {NULL, 1, "c:", "d\", "file", "ext", "\0XXXXXXXXXXXX", expected0, 13}, - {NULL, 2, "c:", "d\", "file", "ext", "\0XXXXXXXXXXXX", expected1, 13}, - {NULL, 3, "c:", "d\", "file", "ext", "\0:XXXXXXXXXXX", expected2, 13}, - {NULL, 4, "c:", "d\", "file", "ext", "\0:dXXXXXXXXXX", expected3, 13}, - {NULL, 5, "c:", "d\", "file", "ext", "\0:d\XXXXXXXXX", expected4, 13}, - {NULL, 6, "c:", "d\", "file", "ext", "\0:d\fXXXXXXXX", expected5, 13}, - {NULL, 7, "c:", "d\", "file", "ext", "\0:d\fiXXXXXXX", expected6, 13}, - {NULL, 8, "c:", "d\", "file", "ext", "\0:d\filXXXXXX", expected7, 13}, - {NULL, 9, "c:", "d\", "file", "ext", "\0:d\fileXXXXX", expected8, 13}, - {NULL, 10, "c:", "d\", "file", "ext", "\0:d\file.XXXX", expected9, 13}, - {NULL, 11, "c:", "d\", "file", "ext", "\0:d\file.eXXX", expected10, 13}, - {NULL, 12, "c:", "d\", "file", "ext", "\0:d\file.exXX", expected11, 13}, + {NULL, 1, "c:", "d\", "file", "ext", "\0XXXXXXXXXXXX", L"\0XXXXXXXXXXXX", 13}, + {NULL, 2, "c:", "d\", "file", "ext", "\0XXXXXXXXXXXX", L"\0XXXXXXXXXXXX", 13}, + {NULL, 3, "c:", "d\", "file", "ext", "\0:XXXXXXXXXXX", L"\0:XXXXXXXXXXX", 13}, + {NULL, 4, "c:", "d\", "file", "ext", "\0:dXXXXXXXXXX", L"\0:dXXXXXXXXXX", 13}, + {NULL, 5, "c:", "d\", "file", "ext", "\0:d\XXXXXXXXX", L"\0:d\XXXXXXXXX", 13}, + {NULL, 6, "c:", "d\", "file", "ext", "\0:d\fXXXXXXXX", L"\0:d\fXXXXXXXX", 13}, + {NULL, 7, "c:", "d\", "file", "ext", "\0:d\fiXXXXXXX", L"\0:d\fiXXXXXXX", 13}, + {NULL, 8, "c:", "d\", "file", "ext", "\0:d\filXXXXXX", L"\0:d\filXXXXXX", 13}, + {NULL, 9, "c:", "d\", "file", "ext", "\0:d\fileXXXXX", L"\0:d\fileXXXXX", 13}, + {NULL, 10, "c:", "d\", "file", "ext", "\0:d\file.XXXX", L"\0:d\file.XXXX", 13}, + {NULL, 11, "c:", "d\", "file", "ext", "\0:d\file.eXXX", L"\0:d\file.eXXX", 13}, + {NULL, 12, "c:", "d\", "file", "ext", "\0:d\file.exXX", L"\0:d\file.exXX", 13}, /* Behavior with directory parameter lacking backslash. */ - {NULL, 3, "c:", "dir", "f", "ext", "\0:XXXXXXXX", expected12, 10}, - {NULL, 4, "c:", "dir", "f", "ext", "\0:dXXXXXXX", expected13, 10}, - {NULL, 5, "c:", "dir", "f", "ext", "\0:diXXXXXX", expected14, 10}, - {NULL, 6, "c:", "dir", "f", "ext", "\0:dirXXXXX", expected15, 10}, - {NULL, 7, "c:", "dir", "f", "ext", "\0:dir\XXXX", expected16, 10}, + {NULL, 3, "c:", "dir", "f", "ext", "\0:XXXXXXXX", L"\0:XXXXXXXX", 10}, + {NULL, 4, "c:", "dir", "f", "ext", "\0:dXXXXXXX", L"\0:dXXXXXXX", 10}, + {NULL, 5, "c:", "dir", "f", "ext", "\0:diXXXXXX", L"\0:diXXXXXX", 10}, + {NULL, 6, "c:", "dir", "f", "ext", "\0:dirXXXXX", L"\0:dirXXXXX", 10}, + {NULL, 7, "c:", "dir", "f", "ext", "\0:dir\XXXX", L"\0:dir\XXXX", 10}, /* Behavior with overlapped buffer. */ - {"foo", 2, USE_BUFF, NULL, NULL, NULL, "\0oo", expected17, 3}, - {"foo", 4, NULL, USE_BUFF, NULL, NULL, "\0oo\0X", expected18, 5}, - {"foo", 3, NULL, NULL, USE_BUFF, NULL, "\0oo\0", expected19, 4}, - {"foo", 4, NULL, USE_BUFF, "file", NULL, "\0oo\0XXXXX", expected20, 9}, - {"foo", 8, NULL, USE_BUFF, "file", NULL, "\0oo\filXX", expected21, 9}, - {"foo", 4, NULL, USE_BUFF, "file", "ext", "\0oo\0XXXXXXXXX", expected22, 13}, - {"foo", 8, NULL, USE_BUFF, "file", "ext", "\0oo\filXXXXXX", expected23, 13}, - {"foo", 12, NULL, USE_BUFF, "file", "ext", "\0oo\file.exXX", expected24, 13}, - {"foo", 4, NULL, NULL, USE_BUFF, "ext", "\0oo\0XXXX", expected25, 8}, - {"foo", 7, NULL, NULL, USE_BUFF, "ext", "\0oo.exXX", expected26, 8}, + {"foo", 2, USE_BUFF, NULL, NULL, NULL, "\0oo", L"\0oo", 3}, + {"foo", 4, NULL, USE_BUFF, NULL, NULL, "\0oo\0X", L"\0oo\0X", 5}, + {"foo", 3, NULL, NULL, USE_BUFF, NULL, "\0oo\0", L"\0oo", 4}, + {"foo", 4, NULL, USE_BUFF, "file", NULL, "\0oo\0XXXXX", L"\0oo\0XXXXX", 9}, + {"foo", 8, NULL, USE_BUFF, "file", NULL, "\0oo\filXX", L"\0oo\filXX", 9}, + {"foo", 4, NULL, USE_BUFF, "file", "ext", "\0oo\0XXXXXXXXX", L"\0oo\0XXXXXXXXX", 13}, + {"foo", 8, NULL, USE_BUFF, "file", "ext", "\0oo\filXXXXXX", L"\0oo\filXXXXXX", 13}, + {"foo", 12, NULL, USE_BUFF, "file", "ext", "\0oo\file.exXX", L"\0oo\file.exXX", 13}, + {"foo", 4, NULL, NULL, USE_BUFF, "ext", "\0oo\0XXXX", L"\0oo\0XXXX", 8}, + {"foo", 7, NULL, NULL, USE_BUFF, "ext", "\0oo.exXX", L"\0oo.exXX", 8}, };
static void test_makepath_s(void) @@ -438,10 +408,6 @@ static void test_searchenv(void) "\search_env_test\dir3longer\3.dat" };
- const WCHAR env_w[] = {'T','E','S','T','_','P','A','T','H',0}; - const WCHAR dat1_w[] = {'1','.','d','a','t',0}; - const WCHAR dat3_w[] = {'3','.','d','a','t',0}; - char env1[4*MAX_PATH], env2[4*MAX_PATH], tmppath[MAX_PATH], path[2*MAX_PATH]; char result[MAX_PATH], exp[2*MAX_PATH]; WCHAR result_w[MAX_PATH]; @@ -510,13 +476,13 @@ static void test_searchenv(void) }
memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat1_w, env_w, result_w); + _wsearchenv(L"1.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"1.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -535,13 +501,13 @@ static void test_searchenv(void) }
memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat3_w, env_w, result_w); + _wsearchenv(L"3.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"3.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -561,13 +527,13 @@ static void test_searchenv(void) }
memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat1_w, env_w, result_w); + _wsearchenv(L"1.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"1.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); } @@ -586,17 +552,31 @@ static void test_searchenv(void) }
memset(result_w, 'x', sizeof(result_w)); - _wsearchenv(dat3_w, env_w, result_w); + _wsearchenv(L"3.dat", L"TEST_PATH", result_w); WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
if (p_wsearchenv_s) { memset(result_w, 'x', sizeof(result_w)); - i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH); + i = p_wsearchenv_s(L"3.dat", L"TEST_PATH", result_w, MAX_PATH); ok(!i, "wsearchenv_s returned %d\n", i); ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); }
+ strcpy(env1, "TEST_PATH="); + strcat(env1, tmppath); + strcat(env1, ""\search_env_test\"d"i"r"1"); + putenv(env1); + strcpy(exp, tmppath); + strcat(exp, files[0]); + _searchenv("1.dat", "TEST_PATH", result); + ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp); + + strcat(env1, ";"); + putenv(env1); + _searchenv("1.dat", "TEST_PATH", result); + ok(!result[0], "got %s, expected ''\n", result); + putenv("TEST_PATH=");
for (i=ARRAY_SIZE(files)-1; i>=0; i--) { diff --git a/modules/rostests/winetests/msvcrt/environ.c b/modules/rostests/winetests/msvcrt/environ.c index b8e0ae6251a..9951c5b1308 100644 --- a/modules/rostests/winetests/msvcrt/environ.c +++ b/modules/rostests/winetests/msvcrt/environ.c @@ -19,7 +19,15 @@ */
#include "wine/test.h" +#include <errno.h> #include <stdlib.h> +#include <process.h> +#include <winnls.h> + +#ifdef __REACTOS__ +_CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int, int *); +_CRTIMP void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); +#endif
static const char *a_very_long_env_string = "LIBRARY_PATH=" @@ -42,13 +50,15 @@ static const char *a_very_long_env_string = "/usr/lib/mingw32/3.4.2/;" "/usr/lib/";
-void __cdecl __getmainargs(int *, char ***, char ***, int, int *); -void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); - static char ***(__cdecl *p__p__environ)(void); static WCHAR ***(__cdecl *p__p__wenviron)(void); -static void (*p_get_environ)(char ***); -static void (*p_get_wenviron)(WCHAR ***); +static char ***(__cdecl *p__p___initenv)(void); +static wchar_t ***(__cdecl *p__p___winitenv)(void); +static void (__cdecl *p_get_environ)(char ***); +static void (__cdecl *p_get_wenviron)(WCHAR ***); +static errno_t (__cdecl *p_putenv_s)(const char*, const char*); +static errno_t (__cdecl *p_wputenv_s)(const wchar_t*, const wchar_t*); +static errno_t (__cdecl *p_getenv_s)(size_t*, char*, size_t, const char*);
static char ***p_environ; static WCHAR ***p_wenviron; @@ -59,10 +69,15 @@ static void init(void)
p__p__environ = (void *)GetProcAddress(hmod, "__p__environ"); p__p__wenviron = (void *)GetProcAddress(hmod, "__p__wenviron"); + p__p___initenv = (void *)GetProcAddress(hmod, "__p___initenv"); + p__p___winitenv = (void *)GetProcAddress(hmod, "__p___winitenv"); p_environ = (void *)GetProcAddress(hmod, "_environ"); p_wenviron = (void *)GetProcAddress(hmod, "_wenviron"); p_get_environ = (void *)GetProcAddress(hmod, "_get_environ"); p_get_wenviron = (void *)GetProcAddress(hmod, "_get_wenviron"); + p_putenv_s = (void *)GetProcAddress(hmod, "_putenv_s"); + p_wputenv_s = (void *)GetProcAddress(hmod, "_wputenv_s"); + p_getenv_s = (void *)GetProcAddress(hmod, "getenv_s"); }
static void test_system(void) @@ -74,30 +89,46 @@ static void test_system(void) ok(ret == 0, "Expected system to return 0, got %d\n", ret); }
-static void test__environ(void) +static unsigned env_get_entry_countA( char **env ) { - int argc; - char **argv, **envp = NULL; - int i, mode = 0; + unsigned count;
- ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); - if (p_environ) - ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); + if (!env) return 0; + for (count = 0; env[count] != NULL; count++) {} + return count; +}
- if (!p_environ || !*p_environ) - { - skip( "_environ pointers are not valid\n" ); - return; - } +static wchar_t *env_get_valueW( wchar_t **envp, const wchar_t *var ) +{ + unsigned i; + size_t len = wcslen( var );
- /* Examine the returned pointer from __p__environ(), if available. */ - if (p__p__environ) + if (!envp) return NULL; + for (i = 0; envp[i] != NULL; i++) { - ok( *p__p__environ() == *p_environ, - "Expected _environ pointers to be identical\n" ); + wchar_t *ptr; + + if (!(ptr = wcschr( envp[i], L'=' ))) continue; + + if (ptr - envp[i] == len && !memcmp( envp[i], var, len * sizeof(wchar_t) )) + return ptr + 1; } + return NULL; +} + +static void test__environ(void) +{ + int argc; + char **argv, **envp = NULL, **initenv = NULL; + int mode = 0; + + ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); + ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); + + if (sizeof(void*) != sizeof(int)) + ok( !p__p__environ, "__p__environ() should be 32-bit only\n"); else - skip( "__p__environ() is not available\n" ); + ok( *p__p__environ() == *p_environ, "Expected _environ pointers to be identical\n" );
if (p_get_environ) { @@ -109,76 +140,74 @@ static void test__environ(void) else win_skip( "_get_environ() is not available\n" );
+ if (p__p___initenv) + { + initenv = *p__p___initenv(); + + ok( initenv == *p_environ, + "Expected _environ to be equal to initial env\n" ); + } + else + skip( "__p___initenv() is not available\n" ); + /* Note that msvcrt from Windows versions older than Vista * expects the mode pointer parameter to be valid.*/ __getmainargs(&argc, &argv, &envp, 0, &mode);
- ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!envp) - { - skip( "Initial environment block pointer is not valid\n" ); - return; - } + ok( envp != NULL, + "Expected initial environment block pointer to be non-NULL\n" ); + ok( envp == *p_environ, + "Expected initial environment to be equal to _environ\n" );
- for (i = 0; ; i++) + ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); + if (p__p___initenv) { - if ((*p_environ)[i]) - { - ok( envp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !strcmp((*p_environ)[i], envp[i]), - "Expected _environ and environment block pointer strings (%s vs. %s) to match\n", - (*p_environ)[i], envp[i] ); - } - else - { - ok( !envp[i], "Expected environment block pointer element to be NULL, got %p\n", envp[i] ); - break; - } + char **retptr = *p__p___initenv(); + + ok( retptr != *p_environ, + "Expected _environ[] not to be equal to initial env\n" ); + ok( retptr == initenv, + "Unexpected modification of initial env\n" ); } + ok( _putenv("cat=") == 0, "failed setting cat=\n" ); }
static void test__wenviron(void) { - static const WCHAR cat_eq_dogW[] = {'c','a','t','=','d','o','g',0}; - static const WCHAR cat_eqW[] = {'c','a','t','=',0}; - int argc; char **argv, **envp = NULL; WCHAR **wargv, **wenvp = NULL; - int i, mode = 0; + int mode = 0;
ok( p_wenviron != NULL, "Expected the pointer to _wenviron to be non-NULL\n" ); - if (p_wenviron) - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); - else - { - win_skip( "Pointer to _wenviron is not valid\n" ); - return; - } + ok( !*p_wenviron, "Expected _wenviron[] to be NULL, got %p\n", *p_wenviron );
- /* Examine the returned pointer from __p__wenviron(), if available. */ - if (p__p__wenviron) - { - ok( *p__p__wenviron() == NULL, - "Expected _wenviron pointers to be NULL\n" ); - } + if (sizeof(void*) != sizeof(int)) + ok( !p__p__wenviron, "__p__wenviron() should be 32-bit only\n"); else - skip( "__p__wenviron() is not available\n" ); + ok( !*p__p__wenviron(), "Expected _wenviron to be NULL, got %p\n", *p_wenviron );
if (p_get_wenviron) { WCHAR **retptr; p_get_wenviron(&retptr); - ok( retptr == NULL, - "Expected _wenviron pointers to be NULL\n" ); + ok( retptr == *p_wenviron, "Expected _wenviron pointers to be NULL\n" ); } else win_skip( "_get_wenviron() is not available\n" );
+ if (p__p___winitenv) + { + wchar_t ***retptr = p__p___winitenv(); + ok( !*retptr, "Expected initial env to be NULL\n" ); + } + else + skip( "__p___winitenv() is not available\n" ); + /* __getmainargs doesn't initialize _wenviron. */ __getmainargs(&argc, &argv, &envp, 0, &mode);
- ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); + ok( !*p_wenviron, "Expected _wenviron to be NULL\n"); ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); if (!envp) { @@ -188,24 +217,31 @@ static void test__wenviron(void)
/* Neither does calling the non-Unicode environment manipulation functions. */ ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); - ok( _putenv("cat=") == 0, "failed deleting cat\n" ); + ok( !*p_wenviron, "Expected _wenviron to be NULL\n" );
/* _wenviron isn't initialized until __wgetmainargs is called or * one of the Unicode environment manipulation functions is called. */ - ok( _wputenv(cat_eq_dogW) == 0, "failed setting cat=dog\n" ); + ok( _wputenv(L"cat=dog2") == 0, "failed setting cat=dog2\n" ); ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); - ok( _wputenv(cat_eqW) == 0, "failed deleting cat\n" );
__wgetmainargs(&argc, &wargv, &wenvp, 0, &mode); - - ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); ok( wenvp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!wenvp) + ok( wenvp == *p_wenviron, "Expected initial environment to be _wenviron[]\n" ); + + if (p__p___winitenv) { - skip( "Initial environment block pointer is not valid\n" ); - return; + wchar_t ***retptr = p__p___winitenv(); + wchar_t *value; + + ok( *retptr != NULL, "Expected *__p___winitenv() to be NULL\n" ); + ok( *retptr != *p_wenviron, + "Expected _wenviron to be different from __p___winitenv() %p %p\n", *retptr, *p_wenviron ); + /* test that w-initial env is derived from current _environ[] and not from ansi initial env */ + value = env_get_valueW( *retptr, L"cat" ); + ok( value && !wcscmp( value, L"dog" ), + "Expecting initial env to be derived from current env (got %ls)\n", value ); } + _putenv("cat=");
/* Examine the returned pointer from __p__wenviron(), * if available, after _wenviron is initialized. */ @@ -222,29 +258,27 @@ static void test__wenviron(void) ok( retptr == *p_wenviron, "Expected _wenviron pointers to be identical\n" ); } - - for (i = 0; ; i++) - { - if ((*p_wenviron)[i]) - { - ok( wenvp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !winetest_strcmpW((*p_wenviron)[i], wenvp[i]), - "Expected _wenviron and environment block pointer strings (%s vs. %s) to match\n", - wine_dbgstr_w((*p_wenviron)[i]), wine_dbgstr_w(wenvp[i]) ); - } - else - { - ok( !wenvp[i], "Expected environment block pointer element to be NULL, got %p\n", wenvp[i] ); - break; - } - } }
static void test_environment_manipulation(void) { + char buf[256]; + errno_t ret; + size_t len; + unsigned count; + char* first; + char* second; + ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" ); + if (p_getenv_s) + { + ret = p_getenv_s(&len, buf, sizeof(buf), "cat"); + ok( !ret, "getenv_s returned %d\n", ret ); + ok( len == 4, "getenv_s returned length is %Id\n", len); + ok( !strcmp(buf, "dog"), "getenv_s did not return 'dog'\n"); + } ok( _putenv("cat=") == 0, "failed deleting cat\n" );
ok( _putenv("=") == -1, "should not accept '=' as input\n" ); @@ -252,16 +286,190 @@ static void test_environment_manipulation(void) ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n");
ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); + + if (p_putenv_s) + { + ret = p_putenv_s(NULL, "dog"); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", NULL); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("a=b", NULL); + ok( ret == EINVAL, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", "a=b"); + ok( !ret, "_putenv_s returned %d\n", ret); + ret = p_putenv_s("cat", ""); + ok( !ret, "_putenv_s returned %d\n", ret); + } + + if (p_wputenv_s) + { + ret = p_wputenv_s(NULL, L"dog"); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", NULL); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"a=b", NULL); + ok( ret == EINVAL, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", L"a=b"); + ok( !ret, "_wputenv_s returned %d\n", ret); + ret = p_wputenv_s(L"cat", L""); + ok( !ret, "_wputenv_s returned %d\n", ret); + } + + if (p_getenv_s) + { + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s(&len, buf, sizeof(buf), "nonexistent"); + ok( !ret, "_getenv_s returned %d\n", ret); + ok( !len, "getenv_s returned length is %Id\n", len); + ok( !buf[0], "buf = %s\n", buf); + ok( errno == 0xdeadbeef, "errno = %d\n", errno); + + buf[0] = 'x'; + len = 1; + errno = 0xdeadbeef; + ret = p_getenv_s(&len, buf, sizeof(buf), NULL); + ok( !ret, "_getenv_s returned %d\n", ret); + ok( !len, "getenv_s returned length is %Id\n", len); + ok( !buf[0], "buf = %s\n", buf); + ok( errno == 0xdeadbeef, "errno = %d\n", errno); + } + + /* test stability of _environ[] pointers */ + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + count = env_get_entry_countA( *p_environ ); + ok( _putenv( "__winetest_cat=mew") == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=mew"), "Unexpected env var value\n" ); + first = (*p_environ)[count]; + ok( getenv("__winetest_cat") == strchr( (*p_environ)[count], '=') + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( first == (*p_environ)[count], "Expected stability of _environ[count] pointer\n" ); + second = (*p_environ)[count + 1]; + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + ok( _putenv( "__winetest_cat=purr" ) == 0, "Couldn't set env var\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_cat=purr" ), "Unexpected env var value\n" ); + ok( getenv( "__winetest_cat" ) == strchr( (*p_environ)[count], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( second == (*p_environ)[count + 1], "Expected stability of _environ[count] pointer\n" ); + ok( !strcmp( (*p_environ)[count + 1], "__winetest_dog=bark" ), "Couldn't get env var value\n" ); + ok( getenv( "__winetest_dog" ) == strchr( (*p_environ)[count + 1], '=' ) + 1, "Expected getenv() to return pointer inside _environ[] entry\n" ); + ok( count + 2 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env vat\n" ); + ok( second == (*p_environ)[count], "Expected _environ[count] to be second\n" ); + ok( !strcmp( (*p_environ)[count], "__winetest_dog=bark" ), "Unexpected env var value\n" ); + ok( count + 1 == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected count\n" ); + + /* in putenv, only changed variable is updated (no other reload of kernel info is done) */ + ret = SetEnvironmentVariableA( "__winetest_cat", "meow" ); + ok( ret, "SetEnvironmentVariableA failed: %lu\n", GetLastError() ); + ok( _putenv( "__winetest_dog=bark" ) == 0, "Couldn't set env var\n" ); + ok( getenv( "__winetest_cat" ) == NULL, "msvcrt env cache shouldn't have been updated\n" ); + ok( _putenv( "__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + ok( _putenv( "__winetest_dog=" ) == 0, "Couldn't reset env var\n" ); + + /* test setting unicode bits */ + count = env_get_entry_countA( *p_environ ); + ret = WideCharToMultiByte( CP_ACP, 0, L"\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_cat=\u263a" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_cat" ) && !wcscmp( _wgetenv( L"__winetest_cat" ), L"\u263a" ), "Couldn't retrieve env var\n" ); + ok( getenv( "__winetest_cat" ) && !strcmp( getenv( "__winetest_cat" ), buf ), "Couldn't retrieve env var\n" ); + ok( _wputenv( L"__winetest_cat=" ) == 0, "Couldn't reset env var\n" ); + + ret = WideCharToMultiByte( CP_ACP, 0, L"__winetest_\u263a", -1, buf, ARRAY_SIZE(buf), 0, 0 ); + ok( ret, "WideCharToMultiByte failed: %lu\n", GetLastError() ); + ok( _wputenv( L"__winetest_\u263a=bark" ) == 0, "Couldn't set env var\n" ); + ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"bark"), "Couldn't retrieve env var\n" ); + ok( getenv( buf ) && !strcmp( getenv( buf ), "bark"), "Couldn't retrieve env var %s\n", wine_dbgstr_a(buf) ); + ok( _wputenv( L"__winetest_\u263a=" ) == 0, "Couldn't reset env var\n" ); + ok( count == env_get_entry_countA( *p_environ ), "Unexpected modification of _environ[]\n" ); +} + +static void test_child_env(char** argv) +{ + STARTUPINFOA si = {sizeof(si)}; + WCHAR *cur_env, *env, *p, *q; + PROCESS_INFORMATION pi; + char tmp[1024]; + BOOL ret; + int len; + + cur_env = GetEnvironmentStringsW(); + ok( cur_env != NULL, "GetEnvironemntStrings failed\n" ); + + p = cur_env; + while (*p) p += wcslen( p ) + 1; + len = p - cur_env; + env = malloc( (len + 1024) * sizeof(*env) ); + memcpy(env, cur_env, len * sizeof(*env) ); + q = env + len; + FreeEnvironmentStringsW( cur_env ); + + wcscpy( q, L"__winetest_dog=bark" ); + q += wcslen( L"__winetest_dog=bark" ) + 1; + wcscpy( q, L"__winetest_\u263a=\u03b2" ); + q += wcslen( L"__winetest_\u263a=\u03b2" ) + 1; + *q = 0; + + snprintf( tmp, sizeof(tmp), "%s %s create", argv[0], argv[1] ); + ret = CreateProcessA( NULL, tmp, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi ); + ok( ret, "Couldn't create child process %s\n", tmp ); + winetest_wait_child_process( pi.hProcess ); + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + free( env ); +} + +static void test_case_insensitive(void) +{ + const char *uppercase_env = getenv("APPDATA"); + const char *lowercase_env = getenv("appdata"); + const wchar_t *uppercase_wenv = _wgetenv(L"APPDATA"); + const wchar_t *lowercase_wenv = _wgetenv(L"appdata"); + + ok( uppercase_env == lowercase_env, "getenv() must be case insensitive, %p should be %p\n", + lowercase_env, uppercase_env ); + ok( uppercase_wenv == lowercase_wenv, "_wgetenv() must be case insensitive, %p should be %p\n", + lowercase_wenv, uppercase_wenv ); + + ok( !_putenv("cAt=bar"), "Failed to set CAT=bar\n" ); + ok( !_putenv("CAT=BAR"), "Failed to set CAT=BAR\n" ); + ok( !strcmp(getenv("cAt"), "BAR"), "_putenv() must be case insensitive\n" ); + + ok( !_wputenv(L"cAt=bar"), "Failed to set CAT=bar\n" ); + ok( !_wputenv(L"CAT=BAR"), "Failed to set CAT=BAR\n" ); + ok( !wcscmp(_wgetenv(L"cAt"), L"BAR"), "_wputenv() must be case insensitive\n" ); + + _putenv("cat="); }
START_TEST(environ) { + char **argv; + int argc; + init();
- /* The environ tests should always be run first, as they assume - * that the process has not manipulated the environment. */ + argc = winetest_get_mainargs( &argv ); + if (argc == 3 && !strcmp( argv[2], "create" )) + { + ok( getenv( "__winetest_dog" ) && !strcmp( getenv( "__winetest_dog" ), "bark" ), + "Couldn't find env var\n" ); + ok( _wgetenv( L"__winetest_\u263a" ) && !wcscmp( _wgetenv( L"__winetest_\u263a" ), L"\u03b2" ), + "Couldn't find unicode env var\n" ); + return; + } + test__environ(); test__wenviron(); test_environment_manipulation(); + test_child_env(argv); test_system(); + test_case_insensitive(); } diff --git a/modules/rostests/winetests/msvcrt/file.c b/modules/rostests/winetests/msvcrt/file.c index fe62d5c385e..d082bb269c6 100644 --- a/modules/rostests/winetests/msvcrt/file.c +++ b/modules/rostests/winetests/msvcrt/file.c @@ -35,6 +35,25 @@ #include <process.h> #include <errno.h> #include <locale.h> +#ifdef __REACTOS__ +#include <ntndk.h> +#else +#include <winternl.h> +#endif + +#define WX_OPEN 0x01 +#define WX_ATEOF 0x02 +#define WX_READNL 0x04 +#define WX_PIPE 0x08 +#define WX_DONTINHERIT 0x10 +#define WX_APPEND 0x20 +#define WX_TTY 0x40 +#define WX_TEXT 0x80 + +#define EF_UTF8 0x01 +#define EF_UTF16 0x02 +#define EF_CRIT_INIT 0x04 +#define EF_UNK_UNICODE 0x08
#define MSVCRT_FD_BLOCK_SIZE 32 typedef struct { @@ -52,6 +71,7 @@ static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*); static int (__cdecl *p__wfopen_s)(FILE**, const wchar_t*, const wchar_t*); static errno_t (__cdecl *p__get_fmode)(int*); static errno_t (__cdecl *p__set_fmode)(int); +static int (__cdecl *p__setmaxstdio)(int);
static const char* get_base_name(const char *path) { @@ -76,6 +96,7 @@ static void init(void) __pioinfo = (void*)GetProcAddress(hmod, "__pioinfo"); p__get_fmode = (void*)GetProcAddress(hmod, "_get_fmode"); p__set_fmode = (void*)GetProcAddress(hmod, "_set_fmode"); + p__setmaxstdio = (void*)GetProcAddress(hmod, "_setmaxstdio"); }
static void test_filbuf( void ) @@ -211,7 +232,50 @@ static void test_fileops( void ) ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); /* feof should be set now */ ok(feof(file), "feof after fread failed\n"); - fclose (file); + clearerr(file); + ok(!feof(file), "feof after clearerr failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + rewind(file); + ok(!feof(file), "feof after rewind failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fseek(file, 0, SEEK_SET); + ok(!feof(file), "feof after fseek failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fgetpos(file, &pos); + fsetpos(file, &pos); + ok(!feof(file), "feof after fsetpos failed\n"); + fclose(file); + + file = fopen("fdopen.tst", "rb"); + ok( file != NULL, "fopen failed\n"); + /* sizeof(buffer) > content of file */ + ok(fread(buffer, sizeof(buffer), 1, file) == 0, "fread test failed\n"); + /* feof should be set now */ + ok(feof(file), "feof after fread failed\n"); + fsetpos(file, &pos); + ok(!feof(file), "feof after fsetpos failed\n"); + fclose(file);
unlink ("fdopen.tst"); } @@ -233,7 +297,7 @@ static void test_readmode( BOOL ascii_mode )
fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE); /* an internal buffer of BUFSIZ is maintained, so make a file big - * enough to test operations that cross the buffer boundary + * enough to test operations that cross the buffer boundary */ j = (2*BUFSIZ-4)/strlen(padbuffer); for (i=0; i<j; i++) @@ -243,8 +307,21 @@ static void test_readmode( BOOL ascii_mode ) write (fd, &padbuffer[i], 1); write (fd, nlbuffer, strlen(nlbuffer)); write (fd, outbuffer, sizeof (outbuffer)); + + errno = 0xdeadbeef; + _doserrno = 0xdeadbeef; + ok(read(fd, buffer, 1) == -1, "read succeeded on write-only file\n"); + ok(errno == EBADF, "errno = %d\n", errno); + ok(_doserrno == ERROR_ACCESS_DENIED, "doserrno = %ld\n", _doserrno); + close (fd); - + + fd = open ("fdopen.tst", O_RDONLY, _S_IREAD |_S_IWRITE); + errno = 0xdeadbeef; + ok(dup2(fd, -1) == -1, "dup2(fd, -1) succeeded\n"); + ok(errno == EBADF, "errno = %d\n", errno); + close (fd); + if (ascii_mode) { /* Open file in ascii mode */ fd = open ("fdopen.tst", O_RDONLY); @@ -256,13 +333,13 @@ static void test_readmode( BOOL ascii_mode ) file = fdopen (fd, "rb"); ao = 0; } - + /* first is a test of fgets, ftell, fseek */ ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); ok(fgets(buffer,2*BUFSIZ+256,file) !=0,"padding line fgets failed unexpected in %s\n", IOMODE); l = ftell(file); pl = 2*BUFSIZ-2; - ok(l == pl,"padding line ftell got %d should be %d in %s\n", l, pl, IOMODE); + ok(l == pl,"padding line ftell got %ld should be %d in %s\n", l, pl, IOMODE); ok(lstrlenA(buffer) == pl+ao,"padding line fgets got size %d should be %d in %s\n", lstrlenA(buffer), pl+ao, IOMODE); for (fp=0; fp<strlen(outbuffer); fp++) @@ -270,26 +347,32 @@ static void test_readmode( BOOL ascii_mode ) fp++; ok(fgets(buffer,256,file) !=0,"line 1 fgets failed unexpected in %s\n", IOMODE); l = ftell(file); - ok(l == pl+fp,"line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); + ok(l == pl+fp,"line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE); ok(lstrlenA(buffer) == fp+ao,"line 1 fgets got size %d should be %d in %s\n", lstrlenA(buffer), fp+ao, IOMODE); /* test a seek back across the buffer boundary */ l = pl; ok(fseek(file,l,SEEK_SET)==0,"seek failure in %s\n", IOMODE); l = ftell(file); - ok(l == pl,"ftell after seek got %d should be %d in %s\n", l, pl, IOMODE); + ok(l == pl,"ftell after seek got %ld should be %d in %s\n", l, pl, IOMODE); ok(fgets(buffer,256,file) !=0,"second read of line 1 fgets failed unexpected in %s\n", IOMODE); l = ftell(file); - ok(l == pl+fp,"second read of line 1 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); + ok(l == pl+fp,"second read of line 1 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE); ok(lstrlenA(buffer) == fp+ao,"second read of line 1 fgets got size %d should be %d in %s\n", lstrlenA(buffer), fp+ao, IOMODE); ok(fgets(buffer,256,file) !=0,"line 2 fgets failed unexpected in %s\n", IOMODE); fp += 2; l = ftell(file); - ok(l == pl+fp,"line 2 ftell got %d should be %d in %s\n", l, pl+fp, IOMODE); + ok(l == pl+fp,"line 2 ftell got %ld should be %d in %s\n", l, pl+fp, IOMODE); ok(lstrlenA(buffer) == 2+ao,"line 2 fgets got size %d should be %d in %s\n", lstrlenA(buffer), 2+ao, IOMODE); - + + errno = 0xdeadbeef; + _doserrno = 0xdeadbeef; + ok(write(fd, buffer, 1) == -1, "read succeeded on write-only file\n"); + ok(errno == EBADF, "errno = %d\n", errno); + ok(_doserrno == ERROR_ACCESS_DENIED, "doserrno = %ld\n", _doserrno); + /* test fread across buffer boundary */ rewind(file); ok(ftell(file) == 0,"Did not start at beginning of file in %s\n", IOMODE); @@ -298,7 +381,7 @@ static void test_readmode( BOOL ascii_mode ) i=fread(buffer,1,BUFSIZ+strlen(outbuffer),file); ok(i==BUFSIZ+j,"fread failed, expected %d got %d in %s\n", BUFSIZ+j, i, IOMODE); l = ftell(file); - ok(l == pl+j-(ao*4)-5,"ftell after fread got %d should be %d in %s\n", l, pl+j-(ao*4)-5, IOMODE); + ok(l == pl+j-(ao*4)-5,"ftell after fread got %ld should be %d in %s\n", l, pl+j-(ao*4)-5, IOMODE); for (m=0; m<3; m++) ok(buffer[m]==padbuffer[m+(BUFSIZ-4)%strlen(padbuffer)],"expected %c got %c\n", padbuffer[m], buffer[m]); m+=BUFSIZ+2+ao; @@ -687,7 +770,7 @@ static void test_fflush( void ) char buf1[16], buf2[24]; char *tempf; FILE *tempfh; - int ret; + int ret, fd;
tempf=_tempnam(".","wne");
@@ -728,7 +811,23 @@ static void test_fflush( void ) ok(memcmp(buf1, buf2, sizeof(buf1)) == 0, "Got unexpected data (%c)\n", buf2[0]);
fclose(tempfh); + unlink(tempf); + + /* test flush failure */ + tempfh = fopen(tempf,"wb"); + ok(tempfh != NULL, "Can't open test file.\n"); + fwrite(obuf, 1, sizeof(obuf), tempfh); + fd = tempfh->_file; + tempfh->_file = -1;
+ ok(tempfh->_ptr - tempfh->_base, "buffer is empty\n"); + ret = fflush(tempfh); + ok(ret == EOF, "expected EOF, got %d\n", ret); + ok(!(tempfh->_ptr - tempfh->_base), "buffer should be empty\n"); + ok(!tempfh->_cnt, "tempfh->_cnt = %d\n", tempfh->_cnt); + + tempfh->_file = fd; + fclose(tempfh); unlink(tempf); free(tempf); } @@ -764,10 +863,10 @@ static void test_fgetwc( void ) tempfh = fopen(tempf,"rt"); /* open in TEXT mode */ fgetws(wtextW,LLEN,tempfh); l=ftell(tempfh); - ok(l==BUFSIZ-2, "ftell expected %d got %d\n", BUFSIZ-2, l); + ok(l==BUFSIZ-2, "ftell expected %d got %ld\n", BUFSIZ-2, l); fgetws(wtextW,LLEN,tempfh); l=ftell(tempfh); - ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %d\n", BUFSIZ-2+lstrlenA(mytext), l); + ok(l==BUFSIZ-2+strlen(mytext), "ftell expected %d got %ld\n", BUFSIZ-2+lstrlenA(mytext), l); mytextW = AtoW (mytext); aptr = mytextW; wptr = wtextW; @@ -779,7 +878,7 @@ static void test_fgetwc( void ) ok(*wptr == '\n', "Carriage return was not skipped\n"); fclose(tempfh); unlink(tempf); - + tempfh = fopen(tempf,"wb"); j = 'a'; /* pad to almost the length of the internal buffer. Use an odd number of bytes @@ -800,25 +899,25 @@ static void test_fgetwc( void ) fgetws(wtextW,j,tempfh); l=ftell(tempfh); j=(j-1)*sizeof(WCHAR); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); i=fgetc(tempfh); ok(i=='a', "fgetc expected %d got %d\n", 0x61, i); l=ftell(tempfh); j++; - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); fgetws(wtextW,3,tempfh); ok(wtextW[0]=='\r',"expected carriage return got %04hx\n", wtextW[0]); ok(wtextW[1]=='\n',"expected newline got %04hx\n", wtextW[1]); l=ftell(tempfh); j += 4; - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); for(i=0; i<strlen(mytext); i++) wtextW[i] = 0; /* the first time we get the string, it should be entirely within the local buffer */ fgetws(wtextW,LLEN,tempfh); l=ftell(tempfh); j += (strlen(mytext)-1)*sizeof(WCHAR); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); diff_found = FALSE; aptr = mytextW; wptr = wtextW; @@ -955,6 +1054,38 @@ static void test_fgetwc_unicode(void) ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); fclose(tempfh);
+ tempfh = fopen(tempfile, "r,ccs=utf-8"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) + { + ch = fgetwc(tempfh); + ok(ch == wchar_text[i], + "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); + fclose(tempfh); + + tempfh = fopen(tempfile, "a,ccs=utf-16le"); + ok(tempfh != NULL, "can't open tempfile\n"); + ch = fputwc('a', tempfh); + ok(ch == 'a', "fputwc returned %x\n", ch); + fclose(tempfh); + + tempfh = fopen(tempfile, "a+,ccs=utf-8"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) + { + ch = fgetwc(tempfh); + ok(ch == wchar_text[i], + "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1); + } + ch = fgetwc(tempfh); + ok(ch == 'a', "got %04x, expected 'a'\n", ch); + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); + fclose(tempfh); + tempfh = fopen(tempfile, "wb"); ok(tempfh != NULL, "can't open tempfile\n"); ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, ARRAY_SIZE(wchar_text), @@ -974,6 +1105,57 @@ static void test_fgetwc_unicode(void) ch = fgetwc(tempfh); ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch); fclose(tempfh); + + tempfh = fopen(tempfile, "wb"); + ok(tempfh != NULL, "can't open tempfile\n"); + fwrite(wchar_text+1, 1, sizeof(wchar_text)-1, tempfh); + fclose(tempfh); + + tempfh = fopen(tempfile, "rt,ccs=utf-16le"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) + { + ch = fgetwc(tempfh); + ok(ch == wchar_text[i], + "got %04hx, expected %04x (unicode[%d])\n", ch, wchar_text[i], i-1); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); + fclose(tempfh); + + tempfh = fopen(tempfile, "wb"); + ok(tempfh != NULL, "can't open tempfile\n"); + ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text + 1, ARRAY_SIZE(wchar_text) - 1, + utf8_text, sizeof(utf8_text), NULL, NULL); + ok(ret > 0, "utf-8 conversion failed\n"); + utf8_text[ret] = 0; + fwrite(utf8_text, sizeof(char), ret, tempfh); + fclose(tempfh); + + tempfh = fopen(tempfile, "rt, ccs=UTF-8"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 1; i < ARRAY_SIZE(wchar_text); i++) + { + ch = fgetwc(tempfh); + ok(ch == wchar_text[i], + "got %04hx, expected %04x (utf8[%d])\n", ch, wchar_text[i], i-1); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (utf8)\n", ch); + fclose(tempfh); + + tempfh = fopen(tempfile, "rt, ccs=unicode"); + ok(tempfh != NULL, "can't open tempfile\n"); + for (i = 0; utf8_text[i]; i++) + { + ch = fgetwc(tempfh); + ok(ch == (unsigned char) utf8_text[i], + "got %04hx, expected %04x (unicode[%d])\n", ch, (unsigned char)utf8_text[i], i); + } + ch = fgetwc(tempfh); + ok(ch == WEOF, "got %04hx, expected WEOF (unicode)\n", ch); + fclose(tempfh); + unlink(temppath); }
@@ -1034,6 +1216,98 @@ static void test_fputwc(void) _unlink(tempfile); }
+static void test_freopen( void ) +{ + char filename1[8] = "AXXXXXX"; + char filename2[8] = "BXXXXXX"; + FILE *file; + FILE *new; + int ret; + int fd; + char ch; + long pos; + + mktemp(filename1); + mktemp(filename2); + + file = fopen(filename1, "wt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + ret = fwrite("1", 1, 1, file); + ok(ret == 1, "fwrite() returned %d (%d)\n", ret, errno); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename2, "wt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + ret = fwrite("2", 1, 1, file); + ok(ret == 1, "fwrite() returned %d (%d)\n", ret, errno); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "rt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + file = freopen(filename2, "rt", file); + ok(file != NULL, "fopen(filename2) returned NULL\n"); + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '2', "fread() read %c\n", ch); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "at"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + file = freopen(filename1, "rt", file); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + pos = ftell(file); + ok(pos == 0, "ftell() returned %ld\n", pos); + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '1', "fread() read %c\n", ch); + ret = fclose(file); + ok(ret == 0, "fclose() returned %d\n", ret); + + file = fopen(filename1, "rt"); + ok(file != NULL, "fopen(filename1) returned NULL\n"); + fd = fileno(file); + ok(fd > 0, "fileno() returned %d\n", fd); + /* invalid filename */ + new = freopen("_:", "rt", file); + ok(new == NULL, "fopen(_:) returned non NULL\n"); + errno = 0xdeadbeef; + ch = '#'; + ret = read(fd, &ch, 1); + ok(ret == -1, "read() returned %d\n", ret); + ok(errno == EBADF, "errno is %d\n", errno); + errno = 0xdeadbeef; + ret = fclose(file); + ok(ret == EOF, "fclose(file) succeeded\n"); + ok(errno == 0xdeadbeef, "errno is %d\n", errno); + + file = fopen(filename1, "rb"); + ok(file != NULL, "couldn't open %s\n", filename1); + close(file->_file); + file->_file = -1; + + new = freopen(filename2, "rb", file); + ok(new == file, "freopen() didn't return same FILE*\n"); + + fd = fileno(file); + ok(fd > 0, "fileno() returned %d\n", fd); + + ch = '#'; + ret = fread(&ch, 1, 1, file); + ok(ret == 1, "fread() returned %d\n", ret); + ok(ch == '2', "Unexpected char\n"); + + ret = fclose(file); + ok(ret == 0, "fclose(file) returned %d\n", ret); + + unlink(filename1); + unlink(filename2); +} + static void test_ctrlz( void ) { char* tempf; @@ -1062,17 +1336,17 @@ static void test_ctrlz( void ) ok(i==j, "returned string length expected %d got %d\n", j, i); j+=4; /* ftell should indicate the true end of file */ l=ftell(tempfh); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); ok(feof(tempfh), "did not get EOF\n"); fclose(tempfh); - + tempfh = fopen(tempf,"rb"); /* open in BINARY mode */ ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); i=strlen(buffer); j=strlen(mytext)+3; /* should get through newline */ ok(i==j, "returned string length expected %d got %d\n", j, i); l=ftell(tempfh); - ok(l==j, "ftell expected %d got %d\n", j, l); + ok(l==j, "ftell expected %d got %ld\n", j, l); ok(fgets(buffer,256,tempfh) != 0,"fgets failed unexpected\n"); i=strlen(buffer); ok(i==1, "returned string length expected %d got %d\n", 1, i); @@ -1185,7 +1459,7 @@ static void test_file_write_read( void )
memset(btext, 0, LLEN); tempfd = _open(tempf,_O_APPEND|_O_RDWR); /* open for APPEND in default mode */ - ok(tell(tempfd) == 0, "bad position %u expecting 0\n", tell(tempfd)); + ok(tell(tempfd) == 0, "bad position %lu expecting 0\n", tell(tempfd)); ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext), "_read _O_APPEND got bad length\n"); ok( memcmp(mytext,btext,strlen(mytext)) == 0, "problems with _O_APPEND _read\n"); _close(tempfd); @@ -1206,15 +1480,15 @@ static void test_file_write_read( void ) _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,1); ok(ret == 1 && *btext == 'e', "_read expected 'e' got "%.*s" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 41, "bad position %u expecting 41\n", tell(tempfd)); + ok(tell(tempfd) == 41, "bad position %lu expecting 41\n", tell(tempfd)); _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,2); ok(ret == 1 && *btext == 'e', "_read expected 'e' got "%.*s" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 42, "bad position %u expecting 42\n", tell(tempfd)); + ok(tell(tempfd) == 42, "bad position %lu expecting 42\n", tell(tempfd)); _lseek(tempfd, -3, FILE_END); ret = _read(tempfd,btext,3); ok(ret == 2 && *btext == 'e', "_read expected 'e' got "%.*s" bad length: %d\n", ret, btext, ret); - ok(tell(tempfd) == 43, "bad position %u expecting 43\n", tell(tempfd)); + ok(tell(tempfd) == 43, "bad position %lu expecting 43\n", tell(tempfd)); _close(tempfd);
ret = unlink(tempf); @@ -1336,9 +1610,9 @@ static void test_file_write_read( void ) /* test invalid utf8 sequence */ lseek(tempfd, 5, SEEK_SET); ret = _read(tempfd, btext, sizeof(btext)); - todo_wine ok(ret == 10, "_read returned %d, expected 10\n", ret); + ok(ret == 10, "_read returned %d, expected 10\n", ret); /* invalid char should be replaced by U+FFFD in MultiByteToWideChar */ - todo_wine ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n"); + ok(!memcmp(btext, "\xfd\xff", 2), "invalid UTF8 character was not replaced by U+FFFD\n"); ok(!memcmp(btext+ret-8, "\x62\x00\x7c\x01\x0d\x00\x0a\x00", 8), "btext is incorrect\n"); _close(tempfd); } @@ -1355,13 +1629,27 @@ static void test_file_write_read( void ) free(tempf); }
-static void test_file_inherit_child(const char* fd_s) +static void test_file_inherit_child(const char* fd_s, const char *handle_str) { + HANDLE handle_value; int fd = atoi(fd_s); + HANDLE *handle_ptr; + unsigned int count; char buffer[32]; + STARTUPINFOA si; int ret;
- ret =write(fd, "Success", 8); + GetStartupInfoA(&si); + count = *(unsigned *)si.lpReserved2; + if (handle_str) + { + ok(count == 3, "Got unexpected count %u.\n", count); + sscanf(handle_str, "%p", &handle_value); + handle_ptr = (HANDLE *)(si.lpReserved2 + sizeof(unsigned) + count); + ok(handle_value == handle_ptr[1], "Got unexpected handle %p.\n", handle_ptr[1]); + } + + ret = write(fd, "Success", 8); ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno)); lseek(fd, 0, SEEK_SET); ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n"); @@ -1374,7 +1662,7 @@ static void test_file_inherit_child_no(const char* fd_s) int ret;
ret = write(fd, "Success", 8); - ok( ret == -1 && errno == EBADF, + ok( ret == -1 && errno == EBADF, "Wrong write result in child process on %d (%s)\n", fd, strerror(errno)); }
@@ -1430,7 +1718,7 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst
CreateProcessA( NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, NULL, NULL, startup, &proc ); - winetest_wait_child_process( proc.hProcess ); + wait_child_process( proc.hProcess );
data = read_file( hErrorFile ); if (expect_stdout) @@ -1451,6 +1739,18 @@ static void test_stdout_handle( STARTUPINFOA *startup, char *cmdline, HANDLE hst DeleteFileA( "fdopen.err" ); }
+static unsigned WINAPI read_pipe_thread(void *argument) +{ + unsigned char buffer[2]; + int ret; + int *pipefds = argument; + + ret = _read(pipefds[0], buffer, sizeof(buffer)); + ok(ret == 1, "ret = %d\n", ret); + ok(buffer[0] == 'a', "%x\n", buffer[0]); + return 0; +} + static void test_file_inherit( const char* selfname ) { int fd; @@ -1460,33 +1760,62 @@ static void test_file_inherit( const char* selfname ) STARTUPINFOA startup; SECURITY_ATTRIBUTES sa; HANDLE handles[3]; + HANDLE thread_handle; + int pipefds[2]; + intptr_t ret;
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE); ok(fd != -1, "Couldn't create test file\n"); arg_v[0] = get_base_name(selfname); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "inherit"; arg_v[3] = buffer; sprintf(buffer, "%d", fd); arg_v[4] = 0; - _spawnvp(_P_WAIT, selfname, arg_v); - ok(tell(fd) == 8, "bad position %u expecting 8\n", tell(fd)); + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd)); lseek(fd, 0, SEEK_SET); ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); close (fd); ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); - + fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE); ok(fd != -1, "Couldn't create test file\n"); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "inherit_no"; arg_v[3] = buffer; sprintf(buffer, "%d", fd); arg_v[4] = 0; - _spawnvp(_P_WAIT, selfname, arg_v); - ok(tell(fd) == 0, "bad position %u expecting 0\n", tell(fd)); + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd)); ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer); close (fd); ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n");
+ /* Show that spawn works while a read is active */ + ok(_pipe(pipefds, 1, O_BINARY) == 0, "_pipe() failed\n"); + thread_handle = (HANDLE)_beginthreadex(NULL, 0, read_pipe_thread, pipefds, 0, NULL); + Sleep(100); /* try to make sure the thread is reading */ + fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE); + ok(fd != -1, "Couldn't create test file\n"); + arg_v[1] = "tests/file.c"; + arg_v[2] = "inherit"; + arg_v[3] = buffer; sprintf(buffer, "%d", fd); + arg_v[4] = 0; + ret = _spawnvp(_P_WAIT, selfname, arg_v); + ok(ret == 0, "_spawnvp returned %Id, errno %d\n", ret, errno); + ret = tell(fd); + ok(ret == 8, "bad position %Iu expecting 8\n", ret); + lseek(fd, 0, SEEK_SET); + ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n"); + close (fd); + ok(unlink("fdopen.tst") == 0, "Couldn't unlink\n"); + _write(pipefds[1], "a", 1); + WaitForSingleObject(thread_handle, INFINITE); + CloseHandle(thread_handle); + close(pipefds[0]); + close(pipefds[1]); + /* make file handle inheritable */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; @@ -1544,6 +1873,22 @@ static void test_file_inherit( const char* selfname ) test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" ); CloseHandle( handles[1] ); DeleteFileA("fdopen.tst"); + + /* test inherit block with invalid handle */ + handles[1] = INVALID_HANDLE_VALUE; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "INVALID_HANDLE_VALUE stdout handle" ); + + handles[1] = NULL; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "NULL stdout handle" ); + + handles[1] = (void *)0xdeadbeef; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "invalid stdout handle" ); }
static void test_invalid_stdin_child( void ) @@ -1557,6 +1902,8 @@ static void test_invalid_stdin_child( void ) handle = (HANDLE)_get_osfhandle(STDIN_FILENO); ok(handle == (HANDLE)-2, "handle = %p\n", handle); ok(errno == 0xdeadbeef, "errno = %d\n", errno); + handle = GetStdHandle(STD_INPUT_HANDLE); + ok((LONG_PTR)handle > 0, "Expecting passed handle to be untouched\n");
info = &__pioinfo[STDIN_FILENO/MSVCRT_FD_BLOCK_SIZE][STDIN_FILENO%MSVCRT_FD_BLOCK_SIZE]; ok(info->handle == (HANDLE)-2, "info->handle = %p\n", info->handle); @@ -1631,7 +1978,11 @@ static void test_invalid_stdin( const char* selfname ) }
ret = RegOpenCurrentUser(KEY_READ, &key); - ok(!ret, "RegOpenCurrentUser failed: %x\n", ret); + ok(!ret, "RegOpenCurrentUser failed: %lx\n", ret); + + ret = DuplicateHandle(GetCurrentProcess(), key, GetCurrentProcess(), + (HANDLE *)&key, GENERIC_READ, TRUE, DUPLICATE_CLOSE_SOURCE); + ok(ret, "DuplicateHandle failed: %lx\n", GetLastError());
sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; @@ -1647,10 +1998,10 @@ static void test_invalid_stdin( const char* selfname ) sprintf(cmdline, "%s file stdin", selfname); CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); - winetest_wait_child_process(proc.hProcess); + wait_child_process(proc.hProcess);
ret = RegCloseKey(key); - ok(!ret, "RegCloseKey failed: %x\n", ret); + ok(!ret, "RegCloseKey failed: %lx\n", ret); }
static void test_tmpnam( void ) @@ -1678,8 +2029,8 @@ static void test_chsize( void ) LONG cur, pos, count; char temptext[] = "012345678"; char *tempfile = _tempnam( ".", "tst" ); - - ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile ); + + ok( tempfile != NULL, "Couldn't create test file\n" );
fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE ); ok( fd > 0, "Couldn't open test file\n" ); @@ -1694,14 +2045,14 @@ static void test_chsize( void ) ok( _chsize( fd, sizeof(temptext) / 2 ) == 0, "_chsize() failed\n" );
pos = _lseek( fd, 0, SEEK_CUR ); - ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); + ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos ); ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
/* enlarge the file */ - ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" ); + ok( _chsize( fd, sizeof(temptext) * 2 ) == 0, "_chsize() failed\n" );
pos = _lseek( fd, 0, SEEK_CUR ); - ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos ); + ok( cur == pos, "File pointer changed from: %ld to: %ld\n", cur, pos ); ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
_close( fd ); @@ -1733,7 +2084,7 @@ static void test_fopen_fclose_fcloseall( void ) "filename is empty, errno = %d (expected 2 or 22)\n", errno); errno = 0xfaceabad; stream4 = fopen(NULL, "w+"); - ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), + ok(stream4 == NULL && (errno == EINVAL || errno == ENOENT), "filename is NULL, errno = %d (expected 2 or 22)\n", errno);
/* testing fclose() */ @@ -1748,6 +2099,9 @@ static void test_fopen_fclose_fcloseall( void ) ret = fclose(stream3); ok(ret == EOF, "Closing file '%s' returned %d\n", fname3, ret); ok(errno == 0xdeadbeef, "errno = %d\n", errno); + ret = fclose(NULL); + ok(ret == EOF, "Closing NULL file returned %d\n", ret); + ok(errno == EINVAL, "errno = %d\n", errno);
/* testing fcloseall() */ numclosed = _fcloseall(); @@ -1879,12 +2233,6 @@ static void test_fopen_s( void ) static void test__wfopen_s( void ) { const char name[] = "empty1"; - const WCHAR wname[] = { - 'e','m','p','t','y','1',0 - }; - const WCHAR wmode[] = { - 'w',0 - }; char buff[16]; FILE *file; int ret; @@ -1896,7 +2244,7 @@ static void test__wfopen_s( void ) return; } /* testing _wfopen_s */ - ret = p__wfopen_s(&file, wname, wmode); + ret = p__wfopen_s(&file, L"empty1", L"w"); ok(ret == 0, "_wfopen_s failed with %d\n", ret); ok(file != 0, "_wfopen_s failed to return value\n"); fwrite(name, sizeof(name), 1, file); @@ -2007,8 +2355,12 @@ static void test_get_osfhandle(void)
static void test_setmaxstdio(void) { - ok(2048 == _setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",_setmaxstdio(2048)); - ok(-1 == _setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",_setmaxstdio(2049)); + if (p__setmaxstdio) + { + ok(2048 == p__setmaxstdio(2048),"_setmaxstdio returned %d instead of 2048\n",p__setmaxstdio(2048)); + ok(-1 == p__setmaxstdio(2049),"_setmaxstdio returned %d instead of -1\n",p__setmaxstdio(2049)); + } + else win_skip( "_setmaxstdio not supported\n" ); }
static void test_stat(void) @@ -2168,7 +2520,7 @@ static void test_pipes(const char* selfname) }
arg_v[0] = get_base_name(selfname); - arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "pipes"; arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); @@ -2197,7 +2549,7 @@ static void test_pipes(const char* selfname) return; }
- arg_v[1] = "tests/file.c"; + arg_v[1] = "file"; arg_v[2] = "pipes"; arg_v[3] = str_fdr; sprintf(str_fdr, "%d", pipes[0]); arg_v[4] = str_fdw; sprintf(str_fdw, "%d", pipes[1]); @@ -2313,7 +2665,7 @@ static void test_stdin(void) "GetStdHandle(STD_INPUT_HANDLE) != _get_osfhandle(STDIN_FILENO)\n");
r = SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE); - ok(r == TRUE, "SetStdHandle returned %x, expected TRUE\n", r); + ok(r == TRUE, "SetStdHandle returned %lx, expected TRUE\n", r); h = GetStdHandle(STD_INPUT_HANDLE); ok(h == INVALID_HANDLE_VALUE, "h = %p\n", h);
@@ -2548,7 +2900,7 @@ static void test__creat(void) pos = _tell(fd); ok(pos == 6, "expected pos 6 (text mode), got %d\n", pos); } - ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); + ok(_lseek(fd, 0, SEEK_SET) == 0, "_lseek failed\n"); count = _read(fd, buf, 6); ok(count == 4, "_read returned %d, expected 4\n", count); count = count > 0 ? count > 4 ? 4 : count : 0; @@ -2568,7 +2920,7 @@ static void test__creat(void) pos = _tell(fd); ok(pos == 4, "expected pos 4 (binary mode), got %d\n", pos); } - ok(_lseek(fd, SEEK_SET, 0) == 0, "_lseek failed\n"); + ok(_lseek(fd, 0, SEEK_SET) == 0, "_lseek failed\n"); count = _read(fd, buf, 6); ok(count == 4, "_read returned %d, expected 4\n", count); count = count > 0 ? count > 4 ? 4 : count : 0; @@ -2583,6 +2935,215 @@ static void test__creat(void) p__set_fmode(old_fmode); }
+static void test_lseek(void) +{ + int fd; + char testdata[4] = {'a', '\n', 'b', '\n'}; + + errno = 0xdeadbeef; + ok(_lseek(-42, 0, SEEK_SET) == -1, "expected failure\n"); + ok(errno == EBADF, "errno = %d\n", errno); + + fd = _creat("_creat.tst", _S_IWRITE); + ok(fd > 0, "_creat failed\n"); + _write(fd, testdata, 4); + + errno = 0xdeadbeef; + ok(_lseek(fd, 0, 42) == -1, "expected failure\n"); + ok(errno == EINVAL, "errno = %d\n", errno); + + errno = 0xdeadbeef; + ok(_lseek(fd, -42, SEEK_SET) == -1, "expected failure\n"); + ok(errno == EINVAL, "errno = %d\n", errno); + + _close(fd); + DeleteFileA("_creat.tst"); +} + +static BOOL has_sequential_hint(int fd) +{ + HANDLE handle; + FILE_MODE_INFORMATION mode_info; + IO_STATUS_BLOCK io; + NTSTATUS status; + + handle = (HANDLE)_get_osfhandle(fd); + status = NtQueryInformationFile(handle, &io, &mode_info, sizeof(mode_info), + FileModeInformation); + ok(!status, "NtQueryInformationFile failed\n"); + return (mode_info.Mode & FILE_SEQUENTIAL_ONLY) != 0; +} + +static void test_fopen_hints(void) +{ + static const struct { + const char *mode; + BOOL seq; + } tests[] = { + { "rb", FALSE }, + { "rbS", TRUE }, + { "rbR", FALSE }, + { "rbSR", TRUE }, + { "rbRS", FALSE } + }; + + char temppath[MAX_PATH], tempfile[MAX_PATH]; + FILE *fp; + int i; + + GetTempPathA(MAX_PATH, temppath); + GetTempFileNameA(temppath, "", 0, tempfile); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + fp = fopen(tempfile, tests[i].mode); + ok(fp != NULL, "unable to fopen test file with mode "%s"\n", tests[i].mode); + ok(has_sequential_hint(_fileno(fp)) == tests[i].seq, + "unexpected sequential hint for fopen mode "%s"\n", tests[i].mode); + fclose(fp); + } + unlink(tempfile); +} + +static void test_open_hints(void) +{ + static const struct { + int mode; + BOOL seq; + } tests[] = { + { _O_RDONLY | _O_BINARY, FALSE }, + { _O_RDONLY | _O_BINARY | _O_SEQUENTIAL, TRUE }, + { _O_RDONLY | _O_BINARY | _O_RANDOM, FALSE }, + { _O_RDONLY | _O_BINARY | _O_RANDOM | _O_SEQUENTIAL, TRUE } + }; + + char temppath[MAX_PATH], tempfile[MAX_PATH]; + int fd; + int i; + + GetTempPathA(MAX_PATH, temppath); + GetTempFileNameA(temppath, "", 0, tempfile); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + fd = open(tempfile, tests[i].mode); + ok(fd != -1, "unable to _open test file with flags %x\n", tests[i].mode); + ok(has_sequential_hint(fd) == tests[i].seq, + "unexpected sequential hint for _open flags %x\n", tests[i].mode); + close(fd); + } + unlink(tempfile); +} + +static void test_ioinfo_flags(void) +{ + HANDLE handle; + ioinfo *info; + char *tempf; + int tempfd; + + tempf = _tempnam(".","wne"); + + tempfd = _open(tempf, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_WTEXT, _S_IWRITE); + ok(tempfd != -1, "_open failed with error: %d\n", errno); + + handle = (HANDLE)_get_osfhandle(tempfd); + info = &__pioinfo[tempfd / MSVCRT_FD_BLOCK_SIZE][tempfd % MSVCRT_FD_BLOCK_SIZE]; + ok(!!info, "NULL info.\n"); + ok(info->handle == handle, "Unexpected handle %p, expected %p.\n", info->handle, handle); + ok(info->exflag == (EF_UTF16 | EF_CRIT_INIT | EF_UNK_UNICODE), "Unexpected exflag %#x.\n", info->exflag); + ok(info->wxflag == (WX_TEXT | WX_OPEN), "Unexpected wxflag %#x.\n", info->wxflag); + + close(tempfd); + + ok(info->handle == INVALID_HANDLE_VALUE, "Unexpected handle %p.\n", info->handle); + ok(info->exflag == (EF_UTF16 | EF_CRIT_INIT | EF_UNK_UNICODE), "Unexpected exflag %#x.\n", info->exflag); + ok(!info->wxflag, "Unexpected wxflag %#x.\n", info->wxflag); + + info = &__pioinfo[(tempfd + 4) / MSVCRT_FD_BLOCK_SIZE][(tempfd + 4) % MSVCRT_FD_BLOCK_SIZE]; + ok(!!info, "NULL info.\n"); + ok(info->handle == INVALID_HANDLE_VALUE, "Unexpected handle %p.\n", info->handle); + ok(!info->exflag, "Unexpected exflag %#x.\n", info->exflag); + + unlink(tempf); + free(tempf); +} + +static void test_std_stream_buffering(void) +{ + int dup_fd, ret, pos; + FILE *file; + char ch; + + dup_fd = _dup(STDOUT_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stdout); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stdout, "test"); + pos = _telli64(STDOUT_FILENO); + + fflush(stdout); + _dup2(dup_fd, STDOUT_FILENO); + close(dup_fd); + setvbuf(stdout, NULL, _IONBF, 0); + + ok(ret == 4, "fprintf(stdout) returned %d\n", ret); + ok(!pos, "expected stdout to be buffered\n"); + + dup_fd = _dup(STDERR_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "w", stderr); + ok(file != NULL, "freopen failed\n"); + + ret = fprintf(stderr, "test"); + ok(ret == 4, "fprintf(stderr) returned %d\n", ret); + pos = _telli64(STDERR_FILENO); + ok(!pos, "expected stderr to be buffered\n"); + + fflush(stderr); + _dup2(dup_fd, STDERR_FILENO); + close(dup_fd); + + dup_fd = _dup(STDIN_FILENO); + ok(dup_fd != -1, "_dup failed\n"); + + file = freopen("std_stream_test.tmp", "r", stdin); + ok(file != NULL, "freopen failed\n"); + + ch = 0; + ret = fscanf(stdin, "%c", &ch); + ok(ret == 1, "fscanf returned %d\n", ret); + ok(ch == 't', "ch = 0x%x\n", (unsigned char)ch); + pos = _telli64(STDIN_FILENO); + ok(pos == 4, "pos = %d\n", pos); + + fflush(stdin); + _dup2(dup_fd, STDIN_FILENO); + close(dup_fd); + + ok(DeleteFileA("std_stream_test.tmp"), "DeleteFile failed\n"); +} + +static void test_std_stream_open(void) +{ + FILE *f; + int fd; + + fd = _dup(STDIN_FILENO); + ok(fd != -1, "_dup failed\n"); + + ok(!fclose(stdin), "fclose failed\n"); + f = fopen("nul", "r"); + ok(f == stdin, "f = %p, expected %p\n", f, stdin); + ok(_fileno(f) == STDIN_FILENO, "_fileno(f) = %d\n", _fileno(f)); + + _dup2(fd, STDIN_FILENO); + close(fd); +} + START_TEST(file) { int arg_c; @@ -2596,7 +3157,7 @@ START_TEST(file) if (arg_c >= 3) { if (strcmp(arg_v[2], "inherit") == 0) - test_file_inherit_child(arg_v[3]); + test_file_inherit_child(arg_v[3], arg_c > 4 ? arg_v[4] : NULL); else if (strcmp(arg_v[2], "inherit_no") == 0) test_file_inherit_child_no(arg_v[3]); else if (strcmp(arg_v[2], "pipes") == 0) @@ -2642,6 +3203,7 @@ START_TEST(file) test_fgetwc_locale("AB\x83\xa9", "C", 0); test_fgetwc_unicode(); test_fputwc(); + test_freopen(); test_ctrlz(); test_file_put_get(); test_tmpnam(); @@ -2654,6 +3216,12 @@ START_TEST(file) test_write_flush(); test_close(); test__creat(); + test_lseek(); + test_fopen_hints(); + test_open_hints(); + test_ioinfo_flags(); + test_std_stream_buffering(); + test_std_stream_open();
/* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report * file contains lines in the correct order diff --git a/modules/rostests/winetests/msvcrt/heap.c b/modules/rostests/winetests/msvcrt/heap.c index d934bf0c542..e8da95bb867 100644 --- a/modules/rostests/winetests/msvcrt/heap.c +++ b/modules/rostests/winetests/msvcrt/heap.c @@ -23,17 +23,13 @@ #include <errno.h> #include "wine/test.h"
-#ifdef __REACTOS__ -#if defined(__GNUC__) && __GNUC__ >= 7 -#pragma GCC diagnostic ignored "-Walloc-size-larger-than=9223372036854775807" -#endif -#endif - -static void (__cdecl *p_aligned_free)(void*) = NULL; -static void * (__cdecl *p_aligned_malloc)(size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_offset_malloc)(size_t,size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_realloc)(void*,size_t,size_t) = NULL; -static void * (__cdecl *p_aligned_offset_realloc)(void*,size_t,size_t,size_t) = NULL; +static void (__cdecl *p_aligned_free)(void*); +static void * (__cdecl *p_aligned_malloc)(size_t,size_t); +static void * (__cdecl *p_aligned_offset_malloc)(size_t,size_t,size_t); +static void * (__cdecl *p_aligned_realloc)(void*,size_t,size_t); +static void * (__cdecl *p_aligned_offset_realloc)(void*,size_t,size_t,size_t); +static int (__cdecl *p__set_sbh_threshold)(size_t); +static size_t (__cdecl *p__get_sbh_threshold)(void);
static void test_aligned_malloc(unsigned int size, unsigned int alignment) { @@ -421,28 +417,37 @@ static void test_aligned(void)
static void test_sbheap(void) { + HMODULE msvcrt = GetModuleHandleA("msvcrt.dll"); void *mem; int threshold;
+ p__set_sbh_threshold = (void*)GetProcAddress(msvcrt, "_set_sbh_threshold"); + p__get_sbh_threshold = (void*)GetProcAddress(msvcrt, "_get_sbh_threshold"); + if (!p__set_sbh_threshold || !p__get_sbh_threshold) + { + win_skip("_set_sbh_threshold not available\n"); + return; + } + if(sizeof(void*) == 8) { - ok(!_set_sbh_threshold(0), "_set_sbh_threshold succeeded\n"); - ok(!_set_sbh_threshold(1000), "_set_sbh_threshold succeeded\n"); + ok(!p__set_sbh_threshold(0), "_set_sbh_threshold succeeded\n"); + ok(!p__set_sbh_threshold(1000), "_set_sbh_threshold succeeded\n"); return; }
mem = malloc(1); ok(mem != NULL, "malloc failed\n");
- ok(_set_sbh_threshold(1), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(1), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 16, "threshold = %d\n", threshold);
- ok(_set_sbh_threshold(8), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(8), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 16, "threshold = %d\n", threshold);
- ok(_set_sbh_threshold(1000), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(1000), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 1008, "threshold = %d\n", threshold);
free(mem); @@ -455,13 +460,42 @@ static void test_sbheap(void) ok(mem != NULL, "realloc failed\n"); ok(!((UINT_PTR)mem & 0xf), "incorrect alignment (%p)\n", mem);
- ok(_set_sbh_threshold(0), "_set_sbh_threshold failed\n"); - threshold = _get_sbh_threshold(); + ok(p__set_sbh_threshold(0), "_set_sbh_threshold failed\n"); + threshold = p__get_sbh_threshold(); ok(threshold == 0, "threshold = %d\n", threshold);
free(mem); }
+static void test_malloc(void) +{ + /* use function pointers to bypass gcc builtins */ + void *(__cdecl *p_malloc)(size_t); + void *(__cdecl *p_realloc)(void *,size_t); + void *mem; + + p_malloc = (void *)GetProcAddress( GetModuleHandleA("msvcrt.dll"), "malloc"); + p_realloc = (void *)GetProcAddress( GetModuleHandleA("msvcrt.dll"), "realloc"); + + mem = p_malloc(0); + ok(mem != NULL, "memory not allocated for size 0\n"); + free(mem); + + mem = p_realloc(NULL, 10); + ok(mem != NULL, "memory not allocated\n"); + + mem = p_realloc(mem, 20); + ok(mem != NULL, "memory not reallocated\n"); + + mem = p_realloc(mem, 0); + ok(mem == NULL, "memory not freed\n"); + + mem = p_realloc(NULL, 0); + ok(mem != NULL, "memory not (re)allocated for size 0\n"); + + free(mem); +} + static void test_calloc(void) { /* use function pointer to bypass gcc builtin */ @@ -489,29 +523,16 @@ static void test_calloc(void) free(ptr); }
-START_TEST(heap) +static void test__get_heap_handle(void) { - void *mem; - - mem = malloc(0); - ok(mem != NULL, "memory not allocated for size 0\n"); - free(mem); - - mem = realloc(NULL, 10); - ok(mem != NULL, "memory not allocated\n"); - - mem = realloc(mem, 20); - ok(mem != NULL, "memory not reallocated\n"); - - mem = realloc(mem, 0); - ok(mem == NULL, "memory not freed\n"); - - mem = realloc(NULL, 0); - ok(mem != NULL, "memory not (re)allocated for size 0\n"); - - free(mem); + ok((HANDLE)_get_heap_handle() != GetProcessHeap(), "Expected _get_heap_handle() not to return GetProcessHeap()\n"); +}
+START_TEST(heap) +{ test_aligned(); test_sbheap(); + test_malloc(); test_calloc(); + test__get_heap_handle(); } diff --git a/modules/rostests/winetests/msvcrt/locale.c b/modules/rostests/winetests/msvcrt/locale.c index 08abac00bed..62632ce4b9d 100644 --- a/modules/rostests/winetests/msvcrt/locale.c +++ b/modules/rostests/winetests/msvcrt/locale.c @@ -19,6 +19,7 @@ */
#include <locale.h> +#include <process.h>
#include "wine/test.h" #include "winnls.h" @@ -27,6 +28,9 @@ static BOOL (__cdecl *p__crtGetStringTypeW)(DWORD, DWORD, const wchar_t*, int, W static int (__cdecl *pmemcpy_s)(void *, size_t, void*, size_t); static int (__cdecl *p___mb_cur_max_func)(void); static int *(__cdecl *p__p___mb_cur_max)(void); +static _locale_t(__cdecl *p_create_locale)(int, const char*); +static void(__cdecl *p_free_locale)(_locale_t); +static int (__cdecl *p_wcsicmp_l)(const wchar_t*, const wchar_t*, _locale_t); void* __cdecl _Gettnames(void);
static void init(void) @@ -37,6 +41,9 @@ static void init(void) pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s"); p___mb_cur_max_func = (void*)GetProcAddress(hmod, "___mb_cur_max_func"); p__p___mb_cur_max = (void*)GetProcAddress(hmod, "__p___mb_cur_max"); + p_create_locale = (void*)GetProcAddress(hmod, "_create_locale"); + p_free_locale = (void*)GetProcAddress(hmod, "_free_locale"); + p_wcsicmp_l = (void*)GetProcAddress(hmod, "_wcsicmp_l"); }
static void test_setlocale(void) @@ -45,6 +52,8 @@ static void test_setlocale(void) "LC_MONETARY=Greek_Greece.1253;LC_NUMERIC=Polish_Poland.1250;LC_TIME=C";
char *ret, buf[100]; + char *ptr; + int len;
ret = setlocale(20, "C"); ok(ret == NULL, "ret = %s\n", ret); @@ -571,12 +580,14 @@ static void test_setlocale(void) ret = setlocale(LC_ALL, "trk"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret); + ok(!strcmp(ret, "Turkish_Turkey.1254") + || !strcmp(ret, "Turkish_T\xfcrkiye.1254"), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "turkish"); ok(ret != NULL || broken (ret == NULL), "ret == NULL\n"); if(ret) - ok(!strcmp(ret, "Turkish_Turkey.1254"), "ret = %s\n", ret); + ok(!strcmp(ret, "Turkish_Turkey.1254") + || !strcmp(ret, "Turkish_T\xfcrkiye.1254"), "ret = %s\n", ret);
ret = setlocale(LC_ALL, "uk"); ok(ret != NULL, "ret == NULL\n"); @@ -612,6 +623,27 @@ static void test_setlocale(void) ok(!strcmp(ret, buf), "ret = %s, expected %s\n", ret, buf); }
+ GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTCODEPAGE, buf, sizeof(buf)); + if(IsValidCodePage(atoi(buf))) { + ret = setlocale(LC_ALL, ".OCP"); + ok(ret != NULL, "ret == NULL\n"); + ptr = strchr(ret, '.'); + ok(ptr && !strcmp(ptr + 1, buf), "ret %s, buf %s.\n", ret, buf); + } + + len = GetLocaleInfoA(GetUserDefaultLCID(), LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof(buf)) - 1; + if(buf[0] == '0' && !buf[1]) + len = sprintf(buf, "%d", GetACP()); + ret = setlocale(LC_ALL, ".ACP"); + ok(ret != NULL, "ret == NULL\n"); + ptr = strchr(ret, '.'); + ok(ptr && !strncmp(ptr + 1, buf, len), "ret %s, buf %s.\n", ret, buf); + + ret = setlocale(LC_ALL, ".1250"); + ok(ret != NULL, "ret == NULL\n"); + ptr = strchr(ret, '.'); + ok(ptr && !strcmp(ptr, ".1250"), "ret %s, buf %s.\n", ret, buf); + ret = setlocale(LC_ALL, "English_United States.UTF8"); ok(ret == NULL, "ret != NULL\n");
@@ -621,13 +653,7 @@ static void test_setlocale(void)
static void test_crtGetStringTypeW(void) { - static const wchar_t str0[] = { '0', '\0' }; - static const wchar_t strA[] = { 'A', '\0' }; - static const wchar_t str_space[] = { ' ', '\0' }; - static const wchar_t str_null[] = { '\0', '\0' }; - static const wchar_t str_rand[] = { 1234, '\0' }; - - const wchar_t *str[] = { str0, strA, str_space, str_null, str_rand }; + const wchar_t *str[] = { L"0", L"A", L" ", L"\0", L"\x04d2" };
WORD out_crt, out; BOOL ret_crt, ret; @@ -712,10 +738,14 @@ static void test__Gettnames(void) { size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); - ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(size, "GetLocaleInfo failed: %lx\n", GetLastError()); ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); }
+ ok(ret->wstr[0] != NULL, "ret->wstr[0] = NULL\n"); + ok(ret->str[42] + strlen(ret->str[42])+1 != (char*)ret->wstr[0], + "ret->str[42] = %p len = %Id, ret->wstr[0] = %p\n", + ret->str[42], strlen(ret->str[42]), ret->wstr[0]); free(ret);
if(!setlocale(LC_TIME, "german")) @@ -726,7 +756,7 @@ static void test__Gettnames(void) { size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT), time_data[i], buf, sizeof(buf)); - ok(size, "GetLocaleInfo failed: %x\n", GetLastError()); + ok(size, "GetLocaleInfo failed: %lx\n", GetLastError()); ok(!strcmp(ret->str[i], buf), "ret->str[%i] = %s, expected %s\n", i, ret->str[i], buf); } free(ret); @@ -775,6 +805,178 @@ static void test___mb_cur_max_func(void) } }
+static void test__wcsicmp_l(void) +{ + const struct { + const wchar_t *str1; + const wchar_t *str2; + int exp; + const char *loc; + } tests[] = { + { L"i", L"i", 0 }, + { L"I", L"i", 0 }, + { L"I", L"i", 0, "Turkish" }, + { L"i", L"a", 8 }, + { L"a", L"i", -8 }, + { L"i", L"a", 8, "Turkish" }, + }; + int ret, i; + + if (!p_wcsicmp_l || !p_create_locale) + { + win_skip("_wcsicmp_l or _create_locale not available\n"); + return; + } + ok(!!p_free_locale, "_free_locale not available\n"); + + for(i=0; i<ARRAY_SIZE(tests); i++) { + _locale_t loc = NULL; + + if(tests[i].loc && !(loc = p_create_locale(LC_ALL, tests[i].loc))) { + win_skip("locale %s not available. skipping\n", tests[i].loc); + continue; + } + + ret = p_wcsicmp_l(tests[i].str1, tests[i].str2, loc); + ok(ret == tests[i].exp, "_wcsicmp_l = %d, expected %d for test %d '%ls' vs '%ls' using %s locale\n", + ret, tests[i].exp, i, tests[i].str1, tests[i].str2, loc ? tests[i].loc : "current"); + + if(loc) + p_free_locale(loc); + } +} + +static unsigned __stdcall test_thread_setlocale_func(void *arg) +{ + char *ret; + + ret = setlocale(LC_ALL, NULL); + ok(!strcmp(ret, "C"), "expected ret=C, but received ret=%s\n", ret); + + ret = setlocale(LC_ALL, ""); + ok(strcmp(ret, "Invariant Language_Invariant Country.0"), "expected valid locale\n"); + + return 0; +} + +static void test_thread_setlocale(void) +{ + HANDLE hThread; + + hThread = (HANDLE)_beginthreadex(NULL, 0, test_thread_setlocale_func, NULL, 0, NULL); + ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); + WaitForSingleObject(hThread, 5000); + CloseHandle(hThread); +} + +static void test_locale_info(void) +{ + pthreadlocinfo locinfo, locinfo2; + _locale_t locale, locale2; + int ret; + + if (!p_create_locale) + { + win_skip("_create_locale isn't available.\n"); + return; + } + + if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE) + skip("Skip language-specific tests on Japanese system.\n"); + else + { + locale = p_create_locale(LC_ALL, "Japanese_Japan.932"); + locale2 = p_create_locale(LC_ALL, ".932"); + locinfo = locale->locinfo; + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max == locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo->lc_codepage == 932 && locinfo->lc_codepage == locinfo2->lc_codepage, + "Got wrong codepage %d vs %d.\n", locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage == 932 + && locinfo->lc_id[LC_CTYPE].wCodePage == locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] != locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + locale2 = p_create_locale(LC_ALL, "Japanese_Japan.1252"); + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max != locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo2->lc_codepage == 1252, "Got wrong codepage %d.\n", locinfo2->lc_codepage); + ok(locinfo2->lc_id[LC_CTYPE].wCodePage == 1252, "Got wrong LC_CTYPE codepage %d.\n", + locinfo2->lc_id[LC_CTYPE].wCodePage); + ok(locinfo->lc_codepage != locinfo2->lc_codepage, "Got wrong codepage %d vs %d.\n", + locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage != locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] == locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + locale2 = p_create_locale(LC_ALL, "Japanese_Japan.3000"); /* an invalid codepage */ + ok(!locale2, "Got %p.\n", locale2); + + p_free_locale(locale); + } + + locale = p_create_locale(LC_ALL, "German_Germany.437"); + locale2 = p_create_locale(LC_ALL, "German_Germany.1252"); + locinfo = locale->locinfo; + locinfo2 = locale2->locinfo; + + ok(locinfo->mb_cur_max == locinfo2->mb_cur_max, "Got wrong max char size %d %d.\n", + locinfo->mb_cur_max, locinfo2->mb_cur_max); + ok(locinfo->ctype1_refcount != locinfo2->ctype1_refcount, "Got wrong refcount pointer %p vs %p.\n", + locinfo->ctype1_refcount, locinfo2->ctype1_refcount); + ok(locinfo->lc_codepage != locinfo2->lc_codepage, "Got wrong codepage %d vs %d.\n", + locinfo->lc_codepage, locinfo2->lc_codepage); + ok(locinfo->lc_id[LC_CTYPE].wCodePage != locinfo2->lc_id[LC_CTYPE].wCodePage, + "Got wrong LC_CTYPE codepage %d vs %d.\n", locinfo->lc_id[LC_CTYPE].wCodePage, + locinfo2->lc_id[LC_CTYPE].wCodePage); + ret = strcmp(locinfo->lc_category[LC_CTYPE].locale, locinfo2->lc_category[LC_CTYPE].locale); + ok(!!ret, "Got locale name %s vs %s.\n", locinfo->lc_category[LC_CTYPE].locale, + locinfo2->lc_category[LC_CTYPE].locale); + ret = memcmp(locinfo->ctype1, locinfo2->ctype1, 257 * sizeof(*locinfo->ctype1)); + ok(!!ret, "Got wrong ctype1 data.\n"); + ret = memcmp(locinfo->pclmap, locinfo2->pclmap, 256 * sizeof(*locinfo->pclmap)); + ok(!!ret, "Got wrong pclmap data.\n"); + ret = memcmp(locinfo->pcumap, locinfo2->pcumap, 256 * sizeof(*locinfo->pcumap)); + ok(!!ret, "Got wrong pcumap data.\n"); + ok(locinfo->lc_handle[LC_CTYPE] == locinfo2->lc_handle[LC_CTYPE], + "Got wrong LC_CTYPE %#lx vs %#lx.\n", locinfo->lc_handle[LC_CTYPE], locinfo2->lc_handle[LC_CTYPE]); + + p_free_locale(locale2); + p_free_locale(locale); +} + START_TEST(locale) { init(); @@ -783,4 +985,7 @@ START_TEST(locale) test_setlocale(); test__Gettnames(); test___mb_cur_max_func(); + test__wcsicmp_l(); + test_thread_setlocale(); + test_locale_info(); } diff --git a/modules/rostests/winetests/msvcrt/misc.c b/modules/rostests/winetests/msvcrt/misc.c index d82f71e122e..7b54b3aeb88 100644 --- a/modules/rostests/winetests/msvcrt/misc.c +++ b/modules/rostests/winetests/msvcrt/misc.c @@ -20,31 +20,12 @@
#include "wine/test.h" #include <errno.h> +#include <fcntl.h> +#include <io.h> #include <stdio.h> #include <math.h> -#include "msvcrt.h" #include <process.h>
-static inline float __port_infinity(void) -{ - static const unsigned __inf_bytes = 0x7f800000; - return *(const float *)&__inf_bytes; -} -#ifdef __REACTOS__ -#undef INFINITY -#endif -#define INFINITY __port_infinity() - -static inline float __port_nan(void) -{ - static const unsigned __nan_bytes = 0x7fc00000; - return *(const float *)&__nan_bytes; -} -#ifdef __REACTOS__ -#undef NAN -#endif -#define NAN __port_nan() - static inline BOOL almost_equal(double d1, double d2) { if(d1-d2>-1e-30 && d1-d2<1e-30) return TRUE; @@ -56,14 +37,14 @@ struct uld { ULONG lo, hi, exp; };
static int (__cdecl *prand_s)(unsigned int *); static int (__cdecl *pI10_OUTPUT)(struct uld, int, int, void*); -static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int); +static int (__cdecl *pstrerror_s)(char *, size_t, int); static int (__cdecl *p_get_doserrno)(int *); static int (__cdecl *p_get_errno)(int *); static int (__cdecl *p_set_doserrno)(int); static int (__cdecl *p_set_errno)(int); static void (__cdecl *p__invalid_parameter)(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t); -static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t, +static void (__cdecl *p_qsort_s)(void*, size_t, size_t, int (__cdecl*)(void*, const void*, const void*), void*); static double (__cdecl *p_atan)(double); static double (__cdecl *p_exp)(double); @@ -194,7 +175,7 @@ static void test_I10_OUTPUT(void) j = strlen(I10_OUTPUT_tests[i].remain); todo_wine_if(j && I10_OUTPUT_tests[i].remain[j-1]=='9') ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j), - "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1); + "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1);
for(j=out.len+strlen(I10_OUTPUT_tests[i].remain)+1; j<sizeof(out.str); j++) if(out.str[j] != '#') @@ -233,7 +214,7 @@ static void test_strerror_s(void) memset(buf, 'X', sizeof(buf)); ret = pstrerror_s(buf, 1, 0); ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret); - ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n"); + ok(buf[0] == 0, "Expected output buffer to be null terminated\n");
memset(buf, 'X', sizeof(buf)); ret = pstrerror_s(buf, 2, 0); @@ -263,7 +244,7 @@ static void test__get_doserrno(void) errno = EBADF; ret = p_get_doserrno(NULL); ok(ret == EINVAL, "Expected _get_doserrno to return EINVAL, got %d\n", ret); - ok(_doserrno == ERROR_INVALID_CMM, "Expected _doserrno to be ERROR_INVALID_CMM, got %d\n", _doserrno); + ok(_doserrno == ERROR_INVALID_CMM, "Expected _doserrno to be ERROR_INVALID_CMM, got %ld\n", _doserrno); ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
_doserrno = ERROR_INVALID_CMM; @@ -310,19 +291,19 @@ static void test__set_doserrno(void) ret = p_set_doserrno(ERROR_FILE_NOT_FOUND); ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret); ok(_doserrno == ERROR_FILE_NOT_FOUND, - "Expected _doserrno to be ERROR_FILE_NOT_FOUND, got %d\n", _doserrno); + "Expected _doserrno to be ERROR_FILE_NOT_FOUND, got %ld\n", _doserrno);
_doserrno = ERROR_INVALID_CMM; ret = p_set_doserrno(-1); ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret); ok(_doserrno == -1, - "Expected _doserrno to be -1, got %d\n", _doserrno); + "Expected _doserrno to be -1, got %ld\n", _doserrno);
_doserrno = ERROR_INVALID_CMM; ret = p_set_doserrno(0xdeadbeef); ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret); ok(_doserrno == 0xdeadbeef, - "Expected _doserrno to be 0xdeadbeef, got %d\n", _doserrno); + "Expected _doserrno to be 0xdeadbeef, got %ld\n", _doserrno); }
static void test__set_errno(void) @@ -351,21 +332,42 @@ static void test__set_errno(void) ok(errno == 0xdeadbeef, "Expected errno to be 0xdeadbeef, got %d\n", errno); }
-static void test__popen_child(void) +static void test__popen_child(int fd) { /* don't execute any tests here */ /* ExitProcess is used to set return code of _pclose */ printf("child output\n"); + if ((HANDLE)_get_osfhandle(fd) != INVALID_HANDLE_VALUE) + ExitProcess(1); ExitProcess(0x37); }
+static void test__popen_read_child(void) +{ + char buf[1024], *rets; + + rets = fgets(buf, sizeof(buf), stdin); + if (strcmp(buf, "child-to-parent\n") != 0) + ExitProcess(1); + + rets = fgets(buf, sizeof(buf), stdin); + if (rets) + ExitProcess(2); + ExitProcess(3); +} + static void test__popen(const char *name) { FILE *pipe; - char buf[1024]; - int ret; + char *tempf, buf[1024]; + int ret, fd; + + tempf = _tempnam(".", "wne"); + ok(tempf != NULL, "_tempnam failed\n"); + fd = _open(tempf, _O_CREAT | _O_WRONLY); + ok(fd != -1, "open failed\n");
- sprintf(buf, ""%s" misc popen", name); + sprintf(buf, ""%s" misc popen %d", name, fd); pipe = _popen(buf, "r"); ok(pipe != NULL, "_popen failed with error: %d\n", errno);
@@ -374,12 +376,25 @@ static void test__popen(const char *name)
ret = _pclose(pipe); ok(ret == 0x37, "_pclose returned %x, expected 0x37\n", ret); + _close(fd); + _unlink(tempf); + free(tempf);
errno = 0xdeadbeef; ret = _pclose((FILE*)0xdeadbeef); ok(ret == -1, "_pclose returned %x, expected -1\n", ret); if(p_set_errno) ok(errno == EBADF, "errno = %d\n", errno); + + sprintf(buf, ""%s" misc popen_read", name); + pipe = _popen(buf, "w"); + ok(pipe != NULL, "_popen failed with error: %d\n", errno); + + ret = fputs("child-to-parent\n", pipe); + ok(ret != EOF, "fputs returned %x\n", ret); + + ret = _pclose(pipe); + ok(ret == 0x3, "_pclose returned %x, expected 0x3\n", ret); }
static void test__invalid_parameter(void) @@ -512,8 +527,35 @@ static void test_qsort_s(void) ok(tab[i] == i, "data sorted incorrectly on position %d: %d\n", i, tab[i]); }
+static int eq_nan(UINT64 ai, double b) +{ + UINT64 bi = *(UINT64*)&b; + UINT64 mask; + +#if defined(__i386__) + mask = 0xFFFFFFFF00000000ULL; +#else + mask = ~0; +#endif + + ok((ai & mask) == (bi & mask), "comparing %s and %s\n", + wine_dbgstr_longlong(ai), wine_dbgstr_longlong(bi)); + return (ai & mask) == (bi & mask); +} + +static int eq_nanf(DWORD ai, float b) +{ + DWORD bi = *(DWORD*)&b; + ok(ai == bi, "comparing %08lx and %08lx\n", ai, bi); + return ai == bi; +} + static void test_math_functions(void) { + static const UINT64 test_nan_i = 0xFFF0000123456780ULL; + static const DWORD test_nanf_i = 0xFF801234; + double test_nan = *(double*)&test_nan_i; + float test_nanf = *(float*)&test_nanf_i; double ret;
errno = 0xdeadbeef; @@ -546,6 +588,13 @@ static void test_math_functions(void) errno = 0xdeadbeef; p_exp(INFINITY); ok(errno == 0xdeadbeef, "errno = %d\n", errno); + + ok(eq_nan(test_nan_i | (1ULL << 51), cosh(test_nan)), "cosh not preserving nan\n"); + ok(eq_nan(test_nan_i | (1ULL << 51), sinh(test_nan)), "sinh not preserving nan\n"); + ok(eq_nan(test_nan_i | (1ULL << 51), tanh(test_nan)), "tanh not preserving nan\n"); + ok(eq_nanf(test_nanf_i | (1 << 22), coshf(test_nanf)), "coshf not preserving nan\n"); + ok(eq_nanf(test_nanf_i | (1 << 22), sinhf(test_nanf)), "sinhf not preserving nan\n"); + ok(eq_nanf(test_nanf_i | (1 << 22), tanhf(test_nanf)), "tanhf not preserving nan\n"); }
static void __cdecl test_thread_func(void *end_thread_type) @@ -574,38 +623,51 @@ static void test_thread_handle_close(void) ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); WaitForSingleObject(hThread, INFINITE); ret = CloseHandle(hThread); - ok(!ret, "ret = %d\n", ret); + ok(!ret, "ret = %ld\n", ret);
hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)1); ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); WaitForSingleObject(hThread, INFINITE); ret = CloseHandle(hThread); - ok(!ret, "ret = %d\n", ret); + ok(!ret, "ret = %ld\n", ret);
hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)2); ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); Sleep(150); ret = WaitForSingleObject(hThread, INFINITE); - ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ok(ret == WAIT_OBJECT_0, "ret = %ld\n", ret); ret = CloseHandle(hThread); - ok(ret, "ret = %d\n", ret); + ok(ret, "ret = %ld\n", ret);
hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)3); ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); Sleep(150); ret = WaitForSingleObject(hThread, INFINITE); - ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ok(ret == WAIT_OBJECT_0, "ret = %ld\n", ret); ret = CloseHandle(hThread); - ok(ret, "ret = %d\n", ret); + ok(ret, "ret = %ld\n", ret);
/* _beginthreadex: handle is not closed on _endthread */ hThread = (HANDLE)_beginthreadex(NULL,0, test_thread_func_ex, NULL, 0, NULL); ok(hThread != NULL, "_beginthreadex failed (%d)\n", errno); Sleep(150); ret = WaitForSingleObject(hThread, INFINITE); - ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ok(ret == WAIT_OBJECT_0, "ret = %ld\n", ret); ret = CloseHandle(hThread); - ok(ret, "ret = %d\n", ret); + ok(ret, "ret = %ld\n", ret); +} + +static void test_thread_suspended(void) +{ + HANDLE hThread; + DWORD ret; + + hThread = (HANDLE)_beginthreadex(NULL, 0, test_thread_func_ex, NULL, CREATE_SUSPENDED, NULL); + ok(hThread != NULL, "_beginthreadex failed (%d)\n", errno); + ret = ResumeThread(hThread); + ok(ret == 1, "suspend count = %ld\n", ret); + ret = WaitForSingleObject(hThread, 200); + ok(ret == WAIT_OBJECT_0, "ret = %ld\n", ret); }
static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r) @@ -685,8 +747,10 @@ START_TEST(misc)
arg_c = winetest_get_mainargs(&arg_v); if(arg_c >= 3) { - if(!strcmp(arg_v[2], "popen")) - test__popen_child(); + if (!strcmp(arg_v[2], "popen_read")) + test__popen_read_child(); + else if(arg_c == 4 && !strcmp(arg_v[2], "popen")) + test__popen_child(atoi(arg_v[3])); else ok(0, "invalid argument '%s'\n", arg_v[2]);
@@ -705,5 +769,6 @@ START_TEST(misc) test_qsort_s(); test_math_functions(); test_thread_handle_close(); + test_thread_suspended(); test__lfind_s(); } diff --git a/modules/rostests/winetests/msvcrt/printf.c b/modules/rostests/winetests/msvcrt/printf.c index 4bf55afc1ff..dc0038b3372 100644 --- a/modules/rostests/winetests/msvcrt/printf.c +++ b/modules/rostests/winetests/msvcrt/printf.c @@ -23,9 +23,7 @@ /* With Visual Studio >= 2005, swprintf() takes an extra parameter unless * the following macro is defined. */ -#ifndef _CRT_NON_CONFORMING_SWPRINTFS #define _CRT_NON_CONFORMING_SWPRINTFS -#endif
#include <stdio.h> #include <errno.h> @@ -38,24 +36,6 @@
#include "wine/test.h"
-#ifndef __REACTOS__ - -static inline float __port_infinity(void) -{ - static const unsigned __inf_bytes = 0x7f800000; - return *(const float *)&__inf_bytes; -} -#define INFINITY __port_infinity() - -static inline float __port_nan(void) -{ - static const unsigned __nan_bytes = 0x7fc00000; - return *(const float *)&__nan_bytes; -} -#define NAN __port_nan() - -#endif - static inline float __port_ind(void) { static const unsigned __ind_bytes = 0xffc00000; @@ -63,11 +43,11 @@ static inline float __port_ind(void) } #define IND __port_ind()
-static int (__cdecl *p__vscprintf)(const char *format, __ms_va_list valist); -static int (__cdecl *p__vscwprintf)(const wchar_t *format, __ms_va_list valist); +static int (__cdecl *p__vscprintf)(const char *format, va_list valist); +static int (__cdecl *p__vscwprintf)(const wchar_t *format, va_list valist); static int (__cdecl *p__vsnwprintf_s)(wchar_t *str, size_t sizeOfBuffer, size_t count, const wchar_t *format, - __ms_va_list valist); + va_list valist); static int (__cdecl *p__ecvt_s)(char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign); static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number, @@ -75,17 +55,17 @@ static int (__cdecl *p__fcvt_s)(char *buffer, size_t length, double number, static unsigned int (__cdecl *p__get_output_format)(void); static unsigned int (__cdecl *p__set_output_format)(unsigned int); static int (WINAPIV *p_sprintf)(char*, ...); -static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, __ms_va_list); -static int (__cdecl *p_vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); -static int (__cdecl *p__vswprintf)(wchar_t *str, const wchar_t *format, __ms_va_list valist); +static int (__cdecl *p__vsprintf_p)(char*, size_t, const char*, va_list); +static int (__cdecl *p_vswprintf)(wchar_t *str, const wchar_t *format, va_list valist); +static int (__cdecl *p__vswprintf)(wchar_t *str, const wchar_t *format, va_list valist); static int (__cdecl *p__vswprintf_l)(wchar_t *str, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist); static int (__cdecl *p__vswprintf_c)(wchar_t *str, size_t size, const wchar_t *format, - __ms_va_list valist); + va_list valist); static int (__cdecl *p__vswprintf_c_l)(wchar_t *str, size_t size, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist); static int (__cdecl *p__vswprintf_p_l)(wchar_t *str, size_t size, const wchar_t *format, - void *locale, __ms_va_list valist); + void *locale, va_list valist);
static void init( void ) { @@ -110,466 +90,295 @@ static void init( void )
static void test_sprintf( void ) { - char buffer[100]; - const char *format; - double pnumber=789456123; - int x, r; - WCHAR wide[] = { 'w','i','d','e',0}; - WCHAR buf_w[2]; - - format = "%+#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"+7.894561230000000e+008"),"+#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%-#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"7.894561230000000e+008 "),"-#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%#23.15e"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer," 7.894561230000000e+008"),"#23.15e failed: '%s'\n", buffer); - ok( r==23, "return count wrong\n"); - - format = "%#1.1g"; - r = p_sprintf(buffer,format,pnumber); - ok(!strcmp(buffer,"8.e+008"),"#1.1g failed: '%s'\n", buffer); - ok( r==7, "return count wrong\n"); - - format = "%I64d"; - r = p_sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok(!strcmp(buffer,"-8589934591"),"Problem with long long\n"); - ok( r==11, "return count wrong\n"); - - format = "%+8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," +100") && r==8,"+8I64d failed: '%s'\n", buffer); - - format = "%+.8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00000100") && r==9,"+.8I64d failed: '%s'\n", buffer); - - format = "%+10.8I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," +00000100") && r==10,"+10.8I64d failed: '%s'\n", buffer); - format = "%_1I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"_1I64d") && r==6,"_1I64d failed\n"); - - format = "%-1.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"-1.5I64d failed: '%s'\n", buffer); - - format = "%5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==5,"5I64d failed: '%s'\n", buffer); - - format = "%5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -100") && r==5,"5I64d failed: '%s'\n", buffer); - - format = "%-5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"100 ") && r==5,"-5I64d failed: '%s'\n", buffer); - - format = "%-5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-100 ") && r==5,"-5I64d failed: '%s'\n", buffer); - - format = "%-.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100") && r==5,"-.5I64d failed: '%s'\n", buffer); - - format = "%-.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"-.5I64d failed: '%s'\n", buffer); - - format = "%-8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); - - format = "%-8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100 ") && r==8,"-8.5I64d failed: '%s'\n", buffer); - - format = "%05I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00100") && r==5,"05I64d failed: '%s'\n", buffer); - - format = "%05I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-0100") && r==5,"05I64d failed: '%s'\n", buffer); - - format = "% I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==4,"' I64d' failed: '%s'\n", buffer); - - format = "% I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-100") && r==4,"' I64d' failed: '%s'\n", buffer); - - format = "% 5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 100") && r==5,"' 5I64d' failed: '%s'\n", buffer); - - format = "% 5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -100") && r==5,"' 5I64d' failed: '%s'\n", buffer); - - format = "% .5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); - - format = "% .5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"-00100") && r==6,"' .5I64d' failed: '%s'\n", buffer); - - format = "% 8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer," 00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); - - format = "% 8.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," -00100") && r==8,"' 8.5I64d' failed: '%s'\n", buffer); - - format = "%.0I64d"; - r = p_sprintf(buffer,format,(LONGLONG)0); - ok(r==0,".0I64d failed: '%s'\n", buffer); - - format = "%#+21.18I64x"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," 0x00ffffffffffffff9c") && r==21,"#+21.18I64x failed: '%s'\n", buffer); - - format = "%#.25I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"0001777777777777777777634") && r==25,"#.25I64o failed: '%s'\n", buffer); - - format = "%#+24.20I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer," 01777777777777777777634") && r==24,"#+24.20I64o failed: '%s'\n", buffer); - - format = "%#+18.21I64X"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"0X00000FFFFFFFFFFFFFF9C") && r==23,"#+18.21I64X failed: '%s '\n", buffer); - - format = "%#+20.24I64o"; - r = p_sprintf(buffer,format,(LONGLONG)-100); - ok(!strcmp(buffer,"001777777777777777777634") && r==24,"#+20.24I64o failed: '%s'\n", buffer); - - format = "%#+25.22I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u conversion failed: '%s'\n", buffer); - - format = "%#+25.22I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0018446744073709551615") && r==25,"#+25.22I64u failed: '%s'\n", buffer); - - format = "%#+30.25I64u"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," 0000018446744073709551615") && r==30,"#+30.25I64u failed: '%s'\n", buffer); - - format = "%+#25.22I64d"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer," -0000000000000000000001") && r==25,"+#25.22I64d failed: '%s'\n", buffer); - - format = "%#-8.5I64o"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"00144 ") && r==8,"-8.5I64o failed: '%s'\n", buffer); - - format = "%#-+ 08.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00100 ") && r==8,"'#-+ 08.5I64d failed: '%s'\n", buffer); - - format = "%#-+ 08.5I64d"; - r = p_sprintf(buffer,format,(LONGLONG)100); - ok(!strcmp(buffer,"+00100 ") && r==8,"#-+ 08.5I64d failed: '%s'\n", buffer); - - format = "%.80I64d"; - r = p_sprintf(buffer,format,(LONGLONG)1); - ok(r==80,"%s format failed\n", format); - - format = "% .80I64d"; - r = p_sprintf(buffer,format,(LONGLONG)1); - ok(r==81,"%s format failed\n", format); - - format = "% .80d"; - r = p_sprintf(buffer,format,1); - ok(r==81,"%s format failed\n", format); - - format = "%lld"; - r = p_sprintf(buffer,format,((ULONGLONG)0xffffffff)*0xffffffff); - ok( r == 1 || r == 11, "return count wrong %d\n", r); - if (r == 11) /* %ll works on Vista */ - ok(!strcmp(buffer, "-8589934591"), "Problem with "ll" interpretation '%s'\n", buffer); - else - ok(!strcmp(buffer, "1"), "Problem with "ll" interpretation '%s'\n", buffer); + enum { + NO_ARG, + INT_ARG, + ULONGLONG_ARG, + DOUBLE_ARG, + PTR_ARG, + TODO_FLAG = 0x1000 + };
- format = "%I"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer, "I"), "Problem with "I" interpretation\n"); - ok( r==1, "return count wrong\n"); + struct { + const char *format; + const char *out; + const char *broken; + int type; + int arg_i; + ULONGLONG arg_ull; + double arg_d; + const void *arg_ptr; + } tests[] = { + { "%+#23.15e", "+7.894561230000000e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%-#23.15e", "7.894561230000000e+008 ", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%#23.15e", " 7.894561230000000e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%#1.1g", "8.e+008", 0, DOUBLE_ARG, 0, 0, 789456123 }, + { "%I64d", "-8589934591", 0, ULONGLONG_ARG, 0, ((ULONGLONG)0xffffffff)*0xffffffff }, + { "%+8I64d", " +100", 0, ULONGLONG_ARG, 0, 100 }, + { "%+.8I64d", "+00000100", 0, ULONGLONG_ARG, 0, 100 }, + { "%+10.8I64d", " +00000100", 0, ULONGLONG_ARG, 0, 100 }, + { "%_1I64d", "_1I64d", 0, ULONGLONG_ARG, 0, 100 }, + { "%-1.5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%5I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "%5I64d", " -100", 0, ULONGLONG_ARG, 0, -100 }, + { "%-5I64d", "100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%-5I64d", "-100 ", 0, ULONGLONG_ARG, 0, -100 }, + { "%-.5I64d", "00100", 0, ULONGLONG_ARG, 0, 100 }, + { "%-.5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%-8.5I64d", "00100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%-8.5I64d", "-00100 ", 0, ULONGLONG_ARG, 0, -100 }, + { "%05I64d", "00100", 0, ULONGLONG_ARG, 0, 100 }, + { "%05I64d", "-0100", 0, ULONGLONG_ARG, 0, -100 }, + { "% I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "% I64d", "-100", 0, ULONGLONG_ARG, 0, -100 }, + { "% 5I64d", " 100", 0, ULONGLONG_ARG, 0, 100 }, + { "% 5I64d", " -100", 0, ULONGLONG_ARG, 0, -100 }, + { "% .5I64d", " 00100", 0, ULONGLONG_ARG, 0, 100 }, + { "% .5I64d", "-00100", 0, ULONGLONG_ARG, 0, -100 }, + { "% 8.5I64d", " 00100", 0, ULONGLONG_ARG, 0, 100 }, + { "% 8.5I64d", " -00100", 0, ULONGLONG_ARG, 0, -100 }, + { "%.0I64d", "", 0, ULONGLONG_ARG }, + { "%#+21.18I64x", " 0x00ffffffffffffff9c", 0, ULONGLONG_ARG, 0, -100 }, + { "%#.25I64o", "0001777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+24.20I64o", " 01777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+18.21I64X", "0X00000FFFFFFFFFFFFFF9C", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+20.24I64o", "001777777777777777777634", 0, ULONGLONG_ARG, 0, -100 }, + { "%#+25.22I64u", " 0018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%#+25.22I64u", " 0018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%#+30.25I64u", " 0000018446744073709551615", 0, ULONGLONG_ARG, 0, -1 }, + { "%+#25.22I64d", " -0000000000000000000001", 0, ULONGLONG_ARG, 0, -1 }, + { "%#-8.5I64o", "00144 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%#-+ 08.5I64d", "+00100 ", 0, ULONGLONG_ARG, 0, 100 }, + { "%.80I64d", + "00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, ULONGLONG_ARG, 0, 1 }, + { "% .80I64d", + " 00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, ULONGLONG_ARG, 0, 1 }, + { "% .80d", + " 00000000000000000000000000000000000000000000000000000000000000000000000000000001", + 0, INT_ARG, 1 }, + { "%I", "I", 0, INT_ARG, 1 }, + { "%Iq", "Iq", 0, INT_ARG, 1 }, + { "%Ihd", "Ihd", 0, INT_ARG, 1 }, + { "%I0d", "I0d", 0, INT_ARG, 1 }, + { "%I64D", "D", 0, ULONGLONG_ARG, 0, -1 }, + { "%zx", "1", "zx", INT_ARG, 1 }, + { "%z", "z", 0, INT_ARG, 1 }, + { "%tx", "1", "tx", INT_ARG, 1 }, + { "%t", "t", 0, INT_ARG, 1 }, + { "% d", " 1", 0, INT_ARG, 1 }, + { "%+ d", "+1", 0, INT_ARG, 1 }, + { "%S", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%04c", "0001", 0, INT_ARG, '1' }, + { "%-04c", "1 ", 0, INT_ARG, '1' }, + { "%#012x", "0x0000000001", 0, INT_ARG, 1 }, + { "%#012x", "000000000000", 0, INT_ARG, 0 }, + { "%#04.8x", "0x00000001", 0, INT_ARG, 1 }, + { "%#04.8x", "00000000", 0, INT_ARG, 0 }, + { "%#-08.2x", "0x01 ", 0, INT_ARG, 1 }, + { "%#-08.2x", "00 ", 0, INT_ARG, 0 }, + { "%#.0x", "0x1", 0, INT_ARG, 1 }, + { "%#.0x", "", 0, INT_ARG, 0 }, + { "%#08o", "00000001", 0, INT_ARG, 1 }, + { "%#o", "01", 0, INT_ARG, 1 }, + { "%#o", "0", 0, INT_ARG, 0 }, + { "%04s", "0foo", 0, PTR_ARG, 0, 0, 0, "foo" }, + { "%.1s", "f", 0, PTR_ARG, 0, 0, 0, "foo" }, + { "hello", "hello", 0, NO_ARG }, + { "%ws", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%-10ws", "wide ", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%10ws", " wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%#+ -03whlls", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%w0s", "0s", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%w-s", "-s", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%ls", "wide", 0, PTR_ARG, 0, 0, 0, L"wide" }, + { "%Ls", "not wide", 0, PTR_ARG, 0, 0, 0, "not wide" }, + { "%b", "b", 0, NO_ARG }, + { "%3c", " a", 0, INT_ARG, 'a' }, + { "%3d", "1234", 0, INT_ARG, 1234 }, + { "%3h", "", 0, NO_ARG }, + { "%k%m%q%r%t%v%y%z", "kmqrtvyz", 0, NO_ARG }, + { "%-1d", "2", 0, INT_ARG, 2 }, + { "%2.4f", "8.6000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%0f", "0.600000", 0, DOUBLE_ARG, 0, 0, 0.6 }, + { "%.0f", "1", 0, DOUBLE_ARG, 0, 0, 0.6 }, + { "%2.4e", "8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 2.4e", " 8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 014.4e", " 008.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "% 2.4e", "-8.6000e+000", 0, DOUBLE_ARG, 0, 0, -8.6 }, + { "%+2.4e", "+8.6000e+000", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%2.4g", "8.6", 0, DOUBLE_ARG, 0, 0, 8.6 }, + { "%-i", "-1", 0, INT_ARG, -1 }, + { "%-i", "1", 0, INT_ARG, 1 }, + { "%+i", "+1", 0, INT_ARG, 1 }, + { "%o", "12", 0, INT_ARG, 10 }, + { "%s", "(null)", 0, PTR_ARG, 0, 0, 0, NULL }, + { "%s", "%%%%", 0, PTR_ARG, 0, 0, 0, "%%%%" }, + { "%u", "4294967295", 0, INT_ARG, -1 }, + { "%w", "", 0, INT_ARG, -1 }, + { "%h", "", 0, INT_ARG, -1 }, + { "%j", "", "j", ULONGLONG_ARG, 0, -1 }, + { "%jd", "-1", "jd", ULONGLONG_ARG, 0, -1 }, + { "%F", "", 0, INT_ARG, -1 }, + { "%N", "", 0, INT_ARG, -1 }, + { "%H", "H", 0, INT_ARG, -1 }, + { "x%cx", "xXx", 0, INT_ARG, 0x100+'X' }, + { "%%0", "%0", 0, NO_ARG }, + { "%hx", "2345", 0, INT_ARG, 0x12345 }, + { "%hhx", "123", 0, INT_ARG, 0x123 }, + { "%hhx", "2345", 0, INT_ARG, 0x12345 }, + { "%lf", "-1.#IND00", 0, DOUBLE_ARG, 0, 0, IND }, + { "%lf", "1.#QNAN0", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%lf", "1.#INF00", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%le", "-1.#IND00e+000", 0, DOUBLE_ARG, 0, 0, IND }, + { "%le", "1.#QNAN0e+000", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%le", "1.#INF00e+000", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%lg", "-1.#IND", 0, DOUBLE_ARG, 0, 0, IND }, + { "%lg", "1.#QNAN", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%lg", "1.#INF", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%010.2lf", "-000001.#J", 0, DOUBLE_ARG, 0, 0, IND }, + { "%010.2lf", "0000001.#R", 0, DOUBLE_ARG, 0, 0, NAN }, + { "%010.2lf", "0000001.#J", 0, DOUBLE_ARG, 0, 0, INFINITY }, + { "%c", "a", 0, INT_ARG, 'a' }, + { "%c", "\x82", 0, INT_ARG, 0xa082 }, + { "%C", "a", 0, INT_ARG, 'a' }, + { "%C", "", 0, INT_ARG, 0x3042 }, + { "a%Cb", "ab", 0, INT_ARG, 0x3042 }, + { "%lld", "-8589934591", "1", ULONGLONG_ARG, 0, ((ULONGLONG)0xffffffff)*0xffffffff }, + { "%I32d", "1", "I32d", INT_ARG, 1 }, + { "%.0f", "-2", 0, DOUBLE_ARG, 0, 0, -1.5 }, + { "%.0f", "-1", 0, DOUBLE_ARG, 0, 0, -0.5 }, + { "%.0f", "1", 0, DOUBLE_ARG, 0, 0, 0.5 }, + { "%.0f", "2", 0, DOUBLE_ARG, 0, 0, 1.5 }, + { "%.30f", "0.333333333333333310000000000000", 0, TODO_FLAG | DOUBLE_ARG, 0, 0, 1.0/3.0 }, + { "%.30lf", "1.414213562373095100000000000000", 0, TODO_FLAG | DOUBLE_ARG, 0, 0, sqrt(2) }, + { "%f", "3.141593", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.10f", "3.1415926536", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.11f", "3.14159265359", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.15f", "3.141592653590000", 0, DOUBLE_ARG, 0, 0, 3.141592653590000 }, + { "%.15f", "3.141592653589793", 0, DOUBLE_ARG, 0, 0, M_PI }, + { "%.13f", "37.8662615745371", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%.14f", "37.86626157453708", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%.15f", "37.866261574537077", 0, DOUBLE_ARG, 0, 0, 37.866261574537077 }, + { "%g", "0.0005", 0, DOUBLE_ARG, 0, 0, 0.0005 }, + { "%g", "5e-005", 0, DOUBLE_ARG, 0, 0, 0.00005 }, + { "%g", "5e-006", 0, DOUBLE_ARG, 0, 0, 0.000005 }, + { "%g", "1e+015", 0, DOUBLE_ARG, 0, 0, 999999999999999.0 }, + { "%g", "1e+015", 0, DOUBLE_ARG, 0, 0, 1000000000000000.0 }, + { "%.15g", "0.0005", 0, DOUBLE_ARG, 0, 0, 0.0005 }, + { "%.15g", "5e-005", 0, DOUBLE_ARG, 0, 0, 0.00005 }, + { "%.15g", "5e-006", 0, DOUBLE_ARG, 0, 0, 0.000005 }, + { "%.15g", "999999999999999", 0, DOUBLE_ARG, 0, 0, 999999999999999.0 }, + { "%.15g", "1e+015", 0, DOUBLE_ARG, 0, 0, 1000000000000000.0 }, + };
- format = "%I0d"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"I0d"),"I0d failed\n"); - ok( r==3, "return count wrong\n"); + char buffer[100]; + int i, x, r; + + for (i=0; i<ARRAY_SIZE(tests); i++) { + memset(buffer, 'x', sizeof(buffer)); + switch(tests[i].type & 0xff) { + case NO_ARG: + r = p_sprintf(buffer, tests[i].format); + break; + case INT_ARG: + r = p_sprintf(buffer, tests[i].format, tests[i].arg_i); + break; + case ULONGLONG_ARG: + r = p_sprintf(buffer, tests[i].format, tests[i].arg_ull); + break; + case DOUBLE_ARG: + r = p_sprintf(buffer, tests[i].format, tests[i].arg_d); + break; + case PTR_ARG: + r = p_sprintf(buffer, tests[i].format, tests[i].arg_ptr); + break; + default: + ok(0, "tests[%d].type = %x\n", i, tests[i].type); + continue; + }
- format = "%I32d"; - r = p_sprintf(buffer,format,1); - if (r == 1) - { - ok(!strcmp(buffer,"1"),"I32d failed, got '%s'\n",buffer); - } - else - { - /* Older versions don't grok I32 format */ - ok(r == 4 && !strcmp(buffer,"I32d"),"I32d failed, got '%s',%d\n",buffer,r); + ok(r == strlen(buffer), "%d) r = %d, buffer = "%s"\n", i, r, buffer); + todo_wine_if(tests[i].type & TODO_FLAG) + { + ok(!strcmp(buffer, tests[i].out) || + broken(tests[i].broken && !strcmp(buffer, tests[i].broken)), + "%d) buffer = "%s"\n", i, buffer); + } }
- format = "%I64D"; - r = p_sprintf(buffer,format,(LONGLONG)-1); - ok(!strcmp(buffer,"D"),"I64D failed: %s\n",buffer); - ok( r==1, "return count wrong\n"); - - format = "%zx"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer, "zx"), "Problem with "z" interpretation\n"); - ok( r==2, "return count wrong\n"); - - format = "% d"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer, " 1"),"Problem with sign place-holder: '%s'\n",buffer); - ok( r==2, "return count wrong\n"); - - format = "%+ d"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer, "+1"),"Problem with sign flags: '%s'\n",buffer); - ok( r==2, "return count wrong\n"); - - format = "%S"; - r = p_sprintf(buffer,format,wide); - ok(!strcmp(buffer,"wide"),"Problem with wide string format\n"); - ok( r==4, "return count wrong\n"); - - format = "%04c"; - r = p_sprintf(buffer,format,'1'); - ok(!strcmp(buffer,"0001"),"Character not zero-prefixed "%s"\n",buffer); - ok( r==4, "return count wrong\n"); - - format = "%-04c"; - r = p_sprintf(buffer,format,'1'); - 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 = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"0x0000000001"),"Hexadecimal zero-padded "%s"\n",buffer); - ok( r==12, "return count wrong\n"); - - r = p_sprintf(buffer,format,0); - ok(!strcmp(buffer,"000000000000"),"Hexadecimal zero-padded "%s"\n",buffer); - ok( r==12, "return count wrong\n"); - - format = "%#04.8x"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"0x00000001"), "Hexadecimal zero-padded precision "%s"\n",buffer); - ok( r==10, "return count wrong\n"); - - r = p_sprintf(buffer,format,0); - ok(!strcmp(buffer,"00000000"), "Hexadecimal zero-padded precision "%s"\n",buffer); - ok( r==8, "return count wrong\n"); - - format = "%#-08.2x"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"0x01 "), "Hexadecimal zero-padded not left-adjusted "%s"\n",buffer); - ok( r==8, "return count wrong\n"); - - r = p_sprintf(buffer,format,0); - ok(!strcmp(buffer,"00 "), "Hexadecimal zero-padded not left-adjusted "%s"\n",buffer); - ok( r==8, "return count wrong\n"); - - format = "%#.0x"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"0x1"), "Hexadecimal zero-padded zero-precision "%s"\n",buffer); - ok( r==3, "return count wrong\n"); - - r = p_sprintf(buffer,format,0); - ok(!strcmp(buffer,""), "Hexadecimal zero-padded zero-precision "%s"\n",buffer); - ok( r==0, "return count wrong\n"); - - format = "%#08o"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"00000001"), "Octal zero-padded "%s"\n",buffer); - ok( r==8, "return count wrong\n"); - - format = "%#o"; - r = p_sprintf(buffer,format,1); - ok(!strcmp(buffer,"01"), "Octal zero-padded "%s"\n",buffer); - ok( r==2, "return count wrong\n"); - - r = p_sprintf(buffer,format,0); - ok(!strcmp(buffer,"0"), "Octal zero-padded "%s"\n",buffer); - ok( r==1, "return count wrong\n"); - if (sizeof(void *) == 8) { - format = "%p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%p", (void *)57); ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==16, "return count wrong\n");
- format = "%#020p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%#020p", (void *)57); ok(!strcmp(buffer," 0X0000000000000039"),"Pointer formatted incorrectly\n"); ok( r==20, "return count wrong\n");
- format = "%Fp"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%Fp", (void *)57); ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==16, "return count wrong\n");
- format = "%Np"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%Np", (void *)57); ok(!strcmp(buffer,"0000000000000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==16, "return count wrong\n");
- format = "%#-020p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%#-020p", (void *)57); ok(!strcmp(buffer,"0X0000000000000039 "),"Pointer formatted incorrectly\n"); ok( r==20, "return count wrong\n");
- format = "%Ix %d"; - r = p_sprintf(buffer,format,(size_t)0x12345678123456,1); + r = p_sprintf(buffer, "%Ix %d", (size_t)0x12345678123456,1); ok(!strcmp(buffer,"12345678123456 1"),"buffer = %s\n",buffer); ok( r==16, "return count wrong\n"); + + r = p_sprintf(buffer, "%p", 0); + ok(!strcmp(buffer,"0000000000000000"), "failed\n"); + ok( r==16, "return count wrong\n"); } else { - format = "%p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%p", (void *)57); ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==8, "return count wrong\n");
- format = "%#012p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%#012p", (void *)57); ok(!strcmp(buffer," 0X00000039"),"Pointer formatted incorrectly\n"); ok( r==12, "return count wrong\n");
- format = "%Fp"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%Fp", (void *)57); ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==8, "return count wrong\n");
- format = "%Np"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%Np",(void *)57); ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly "%s"\n",buffer); ok( r==8, "return count wrong\n");
- format = "%#-012p"; - r = p_sprintf(buffer,format,(void *)57); + r = p_sprintf(buffer, "%#-012p", (void *)57); ok(!strcmp(buffer,"0X00000039 "),"Pointer formatted incorrectly\n"); ok( r==12, "return count wrong\n");
- format = "%Ix %d"; - r = p_sprintf(buffer,format,0x123456,1); + r = p_sprintf(buffer, "%Ix %d", 0x123456, 1); ok(!strcmp(buffer,"123456 1"),"buffer = %s\n",buffer); ok( r==8, "return count wrong\n"); - }
- format = "%04s"; - r = p_sprintf(buffer,format,"foo"); - ok(!strcmp(buffer,"0foo"),"String not zero-prefixed "%s"\n",buffer); - ok( r==4, "return count wrong\n"); - - format = "%.1s"; - r = p_sprintf(buffer,format,"foo"); - ok(!strcmp(buffer,"f"),"Precision ignored "%s"\n",buffer); - ok( r==1, "return count wrong\n"); + r = p_sprintf(buffer, "%p", 0); + ok(!strcmp(buffer,"00000000"), "failed\n"); + ok( r==8, "return count wrong\n"); + }
- format = "%.*s"; - r = p_sprintf(buffer,format,1,"foo"); + r = p_sprintf(buffer, "%.*s", 1, "foo"); ok(!strcmp(buffer,"f"),"Precision ignored "%s"\n",buffer); ok( r==1, "return count wrong\n");
- format = "%*s"; - r = p_sprintf(buffer,format,-5,"foo"); + r = p_sprintf(buffer, "%*s", -5, "foo"); ok(!strcmp(buffer,"foo "),"Negative field width ignored "%s"\n",buffer); ok( r==5, "return count wrong\n");
- format = "hello"; - r = p_sprintf(buffer, format); - ok(!strcmp(buffer,"hello"), "failed\n"); - ok( r==5, "return count wrong\n"); - - format = "%ws"; - r = p_sprintf(buffer, format, wide); - ok(!strcmp(buffer,"wide"), "failed\n"); - ok( r==4, "return count wrong\n"); - - format = "%-10ws"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer,"wide "), "failed\n"); - ok( r==10, "return count wrong\n"); - - format = "%10ws"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer," wide"), "failed\n"); - ok( r==10, "return count wrong\n"); - - format = "%#+ -03whlls"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer,"wide"), "failed\n"); - ok( r==4, "return count wrong\n"); - - format = "%w0s"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer,"0s"), "failed\n"); - ok( r==2, "return count wrong\n"); - - format = "%w-s"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer,"-s"), "failed\n"); - ok( r==2, "return count wrong\n"); - - format = "%ls"; - r = p_sprintf(buffer, format, wide ); - ok(!strcmp(buffer,"wide"), "failed\n"); - ok( r==4, "return count wrong\n"); - - format = "%Ls"; - r = p_sprintf(buffer, format, "not wide" ); - ok(!strcmp(buffer,"not wide"), "failed\n"); - ok( r==8, "return count wrong\n"); - - format = "%b"; - r = p_sprintf(buffer, format); - ok(!strcmp(buffer,"b"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%3c"; - r = p_sprintf(buffer, format,'a'); - ok(!strcmp(buffer," a"), "failed\n"); - ok( r==3, "return count wrong\n"); - - format = "%3d"; - r = p_sprintf(buffer, format,1234); - ok(!strcmp(buffer,"1234"), "failed\n"); - ok( r==4, "return count wrong\n"); - - format = "%3h"; - r = p_sprintf(buffer, format); - ok(!strcmp(buffer,""), "failed\n"); - ok( r==0, "return count wrong\n"); - - format = "%j%k%m%q%r%t%v%y%z"; - r = p_sprintf(buffer, format); - ok(!strcmp(buffer,"jkmqrtvyz"), "failed\n"); - ok( r==9, "return count wrong\n"); - - format = "asdf%n"; x = 0; - r = p_sprintf(buffer, format, &x ); + r = p_sprintf(buffer, "asdf%n", &x ); if (r == -1) { /* %n format is disabled by default on vista */ @@ -583,228 +392,7 @@ static void test_sprintf( void ) ok( r==4, "return count wrong: %d\n", r); }
- format = "%-1d"; - r = p_sprintf(buffer, format,2); - ok(!strcmp(buffer,"2"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%2.4f"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer,"8.6000"), "failed\n"); - ok( r==6, "return count wrong\n"); - - format = "%0f"; - r = p_sprintf(buffer, format,0.6); - ok(!strcmp(buffer,"0.600000"), "failed\n"); - ok( r==8, "return count wrong\n"); - - format = "%.0f"; - r = p_sprintf(buffer, format,0.6); - ok(!strcmp(buffer,"1"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%2.4e"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer,"8.6000e+000"), "failed\n"); - ok( r==11, "return count wrong\n"); - - format = "% 2.4e"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer," 8.6000e+000"), "failed: %s\n", buffer); - ok( r==12, "return count wrong\n"); - - format = "% 014.4e"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer," 008.6000e+000"), "failed: %s\n", buffer); - ok( r==14, "return count wrong\n"); - - format = "% 2.4e"; - r = p_sprintf(buffer, format,-8.6); - ok(!strcmp(buffer,"-8.6000e+000"), "failed: %s\n", buffer); - ok( r==12, "return count wrong\n"); - - format = "%+2.4e"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer,"+8.6000e+000"), "failed: %s\n", buffer); - ok( r==12, "return count wrong\n"); - - format = "%2.4g"; - r = p_sprintf(buffer, format,8.6); - ok(!strcmp(buffer,"8.6"), "failed\n"); - ok( r==3, "return count wrong\n"); - - format = "%-i"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,"-1"), "failed\n"); - ok( r==2, "return count wrong\n"); - - format = "%-i"; - r = p_sprintf(buffer, format,1); - ok(!strcmp(buffer,"1"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%+i"; - r = p_sprintf(buffer, format,1); - ok(!strcmp(buffer,"+1"), "failed\n"); - ok( r==2, "return count wrong\n"); - - format = "%o"; - r = p_sprintf(buffer, format,10); - ok(!strcmp(buffer,"12"), "failed\n"); - ok( r==2, "return count wrong\n"); - - format = "%p"; - r = p_sprintf(buffer, format,0); - if (sizeof(void *) == 8) - { - ok(!strcmp(buffer,"0000000000000000"), "failed\n"); - ok( r==16, "return count wrong\n"); - } - else - { - ok(!strcmp(buffer,"00000000"), "failed\n"); - ok( r==8, "return count wrong\n"); - } - - format = "%s"; - r = p_sprintf(buffer, format,0); - ok(!strcmp(buffer,"(null)"), "failed\n"); - ok( r==6, "return count wrong\n"); - - format = "%s"; - r = p_sprintf(buffer, format,"%%%%"); - ok(!strcmp(buffer,"%%%%"), "failed\n"); - ok( r==4, "return count wrong\n"); - - format = "%u"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,"4294967295"), "failed\n"); - ok( r==10, "return count wrong\n"); - - format = "%w"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,""), "failed\n"); - ok( r==0, "return count wrong\n"); - - format = "%h"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,""), "failed\n"); - ok( r==0, "return count wrong\n"); - - format = "%z"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,"z"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%j"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,"j"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "%F"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,""), "failed\n"); - ok( r==0, "return count wrong\n"); - - format = "%N"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,""), "failed\n"); - ok( r==0, "return count wrong\n"); - - format = "%H"; - r = p_sprintf(buffer, format,-1); - ok(!strcmp(buffer,"H"), "failed\n"); - ok( r==1, "return count wrong\n"); - - format = "x%cx"; - r = p_sprintf(buffer, format, 0x100+'X'); - ok(!strcmp(buffer,"xXx"), "failed\n"); - ok( r==3, "return count wrong\n"); - - format = "%%0"; - r = p_sprintf(buffer, format); - ok(!strcmp(buffer,"%0"), "failed: "%s"\n", buffer); - ok( r==2, "return count wrong\n"); - - format = "%hx"; - r = p_sprintf(buffer, format, 0x12345); - ok(!strcmp(buffer,"2345"), "failed "%s"\n", buffer); - - format = "%hhx"; - r = p_sprintf(buffer, format, 0x123); - ok(!strcmp(buffer,"123"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, 0x12345); - ok(!strcmp(buffer,"2345"), "failed "%s"\n", buffer); - - format = "%lf"; - r = p_sprintf(buffer, format, IND); - ok(r==9, "r = %d\n", r); - ok(!strcmp(buffer, "-1.#IND00"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, NAN); - ok(r==8, "r = %d\n", r); - ok(!strcmp(buffer, "1.#QNAN0"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, INFINITY); - ok(r==8, "r = %d\n", r); - ok(!strcmp(buffer, "1.#INF00"), "failed: "%s"\n", buffer); - - format = "%le"; - r = p_sprintf(buffer, format, IND); - ok(r==14, "r = %d\n", r); - ok(!strcmp(buffer, "-1.#IND00e+000"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, NAN); - ok(r==13, "r = %d\n", r); - ok(!strcmp(buffer, "1.#QNAN0e+000"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, INFINITY); - ok(r==13, "r = %d\n", r); - ok(!strcmp(buffer, "1.#INF00e+000"), "failed: "%s"\n", buffer); - - format = "%lg"; - r = p_sprintf(buffer, format, IND); - ok(r==7, "r = %d\n", r); - ok(!strcmp(buffer, "-1.#IND"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, NAN); - ok(r==7, "r = %d\n", r); - ok(!strcmp(buffer, "1.#QNAN"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, INFINITY); - ok(r==6, "r = %d\n", r); - ok(!strcmp(buffer, "1.#INF"), "failed: "%s"\n", buffer); - - format = "%010.2lf"; - r = p_sprintf(buffer, format, IND); - ok(r==10, "r = %d\n", r); - ok(!strcmp(buffer, "-000001.#J"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, NAN); - ok(r==10, "r = %d\n", r); - ok(!strcmp(buffer, "0000001.#R"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, INFINITY); - ok(r==10, "r = %d\n", r); - ok(!strcmp(buffer, "0000001.#J"), "failed: "%s"\n", buffer); - - format = "%c"; - r = p_sprintf(buffer, format, 'a'); - ok(r==1, "r = %d\n", r); - ok(!strcmp(buffer, "a"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, 0xa082); - ok(r==1, "r = %d\n", r); - ok(!strcmp(buffer, "\x82"), "failed: "%s"\n", buffer); - - format = "%C"; - r = p_sprintf(buffer, format, 'a'); - ok(r==1, "r = %d\n", r); - ok(!strcmp(buffer, "a"), "failed: "%s"\n", buffer); - r = p_sprintf(buffer, format, 0x3042); - ok(r==0, "r = %d\n", r); - ok(!strcmp(buffer, ""), "failed: "%s"\n", buffer); - - format = "a%Cb"; - r = p_sprintf(buffer, format, 0x3042); - ok(r==2, "r = %d\n", r); - ok(!strcmp(buffer, "ab"), "failed: "%s"\n", buffer); - - format = "%S"; - buf_w[0] = 0x3042; - buf_w[1] = 0; - r = p_sprintf(buffer, format, buf_w); + r = p_sprintf(buffer, "%S", L"\x3042"); ok(r==-1 || broken(!r), "r = %d\n", r);
if(!setlocale(LC_ALL, "Japanese_Japan.932")) { @@ -812,13 +400,11 @@ static void test_sprintf( void ) return; }
- format = "%c"; - r = p_sprintf(buffer, format, 0xa082); + r = p_sprintf(buffer, "%c", 0xa082); ok(r==1, "r = %d\n", r); ok(!strcmp(buffer, "\x82"), "failed: "%s"\n", buffer);
- format = "%C"; - r = p_sprintf(buffer, format, 0x3042); + r = p_sprintf(buffer, "%C", 0x3042); ok(r==2, "r = %d\n", r); ok(!strcmp(buffer, "\x82\xa0"), "failed: "%s"\n", buffer);
@@ -828,28 +414,34 @@ static void test_sprintf( void ) ok(!strcmp(buffer, "string to copy"), "failed: "%s"\n", buffer);
setlocale(LC_ALL, "C"); + + r = p_sprintf(buffer, "%*1d", 1, 3); + ok(r==11, "r = %d\n", r); + ok(!strcmp(buffer, " 3"), "failed: "%s"\n", buffer); + + r = p_sprintf(buffer, "%0*0d", 1, 2); + ok(r==10, "r = %d\n", r); + ok(!strcmp(buffer, "0000000002"), "failed: "%s"\n", buffer); + + r = p_sprintf(buffer, "% *2d", 0, 7); + ok(r==2, "r = %d\n", r); + ok(!strcmp(buffer, " 7"), "failed: "%s"\n", buffer); }
static void test_swprintf( void ) { wchar_t buffer[100]; - const wchar_t I64d[] = {'%','I','6','4','d',0}; - double pnumber=789456123; - const wchar_t TwentyThreePoint15e[]= {'%','+','#','2','3','.','1','5','e',0}; - const wchar_t e008[] = {'e','+','0','0','8',0}; - const wchar_t string_w[] = {'s','t','r','i','n','g',0}; + double pnumber = 789456123; const char string[] = "string"; - const wchar_t S[]={'%','S',0}; - const wchar_t hs[] = {'%', 'h', 's', 0}; - - swprintf(buffer,TwentyThreePoint15e,pnumber); - ok(wcsstr(buffer,e008) != 0,"Sprintf different\n"); - swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff); - ok(wcslen(buffer) == 11,"Problem with long long\n"); - swprintf(buffer,S,string); - ok(wcslen(buffer) == 6,"Problem with "%%S" interpretation\n"); - swprintf(buffer, hs, string); - ok( wcscmp(string_w,buffer) == 0, "swprintf failed with %%hs\n"); + + swprintf(buffer, L"%+#23.15e", pnumber); + ok(wcsstr(buffer, L"e+008") != 0, "Sprintf different\n"); + swprintf(buffer, L"%I64d", ((ULONGLONG)0xffffffff)*0xffffffff); + ok(wcslen(buffer) == 11, "Problem with long long\n"); + swprintf(buffer, L"%S", string); + ok(wcslen(buffer) == 6, "Problem with "%%S" interpretation\n"); + swprintf(buffer, L"%hs", string); + ok(!wcscmp(L"string", buffer), "swprintf failed with %%hs\n"); }
static void test_snprintf (void) @@ -867,10 +459,12 @@ static void test_snprintf (void) const int bufsiz = sizeof buffer; unsigned int i;
+ int (__cdecl *p_snprintf)(char*,size_t,const char*,...) = _snprintf; + for (i = 0; i < ARRAY_SIZE(tests); i++) { const char *fmt = tests[i].format; const int expect = tests[i].expected; - const int n = _snprintf (buffer, bufsiz, fmt); + const int n = p_snprintf(buffer, bufsiz, fmt); const int valid = n < 0 ? bufsiz : (n == bufsiz ? n : n+1);
ok (n == expect, ""%s": expected %d, returned %d\n", @@ -882,10 +476,7 @@ static void test_snprintf (void)
static void test_fprintf(void) { - static const char file_name[] = "fprintf.tst"; - static const WCHAR utf16_test[] = {'u','n','i','c','o','d','e','\n',0}; - - FILE *fp = fopen(file_name, "wb"); + FILE *fp = fopen("fprintf.tst", "wb"); char buf[1024]; int ret;
@@ -899,14 +490,14 @@ static void test_fprintf(void) ret = ftell(fp); ok(ret == 26, "ftell returned %d\n", ret);
- ret = fwprintf(fp, utf16_test); + ret = fwprintf(fp, L"unicode\n"); ok(ret == 8, "ret = %d\n", ret); ret = ftell(fp); ok(ret == 42, "ftell returned %d\n", ret);
fclose(fp);
- fp = fopen(file_name, "rb"); + fp = fopen("fprintf.tst", "rb"); ret = fscanf(fp, "%[^\n] ", buf); ok(ret == 1, "ret = %d\n", ret); ret = ftell(fp); @@ -922,12 +513,11 @@ static void test_fprintf(void) fgets(buf, sizeof(buf), fp); ret = ftell(fp); ok(ret == 41, "ret = %d\n", ret); - ok(!memcmp(buf, utf16_test, sizeof(utf16_test)), - "buf = %s\n", wine_dbgstr_w((WCHAR*)buf)); + ok(!wcscmp((wchar_t*)buf, L"unicode\n"), "buf = %s\n", wine_dbgstr_w((WCHAR*)buf));
fclose(fp);
- fp = fopen(file_name, "wt"); + fp = fopen("fprintf.tst", "wt");
ret = fprintf(fp, "simple test\n"); ok(ret == 12, "ret = %d\n", ret); @@ -939,14 +529,14 @@ static void test_fprintf(void) ret = ftell(fp); ok(ret == 28, "ftell returned %d\n", ret);
- ret = fwprintf(fp, utf16_test); + ret = fwprintf(fp, L"unicode\n"); ok(ret == 8, "ret = %d\n", ret); ret = ftell(fp); ok(ret == 37, "ftell returned %d\n", ret);
fclose(fp);
- fp = fopen(file_name, "rb"); + fp = fopen("fprintf.tst", "rb"); ret = fscanf(fp, "%[^\n] ", buf); ok(ret == 1, "ret = %d\n", ret); ret = ftell(fp); @@ -964,7 +554,7 @@ static void test_fprintf(void) ok(!strcmp(buf, "unicode\r\n"), "buf = %s\n", buf);
fclose(fp); - unlink(file_name); + unlink("fprintf.tst"); }
static void test_fcvt(void) @@ -1076,27 +666,23 @@ static struct { int expsign; } test_cvt_testcases[] = { { 45.0, 2, "45", "4500", 2, 2, 0 }, - /* Numbers less than 1.0 with different precisions */ { 0.0001, 1, "1", "", -3, -3, 0 }, { 0.0001, 10,"1000000000", "1000000", -3, -3, 0 }, - /* Basic sign test */ { -111.0001, 5, "11100", "11100010", 3, 3, 1 }, { 111.0001, 5, "11100", "11100010", 3, 3, 0 }, - /* big numbers with low precision */ { 3333.3, 2, "33", "333330", 4, 4, 0 }, {999999999999.9, 3, "100","999999999999900", 13, 12, 0 }, - /* 0.0 with different precisions */ { 0.0, 5, "00000", "00000", 0, 0, 0 }, { 0.0, 0, "", "", 0, 0, 0 }, { 0.0, -1, "", "", 0, 0, 0 }, - /* Numbers > 1.0 with 0 or -ve precision */ + { -0.0, 5, "00000", "00000", 0, 0, 1 }, + { -0.0, 0, "", "", 0, 0, 1 }, + { -0.0, -1, "", "", 0, 0, 1 }, { -123.0001, 0, "", "123", 3, 3, 1 }, { -123.0001, -1, "", "12", 3, 3, 1 }, { -123.0001, -2, "", "1", 3, 3, 1 }, { -123.0001, -3, "", "", 3, 3, 1 }, - /* Numbers > 1.0, but with rounding at the point of precision */ { 99.99, 1, "1", "1000", 3, 3, 0 }, - /* Numbers < 1.0 where rounding occurs at the point of precision */ { 0.0063, 2, "63", "1", -2, -1, 0 }, { 0.0063, 3, "630", "6", -2, -2, 0 }, { 0.09999999996, 2, "10", "10", 0, 0, 0 }, @@ -1105,12 +691,18 @@ static struct { { 0.4, 0, "", "", 0, 0, 0 }, { 0.49, 0, "", "", 0, 0, 0 }, { 0.51, 0, "", "1", 1, 1, 0 }, - /* ask for ridiculous precision, ruin formatting this table */ + { NAN, 2, "1$", "1#R", 1, 1, 0 }, + { NAN, 5, "1#QNB", "1#QNAN", 1, 1, 0 }, + { -NAN, 2, "1$", "1#J", 1, 1, 1 }, + { -NAN, 5, "1#IND", "1#IND0", 1, 1, 1 }, + { INFINITY, 2, "1$", "1#J", 1, 1, 0 }, + { INFINITY, 5, "1#INF", "1#INF0", 1, 1, 0 }, + { -INFINITY, 2, "1$", "1#J", 1, 1, 1 }, + { -INFINITY, 5, "1#INF", "1#INF0", 1, 1, 1 }, { 1.0, 30, "100000000000000000000000000000", "1000000000000000000000000000000", 1, 1, 0}, { 123456789012345678901.0, 30, "123456789012345680000000000000", "123456789012345680000000000000000000000000000000000", 21, 21, 0}, - /* end marker */ { 0, 0, "END"} };
@@ -1125,14 +717,14 @@ static void test_xcvt(void) test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), - "_ecvt() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_e, 15), + "%d) _ecvt() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_e); ok( decpt == test_cvt_testcases[i].expdecpt_e, - "_ecvt() decimal point wrong, got %d expected %d\n", decpt, + "%d) _ecvt() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_e); ok( sign == test_cvt_testcases[i].expsign, - "_ecvt() sign wrong, got %d expected %d\n", sign, + "%d) _ecvt() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ @@ -1141,14 +733,14 @@ static void test_xcvt(void) test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), - "_fcvt() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_f, 15), + "%d) _fcvt() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_f); ok( decpt == test_cvt_testcases[i].expdecpt_f, - "_fcvt() decimal point wrong, got %d expected %d\n", decpt, + "%d) _fcvt() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_f); ok( sign == test_cvt_testcases[i].expsign, - "_fcvt() sign wrong, got %d expected %d\n", sign, + "%d) _fcvt() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); }
@@ -1159,14 +751,14 @@ static void test_xcvt(void) decpt = sign = 100; err = p__ecvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); ok(err == 0, "_ecvt_s() failed with error code %d\n", err); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_e, 15), - "_ecvt_s() bad return, got \n'%s' expected \n'%s'\n", str, + ok( !strncmp( str, test_cvt_testcases[i].expstr_e, 15), + "%d) _ecvt_s() bad return, got '%s' expected '%s'\n", i, str, test_cvt_testcases[i].expstr_e); ok( decpt == test_cvt_testcases[i].expdecpt_e, - "_ecvt_s() decimal point wrong, got %d expected %d\n", decpt, + "%d) _ecvt_s() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_e); ok( sign == test_cvt_testcases[i].expsign, - "_ecvt_s() sign wrong, got %d expected %d\n", sign, + "%d) _ecvt_s() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } free(str); @@ -1203,15 +795,15 @@ static void test_xcvt(void) for( i = 0; strcmp( test_cvt_testcases[i].expstr_e, "END"); i++){ decpt = sign = 100; err = p__fcvt_s(str, 1024, test_cvt_testcases[i].value, test_cvt_testcases[i].nrdigits, &decpt, &sign); - ok(err == 0, "_fcvt_s() failed with error code %d\n", err); - ok( 0 == strncmp( str, test_cvt_testcases[i].expstr_f, 15), - "_fcvt_s() bad return, got '%s' expected '%s'. test %d\n", str, + ok(!err, "%d) _fcvt_s() failed with error code %d\n", i, err); + ok( !strncmp( str, test_cvt_testcases[i].expstr_f, 15), + "%d) _fcvt_s() bad return, got '%s' expected '%s'. test %d\n", i, str, test_cvt_testcases[i].expstr_f, i); ok( decpt == test_cvt_testcases[i].expdecpt_f, - "_fcvt_s() decimal point wrong, got %d expected %d\n", decpt, + "%d) _fcvt_s() decimal point wrong, got %d expected %d\n", i, decpt, test_cvt_testcases[i].expdecpt_f); ok( sign == test_cvt_testcases[i].expsign, - "_fcvt_s() sign wrong, got %d expected %d\n", sign, + "%d) _fcvt_s() sign wrong, got %d expected %d\n", i, sign, test_cvt_testcases[i].expsign); } free(str); @@ -1223,104 +815,94 @@ static void test_xcvt(void) static int WINAPIV _vsnwprintf_wrapper(wchar_t *str, size_t len, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = _vsnwprintf(str, len, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static void test_vsnwprintf(void) { - const wchar_t format[] = {'%','w','s','%','w','s','%','w','s',0}; - const wchar_t one[] = {'o','n','e',0}; - const wchar_t two[] = {'t','w','o',0}; - const wchar_t three[] = {'t','h','r','e','e',0}; - int ret; wchar_t str[32]; char buf[32];
- ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), format, one, two, three ); - + ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == 11, "got %d expected 11\n", ret ); WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL ); ok( !strcmp(buf, "onetwothree"), "got %s expected 'onetwothree'\n", buf );
- ret = _vsnwprintf_wrapper( str, 0, format, one, two, three ); + ret = _vsnwprintf_wrapper( str, 0, L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == -1, "got %d, expected -1\n", ret );
- ret = _vsnwprintf_wrapper( NULL, 0, format, one, two, three ); + ret = _vsnwprintf_wrapper( NULL, 0, L"%ws%ws%ws", L"one", L"two", L"three" ); ok( ret == 11 || broken(ret == -1 /* Win2k */), "got %d, expected 11\n", ret ); }
static int WINAPIV vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p_vswprintf(str, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static int WINAPIV _vswprintf_wrapper(wchar_t *str, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vswprintf(str, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static int WINAPIV _vswprintf_l_wrapper(wchar_t *str, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_l(str, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static int WINAPIV _vswprintf_c_wrapper(wchar_t *str, size_t size, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vswprintf_c(str, size, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static int WINAPIV _vswprintf_c_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_c_l(str, size, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static int WINAPIV _vswprintf_p_l_wrapper(wchar_t *str, size_t size, const wchar_t *format, void *locale, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, locale); + va_list valist; + va_start(valist, locale); ret = p__vswprintf_p_l(str, size, format, locale, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static void test_vswprintf(void) { - const wchar_t format[] = {'%','s',' ','%','d',0}; - const wchar_t number[] = {'n','u','m','b','e','r',0}; - const wchar_t out[] = {'n','u','m','b','e','r',' ','1','2','3',0}; wchar_t buf[20]; - int ret;
if (!p_vswprintf || !p__vswprintf || !p__vswprintf_l ||!p__vswprintf_c @@ -1330,43 +912,48 @@ static void test_vswprintf(void) return; }
- ret = vswprintf_wrapper(buf, format, number, 123); + ret = vswprintf_wrapper(buf, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf));
memset(buf, 0, sizeof(buf)); - ret = _vswprintf_wrapper(buf, format, number, 123); + ret = _vswprintf_wrapper(buf, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf));
memset(buf, 0, sizeof(buf)); - ret = _vswprintf_l_wrapper(buf, format, NULL, number, 123); + ret = _vswprintf_l_wrapper(buf, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf));
memset(buf, 0, sizeof(buf)); - ret = _vswprintf_c_wrapper(buf, 20, format, number, 123); + ret = _vswprintf_c_wrapper(buf, 20, L"%s %d", L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); + + memset(buf, 'x', sizeof(buf)); + ret = _vswprintf_c_wrapper(buf, 10, L"%s %d", L"number", 123); + ok(ret == -1, "got %d, expected -1\n", ret); + ok(!wcscmp(buf, L"number 12"), "buf = %s\n", wine_dbgstr_w(buf));
memset(buf, 0, sizeof(buf)); - ret = _vswprintf_c_l_wrapper(buf, 20, format, NULL, number, 123); + ret = _vswprintf_c_l_wrapper(buf, 20, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf));
memset(buf, 0, sizeof(buf)); - ret = _vswprintf_p_l_wrapper(buf, 20, format, NULL, number, 123); + ret = _vswprintf_p_l_wrapper(buf, 20, L"%s %d", NULL, L"number", 123); ok(ret == 10, "got %d, expected 10\n", ret); - ok(!memcmp(buf, out, sizeof(out)), "buf = %s\n", wine_dbgstr_w(buf)); + ok(!wcscmp(buf, L"number 123"), "buf = %s\n", wine_dbgstr_w(buf)); }
static int WINAPIV _vscprintf_wrapper(const char *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vscprintf(format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
@@ -1387,18 +974,15 @@ static void test_vscprintf(void) static int WINAPIV _vscwprintf_wrapper(const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vscwprintf(format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static void test_vscwprintf(void) { - const wchar_t format[] = {'%','s',' ','%','d',0}; - const wchar_t number[] = {'n','u','m','b','e','r',0}; - int ret;
if (!p__vscwprintf) @@ -1407,7 +991,7 @@ static void test_vscwprintf(void) return; }
- ret = _vscwprintf_wrapper( format, number, 1 ); + ret = _vscwprintf_wrapper(L"%s %d", L"number", 1 ); ok( ret == 8, "got %d expected 8\n", ret ); }
@@ -1415,22 +999,17 @@ static int WINAPIV _vsnwprintf_s_wrapper(wchar_t *str, size_t sizeOfBuffer, size_t count, const wchar_t *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vsnwprintf_s(str, sizeOfBuffer, count, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
static void test_vsnwprintf_s(void) { - const wchar_t format[] = { 'A','B','%','u','C',0 }; - const wchar_t out7[] = { 'A','B','1','2','3','C',0 }; - const wchar_t out6[] = { 'A','B','1','2','3',0 }; - const wchar_t out2[] = { 'A',0 }; - const wchar_t out1[] = { 0 }; wchar_t buffer[14] = { 0 }; - int exp, got; + int ret;
if (!p__vsnwprintf_s) { @@ -1439,44 +1018,40 @@ static void test_vsnwprintf_s(void) }
/* Enough room. */ - exp = wcslen(out7); - - got = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 14, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
- got = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 12, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
- got = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out7, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 7, _TRUNCATE, L"AB%uC", 123); + ok( ret == 6, "length wrong, expect=6, got=%d\n", ret); + ok( !wcscmp(L"AB123C", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
/* Not enough room. */ - exp = -1; - - got = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out6, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 6, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"AB123", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
- got = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out2, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 2, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"A", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer));
- got = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, format, 123); - ok( exp == got, "length wrong, expect=%d, got=%d\n", exp, got); - ok( !wcscmp(out1, buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); + ret = _vsnwprintf_s_wrapper(buffer, 1, _TRUNCATE, L"AB%uC", 123); + ok( ret == -1, "length wrong, expect=-1, got=%d\n", ret); + ok( !wcscmp(L"", buffer), "buffer wrong, got=%s\n", wine_dbgstr_w(buffer)); }
static int WINAPIV _vsprintf_p_wrapper(char *str, size_t sizeOfBuffer, const char *format, ...) { int ret; - __ms_va_list valist; - __ms_va_start(valist, format); + va_list valist; + va_start(valist, format); ret = p__vsprintf_p(str, sizeOfBuffer, format, valist); - __ms_va_end(valist); + va_end(valist); return ret; }
diff --git a/modules/rostests/winetests/msvcrt/scanf.c b/modules/rostests/winetests/msvcrt/scanf.c index 6d38e438c8c..e175342796b 100644 --- a/modules/rostests/winetests/msvcrt/scanf.c +++ b/modules/rostests/winetests/msvcrt/scanf.c @@ -22,6 +22,41 @@
#include "wine/test.h"
+static void test_fscanf( void ) +{ + static const char file_name[] = "fscanf.tst"; + static const char contents[] = + "line1\n" + "line2 " + ; + char buf[1024]; + FILE *fp; + int ret; + + fp = fopen(file_name, "wb"); + ok(fp != NULL, "fp = %p\n", fp); + if(!fp) { + skip("failed to create temporary test file\n"); + return; + } + + ret = fprintf(fp, contents); + fclose(fp); + + fp = fopen(file_name, "rb"); + ret = fscanf(fp, "%s", buf); + ok(ret == 1, "ret = %d\n", ret); + ok(strcmp(buf, "line1") == 0, "buf = %s\n", buf); + ret = fscanf(fp, "%s", buf); + ok(ret == 1, "ret = %d\n", ret); + ok(strcmp(buf, "line2") == 0, "buf = %s\n", buf); + ret = fscanf(fp, "%s", buf); + ok(ret == EOF, "ret = %d\n", ret); + fclose(fp); + + unlink(file_name); +} + static void test_sscanf( void ) { /* use function pointers to bypass gcc builtin */ @@ -48,6 +83,14 @@ static void test_sscanf( void ) ret = p_sscanf(buffer, "%d", &result); ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF );
+ ret = p_sscanf(" \t\n\n", "%s", buffer); + ok( ret == EOF, "ret = %d\n", ret ); + + buffer1[0] = 'a'; + ret = p_sscanf("test\n", "%s%c", buffer, buffer1); + ok( ret == 2, "ret = %d\n", ret ); + ok( buffer1[0] == '\n', "buffer1[0] = %d\n", buffer1[0] ); + /* check %p */ ok( p_sscanf("000000000046F170", "%p", &ptr) == 1, "sscanf failed\n" ); ok( ptr == (void *)0x46F170,"sscanf reads %p instead of %x\n", ptr, 0x46F170 ); @@ -122,6 +165,12 @@ static void test_sscanf( void ) ok(double_res >= 1.1e-30-1e-45 && double_res <= 1.1e-30+1e-45, "Got %.18le, expected %.18le\n", double_res, 1.1e-30);
+ buffer[0] = 0; + double_res = 1; + ret = p_sscanf(buffer, "%lf", &double_res); + ok(ret == -1, "expected 0, got %u\n", ret); + ok(double_res == 1, "Got %lf, expected 1\n", double_res); + /* check strings */ ret = p_sprintf(buffer," %s", pname); ok( ret == 26, "expected 26, got %u\n", ret); @@ -137,6 +186,22 @@ static void test_sscanf( void ) ok( ret == 1, "Error with format "%s"\n","%*[a-cd-dg-e]%c"); ok( buffer[0] == 'h', "Error with "abcefgdh" "%c"\n", buffer[0]);
+ ret = p_sscanf("-123", "%[-0-9]", buffer); + ok( ret == 1, "Error with format "%s"\n", "%[-0-9]"); + ok( strcmp("-123", buffer) == 0, "Error with "-123" "%s"\n", buffer); + + ret = p_sscanf("-321", "%[0-9-]", buffer); + ok( ret == 1, "Error with format "%s"\n", "%[0-9-]"); + ok( strcmp("-321", buffer) == 0, "Error with "-321" "%s"\n", buffer); + + ret = p_sscanf("-4123", "%[1-2-4]", buffer); + ok( ret == 1, "Error with format "%s"\n", "%[1-2-4]"); + ok( strcmp("-412", buffer) == 0, "Error with "-412" "%s"\n", buffer); + + ret = p_sscanf("-456123", "%[1-2-45-6]", buffer); + ok( ret == 1, "Error with format "%s"\n", "%[1-2-45-6]"); + ok( strcmp("-45612", buffer) == 0, "Error with "-45612" "%s"\n", buffer); + buffer1[0] = 'b'; ret = p_sscanf("a","%s%s", buffer, buffer1); ok( ret == 1, "expected 1, got %u\n", ret); @@ -162,6 +227,30 @@ static void test_sscanf( void ) ok(ret == 1, "Wrong number of arguments read: %d\n", ret); ok(result == 0xdead614e, "Wrong number read (%x)\n", result);
+ result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%02hd", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%h02d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%000h02d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead000c, "Wrong number read (%x)\n", result); + + result = 0xdeadbeef; + strcpy(buffer,"12345678"); + ret = p_sscanf(buffer, "%2h0d", &result); + ok(ret == 1, "Wrong number of arguments read: %d\n", ret); + ok(result == 0xdead614e, "Wrong number read (%x)\n", result); + result = 0xdeadbeef; ret = p_sscanf(buffer, "%hhd", &result); ok(ret == 1, "Wrong number of arguments read: %d\n", ret); @@ -313,35 +402,34 @@ static void test_sscanf_s(void)
static void test_swscanf( void ) { - wchar_t buffer[100]; + wchar_t buffer[100], results[100]; int result, ret; - static const WCHAR formatd[] = {'%','d',0}; - const WCHAR format2[] = {'a',0x1234,'%',0x1234,'%','c',0}; WCHAR c;
/* 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); + ret = swscanf(buffer, L"%d", &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 );
+ ret = swscanf(L" \t\n\n", L"%s", results); + /* sscanf returns EOF under this case, but swscanf does not return WEOF */ + ok( ret == 0, "ret = %d\n", ret ); + buffer[0] = 'a'; buffer[1] = 0x1234; buffer[2] = 0x1234; buffer[3] = 'b'; - ret = swscanf(buffer, format2, &c); + ret = swscanf(buffer, L"a\x1234%\x1234%c", &c); ok(ret == 1, "swscanf returned %d\n", ret); ok(c == 'b', "c = %x\n", c); }
static void test_swscanf_s(void) { - static const wchar_t fmt1[] = {'%','c',0}; - static const wchar_t fmt2[] = {'%','[','a','-','z',']',0}; - int (WINAPIV *pswscanf_s)(const wchar_t*,const wchar_t*,...); HMODULE hmod = GetModuleHandleA("msvcrt.dll"); wchar_t buf[2], out[2]; @@ -356,15 +444,15 @@ static void test_swscanf_s(void) buf[0] = 'a'; buf[1] = '1'; out[1] = 'b'; - ret = pswscanf_s(buf, fmt1, out, 1); + ret = pswscanf_s(buf, L"%c", out, 1); ok(ret == 1, "swscanf_s returned %d\n", ret); ok(out[0] == 'a', "out[0] = %x\n", out[0]); ok(out[1] == 'b', "out[1] = %x\n", out[1]);
- ret = pswscanf_s(buf, fmt2, out, 1); + ret = pswscanf_s(buf, L"%[a-z]", out, 1); ok(!ret, "swscanf_s returned %d\n", ret);
- ret = pswscanf_s(buf, fmt2, out, 2); + ret = pswscanf_s(buf, L"%[a-z]", out, 2); ... 2945 lines suppressed ...