[PATCH 1/4] msvcr120: Add fegetexceptflag.

Daniel Lehman dlehman25 at gmail.com
Mon Mar 1 22:06:57 CST 2021


Signed-off-by: Daniel Lehman <dlehman25 at 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);
 
-- 
2.25.1




More information about the wine-devel mailing list