1258945Sroberto/*
2258945Sroberto * ntp_assert.h - design by contract stuff
3258945Sroberto *
4258945Sroberto * example:
5258945Sroberto *
6258945Sroberto * int foo(char *a) {
7258945Sroberto *	int result;
8258945Sroberto *	int value;
9258945Sroberto *
10258945Sroberto *	REQUIRE(a != NULL);
11258945Sroberto *	...
12258945Sroberto *	bar(&value);
13258945Sroberto *	INSIST(value > 2);
14258945Sroberto *	...
15258945Sroberto *
16258945Sroberto *	ENSURE(result != 12);
17258945Sroberto *	return result;
18258945Sroberto * }
19258945Sroberto *
20258945Sroberto * open question: when would we use INVARIANT()?
21258945Sroberto *
22258945Sroberto * For cases where the overhead for non-debug builds is deemed too high,
23258945Sroberto * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
24258945Sroberto * DEBUG_INVARIANT().
25258945Sroberto */
26258945Sroberto
27258945Sroberto#ifndef NTP_ASSERT_H
28258945Sroberto#define NTP_ASSERT_H
29258945Sroberto
30258945Sroberto# ifdef CALYSTO
31280849Scy/* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */
32258945Sroberto
33258945Srobertoextern void calysto_assume(unsigned char cnd); /* assume this always holds */
34258945Srobertoextern void calysto_assert(unsigned char cnd); /* check whether this holds */
35258945Sroberto#define ALWAYS_REQUIRE(x)	calysto_assert(x)
36258945Sroberto#define ALWAYS_INSIST(x)	calysto_assume(x) /* DLH calysto_assert()? */
37258945Sroberto#define ALWAYS_INVARIANT(x)	calysto_assume(x)
38258945Sroberto#define ALWAYS_ENSURE(x)	calysto_assert(x)
39258945Sroberto
40258945Sroberto/* # elif defined(__COVERITY__) */
41258945Sroberto/*
42258945Sroberto * DH: try letting coverity scan our actual assertion macros, now that
43258945Sroberto * isc_assertioncallback_t is marked __attribute__ __noreturn__.
44258945Sroberto */
45258945Sroberto
46258945Sroberto/*
47258945Sroberto * Coverity has special knowledge that assert(x) terminates the process
48258945Sroberto * if x is not true.  Rather than teach it about our assertion macros,
49258945Sroberto * just use the one it knows about for Coverity Prevent scans.  This
50258945Sroberto * means our assertion code (and ISC's) escapes Coverity analysis, but
51258945Sroberto * that seems to be a reasonable trade-off.
52258945Sroberto */
53258945Sroberto
54258945Sroberto/*
55258945Sroberto#define ALWAYS_REQUIRE(x)	assert(x)
56258945Sroberto#define ALWAYS_INSIST(x)	assert(x)
57258945Sroberto#define ALWAYS_INVARIANT(x)	assert(x)
58258945Sroberto#define ALWAYS_ENSURE(x)	assert(x)
59258945Sroberto*/
60258945Sroberto
61258945Sroberto
62280849Scy#elif defined(__FLEXELINT__)
63280849Scy
64280849Scy#include <assert.h>
65280849Scy
66280849Scy#define ALWAYS_REQUIRE(x)	assert(x)
67280849Scy#define ALWAYS_INSIST(x)	assert(x)
68280849Scy#define ALWAYS_INVARIANT(x)	assert(x)
69280849Scy#define ALWAYS_ENSURE(x)	assert(x)
70280849Scy
71280849Scy# else	/* neither Calysto, Coverity or FlexeLint */
72280849Scy
73258945Sroberto#include "isc/assertions.h"
74258945Sroberto
75258945Sroberto#define ALWAYS_REQUIRE(x)	ISC_REQUIRE(x)
76258945Sroberto#define ALWAYS_INSIST(x)	ISC_INSIST(x)
77258945Sroberto#define ALWAYS_INVARIANT(x)	ISC_INVARIANT(x)
78258945Sroberto#define ALWAYS_ENSURE(x)	ISC_ENSURE(x)
79258945Sroberto
80258945Sroberto# endif /* neither Coverity nor Calysto */
81258945Sroberto
82258945Sroberto#define	REQUIRE(x)		ALWAYS_REQUIRE(x)
83258945Sroberto#define	INSIST(x)		ALWAYS_INSIST(x)
84258945Sroberto#define	INVARIANT(x)		ALWAYS_INVARIANT(x)
85258945Sroberto#define	ENSURE(x)		ALWAYS_ENSURE(x)
86258945Sroberto
87258945Sroberto/*
88258945Sroberto * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
89258945Sroberto * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
90258945Sroberto */
91258945Sroberto
92258945Sroberto# ifdef DEBUG
93258945Sroberto#define	DEBUG_REQUIRE(x)	REQUIRE(x)
94258945Sroberto#define	DEBUG_INSIST(x)		INSIST(x)
95258945Sroberto#define	DEBUG_INVARIANT(x)	INVARIANT(x)
96258945Sroberto#define	DEBUG_ENSURE(x)		ENSURE(x)
97258945Sroberto# else
98280849Scy#define	DEBUG_REQUIRE(x)	do {} while (FALSE)
99280849Scy#define	DEBUG_INSIST(x)		do {} while (FALSE)
100280849Scy#define	DEBUG_INVARIANT(x)	do {} while (FALSE)
101280849Scy#define	DEBUG_ENSURE(x)		do {} while (FALSE)
102258945Sroberto# endif
103258945Sroberto
104258945Sroberto#endif	/* NTP_ASSERT_H */
105