Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / ep / ep_assert.h @ master

History | View | Annotate | Download (5.62 KB)

1
/* vim: set ai sw=8 sts=8 ts=8 :*/
2

    
3
/***********************************************************************
4
**  ----- BEGIN LICENSE BLOCK -----
5
**        LIBEP: Enhanced Portability Library (Reduced Edition)
6
**
7
**        Copyright (c) 2008-2019, Eric P. Allman.  All rights reserved.
8
**        Copyright (c) 2015-2019, Regents of the University of California.
9
**        All rights reserved.
10
**
11
**        Permission is hereby granted, without written agreement and without
12
**        license or royalty fees, to use, copy, modify, and distribute this
13
**        software and its documentation for any purpose, provided that the above
14
**        copyright notice and the following two paragraphs appear in all copies
15
**        of this software.
16
**
17
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
18
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
19
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
20
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
**
22
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
25
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
26
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
27
**        OR MODIFICATIONS.
28
**  ----- END LICENSE BLOCK -----
29
***********************************************************************/
30

    
31

    
32
/*
33
**  ASSERTIONS
34
**
35
**        Normally assertions are _not_ fatal.  This can be changed either
36
**        by the swarm.gdp.debug.assert.allabort runtime parameter or
37
**        by setting the EpAssertAllAbort global variable.  If either
38
**        is set, then all assertions (actually all calls to
39
**        _ep_assert_printv) cause immediate death.  This is to simplify
40
**        debugging, where ignoring an assertion could result in cascading
41
**        failures.
42
**
43
**        There are multiple ways to test assertions.
44
**
45
**                EP_ASSERT(condition)
46
**
47
**        If condition evaluates false, a message is printed and the
48
**        macro returns false, unless one of the previously mentioned
49
**        parameters indicate that abort should be immediate, in which
50
**        case the process exits.
51
**
52
**        Since the EP_ASSERT returns the boolean result of the condition
53
**        (equivalent to returning !!condition), recovery can be
54
**        performed by testing the result, e.g.,
55
**
56
**                if (!EP_ASSERT(condition))
57
**                        do recovery;
58
**
59
**        A bit of syntactic sugar permits us to use:
60
**
61
**                EP_ASSERT_ELSE(condition, do recovery)
62
**
63
**        If the condition test is unneeded, just the error action
64
**        can be performed using EP_ASSERT_FAILURE or EP_ASSERT_PRINT;
65
**        the first aborts the process (unconditionally) and the second
66
**        behaves like EP_ASSERT with a false condition.
67
**
68
**        If the EpAssertInfo function pointer is set, that function
69
**        will be called as part of the process of printing the error.
70
**        It can be used to dump global state.  It is called before
71
**        EpAssertAllAbort is tested, so it can set that variable true
72
**        if it wants the process to exit immediately.
73
**
74
**        If the process does abort and EpAssertAbort is set, that
75
**        function is called immediately before the process exits.
76
**        If it returns, abort(3) is called.  It could, for example,
77
**        kill the current thread as opposed to the current process.
78
**
79
**        If _EP_CCCF_ASSERT_NONE is set during compilation, then all
80
**        assertions are compiled out.
81
*/
82

    
83

    
84
#ifndef _EP_ASSERT_H_
85
#define _EP_ASSERT_H_
86

    
87
#include "ep.h"
88

    
89
__BEGIN_DECLS
90

    
91
#if !_EP_CCCF_ASSERT_NONE
92

    
93
// assert that an expression must be true
94
#define EP_ASSERT(e)                                                        \
95
                ((e)                                                        \
96
                        ? (true)                                        \
97
                        : (ep_assert_print(__FILE__, __LINE__,                \
98
                                        "%s", #e), false))
99

    
100
// test for condition (a bit odd because the macro is true if the
101
// expression is false)  [DEPRECATED]
102
#define EP_ASSERT_TEST(e)                                                \
103
                ((e)                                                        \
104
                        ? (false)                                        \
105
                        : (ep_assert_print(__FILE__, __LINE__,                \
106
                                        "%s", #e), true))
107

    
108
// assert condition with recovery (note: doesn't use do ... while (false)
109
// paradigm to allow break & continue in recovery actions)
110
#define EP_ASSERT_ELSE(e, r)                                                \
111
                if (!(e))                                                \
112
                {                                                        \
113
                        ep_assert_print(__FILE__, __LINE__,                \
114
                                        "%s", #e);                        \
115
                        r;                                                \
116
                }
117

    
118

    
119
// force assertion failure and abort
120
#define EP_ASSERT_FAILURE(...)                                                \
121
                ep_assert_failure(__FILE__, __LINE__, __VA_ARGS__)
122

    
123
// print assertion failure and optionally continue
124
#define EP_ASSERT_PRINT(...)                                                \
125
                ep_assert_print(__FILE__, __LINE__, __VA_ARGS__)
126

    
127
// force abort due to assertion failure (should be called ep_assert_abort)
128
extern void EP_TYPE_PRINTFLIKE(3, 4)
129
                ep_assert_failure(
130
                        const char *file,
131
                        int line,
132
                        const char *msg,
133
                        ...)
134
                        EP_ATTR_NORETURN;
135

    
136
// print an assertion failure, but generally won't cause an abort
137
extern void        ep_assert_printv(
138
                        const char *file,
139
                        int line,
140
                        const char *msg,
141
                        va_list av);
142

    
143
extern void EP_TYPE_PRINTFLIKE(3, 4)
144
                ep_assert_print(
145
                        const char *file,
146
                        int line,
147
                        const char *msg,
148
                        ...);
149

    
150
#else // _EP_CCCF_ASSERT_NONE
151

    
152
#define EP_ASSERT(e)                        true
153
#define EP_ASSERT_TEST(e)                false
154
#define EP_ASSERT_ELSE(e, r)
155
#define EP_ASSERT_FAILURE(...)
156
#define EP_ASSERT_PRINT(...)
157
#define ep_assert_failure(f, l, m, ...)
158
#define ep_assert_printv(f, l, m, av)
159
#define ep_assert_print(f, l, m, ...)
160

    
161
#endif // _EP_CCCF_ASSERT_NONE
162

    
163
// callback functions
164
extern void        (*EpAssertInfo)(void);                // show additional info
165
extern void        (*EpAssertAbort)(void);                // abort the thread/process
166

    
167
// control flags
168
extern bool        EpAssertAllAbort;                // abort on all assertions
169

    
170
// back compatibility --- these are deprecated
171
#define EP_ASSERT_REQUIRE(e)                EP_ASSERT(e)
172
#define EP_ASSERT_ENSURE(e)                EP_ASSERT(e)
173
#define EP_ASSERT_INSIST(e)                EP_ASSERT(e)
174
#define EP_ASSERT_INVARIANT(e)                EP_ASSERT(e)
175

    
176
__END_DECLS
177

    
178
#endif /*_EP_ASSERT_H_*/