From 6431757897fca748f1d782cbafe722bd59c59ffc Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 9 May 2018 22:54:29 +0200
Subject: [PATCH] Trying to deal with Mac OS-X target

---
 src/utils/CMakeLists.txt       | 11 +++++++++
 src/utils/FPEManager.cpp       | 45 ++++++++++++++++++++++++++++++++++
 src/utils/SignalManager.cpp    |  8 +++---
 src/utils/pastis_config.hpp.in |  3 +++
 4 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt
index 935d1577a..ad047d0ea 100644
--- a/src/utils/CMakeLists.txt
+++ b/src/utils/CMakeLists.txt
@@ -83,6 +83,17 @@ add_dependencies(
 include(CheckIncludeFile)
 check_include_file(fenv.h PASTIS_HAS_FENV_H)
 
+# Checks for host system name
+if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+  set(SYSTEM_IS_LINUX 1)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+  set(SYSTEM_IS_DARWIN 1)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+  set(SYSTEM_IS_WINDOWS 1)
+else()
+  message(WARNMSG "Your system is ${CMAKE_HOST_SYSTEM_NAME} which may not be managed!")
+endif()
+
 # Generates pastis_config.hpp
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pastis_config.hpp.in"
   "${CMAKE_CURRENT_BINARY_DIR}/pastis_config.hpp"
diff --git a/src/utils/FPEManager.cpp b/src/utils/FPEManager.cpp
index 455eb6d83..176787a01 100644
--- a/src/utils/FPEManager.cpp
+++ b/src/utils/FPEManager.cpp
@@ -7,6 +7,51 @@
 
 #define MANAGED_FPE (FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW)
 
+#ifdef SYSTEM_IS_DARWIN
+// MacOS-X requires definition of feenableexcept and fedisableexcept
+
+// Public domain polyfill for feenableexcept on OS X
+// http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
+inline int feenableexcept(unsigned int excepts)
+{
+  static fenv_t fenv;
+  unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
+  // previous masks
+  unsigned int old_excepts;
+
+  if (fegetenv(&fenv)) {
+    return -1;
+  }
+  old_excepts = fenv.__control & FE_ALL_EXCEPT;
+
+  // unmask
+  fenv.__control &= ~new_excepts;
+  fenv.__mxcsr   &= ~(new_excepts << 7);
+
+  return fesetenv(&fenv) ? -1 : old_excepts;
+}
+
+inline int fedisableexcept(unsigned int excepts)
+{
+  static fenv_t fenv;
+  unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
+  // all previous masks
+  unsigned int old_excepts;
+
+  if (fegetenv(&fenv)) {
+    return -1;
+  }
+  old_excepts = fenv.__control & FE_ALL_EXCEPT;
+
+  // mask
+  fenv.__control |= new_excepts;
+  fenv.__mxcsr   |= new_excepts << 7;
+
+  return fesetenv(&fenv) ? -1 : old_excepts;
+}
+
+#endif // SYSTEM_IS_DARWIN
+
 void FPEManager::enable()
 {
   std::cout << "FE management: "
diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp
index 271720d0d..9f9da08f4 100644
--- a/src/utils/SignalManager.cpp
+++ b/src/utils/SignalManager.cpp
@@ -4,6 +4,9 @@
 #include <ConsoleManager.hpp>
 
 #include <csignal>
+#include <unistd.h>
+
+#include <pastis_config.hpp>
 #include <rang.hpp>
 
 std::string SignalManager::s_pause_on_error = "auto";
@@ -43,10 +46,7 @@ void SignalManager::pauseForDebug(const int& signal)
   std::cout  << "======================================\n";
   std::cout << std::flush;
 
-  ::sigset_t sig; 
-  ::sigaddset(&sig,SIGSTOP); 
-  ::sigsuspend(&sig); 
-
+  pause();
   std::exit(signal);
 }
 
diff --git a/src/utils/pastis_config.hpp.in b/src/utils/pastis_config.hpp.in
index b415195c0..aa8d0505a 100644
--- a/src/utils/pastis_config.hpp.in
+++ b/src/utils/pastis_config.hpp.in
@@ -2,5 +2,8 @@
 #define PASTIS_CONFIG_HPP
 
 #cmakedefine PASTIS_HAS_FENV_H
+#cmakedefine SYSTEM_IS_LINUX
+#cmakedefine SYSTEM_IS_DARWIN
+#cmakedefine SYSTEM_IS_WINDOWS
 
 #endif // PASTIS_CONFIG_HPP
-- 
GitLab