summaryrefslogtreecommitdiffstats
path: root/src/lib/netlist/plib/pexception.cpp
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2017-01-04 18:00:38 +0100
committer couriersud <couriersud@arcor.de>2017-01-04 18:01:22 +0100
commit78ef96336e916fe0adbc313cbf706c413fcc75aa (patch)
treea7e2965e5e98cd2a502dab35b975aa610c3e1171 /src/lib/netlist/plib/pexception.cpp
parent85d1aca315bf336ca0f4cc51ba035f1607903cf8 (diff)
Added SIGFPE enabling code to plib/pexception.*. Moved plib exceptions
into these files as well. The code uses <cfenv> which is part of c++11 standard. Non-standard glib extensions are currently only used on linux and (i386 or x86_64). (nw)
Diffstat (limited to 'src/lib/netlist/plib/pexception.cpp')
-rw-r--r--src/lib/netlist/plib/pexception.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
new file mode 100644
index 00000000000..a49fa699ce5
--- /dev/null
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -0,0 +1,109 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * palloc.c
+ *
+ */
+
+#include <cfenv>
+
+#include "pexception.h"
+#include "pfmtlog.h"
+
+#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__)
+#define HAS_FEENABLE_EXCEPT (1)
+#else
+#define HAS_FEENABLE_EXCEPT (0)
+#endif
+
+namespace plib {
+//============================================================
+// Exceptions
+//============================================================
+
+pexception::pexception(const pstring text)
+{
+ m_text = text;
+}
+
+file_e::file_e(const pstring fmt, const pstring &filename)
+ : pexception(pfmt(fmt)(filename))
+{
+}
+
+file_open_e::file_open_e(const pstring &filename)
+ : file_e("File open failed: {}", filename)
+{
+}
+
+file_read_e::file_read_e(const pstring &filename)
+ : file_e("File read failed: {}", filename)
+{
+}
+
+file_write_e::file_write_e(const pstring &filename)
+ : file_e("File write failed: {}", filename)
+{
+}
+
+null_argument_e::null_argument_e(const pstring &argument)
+ : pexception(pfmt("Null argument passed: {}")(argument))
+{
+}
+
+out_of_mem_e::out_of_mem_e(const pstring &location)
+ : pexception(pfmt("Out of memory: {}")(location))
+{
+}
+
+fpexception::fpexception(const pstring &text)
+ : pexception(pfmt("Out of memory: {}")(text))
+{
+}
+
+bool fpsignalenabler::m_enable = false;
+
+fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
+ {
+ unsigned b = 0;
+ if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
+ if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
+ if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
+ if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
+ if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
+ m_last_enabled = feenableexcept(b);
+ }
+#else
+ m_last_enabled = 0;
+#endif
+}
+
+
+fpsignalenabler::~fpsignalenabler()
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
+ {
+ fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
+ feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
+ }
+#endif
+}
+
+bool fpsignalenabler::supported()
+{
+ return true;
+}
+
+bool fpsignalenabler::global_enable(bool enable)
+{
+ bool old = m_enable;
+ m_enable = enable;
+ return old;
+}
+
+
+}