Module: wine Branch: master Commit: 1150c0454d1b93fd30bdee552ea8e82d35eda51a URL: http://source.winehq.org/git/wine.git/?a=commit;h=1150c0454d1b93fd30bdee552e...
Author: Piotr Caban piotr@codeweavers.com Date: Mon Jul 4 11:04:23 2016 +0200
msvcr120: Add fegetenv implementation.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
.../api-ms-win-crt-runtime-l1-1-0.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120/tests/msvcr120.c | 25 ++++++++++++++++++++++ dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcrt/math.c | 11 ++++++++++ dlls/msvcrt/msvcrt.h | 6 ++++++ dlls/ucrtbase/ucrtbase.spec | 2 +- 7 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec index 8d96f98..17b9861 100644 --- a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec +++ b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec @@ -88,7 +88,7 @@ @ cdecl abort() ucrtbase.abort @ cdecl exit(long) ucrtbase.exit @ stub feclearexcept -@ stub fegetenv +@ cdecl fegetenv(ptr) ucrtbase.fegetenv @ stub fegetexceptflag @ stub fegetround @ stub feholdexcept diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 86f466b..a2e7832 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2144,7 +2144,7 @@ @ stub fdimf @ stub fdiml @ stub feclearexcept -@ stub fegetenv +@ cdecl fegetenv(ptr) MSVCRT_fegetenv @ stub fegetexceptflag @ stub fegetround @ stub feholdexcept diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 6ee659f..25330f1 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -147,6 +147,12 @@ struct MSVCRT_lconv wchar_t* _W_negative_sign; };
+typedef struct +{ + unsigned int control; + unsigned int status; +} fenv_t; + static char* (CDECL *p_setlocale)(int category, const char* locale); static struct MSVCRT_lconv* (CDECL *p_localeconv)(void); static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max); @@ -162,6 +168,8 @@ static int (CDECL *p__finite)(double); static float (CDECL *p_wcstof)(const wchar_t*, wchar_t**); static double (CDECL *p_remainder)(double, double); static int* (CDECL *p_errno)(void); +static int (CDECL *p_fegetenv)(fenv_t*); +static int (CDECL *p__clearfp)(void);
/* make sure we use the correct errno */ #undef errno @@ -207,6 +215,8 @@ static BOOL init(void) p_wcstof = (void*)GetProcAddress(module, "wcstof"); p_remainder = (void*)GetProcAddress(module, "remainder"); p_errno = (void*)GetProcAddress(module, "_errno"); + SET(p_fegetenv, "fegetenv"); + SET(p__clearfp, "_clearfp"); if(sizeof(void*) == 8) { /* 64-bit initialization */ SET(p_critical_section_ctor, "??0critical_section@Concurrency@@QEAA@XZ"); @@ -686,6 +696,20 @@ static void test_critical_section(void) call_func1(p_critical_section_dtor, &cs); }
+static void test_fegetenv(void) +{ + int ret; + fenv_t env; + + p__clearfp(); + + ret = p_fegetenv(&env); + ok(!ret, "fegetenv returned %x\n", ret); + ok(env.control == (_EM_INEXACT|_EM_UNDERFLOW|_EM_OVERFLOW|_EM_ZERODIVIDE|_EM_INVALID), + "env.control = %x\n", env.control); + ok(!env.status, "env.status = %x\n", env.status); +} + START_TEST(msvcr120) { if (!init()) return; @@ -699,4 +723,5 @@ START_TEST(msvcr120) test__strtof(); test_remainder(); test_critical_section(); + test_fegetenv(); } diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index e498fc7..94c0e08 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -1810,7 +1810,7 @@ @ stub fdimf @ stub fdiml @ stub feclearexcept -@ stub fegetenv +@ cdecl fegetenv(ptr) msvcr120.fegetenv @ stub fegetexceptflag @ stub fegetround @ stub feholdexcept diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 3d2104b..e9d594c 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -1199,6 +1199,17 @@ int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask }
/********************************************************************* + * fegetenv (MSVCR120.@) + */ +int CDECL MSVCRT_fegetenv(fenv_t *env) +{ + env->control = _controlfp(0, 0) & (MSVCRT__EM_INEXACT | MSVCRT__EM_UNDERFLOW | + MSVCRT__EM_OVERFLOW | MSVCRT__EM_ZERODIVIDE | MSVCRT__EM_INVALID); + env->status = _statusfp(); + return 0; +} + +/********************************************************************* * __fpe_flt_rounds (UCRTBASE.@) */ int CDECL __fpe_flt_rounds(void) diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 6c2ab42..958ca4e 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -910,6 +910,12 @@ struct MSVCRT__stat64 { #define MSVCRT__DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000 #define MSVCRT__EM_AMBIGUOUS 0x80000000
+typedef struct +{ + unsigned int control; + unsigned int status; +} fenv_t; + #define MSVCRT_CLOCKS_PER_SEC 1000
/* signals */ diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index c03a434..0d6b397 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2286,7 +2286,7 @@ @ stub fdimf @ stub fdiml @ stub feclearexcept -@ stub fegetenv +@ cdecl fegetenv(ptr) MSVCRT_fegetenv @ stub fegetexceptflag @ stub fegetround @ stub feholdexcept