Signed-off-by: Daniel Lehman dlehman25@gmail.com --- .../api-ms-win-crt-runtime-l1-1-0.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120/tests/msvcr120.c | 37 ++++++++++++++++++- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcrt/math.c | 13 +++++++ dlls/ucrtbase/ucrtbase.spec | 2 +- include/msvcrt/fenv.h | 3 ++ 7 files changed, 56 insertions(+), 5 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 74d682b33bf..59b0c567216 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 @@ -89,7 +89,7 @@ @ cdecl exit(long) ucrtbase.exit @ stub feclearexcept @ cdecl fegetenv(ptr) ucrtbase.fegetenv -@ stub fegetexceptflag +@ cdecl fegetexceptflag(ptr long) ucrtbase.fegetexceptflag @ cdecl fegetround() ucrtbase.fegetround @ stub feholdexcept @ cdecl fesetenv(ptr) ucrtbase.fesetenv diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 0e1c7705166..776d701e780 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2145,7 +2145,7 @@ @ cdecl fdiml(double double) fdim @ stub feclearexcept @ cdecl fegetenv(ptr) -@ stub fegetexceptflag +@ cdecl fegetexceptflag(ptr long) @ cdecl fegetround() @ stub feholdexcept @ cdecl feof(ptr) diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index e8ef2be3520..d6e93b97629 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -182,6 +182,7 @@ static int (CDECL *p_fegetenv)(fenv_t*); static int (CDECL *p_fesetenv)(const fenv_t*); static int (CDECL *p_fegetround)(void); static int (CDECL *p_fesetround)(int); +static int (CDECL *p_fegetexceptflag)(fexcept_t*,int); static int (CDECL *p__clearfp)(void); static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *); static void (__cdecl *p_free_locale)(_locale_t); @@ -257,6 +258,7 @@ static BOOL init(void) SET(p_fesetenv, "fesetenv"); SET(p_fegetround, "fegetround"); SET(p_fesetround, "fesetround"); + SET(p_fegetexceptflag, "fegetexceptflag");
SET(p__clearfp, "_clearfp"); SET(p_vsscanf, "vsscanf"); @@ -788,8 +790,25 @@ static void test_critical_section(void)
static void test_feenv(void) { + static const struct { + unsigned long set; + unsigned long get; + fexcept_t expect; + } tests[] = { + { 0, 0, 0 }, + { FE_INEXACT, 0, 0 }, + { FE_INEXACT, FE_ALL_EXCEPT, FE_INEXACT }, + { FE_INEXACT, FE_INEXACT, FE_INEXACT }, + { FE_INEXACT, FE_OVERFLOW, 0 }, + { FE_ALL_EXCEPT, FE_ALL_EXCEPT, FE_ALL_EXCEPT }, + { FE_ALL_EXCEPT, FE_INEXACT, FE_INEXACT }, + { FE_ALL_EXCEPT, 0, 0 }, + { FE_ALL_EXCEPT, ~0, FE_ALL_EXCEPT }, + { FE_ALL_EXCEPT, ~FE_ALL_EXCEPT, 0 }, + }; fenv_t env, env2; - int ret; + fexcept_t except; + int i, ret;
p__clearfp();
@@ -807,6 +826,22 @@ static void test_feenv(void) ok(!ret, "fesetenv returned %x\n", ret); ret = p_fegetround(); ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret); + + if(0) /* crashes on windows */ + p_fegetexceptflag(NULL, 0); + + for(i=0; i<ARRAY_SIZE(tests); i++) { + env._Fe_stat = tests[i].set; + ret = p_fesetenv(&env); + ok(!ret, "fesetenv returned %x\n", ret); + + except = ~0; + ret = p_fegetexceptflag(&except, tests[i].get); + ok(!ret, "fegetexceptflag returned %x.\n", ret); + ok(except == tests[i].expect, "expected %lx, got %lx\n", tests[i].expect, except); + } + + p__clearfp(); }
static void test__wcreate_locale(void) diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index 05b8a97a084..a3be94e4a6c 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -1811,7 +1811,7 @@ @ cdecl fdiml(double double) msvcr120.fdiml @ stub feclearexcept @ cdecl fegetenv(ptr) msvcr120.fegetenv -@ stub fegetexceptflag +@ cdecl fegetexceptflag(ptr long) msvcr120.fegetexceptflag @ cdecl fegetround() msvcr120.fegetround @ stub feholdexcept @ cdecl feof(ptr) msvcr120.feof diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index d6b0d9422e7..996059cc036 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -2214,6 +2214,19 @@ int CDECL fegetenv(fenv_t *env) env->_Fe_stat = _statusfp(); return 0; } + +/********************************************************************* + * fegetexceptflag (MSVCR120.@) + */ +int CDECL fegetexceptflag(fexcept_t *status, int excepts) +{ + fenv_t env; + int rc; + + rc = fegetenv(&env); + *status = env._Fe_stat & excepts & FE_ALL_EXCEPT; + return rc; +} #endif
#if _MSVCR_VER>=140 diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 0a8d74521f5..41b1b79896d 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2288,7 +2288,7 @@ @ cdecl fdiml(double double) fdim @ stub feclearexcept @ cdecl fegetenv(ptr) -@ stub fegetexceptflag +@ cdecl fegetexceptflag(ptr long) @ cdecl fegetround() @ stub feholdexcept @ cdecl feof(ptr) diff --git a/include/msvcrt/fenv.h b/include/msvcrt/fenv.h index 92b341bd46b..56db8ea28b8 100644 --- a/include/msvcrt/fenv.h +++ b/include/msvcrt/fenv.h @@ -30,8 +30,11 @@ typedef struct __msvcrt_ulong _Fe_stat; } fenv_t;
+typedef __msvcrt_ulong fexcept_t; + _ACRTIMP int __cdecl fegetenv(fenv_t*); _ACRTIMP int __cdecl fesetenv(const fenv_t*); +_ACRTIMP int __cdecl fegetexceptflag(fexcept_t*, int); _ACRTIMP int __cdecl fegetround(void); _ACRTIMP int __cdecl fesetround(int);