gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Removing fixme an log assert handler from assertion system
0 2 0
default
2 files changed with 18 insertions and 67 deletions:
↑ Collapse diff ↑
Show white space 32 line context
... ...
@@ -14,91 +14,79 @@
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Extended assertion handling
25 25

	
26 26
#include <lemon/error.h>
27 27

	
28 28
namespace lemon {
29 29

	
30
  inline void assert_fail_log(const char *file, int line, const char *function,
31
                              const char *message, const char *assertion)
30
  inline void assert_fail_abort(const char *file, int line,
31
                                const char *function, const char* message,
32
                                const char *assertion)
32 33
  {
33 34
    std::cerr << file << ":" << line << ": ";
34 35
    if (function)
35 36
      std::cerr << function << ": ";
36 37
    std::cerr << message;
37 38
    if (assertion)
38 39
      std::cerr << " (assertion '" << assertion << "' failed)";
39 40
    std::cerr << std::endl;
40
  }
41

	
42
  inline void assert_fail_abort(const char *file, int line,
43
                                const char *function, const char* message,
44
                                const char *assertion)
45
  {
46
    assert_fail_log(file, line, function, message, assertion);
47 41
    std::abort();
48 42
  }
49 43

	
50 44
  namespace _assert_bits {
51 45

	
52 46

	
53 47
    inline const char* cstringify(const std::string& str) {
54 48
      return str.c_str();
55 49
    }
56 50

	
57 51
    inline const char* cstringify(const char* str) {
58 52
      return str;
59 53
    }
60 54
  }
61 55
}
62 56

	
63 57
#endif // LEMON_ASSERT_H
64 58

	
65 59
#undef LEMON_ASSERT
66
#undef LEMON_FIXME
67 60
#undef LEMON_DEBUG
68 61

	
69
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +               \
70
  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
62
#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
71 63
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
72 64
#error "LEMON assertion system is not set properly"
73 65
#endif
74 66

	
75
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +              \
76
     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
67
#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
77 68
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
78 69
     defined(LEMON_ENABLE_ASSERTS)) &&                  \
79 70
  (defined(LEMON_DISABLE_ASSERTS) ||                    \
80 71
   defined(NDEBUG))
