[PATCH 3/4] msvcr120: Add fesetexceptflag.

Daniel Lehman dlehman25 at gmail.com
Mon Mar 1 22:06:59 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                | 50 ++++++++++++++++++-
 dlls/msvcr120_app/msvcr120_app.spec           |  2 +-
 dlls/msvcrt/math.c                            | 20 ++++++++
 dlls/ucrtbase/ucrtbase.spec                   |  2 +-
 include/msvcrt/fenv.h                         |  1 +
 7 files changed, 74 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 1d0b6e06b7c..610af8e436b 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
@@ -93,7 +93,7 @@
 @ cdecl fegetround() ucrtbase.fegetround
 @ stub feholdexcept
 @ cdecl fesetenv(ptr) ucrtbase.fesetenv
-@ stub fesetexceptflag
+@ cdecl fesetexceptflag(ptr long) ucrtbase.fesetexceptflag
 @ cdecl fesetround(long) ucrtbase.fesetround
 @ cdecl fetestexcept(long) ucrtbase.fetestexcept
 @ cdecl perror(str) ucrtbase.perror
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index d9628883f34..430124740bb 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -2152,7 +2152,7 @@
 @ stub feraiseexcept
 @ cdecl ferror(ptr)
 @ cdecl fesetenv(ptr)
-@ stub fesetexceptflag
+@ cdecl fesetexceptflag(ptr long)
 @ cdecl fesetround(long)
 @ cdecl fetestexcept(long)
 @ stub feupdateenv
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c
index a34c336d94d..5266e73a3a0 100644
--- a/dlls/msvcr120/tests/msvcr120.c
+++ b/dlls/msvcr120/tests/msvcr120.c
@@ -183,6 +183,7 @@ 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_fesetexceptflag)(const fexcept_t*,int);
 static int (CDECL *p_fetestexcept)(int);
 static int (CDECL *p__clearfp)(void);
 static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *);
@@ -260,6 +261,7 @@ static BOOL init(void)
     SET(p_fegetround, "fegetround");
     SET(p_fesetround, "fesetround");
     SET(p_fegetexceptflag, "fegetexceptflag");
+    SET(p_fesetexceptflag, "fesetexceptflag");
     SET(p_fetestexcept, "fetestexcept");
 
     SET(p__clearfp, "_clearfp");
@@ -808,6 +810,15 @@ static void test_feenv(void)
         { FE_ALL_EXCEPT, ~0,             FE_ALL_EXCEPT },
         { FE_ALL_EXCEPT, ~FE_ALL_EXCEPT, 0 },
     };
+    static const unsigned long tests2[] = {
+        0,
+        FE_INEXACT,
+        FE_UNDERFLOW,
+        FE_OVERFLOW,
+        FE_DIVBYZERO,
+        FE_INVALID,
+        FE_ALL_EXCEPT,
+    };
     fenv_t env, env2;
     fexcept_t except;
     int i, ret;
@@ -829,8 +840,10 @@ static void test_feenv(void)
     ret = p_fegetround();
     ok(ret == FE_TONEAREST, "Got unexpected round mode %#x.\n", ret);
 
-    if(0) /* crashes on windows */
+    if(0) { /* crashes on windows */
         p_fegetexceptflag(NULL, 0);
+        p_fesetexceptflag(NULL, FE_ALL_EXCEPT);
+    }
 
     for(i=0; i<ARRAY_SIZE(tests); i++) {
         env._Fe_stat = tests[i].set;
@@ -846,6 +859,41 @@ static void test_feenv(void)
         ok(except == tests[i].expect, "expected %lx, got %lx\n", tests[i].expect, except);
     }
 
