ntp_assert.h revision 290001
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
33extern void calysto_assume(unsigned char cnd); /* assume this always holds */
34extern 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