summaryrefslogtreecommitdiff
path: root/src/_safety.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/_safety.h')
-rw-r--r--src/_safety.h71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/_safety.h b/src/_safety.h
new file mode 100644
index 00000000..5fd70493
--- /dev/null
+++ b/src/_safety.h
@@ -0,0 +1,71 @@
+#ifndef ___ASSERT_H__
+#define ___ASSERT_H__
+
+#include <errno.h>
+#include <stdio.h>
+#include "stdlib/_stdlib.h"
+#include "signal/_signal.h"
+
+#if 0
+_Thread_local
+#endif
+extern struct __checked_call {
+ char *file;
+ char *func;
+ unsigned long long line;
+} __checked_call;
+
+#ifndef NDEBUG
+#define ASSERT_NONNULL(__ptr) do { \
+ if (!__ptr) { \
+ struct __constraint_info _ci = {0}; \
+ _ci.func = __func__; \
+ __stdlib.constraint_handler("Undefined behavior: " \
+ "Parameter " #__ptr " can not be NULL", &_ci, 0 /* was EFAULT */); \
+ } \
+} while (0)
+
+#define ASSERT_NONZERO(__n) do { \
+ if (!__n) { \
+ struct __constraint_info _ci = {0}; \
+ _ci.func = __func__; \
+ __stdlib.constraint_handler("Undefined behavior: " \
+ "Parameter " #__n " can not be 0", &_ci, ERANGE); \
+ } \
+} while (0)
+
+#define ASSERT_NOOVERLAP(__x, __y, __s) do { \
+ /* TODO */ \
+} while (0)
+
+#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) do { \
+ if (!(((_n) == (_sentinel)) || (((_min) <= (_n)) && ((_n) <= (_max))))) { \
+ struct __constraint_info _ci = {0}; \
+ _ci.func = __func__; \
+ _ci.value = _n; \
+ __stdlib.constraint_handler("Undefined behavior: " \
+ "Parameter " #_n " must be representable as a " #_type \
+ " or be equal to " #_sentinel, &_ci, ERANGE); \
+ } \
+ } while (0)
+
+#define SIGNAL_SAFE(__n) do { \
+ if (__n == 0 && __signal.current != 0) { \
+ struct __constraint_info _ci = {0}; \
+ _ci.func = __func__; \
+ _ci.value = __signal.current; \
+ __stdlib.constraint_handler("Undefined behavior: " \
+ "Standard library function called from signal handler", \
+ &_ci, 0); \
+ } \
+} while (0)
+#else
+
+#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel)
+#define ASSERT_NOOVERLAP(__x, __y, __s)
+#define ASSERT_NONNULL(x)
+#define ASSERT_NONZERO(n)
+
+#endif
+
+#endif