+    ret = p_fesetexceptflag(NULL, 0);
+    ok(!ret, "fesetexceptflag returned %x\n", ret);
+
+    for(i=0; i<ARRAY_SIZE(tests2); i++) {
+        p__clearfp();
+
+        except = FE_ALL_EXCEPT;
+        ret = p_fesetexceptflag(&except, tests2[i]);
+        ok(!ret, "fesetexceptflag returned %x\n", ret);
+
+        except = p_fetestexcept(tests2[i]);
+        ok(except == tests2[i], "expected %lx, got %lx\n", tests2[i], except);
+
+        p__clearfp();
+
+        except = tests2[i];
+        ret = p_fesetexceptflag(&except, FE_ALL_EXCEPT);
+        ok(!ret, "fesetexceptflag returned %x\n", ret);
+
+        except = p_fetestexcept(tests2[i]);
+        ok(except == tests2[i], "expected %lx, got %lx\n", tests2[i], except);
+    }
+
+    except = FE_ALL_EXCEPT;
+    ret = p_fesetexceptflag(&except, 0);
+    ok(!ret, "fesetexceptflag returned %x\n", ret);
+    except = p_fetestexcept(FE_ALL_EXCEPT);
+    ok(except == FE_ALL_EXCEPT, "expected %x, got %lx\n", FE_ALL_EXCEPT, except);
+
+    except = 0;
+    ret = p_fesetexceptflag(&except, FE_ALL_EXCEPT);
+    ok(!ret, "fesetexceptflag returned %x\n", ret);
+    except = p_fetestexcept(FE_ALL_EXCEPT);
+    ok(!except, "expected 0, got %lx\n", except);
+
     p__clearfp();
 }
 
diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec
index 152eda3be81..2905f4d7b08 100644
--- a/dlls/msvcr120_app/msvcr120_app.spec
+++ b/dlls/msvcr120_app/msvcr120_app.spec
@@ -1818,7 +1818,7 @@
 @ stub feraiseexcept
 @ cdecl ferror(ptr) msvcr120.ferror
 @ cdecl fesetenv(ptr) msvcr120.fesetenv
-@ stub fesetexceptflag
+@ cdecl fesetexceptflag(ptr long) msvcr120.fesetexceptflag
 @ cdecl fesetround(long) msvcr120.fesetround
 @ cdecl fetestexcept(long) msvcr120.fetestexcept
 @ stub feupdateenv
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 5ae5f2e5d6c..8157e02f94a 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -2237,6 +2237,26 @@ int CDECL fetestexcept(int flags)
     fegetexceptflag(&except, flags);
     return except;
 }
+
+/*********************************************************************
+ *      fesetexceptflag (MSVCR120.@)
+ */
+int CDECL fesetexceptflag(const fexcept_t *status, int excepts)
+{
+    fenv_t env;
+
+    if(!status)
+        return 0;
+
+    if(!*status) {
+        _clearfp();
+        return 0;
+    }
+
+    fegetenv(&env);
+    env._Fe_stat |= (*status & excepts & FE_ALL_EXCEPT);
+    return fesetenv(&env);
+}
 #endif
 
 #if _MSVCR_VER>=140
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index 4f842c58d27..e5fbc6b14b9 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -2294,7 +2294,7 @@
 @ cdecl feof(ptr)
 @ cdecl ferror(ptr)
 @ cdecl fesetenv(ptr)
-@ stub fesetexceptflag
+@ cdecl fesetexceptflag(ptr long)
 @ cdecl fesetround(long)
 @ cdecl fetestexcept(long)
 @ cdecl fflush(ptr)
diff --git a/include/msvcrt/fenv.h b/include/msvcrt/fenv.h
index 0ddb6852368..45cd0b9e534 100644
--- a/include/msvcrt/fenv.h
+++ b/include/msvcrt/fenv.h
@@ -35,6 +35,7 @@ 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 fesetexceptflag(const fexcept_t*, int);
 _ACRTIMP int __cdecl fegetround(void);
 _ACRTIMP int __cdecl fesetround(int);
 _ACRTIMP int __cdecl fetestexcept(int);
-- 
2.25.1




More information about the wine-devel mailing list