Signed-off-by: Daniel Lehman dlehman25@gmail.com
--- v2: - use _statusfp() - improved tests --- .../api-ms-win-crt-runtime-l1-1-0.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120/tests/msvcr120.c | 33 ++++++++++++++++++- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcrt/math.c | 8 +++++ dlls/ucrtbase/ucrtbase.spec | 2 +- include/msvcrt/fenv.h | 1 + 7 files changed, 45 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..66c2d8cc264 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 @@ -95,7 +95,7 @@ @ cdecl fesetenv(ptr) ucrtbase.fesetenv @ stub fesetexceptflag @ cdecl fesetround(long) ucrtbase.fesetround -@ stub fetestexcept +@ cdecl fetestexcept(long) ucrtbase.fetestexcept @ cdecl perror(str) ucrtbase.perror @ cdecl quick_exit(long) ucrtbase.quick_exit @ cdecl raise(long) ucrtbase.raise diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 0e1c7705166..27ae5a930f6 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -2154,7 +2154,7 @@ @ cdecl fesetenv(ptr) @ stub fesetexceptflag @ cdecl fesetround(long) -@ stub fetestexcept +@ cdecl fetestexcept(long) @ stub feupdateenv @ cdecl fflush(ptr) @ cdecl fgetc(ptr) diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index e8ef2be3520..537e9077402 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_fetestexcept)(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_fetestexcept, "fetestexcept");
SET(p__clearfp, "_clearfp"); SET(p_vsscanf, "vsscanf"); @@ -788,8 +790,17 @@ static void test_critical_section(void)
static void test_feenv(void) { + static const int tests[] = { + 0, + FE_INEXACT, + FE_UNDERFLOW, + FE_OVERFLOW, + FE_DIVBYZERO, + FE_INVALID, + FE_ALL_EXCEPT, + }; fenv_t env, env2; - int ret; + int i, ret, flags;
p__clearfp();
@@ -807,6 +818,26 @@ 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); + + ret = p_fetestexcept(FE_ALL_EXCEPT); + ok(!ret, "fetestexcept returned %x\n", ret); + + flags = 0; + for(i=0; i<ARRAY_SIZE(tests); i++) { + ret = p_fegetenv(&env); + ok(!ret, "Test %d: fegetenv returned %x\n", i, ret); + env._Fe_stat |= tests[i]; + ret = p_fesetenv(&env); + ok(!ret, "Test %d: fesetenv returned %x\n", i, ret); + + ret = p_fetestexcept(tests[i]); + ok(ret == tests[i], "Test %d: expected %x, got %x\n", i, tests[i], ret); + + flags |= tests[i]; + ret = p_fetestexcept(FE_ALL_EXCEPT); + ok(ret == flags, "Test %d: expected %x, got %x\n", i, flags, ret); + } + 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..daee644d965 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -1820,7 +1820,7 @@ @ cdecl fesetenv(ptr) msvcr120.fesetenv @ stub fesetexceptflag @ cdecl fesetround(long) msvcr120.fesetround -@ stub fetestexcept +@ cdecl fetestexcept(long) msvcr120.fetestexcept @ stub feupdateenv @ cdecl fflush(ptr) msvcr120.fflush @ cdecl fgetc(ptr) msvcr120.fgetc diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index d6b0d9422e7..6c1d665c843 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -2214,6 +2214,14 @@ int CDECL fegetenv(fenv_t *env) env->_Fe_stat = _statusfp(); return 0; } + +/********************************************************************* + * fetestexcept (MSVCR120.@) + */ +int CDECL fetestexcept(int flags) +{ + return _statusfp() & flags; +} #endif
#if _MSVCR_VER>=140 diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 0a8d74521f5..d40df5e0efc 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2296,7 +2296,7 @@ @ cdecl fesetenv(ptr) @ stub fesetexceptflag @ cdecl fesetround(long) -@ stub fetestexcept +@ cdecl fetestexcept(long) @ cdecl fflush(ptr) @ cdecl fgetc(ptr) @ cdecl fgetpos(ptr ptr) diff --git a/include/msvcrt/fenv.h b/include/msvcrt/fenv.h index 92b341bd46b..3dcbcf0b8fe 100644 --- a/include/msvcrt/fenv.h +++ b/include/msvcrt/fenv.h @@ -34,6 +34,7 @@ _ACRTIMP int __cdecl fegetenv(fenv_t*); _ACRTIMP int __cdecl fesetenv(const fenv_t*); _ACRTIMP int __cdecl fegetround(void); _ACRTIMP int __cdecl fesetround(int); +_ACRTIMP int __cdecl fetestexcept(int);
#ifdef __cplusplus }