From 43942e1ab5cccd54be3fc74fe926bcceb8e03ebb Mon Sep 17 00:00:00 2001
From: Lukas Nellen <lukas@nucleares.unam.mx>
Date: Tue, 15 Jan 2019 18:43:26 -0600
Subject: [PATCH] Refactor cfenv feature handling - more robust and flexible

Test for missing functions
Provide implementation for OS X and (incomplete) fallback for
unknown platforms
---
 Framework/Utilities/CMakeLists.txt            | 20 +++++++++-
 Framework/Utilities/CorsikaFenv.h             |  6 ++-
 Framework/Utilities/CorsikaFenvDefault.cc     | 20 ++++++++++
 Framework/Utilities/CorsikaFenvFallback.cc    | 37 +++++++++++++++++++
 .../{CorsikaFenv.cc => CorsikaFenvOSX.cc}     | 34 +----------------
 Framework/Utilities/try_feenableexcept.cc     | 24 ++++++++++++
 6 files changed, 106 insertions(+), 35 deletions(-)
 create mode 100644 Framework/Utilities/CorsikaFenvDefault.cc
 create mode 100644 Framework/Utilities/CorsikaFenvFallback.cc
 rename Framework/Utilities/{CorsikaFenv.cc => CorsikaFenvOSX.cc} (66%)
 create mode 100644 Framework/Utilities/try_feenableexcept.cc

diff --git a/Framework/Utilities/CMakeLists.txt b/Framework/Utilities/CMakeLists.txt
index 4f68582b0..2f9b8e1e4 100644
--- a/Framework/Utilities/CMakeLists.txt
+++ b/Framework/Utilities/CMakeLists.txt
@@ -1,8 +1,26 @@
+#
+# cfenv feature test - select implementation to use
+#
+try_compile (HAS_FEENABLEEXCEPT "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/try_feenableexcept.cc")
+if (HAS_FEENABLEEXCEPT)
+  set (CORSIKA_FENV "CorsikaFenvDefault.cc")
+  set_property(DIRECTORY ${CMAKE_HOME_DIRECTORY} APPEND PROPERTY COMPILE_DEFINITIONS "HAS_FEENABLEEXCEPT")
+else ()
+  if (APPLE)
+    set (CORSIKA_FENV "CorsikaFenvOSX.cc")
+  else()
+    set (CORSIKA_FENV "CorsikaFenvFallback.cc")
+  endif()
+endif ()
 
+
+#
+# library setup
+#
 set (
   UTILITIES_SOURCES  
   COMBoost.cc
-  CorsikaFenv.cc)
+  ${CORSIKA_FENV})
 
 set (
   UTILITIES_HEADERS
diff --git a/Framework/Utilities/CorsikaFenv.h b/Framework/Utilities/CorsikaFenv.h
index eeaecef96..e1977d6d2 100644
--- a/Framework/Utilities/CorsikaFenv.h
+++ b/Framework/Utilities/CorsikaFenv.h
@@ -21,7 +21,10 @@
 
 #include <cfenv>
 
-#if !defined(__GLIBC__)
+/*
+ * Same declaration of function as provided in GLIBC
+ * Repetition allowed in the case where cfenv defines the functions already, no clash.
+ */
 extern "C" {
 
   int
@@ -30,6 +33,5 @@ extern "C" {
   fedisableexcept(int excepts);
 
 }
-#endif
 
 #endif //CORSIKA_CORSIKAFENV_H
diff --git a/Framework/Utilities/CorsikaFenvDefault.cc b/Framework/Utilities/CorsikaFenvDefault.cc
new file mode 100644
index 000000000..f51fe55dc
--- /dev/null
+++ b/Framework/Utilities/CorsikaFenvDefault.cc
@@ -0,0 +1,20 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ *
+ * Versions of feenableexcept() and fedisableexcept()
+ * exist in fenv.h / cfenv headers for C 99 or C++ 11
+ * Nothing needed.
+ *
+ *
+ * \author Lukas Nellen
+ * \date 14 Jan 2019
+ *
+ */
+
+// do nothing, functions exist in system libraries
diff --git a/Framework/Utilities/CorsikaFenvFallback.cc b/Framework/Utilities/CorsikaFenvFallback.cc
new file mode 100644
index 000000000..ad495c4d3
--- /dev/null
+++ b/Framework/Utilities/CorsikaFenvFallback.cc
@@ -0,0 +1,37 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ *
+ * Provide fallback versions of feenableexcept() and fedisableexcept()
+ * Don't exist in the standard
+ * fenv.h / cfenv headers for C 99 or C++ 11
+ *
+ * For platforms without implementation; do-nothing dummy.
+ *
+ * \author Lukas Nellen
+ * \date 14 Jan 2019
+ *
+ */
+
+#include <corsika/utl/CorsikaFenv.h>
+#include <cfenv>
+
+extern "C" {
+#warning No enabling/disabling of floating point exceptions - platform needs better implementation
+
+  int feenableexcept(int excepts)
+  {
+    return -1;
+  }
+
+  int fedisableexcept(int excepts)
+  {
+    return -1;
+  }
+
+}
diff --git a/Framework/Utilities/CorsikaFenv.cc b/Framework/Utilities/CorsikaFenvOSX.cc
similarity index 66%
rename from Framework/Utilities/CorsikaFenv.cc
rename to Framework/Utilities/CorsikaFenvOSX.cc
index 145adb476..224e04e73 100644
--- a/Framework/Utilities/CorsikaFenv.cc
+++ b/Framework/Utilities/CorsikaFenvOSX.cc
@@ -1,11 +1,5 @@
 /**
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * See file AUTHORS for a list of contributors.
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
+ * Import public domain code
  *
  * Provide portable or fallback versions of feenableexcept() and fedisableexcept()
  * Exist by default in glibc since version 2.2, but not in the standard
@@ -19,11 +13,7 @@
 #include <corsika/utl/CorsikaFenv.h>
 #include <cfenv>
 
-#if defined(__GLIBC__)
-// do nothing functions exist
-
-#elif defined(__APPLE__) && defined(__MACH__)
-// Implementation of OS X on intel X64_86
+// Implementation for OS X on intel X64_86
 // code from https://stackoverflow.com/questions/37819235/how-do-you-enable-floating-point-exceptions-for-clang-in-os-x
 // based on http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
 
@@ -68,23 +58,3 @@ extern "C" {
   }
 
 }
-
-#else
-// unknown environment, dummy implementations
-
-extern "C" {
-#warning No enabling/disabling of floating point exceptions
-
-  int feenableexcept(int excepts)
-  {
-    return -1;
-  }
-
-  int fedisableexcept(int excepts)
-  {
-    return -1;
-  }
-
-}
-
-#endif
diff --git a/Framework/Utilities/try_feenableexcept.cc b/Framework/Utilities/try_feenableexcept.cc
new file mode 100644
index 000000000..270307b40
--- /dev/null
+++ b/Framework/Utilities/try_feenableexcept.cc
@@ -0,0 +1,24 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ *
+ * Test code for cmake to check if feenableexcept exists in cfenv
+ *
+ * \author Lukas Nellen
+ * \date 15 Jan 2019
+ *
+ */
+
+#include <cfenv>
+
+int
+main()
+{
+  feenableexcept(FE_ALL_EXCEPT);
+  return 0;
+}
\ No newline at end of file
-- 
GitLab