81 72
#error "LEMON assertion system is not set properly"
82 73
#endif
83 74

	
84 75

	
85
#if defined LEMON_ASSERT_LOG
86
#  undef LEMON_ASSERT_HANDLER
87
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
88
#elif defined LEMON_ASSERT_ABORT
76
#if defined LEMON_ASSERT_ABORT
89 77
#  undef LEMON_ASSERT_HANDLER
90 78
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 79
#elif defined LEMON_ASSERT_CUSTOM
92 80
#  undef LEMON_ASSERT_HANDLER
93 81
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
94 82
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
95 83
#  endif
96 84
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
97 85
#elif defined LEMON_DISABLE_ASSERTS
98 86
#  undef LEMON_ASSERT_HANDLER
99 87
#elif defined NDEBUG
100 88
#  undef LEMON_ASSERT_HANDLER
101 89
#else
102 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
103 91
#endif
104 92

	
... ...
@@ -107,147 +95,120 @@
107 95
#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
108 96
#  elif defined _MSC_VER
109 97
#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
110 98
#  elif __STDC_VERSION__ >= 199901L
111 99
#    define LEMON_FUNCTION_NAME (__func__)
112 100
#  else
113 101
#    define LEMON_FUNCTION_NAME ("<unknown>")
114 102
#  endif
115 103
#endif
116 104

	
117 105
#ifdef DOXYGEN
118 106

	
119 107
/// \ingroup exceptions
120 108
///
121 109
/// \brief Macro for assertion with customizable message
122 110
///
123
/// Macro for assertion with customizable message.  \param exp An
124
/// expression that must be convertible to \c bool.  If it is \c
125
/// false, then an assertion is raised. The concrete behaviour depends
126
/// on the settings of the assertion system.  \param msg A <tt>const
127
/// char*</tt> parameter, which can be used to provide information
128
/// about the circumstances of the failed assertion.
111
/// Macro for assertion with customizable message.  
112
/// \param exp An expression that must be convertible to \c bool.  If it is \c
113
/// false, then an assertion is raised. The concrete behaviour depends on the
114
/// settings of the assertion system.
115
/// \param msg A <tt>const char*</tt> parameter, which can be used to provide
116
/// information about the circumstances of the failed assertion.
129 117
///
130 118
/// The assertions are enabled in the default behaviour.
131 119
/// You can disable them with the following code:
132 120
/// \code
133 121
/// #define LEMON_DISABLE_ASSERTS
134 122
/// \endcode
135 123
/// or with compilation parameters:
136 124
/// \code
137 125
/// g++ -DLEMON_DISABLE_ASSERTS
138 126
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
139 127
/// \endcode
140 128
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
141 129
///
142
/// The LEMON assertion system has a wide range of customization
143
/// properties. As a default behaviour the failed assertion prints a
144
/// short log message to the standard error and aborts the execution.
130
/// As a default behaviour the failed assertion prints a short log message to
131
/// the standard error and aborts the execution.
145 132
///
146
/// The following modes can be used in the assertion system:
147
///
148
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
149
///   message to the standard error and continues the execution.
150
/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
151
///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
152
///   behaviour.
133
/// However, the following modes can be used in the assertion system:
134
/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
135
///   the standard error and aborts the program. It is the default behaviour.
153 136
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
154 137
///   function.
155 138
///   \code
156 139
///     void custom_assert_handler(const char* file, int line,
157 140
///                                const char* function, const char* message,
158 141
///                                const char* assertion);
159 142
///   \endcode
160 143
///   The name of the function should be defined as the \c
161 144
///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
162 145
///   \code
163 146
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
164 147
///   \endcode
165 148
///   Whenever an assertion is occured, the custom assertion
166 149
///   handler is called with appropiate parameters.
167 150
///
168 151
/// The assertion mode can also be changed within one compilation unit.
169 152
/// If the macros are redefined with other settings and the
170 153
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
171 154
/// behaviour is changed appropiately to the new settings.
172 155
#  define LEMON_ASSERT(exp, msg)                                        \
173 156
  (static_cast<void> (!!(exp) ? 0 : (                                   \
174 157
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
175 158
                         LEMON_FUNCTION_NAME,                           \
176 159
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
177 160

	
178 161
/// \ingroup exceptions
179 162
///
180
/// \brief Macro for mark not yet implemented features.
181
///
182
/// Macro for mark not yet implemented features and outstanding bugs.
183
/// It is close to be the shortcut of the following code:
184
/// \code
185
///   LEMON_ASSERT(false, msg);
186
/// \endcode
187
///
188
/// \see LEMON_ASSERT
189
#  define LEMON_FIXME(msg)                                              \
190
  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,        \
191
                        ::lemon::_assert_bits::cstringify(msg),         \
192
                        static_cast<const char*>(0)))
193

	
194
/// \ingroup exceptions
195
///
196 163
/// \brief Macro for internal assertions
197 164
///
198 165
/// Macro for internal assertions, it is used in the library to check
199 166
/// the consistency of results of algorithms, several pre- and
200 167
/// postconditions and invariants. The checking is disabled by
201 168
/// default, but it can be turned on with the macro \c
202 169
/// LEMON_ENABLE_DEBUG.
203 170
/// \code
204 171
/// #define LEMON_ENABLE_DEBUG
205 172
/// \endcode
206 173
/// or with compilation parameters:
207 174
/// \code
208 175
/// g++ -DLEMON_ENABLE_DEBUG
209 176
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
210 177
/// \endcode
211 178
///
212 179
/// This macro works like the \c LEMON_ASSERT macro, therefore the
213 180
/// current behaviour depends on the settings of \c LEMON_ASSERT
214 181
/// macro.
215 182
///
216 183
/// \see LEMON_ASSERT
217 184
#  define LEMON_DEBUG(exp, msg)                                         \
218 185
  (static_cast<void> (!!(exp) ? 0 : (                                   \
219 186
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
220 187
                         LEMON_FUNCTION_NAME,                           \
221 188
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
222 189

	
223 190
#else
224 191

	
225 192
#  ifndef LEMON_ASSERT_HANDLER
226 193
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
227
#    define LEMON_FIXME(msg) (static_cast<void>(0))
228 194
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
229 195
#  else
230 196
#    define LEMON_ASSERT(exp, msg)                                      \
231 197
       (static_cast<void> (!!(exp) ? 0 : (                              \
232 198
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
233 199
                             LEMON_FUNCTION_NAME,                       \
234 200
                             ::lemon::_assert_bits::cstringify(msg),    \
235 201
                             #exp), 0)))
236
#    define LEMON_FIXME(msg)                                            \
237
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
238
                             ::lemon::_assert_bits::cstringify(msg),    \
239
                             static_cast<const char*>(0)))
240

	
241 202
#    if LEMON_ENABLE_DEBUG
242 203
#      define LEMON_DEBUG(exp, msg)                                     \
243 204
         (static_cast<void> (!!(exp) ? 0 : (                            \
244 205
           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
245 206
                                LEMON_FUNCTION_NAME,                    \
246 207
                                ::lemon::_assert_bits::cstringify(msg), \
247 208
                                #exp), 0)))
248 209
#    else
249 210
#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
250 211
#    endif
251 212
#  endif
252 213

	
253 214
#endif
Show white space 32 line context
... ...
@@ -34,67 +34,57 @@
34 34
#ifdef NDEBUG
35 35
#undef NDEBUG
36 36
#endif
37 37

	
38 38
//checking disabled asserts
39 39
#define LEMON_DISABLE_ASSERTS
40 40
#include <lemon/assert.h>
41 41

	
42 42
void no_assertion_text_disable() {
43 43
  LEMON_ASSERT(true, "This is a fault message");
44 44
}
45 45

	
46 46
void assertion_text_disable() {
47 47
  LEMON_ASSERT(false, "This is a fault message");
48 48
}
49 49

	
50
void fixme_disable() {
51
  LEMON_FIXME("fixme_disable() is fixme!");
52
}
53

	
54 50
void check_assertion_disable() {
55 51
  no_assertion_text_disable();
56 52
  assertion_text_disable();
57
  fixme_disable();
58 53
}
59 54
#undef LEMON_DISABLE_ASSERTS
60 55

	
61 56
//checking custom assert handler
62 57
#define LEMON_ASSERT_CUSTOM
63 58

	
64 59
static int cnt = 0;
65 60
void my_assert_handler(const char*, int, const char*,
66 61
                       const char*, const char*) {
67 62
  ++cnt;
68 63
}
69 64

	
70 65
#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
71 66
#include <lemon/assert.h>
72 67

	
73 68
void no_assertion_text_custom() {
74 69
  LEMON_ASSERT(true, "This is a fault message");
75 70
}
76 71

	
77 72
void assertion_text_custom() {
78 73
  LEMON_ASSERT(false, "This is a fault message");
79 74
}
80 75

	
81
void fixme_custom() {
82
  LEMON_FIXME("fixme_custom() is fixme!");
83
}
84

	
85 76
void check_assertion_custom() {
86 77
  no_assertion_text_custom();
87 78
  assertion_text_custom();
88
  fixme_custom();
89
  check(cnt == 2, "The custom assert handler does not work");
79
  check(cnt == 1, "The custom assert handler does not work");
90 80
}
91 81

	
92 82
#undef LEMON_ASSERT_CUSTOM
93 83

	
94 84

	
95 85
int main() {
96 86
  check_assertion_disable();
97 87
  check_assertion_custom();
98 88

	
99 89
  return 0;
100 90
}
0 comments (0 inline)