summaryrefslogtreecommitdiff
path: root/include/ntp_assert.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ntp_assert.h')
-rw-r--r--include/ntp_assert.h108
1 files changed, 108 insertions, 0 deletions
diff --git a/include/ntp_assert.h b/include/ntp_assert.h
new file mode 100644
index 0000000..2f3bbc8
--- /dev/null
+++ b/include/ntp_assert.h
@@ -0,0 +1,108 @@
+/*
+ * ntp_assert.h - design by contract stuff
+ *
+ * example:
+ *
+ * int foo(char *a) {
+ * int result;
+ * int value;
+ *
+ * REQUIRE(a != NULL);
+ * ...
+ * bar(&value);
+ * INSIST(value > 2);
+ * ...
+ *
+ * ENSURE(result != 12);
+ * return result;
+ * }
+ *
+ * open question: when would we use INVARIANT()?
+ *
+ * For cases where the overhead for non-debug builds is deemed too high,
+ * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
+ * DEBUG_INVARIANT().
+ */
+
+#ifndef NTP_ASSERT_H
+#define NTP_ASSERT_H
+
+# ifdef CALYSTO
+/* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */
+
+extern void calysto_assume(unsigned char cnd); /* assume this always holds */
+extern void calysto_assert(unsigned char cnd); /* check whether this holds */
+#define ALWAYS_REQUIRE(x) calysto_assert(x)
+#define ALWAYS_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */
+#define ALWAYS_INVARIANT(x) calysto_assume(x)
+#define ALWAYS_ENSURE(x) calysto_assert(x)
+
+/* # elif defined(__COVERITY__) */
+/*
+ * DH: try letting coverity scan our actual assertion macros, now that
+ * isc_assertioncallback_t is marked __attribute__ __noreturn__.
+ */
+
+/*
+ * Coverity has special knowledge that assert(x) terminates the process
+ * if x is not true. Rather than teach it about our assertion macros,
+ * just use the one it knows about for Coverity Prevent scans. This
+ * means our assertion code (and ISC's) escapes Coverity analysis, but
+ * that seems to be a reasonable trade-off.
+ */
+
+/*
+#define ALWAYS_REQUIRE(x) assert(x)
+#define ALWAYS_INSIST(x) assert(x)
+#define ALWAYS_INVARIANT(x) assert(x)
+#define ALWAYS_ENSURE(x) assert(x)
+*/
+
+
+#elif defined(__FLEXELINT__)
+
+#include <assert.h>
+
+#define ALWAYS_REQUIRE(x) assert(x)
+#define ALWAYS_INSIST(x) assert(x)
+#define ALWAYS_INVARIANT(x) assert(x)
+#define ALWAYS_ENSURE(x) assert(x)
+
+# else /* neither Calysto, Coverity or FlexeLint */
+
+#include "isc/assertions.h"
+
+#define ALWAYS_REQUIRE(x) ISC_REQUIRE(x)
+#define ALWAYS_INSIST(x) ISC_INSIST(x)
+#define ALWAYS_INVARIANT(x) ISC_INVARIANT(x)
+#define ALWAYS_ENSURE(x) ISC_ENSURE(x)
+
+# endif /* neither Coverity nor Calysto */
+
+#define REQUIRE(x) ALWAYS_REQUIRE(x)
+#define INSIST(x) ALWAYS_INSIST(x)
+#define INVARIANT(x) ALWAYS_INVARIANT(x)
+#define ENSURE(x) ALWAYS_ENSURE(x)
+
+/*
+ * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
+ * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
+ */
+#define NTP_REQUIRE(x) REQUIRE(x)
+#define NTP_INSIST(x) INSIST(x)
+#define NTP_INVARIANT(x) INVARIANT(x)
+#define NTP_ENSURE(x) ENSURE(x)
+
+# ifdef DEBUG
+#define DEBUG_REQUIRE(x) REQUIRE(x)
+#define DEBUG_INSIST(x) INSIST(x)
+#define DEBUG_INVARIANT(x) INVARIANT(x)
+#define DEBUG_ENSURE(x) ENSURE(x)
+# else
+#define DEBUG_REQUIRE(x) do {} while (FALSE)
+#define DEBUG_INSIST(x) do {} while (FALSE)
+#define DEBUG_INVARIANT(x) do {} while (FALSE)
+#define DEBUG_ENSURE(x) do {} while (FALSE)
+# endif
+
+#endif /* NTP_ASSERT_H */