1 /* 2 * ntp_assert.h - design by contract stuff 3 * 4 * example: 5 * 6 * int foo(char *a) { 7 * int result; 8 * int value; 9 * 10 * REQUIRE(a != NULL); 11 * ... 12 * bar(&value); 13 * INSIST(value > 2); 14 * ... 15 * 16 * ENSURE(result != 12); 17 * return result; 18 * } 19 * 20 * open question: when would we use INVARIANT()? 21 * 22 * For cases where the overhead for non-debug builds is deemed too high, 23 * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or 24 * DEBUG_INVARIANT(). 25 */ 26 27 #ifndef NTP_ASSERT_H 28 #define NTP_ASSERT_H 29 30 # ifdef CALYSTO 31 /* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */ 32 33 extern void calysto_assume(unsigned char cnd); /* assume this always holds */ 34 extern void calysto_assert(unsigned char cnd); /* check whether this holds */ 35 #define ALWAYS_REQUIRE(x) calysto_assert(x) 36 #define ALWAYS_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */ 37 #define ALWAYS_INVARIANT(x) calysto_assume(x) 38 #define ALWAYS_ENSURE(x) calysto_assert(x) 39 40 /* # elif defined(__COVERITY__) */ 41 /* 42 * DH: try letting coverity scan our actual assertion macros, now that 43 * isc_assertioncallback_t is marked __attribute__ __noreturn__. 44 */ 45 46 /* 47 * Coverity has special knowledge that assert(x) terminates the process 48 * if x is not true. Rather than teach it about our assertion macros, 49 * just use the one it knows about for Coverity Prevent scans. This 50 * means our assertion code (and ISC's) escapes Coverity analysis, but 51 * that seems to be a reasonable trade-off. 52 */ 53 54 /* 55 #define ALWAYS_REQUIRE(x) assert(x) 56 #define ALWAYS_INSIST(x) assert(x) 57 #define ALWAYS_INVARIANT(x) assert(x) 58 #define ALWAYS_ENSURE(x) assert(x) 59 */ 60 61 62 #elif defined(__FLEXELINT__) 63 64 #include <assert.h> 65 66 #define ALWAYS_REQUIRE(x) assert(x) 67 #define ALWAYS_INSIST(x) assert(x) 68 #define ALWAYS_INVARIANT(x) assert(x) 69 #define ALWAYS_ENSURE(x) assert(x) 70 71 # else /* neither Calysto, Coverity or FlexeLint */ 72 73 #include "isc/assertions.h" 74 75 #define ALWAYS_REQUIRE(x) ISC_REQUIRE(x) 76 #define ALWAYS_INSIST(x) ISC_INSIST(x) 77 #define ALWAYS_INVARIANT(x) ISC_INVARIANT(x) 78 #define ALWAYS_ENSURE(x) ISC_ENSURE(x) 79 80 # endif /* neither Coverity nor Calysto */ 81 82 #define REQUIRE(x) ALWAYS_REQUIRE(x) 83 #define INSIST(x) ALWAYS_INSIST(x) 84 #define INVARIANT(x) ALWAYS_INVARIANT(x) 85 #define ENSURE(x) ALWAYS_ENSURE(x) 86 87 /* 88 * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that 89 * is unneccesarily verbose, as libisc use of REQUIRE() etc shows. 90 */ 91 92 # ifdef DEBUG 93 #define DEBUG_REQUIRE(x) REQUIRE(x) 94 #define DEBUG_INSIST(x) INSIST(x) 95 #define DEBUG_INVARIANT(x) INVARIANT(x) 96 #define DEBUG_ENSURE(x) ENSURE(x) 97 # else 98 #define DEBUG_REQUIRE(x) do {} while (FALSE) 99 #define DEBUG_INSIST(x) do {} while (FALSE) 100 #define DEBUG_INVARIANT(x) do {} while (FALSE) 101 #define DEBUG_ENSURE(x) do {} while (FALSE) 102 # endif 103 104 #endif /* NTP_ASSERT_H */ 105