From: Piotr Caban Subject: [PATCH 1/2] msvcp100: Add std::iostream_category() implementation Message-Id: <5440EA5B.7030406@codeweavers.com> Date: Fri, 17 Oct 2014 12:07:23 +0200 --- dlls/msvcp100/msvcp100.spec | 4 +- dlls/msvcp90/misc.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcp90/msvcp90.h | 1 + dlls/msvcp90/msvcp_main.c | 1 + 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/dlls/msvcp100/msvcp100.spec b/dlls/msvcp100/msvcp100.spec index 6cb9b77..0055d79 100644 --- a/dlls/msvcp100/msvcp100.spec +++ b/dlls/msvcp100/msvcp100.spec @@ -2045,8 +2045,8 @@ # extern ?intl@?$moneypunct@G$0A@@std@@2_NB # extern ?intl@?$moneypunct@_W$00@std@@2_NB # extern ?intl@?$moneypunct@_W$0A@@std@@2_NB -@ stub -arch=win32 ?iostream_category@std@@YAABVerror_category@1@XZ -@ stub -arch=win64 ?iostream_category@std@@YAAEBVerror_category@1@XZ +@ cdecl -arch=win32 ?iostream_category@std@@YAABVerror_category@1@XZ() std_iostream_category +@ cdecl -arch=win64 ?iostream_category@std@@YAAEBVerror_category@1@XZ() std_iostream_category @ thiscall -arch=win32 ?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE_N_N@Z(ptr long) basic_istream_char_ipfx @ cdecl -arch=win64 ?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAA_N_N@Z(ptr long) basic_istream_char_ipfx @ thiscall -arch=win32 ?ipfx@?$basic_istream@GU?$char_traits@G@std@@@std@@QAE_N_N@Z(ptr long) basic_istream_wchar_ipfx diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index abd53d7..ac64e42 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -478,3 +478,118 @@ critical_section* __cdecl _Mtx_getconcrtcs(_Mtx_t *mtx) return &(*mtx)->cs; } #endif + +#if _MSVCP_VER == 100 +typedef struct { + const vtable_ptr *vtable; +} error_category; + +typedef struct { + error_category base; + const char *type; +} custom_category; +static custom_category iostream_category; + +DEFINE_RTTI_DATA0(error_category, 0, ".?AVerror_category@std@@") +DEFINE_RTTI_DATA1(iostream_category, 0, &error_category_rtti_base_descriptor, ".?AV_Iostream_error_category@std@@") + +extern const vtable_ptr MSVCP_iostream_category_vtable; + +static void iostream_category_ctor(custom_category *this) +{ + this->base.vtable = &MSVCP_iostream_category_vtable;; + this->type = "iostream"; +} + +DEFINE_THISCALL_WRAPPER(custom_category_vector_dtor, 8) +custom_category* __thiscall custom_category_vector_dtor(custom_category *this, unsigned int flags) +{ + TRACE("(%p %x)\n", this, flags); + if(flags & 2) { + /* we have an array, with the number of elements stored before the first object */ + INT_PTR i, *ptr = (INT_PTR *)this-1; + + for(i=*ptr-1; i>=0; i--) + MSVCRT_operator_delete(ptr); + } else { + if(flags & 1) + MSVCRT_operator_delete(this); + } + + return this; +} + +DEFINE_THISCALL_WRAPPER(custom_category_name, 4) +const char* __thiscall custom_category_name(const custom_category *this) +{ + return this->type; +} + +DEFINE_THISCALL_WRAPPER(custom_category_message, 12) +basic_string_char* __thiscall custom_category_message(const custom_category *this, + basic_string_char *ret, int err) +{ + if(err == 1) return MSVCP_basic_string_char_ctor_cstr(ret, "iostream error"); + return MSVCP_basic_string_char_ctor_cstr(ret, strerror(err)); +} + +DEFINE_THISCALL_WRAPPER(custom_category_default_error_condition, 12) +/*error_condition*/void* __thiscall custom_category_default_error_condition( + custom_category *this, /*error_condition*/void *ret, int code) +{ + FIXME("(%p %p %x) stub\n", this, ret, code); + return NULL; +} + +DEFINE_THISCALL_WRAPPER(custom_category_equivalent, 12) +MSVCP_bool __thiscall custom_category_equivalent(const custom_category *this, + int code, const /*error_condition*/void *condition) +{ + FIXME("(%p %x %p) stub\n", this, code, condition); + return FALSE; +} + +DEFINE_THISCALL_WRAPPER(custom_category_equivalent_code, 12) +MSVCP_bool __thiscall custom_category_equivalent_code(custom_category *this, + const /*error_code*/void *code, int condition) +{ + FIXME("(%p %p %x) stub\n", this, code, condition); + return FALSE; +} + +/* ?iostream_category@std@@YAABVerror_category@1@XZ */ +/* ?iostream_category@std@@YAAEBVerror_category@1@XZ */ +const error_category* __cdecl std_iostream_category(void) +{ + TRACE("()\n"); + return &iostream_category.base; +} + +#ifndef __GNUC__ +void __asm_dummy_vtables(void) { +#endif + __ASM_VTABLE(iostream_category, + VTABLE_ADD_FUNC(custom_category_vector_dtor) + VTABLE_ADD_FUNC(custom_category_name) + VTABLE_ADD_FUNC(custom_category_message) + VTABLE_ADD_FUNC(custom_category_default_error_condition) + VTABLE_ADD_FUNC(custom_category_equivalent) + VTABLE_ADD_FUNC(custom_category_equivalent_code)); +#ifndef __GNUC__ +} +#endif +#endif + +void init_misc(void *base) +{ +#ifdef __x86_64__ +#if _MSVCP_VER == 100 + init_error_category_rtti(base); + init_iostream_category_rtti(base); +#endif +#endif + +#if _MSVCP_VER == 100 + iostream_category_ctor(&iostream_category); +#endif +} diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 5062bdc..3fb6790 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -536,6 +536,7 @@ void init_exception(void*); void init_locale(void*); void init_io(void*); void free_io(void); +void init_misc(void*); /* class complex */ typedef struct { diff --git a/dlls/msvcp90/msvcp_main.c b/dlls/msvcp90/msvcp_main.c index edbdd50..13d3ff2 100644 --- a/dlls/msvcp90/msvcp_main.c +++ b/dlls/msvcp90/msvcp_main.c @@ -127,6 +127,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) init_exception(hinstDLL); init_locale(hinstDLL); init_io(hinstDLL); + init_misc(hinstDLL); break; case DLL_PROCESS_DETACH: if (lpvReserved) break;