1215976Sjmallett/*
2232812Sjmallett * ntp_assert.h - design by contract stuff
3215976Sjmallett *
4215976Sjmallett * example:
5215976Sjmallett *
6215976Sjmallett * int foo(char *a) {
7215976Sjmallett *	int result;
8215976Sjmallett *	int value;
9215976Sjmallett *
10215976Sjmallett *	REQUIRE(a != NULL);
11215976Sjmallett *	...
12215976Sjmallett *	bar(&value);
13215976Sjmallett *	INSIST(value > 2);
14215976Sjmallett *	...
15215976Sjmallett *
16215976Sjmallett *	ENSURE(result != 12);
17215976Sjmallett *	return result;
18232812Sjmallett * }
19215976Sjmallett *
20215976Sjmallett * open question: when would we use INVARIANT()?
21215976Sjmallett *
22215976Sjmallett * For cases where the overhead for non-debug builds is deemed too high,
23215976Sjmallett * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
24215976Sjmallett * DEBUG_INVARIANT().
25215976Sjmallett */
26215976Sjmallett
27215976Sjmallett#ifndef NTP_ASSERT_H
28215976Sjmallett#define NTP_ASSERT_H
29232812Sjmallett
30215976Sjmallett# ifdef CALYSTO
31215976Sjmallett/* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */
32215976Sjmallett
33215976Sjmallettextern void calysto_assume(unsigned char cnd); /* assume this always holds */
34215976Sjmallettextern void calysto_assert(unsigned char cnd); /* check whether this holds */
35215976Sjmallett#define ALWAYS_REQUIRE(x)	calysto_assert(x)
36215976Sjmallett#define ALWAYS_INSIST(x)	calysto_assume(x) /* DLH calysto_assert()? */
37215976Sjmallett#define ALWAYS_INVARIANT(x)	calysto_assume(x)
38215976Sjmallett#define ALWAYS_ENSURE(x)	calysto_assert(x)
39215976Sjmallett
40215976Sjmallett/* # elif defined(__COVERITY__) */
41215976Sjmallett/*
42215976Sjmallett * DH: try letting coverity scan our actual assertion macros, now that
43215976Sjmallett * isc_assertioncallback_t is marked __attribute__ __noreturn__.
44215976Sjmallett */
45215976Sjmallett
46215976Sjmallett/*
47215976Sjmallett * Coverity has special knowledge that assert(x) terminates the process
48215976Sjmallett * if x is not true.  Rather than teach it about our assertion macros,
49215976Sjmallett * just use the one it knows about for Coverity Prevent scans.  This
50215976Sjmallett * means our assertion code (and ISC's) escapes Coverity analysis, but
51215976Sjmallett * that seems to be a reasonable trade-off.
52232812Sjmallett */
53232812Sjmallett
54215976Sjmallett/*
55215976Sjmallett#define ALWAYS_REQUIRE(x)	assert(x)
56215976Sjmallett#define ALWAYS_INSIST(x)	assert(x)
57232812Sjmallett#define ALWAYS_INVARIANT(x)	assert(x)
58232812Sjmallett#define ALWAYS_ENSURE(x)	assert(x)
59232812Sjmallett*/
60232812Sjmallett
61232812Sjmallett
62232812Sjmallett#elif defined(__FLEXELINT__)
63232812Sjmallett
64232812Sjmallett#include <assert.h>
65232812Sjmallett
66232812Sjmallett#define ALWAYS_REQUIRE(x)	assert(x)
67232812Sjmallett#define ALWAYS_INSIST(x)	assert(x)
68232812Sjmallett#define ALWAYS_INVARIANT(x)	assert(x)
69232812Sjmallett#define ALWAYS_ENSURE(x)	assert(x)
70232812Sjmallett
71232812Sjmallett# else	/* neither Calysto, Coverity or FlexeLint */
72232812Sjmallett
73232812Sjmallett#include "isc/assertions.h"
74232812Sjmallett
75232812Sjmallett#define ALWAYS_REQUIRE(x)	ISC_REQUIRE(x)
76232812Sjmallett#define ALWAYS_INSIST(x)	ISC_INSIST(x)
77232812Sjmallett#define ALWAYS_INVARIANT(x)	ISC_INVARIANT(x)
78232812Sjmallett#define ALWAYS_ENSURE(x)	ISC_ENSURE(x)
79232812Sjmallett
80232812Sjmallett# endif /* neither Coverity nor Calysto */
81215976Sjmallett
82215976Sjmallett#define	REQUIRE(x)		ALWAYS_REQUIRE(x)
83215976Sjmallett#define	INSIST(x)		ALWAYS_INSIST(x)
84215976Sjmallett#define	INVARIANT(x)		ALWAYS_INVARIANT(x)
85232812Sjmallett#define	ENSURE(x)		ALWAYS_ENSURE(x)
86232812Sjmallett
87232812Sjmallett/*
88232812Sjmallett * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
89232812Sjmallett * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
90232812Sjmallett */
91232812Sjmallett
92232812Sjmallett# ifdef DEBUG
93232812Sjmallett#define	DEBUG_REQUIRE(x)	REQUIRE(x)
94232812Sjmallett#define	DEBUG_INSIST(x)		INSIST(x)
95232812Sjmallett#define	DEBUG_INVARIANT(x)	INVARIANT(x)
96232812Sjmallett#define	DEBUG_ENSURE(x)		ENSURE(x)
97232812Sjmallett# else
98232812Sjmallett#define	DEBUG_REQUIRE(x)	do {} while (FALSE)
99232812Sjmallett#define	DEBUG_INSIST(x)		do {} while (FALSE)
100232812Sjmallett#define	DEBUG_INVARIANT(x)	do {} while (FALSE)
101232812Sjmallett#define	DEBUG_ENSURE(x)		do {} while (FALSE)
102232812Sjmallett# endif
103232812Sjmallett
104232812Sjmallett#endif	/* NTP_ASSERT_H */
105232812Sjmallett