Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / ep / ep_assert.h @ master

History | View | Annotate | Download (5.62 KB)

1 a901db09 Eric Allman
/* vim: set ai sw=8 sts=8 ts=8 :*/
2 0c663d10 Eric Allman
3 47c6ea64 Eric Allman
/***********************************************************************
4 055d3009 Eric Allman
**  ----- BEGIN LICENSE BLOCK -----
5
**        LIBEP: Enhanced Portability Library (Reduced Edition)
6
**
7 c87dd166 Eric Allman
**        Copyright (c) 2008-2019, Eric P. Allman.  All rights reserved.
8
**        Copyright (c) 2015-2019, Regents of the University of California.
9 6bd5476b Eric Allman
**        All rights reserved.
10 055d3009 Eric Allman
**
11 6bd5476b Eric Allman
**        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 055d3009 Eric Allman
**
17 6bd5476b Eric Allman
**        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 055d3009 Eric Allman
**
22 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 6bd5476b Eric Allman
**        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 055d3009 Eric Allman
**  ----- END LICENSE BLOCK -----
29 47c6ea64 Eric Allman
***********************************************************************/
30
31 8d7fc458 Eric Allman
32
/*
33
**  ASSERTIONS
34
**
35 2a8cda22 Eric Allman
**        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 8d7fc458 Eric Allman
**
43 2a8cda22 Eric Allman
**        There are multiple ways to test assertions.
44 8d7fc458 Eric Allman
**
45 2a8cda22 Eric Allman
**                EP_ASSERT(condition)
46 8d7fc458 Eric Allman
**
47 2a8cda22 Eric Allman
**        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 8d7fc458 Eric Allman
**
52 2a8cda22 Eric Allman
**        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 8d7fc458 Eric Allman
**
56 2a8cda22 Eric Allman
**                if (!EP_ASSERT(condition))
57
**                        do recovery;
58 8d7fc458 Eric Allman
**
59 2a8cda22 Eric Allman
**        A bit of syntactic sugar permits us to use:
60 8d7fc458 Eric Allman
**
61 2a8cda22 Eric Allman
**                EP_ASSERT_ELSE(condition, do recovery)
62 8d7fc458 Eric Allman
**
63 2a8cda22 Eric Allman
**        If the condition test is unneeded, just the error action
64 8d7fc458 Eric Allman
**        can be performed using EP_ASSERT_FAILURE or EP_ASSERT_PRINT;
65 2a8cda22 Eric Allman
**        the first aborts the process (unconditionally) and the second
66
**        behaves like EP_ASSERT with a false condition.
67 8d7fc458 Eric Allman
**
68
**        If the EpAssertInfo function pointer is set, that function
69
**        will be called as part of the process of printing the error.
70 2a8cda22 Eric Allman
**        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 8d7fc458 Eric Allman
**
74 2a8cda22 Eric Allman
**        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 8c7bf496 Eric Allman
**
79
**        If _EP_CCCF_ASSERT_NONE is set during compilation, then all
80
**        assertions are compiled out.
81 8d7fc458 Eric Allman
*/
82
83 47c6ea64 Eric Allman
84
#ifndef _EP_ASSERT_H_
85
#define _EP_ASSERT_H_
86
87 ddbd01b3 Eric Allman
#include "ep.h"
88 8bafd0b6 Eric Allman
89 e844af35 Eric Allman
__BEGIN_DECLS
90
91 8c7bf496 Eric Allman
#if !_EP_CCCF_ASSERT_NONE
92
93 47c6ea64 Eric Allman
// assert that an expression must be true
94 8d7fc458 Eric Allman
#define EP_ASSERT(e)                                                        \
95
                ((e)                                                        \
96 2a8cda22 Eric Allman
                        ? (true)                                        \
97
                        : (ep_assert_print(__FILE__, __LINE__,                \
98
                                        "%s", #e), false))
99 47c6ea64 Eric Allman
100 2a8cda22 Eric Allman
// test for condition (a bit odd because the macro is true if the
101
// expression is false)  [DEPRECATED]
102 8d7fc458 Eric Allman
#define EP_ASSERT_TEST(e)                                                \
103
                ((e)                                                        \
104
                        ? (false)                                        \
105
                        : (ep_assert_print(__FILE__, __LINE__,                \
106
                                        "%s", #e), true))
107 47c6ea64 Eric Allman
108 8c7bf496 Eric Allman
// assert condition with recovery (note: doesn't use do ... while (false)
109
// paradigm to allow break & continue in recovery actions)
110 8d7fc458 Eric Allman
#define EP_ASSERT_ELSE(e, r)                                                \
111 8c7bf496 Eric Allman
                if (!(e))                                                \
112
                {                                                        \
113
                        ep_assert_print(__FILE__, __LINE__,                \
114
                                        "%s", #e);                        \
115
                        r;                                                \
116
                }
117
118
119
// force assertion failure and abort
120 8d7fc458 Eric Allman
#define EP_ASSERT_FAILURE(...)                                                \
121 8c7bf496 Eric Allman
                ep_assert_failure(__FILE__, __LINE__, __VA_ARGS__)
122 47c6ea64 Eric Allman
123 2a8cda22 Eric Allman
// print assertion failure and optionally continue
124 8d7fc458 Eric Allman
#define EP_ASSERT_PRINT(...)                                                \
125 8c7bf496 Eric Allman
                ep_assert_print(__FILE__, __LINE__, __VA_ARGS__)
126 bb6cf5bf Eric Allman
127 2a8cda22 Eric Allman
// force abort due to assertion failure (should be called ep_assert_abort)
128 e0adeb80 Eric Allman
extern void EP_TYPE_PRINTFLIKE(3, 4)
129
                ep_assert_failure(
130 47c6ea64 Eric Allman
                        const char *file,
131 6dce256d Eric Allman
                        int line,
132
                        const char *msg,
133
                        ...)
134 8bafd0b6 Eric Allman
                        EP_ATTR_NORETURN;
135 47c6ea64 Eric Allman
136 2a8cda22 Eric Allman
// print an assertion failure, but generally won't cause an abort
137 8d7fc458 Eric Allman
extern void        ep_assert_printv(
138
                        const char *file,
139
                        int line,
140
                        const char *msg,
141
                        va_list av);
142
143 e0adeb80 Eric Allman
extern void EP_TYPE_PRINTFLIKE(3, 4)
144
                ep_assert_print(
145 8d7fc458 Eric Allman
                        const char *file,
146
                        int line,
147
                        const char *msg,
148
                        ...);
149
150 8c7bf496 Eric Allman
#else // _EP_CCCF_ASSERT_NONE
151
152 2a8cda22 Eric Allman
#define EP_ASSERT(e)                        true
153 8c7bf496 Eric Allman
#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 8d7fc458 Eric Allman
// callback functions
164
extern void        (*EpAssertInfo)(void);                // show additional info
165
extern void        (*EpAssertAbort)(void);                // abort the thread/process
166
167 ddbd01b3 Eric Allman
// control flags
168
extern bool        EpAssertAllAbort;                // abort on all assertions
169
170 8d7fc458 Eric Allman
// 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 47c6ea64 Eric Allman
176 e844af35 Eric Allman
__END_DECLS
177
178 47c6ea64 Eric Allman
#endif /*_EP_ASSERT_H_*/