gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements in assert.h
0 1 0
default
1 file changed with 51 insertions and 63 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -70,295 +70,283 @@
70 70
	_message_holder.set(ostr.str());
71 71
	return ostr.str().c_str();
72 72
      }
73 73
      catch(...) {}
74 74
      if( _message_holder.valid() ) return _message_holder.get().c_str();
75 75
      return "lemon::AssertionFailedError";
76 76
    }
77 77
    virtual ~AssertionFailedError() throw() {}
78 78
  };
79 79

	
80 80

	
81 81
  inline void assert_fail_log(const char *file, int line,
82 82
			      const char *function,
83 83
			      const std::exception& exception, 
84 84
			      const char *assertion)
85 85
  {
86 86
    std::cerr << file << ":" << line << ": ";
87 87
    if (function)
88 88
      std::cerr << function << ": ";
89 89
    std::cerr << exception.what();
90 90
    if (assertion)
91 91
      std::cerr << " (assertion '" << assertion << "' failed)";
92 92
    std::cerr << std::endl;
93 93
  }
94 94

	
95 95
  inline void assert_fail_log(const char *file, int line, const char *function,
96 96
			      const char *message, const char *assertion)
97 97
  {
98 98
    std::cerr << file << ":" << line << ": ";
99 99
    if (function)
100 100
      std::cerr << function << ": ";
101 101
    std::cerr << message;
102 102
    if (assertion)
103 103
      std::cerr << " (assertion '" << assertion << "' failed)";
104 104
    std::cerr << std::endl;
105 105
  }
106 106

	
107 107
  inline void assert_fail_log(const char *file, int line, const char *function, 
108 108
			      const std::string& message, const char *assertion)
109 109
  {
110 110
    assert_fail_log(file, line, function, message.c_str(), assertion);
111 111
  }
112 112

	
113 113
  inline void assert_fail_abort(const char *file, int line, 
114 114
				const char *function,
115 115
				const std::exception& exception,
116 116
				const char *assertion)
117 117
  {
118
    std::cerr << file << ":" << line << ": ";
119
    if (function)
120
      std::cerr << function << ": ";
121
    std::cerr << exception.what();
122
    if (assertion)
123
      std::cerr << " (assertion '" << assertion << "' failed)";
124
    std::cerr << std::endl;
118
    assert_fail_log(file, line, function, exception, assertion);
125 119
    std::abort();
126 120
  }
127 121

	
128 122
  inline void assert_fail_abort(const char *file, int line,
129 123
				const char *function, const char* message,
130 124
				const char *assertion)
131 125
  {
132
    std::cerr << file << ":" << line << ": ";
133
    if (function)
134
      std::cerr << function << ": ";
135
    std::cerr << message;
136
    if (assertion)
137
      std::cerr << " (assertion '" << assertion << "' failed)";
138
    std::cerr << std::endl;
126
    assert_fail_log(file, line, function, message, assertion);
139 127
    std::abort();
140 128
  }
141 129

	
142 130
  inline void assert_fail_abort(const char *file, int line, 
143 131
				const char *function, 
144 132
				const std::string& message,
145 133
				const char *assertion)
146 134
  {
147
    assert_fail_abort(file, line, function, message.c_str(), assertion);
135
    assert_fail_log(file, line, function, message.c_str(), assertion);
136
    std::abort();
148 137
  }
149 138

	
150 139
  inline void assert_fail_error(const char *file, int line, 
151 140
				  const char *function,
152 141
				  const std::exception& exception,
153 142
				  const char *assertion)
154 143
  {
155 144
    throw AssertionFailedError(file, line, function, 
156 145
			       exception.what(), assertion);
157 146
  }
158 147

	
159 148
  inline void assert_fail_error(const char *file, int line,
160 149
				  const char *function, const char *message,
161 150
				  const char *assertion)
162 151
  {
163 152
    throw AssertionFailedError(file, line, function, message, assertion);
164 153
  }
165 154

	
166 155
  inline void assert_fail_error(const char *file, int line,
167 156
				  const char *function, 
168 157
				  const std::string& message,
169 158
				  const char *assertion)
170 159
  {
171
    assert_fail_error(file, line, function, message.c_str(), assertion);
160
    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
172 161
  }
173 162

	
174 163
  template <typename Exception>
175 164
  inline void assert_fail_exception(const char *, int, const char *,
176 165
				    const Exception& exception,
177 166
				    const char *, const std::exception* = 
178 167
				    static_cast<const Exception*>(0))
179 168
  {
180 169
    throw exception;
181 170
  }
182 171

	
183 172
  inline void assert_fail_exception(const char *file, int line,
184 173
				    const char *function, const char *message,
185 174
				    const char *assertion)
186 175
  {
187 176
    throw AssertionFailedError(file, line, function, message, assertion);
188 177
  }
189 178

	
190 179
  inline void assert_fail_exception(const char *file, int line, 
191 180
				    const char *function, 
192 181
				    const std::string& message,
193 182
				    const char *assertion)
194 183
  {
195
    assert_fail_exception(file, line, function, message.c_str(), assertion);
184
    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
196 185
  }
197 186

	
198 187
/// @}
199 188

	
200 189
}
201 190
#endif // LEMON_ASSERT_H
202 191

	
203 192
#undef LEMON_ASSERT
204 193
#undef LEMON_FIXME
205 194

	
206 195
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
207 196
  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
208 197
  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
209 198
  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
210 199
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
211
#error "Lemon assertion system is not set properly"
200
#error "LEMON assertion system is not set properly"
212 201
#endif
213 202

	
214 203
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
215 204
     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
216 205
     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
217 206
     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
218 207
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
219
     defined(LEMON_ENABLE_ASSERT)) &&			\
208
     defined(LEMON_ENABLE_ASSERTS)) &&			\
220 209
  defined(LEMON_DISABLE_ASSERTS)
221
#error "Lemon assertion system is not set properly"
210
#error "LEMON assertion system is not set properly"
222 211
#endif
223 212

	
224 213

	
225 214
#if defined LEMON_ASSERT_LOG
226 215
#  undef LEMON_ASSERT_HANDLER
227 216
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
228 217
#elif defined LEMON_ASSERT_ABORT
229 218
#  undef LEMON_ASSERT_HANDLER
230 219
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
231 220
#elif defined LEMON_ASSERT_ERROR
232 221
#  undef LEMON_ASSERT_HANDLER
233 222
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
234 223
#elif defined LEMON_ASSERT_EXCEPTION
235 224
#  undef LEMON_ASSERT_HANDLER
236 225
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
237 226
#elif defined LEMON_ASSERT_CUSTOM
238 227
#  undef LEMON_ASSERT_HANDLER
239 228
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
240 229
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
241 230
#  endif
242 231
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
243 232
#elif defined LEMON_ENABLE_ASSERTS
244 233
#  undef LEMON_ASSERT_HANDLER
245 234
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
246 235
#else
247 236
#  undef LEMON_ASSERT_HANDLER
248 237
#endif
249 238

	
250 239

	
251 240
#ifndef LEMON_FUNCTION_NAME
252 241
#  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
253 242
#endif
254 243

	
255 244
#ifdef DOXYGEN
256 245

	
257 246
/// \ingroup exceptions
258 247
///
259
/// \brief Macro for assertions with customizable message
248
/// \brief Macro for assertion with customizable message
260 249
///
261
/// Macro for assertions with customizable message.  
262
/// \param exp An expression convertible to bool. If the expression is
263
/// false, then an assertion is raised. The concrete behaviour depends
264
/// on the settings of the assertion system.
265
/// \param msg A \e const \e char*, a \e const std::string& or a \e
266
/// const \e std::exception& parameter. The variable can be used to
267
/// provide information about the circumstances of failed assertion.
250
/// Macro for assertion with customizable message.  
251
/// \param exp An expression that must be convertible to \c bool.
252
/// If it is \c false, then an assertion is raised. The concrete
253
/// behaviour depends on the settings of the assertion system.
254
/// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
255
/// a <tt>const std::exception&</tt> parameter, which can be used to
256
/// provide information about the circumstances of the failed assertion.
268 257
///
269
/// The assertions are disabled in the default behaviour. You can
270
/// enable the assertions with the following code:
258
/// The assertions are disabled in the default behaviour.
259
/// You can enable them with the following code:
271 260
/// \code
272 261
/// #define LEMON_ENABLE_ASSERTS
273 262
/// \endcode
274 263
/// or with compilation parameters:
275 264
/// \code
276 265
/// g++ -DLEMON_ENABLE_ASSERTS
277 266
/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
278 267
/// \endcode
279 268
/// 
280
/// The %lemon assertion system has a wide range of customization
281
/// properties. As default behaviour the failed assertion prints a
282
/// short log message to the standard ouput and aborts the execution.
269
/// The LEMON assertion system has a wide range of customization
270
/// properties. As a default behaviour the failed assertion prints a
271
/// short log message to the standard error and aborts the execution.
283 272
///
284 273
/// The following modes can be used in the assertion system: 
285 274
///
286
/// - \e LEMON_ASSERT_LOG The failed assert print a short convenient
287
///   error message to the standard error and continues the
288
///   execution.
289
/// - \e LEMON_ASSERT_ABORT This mode is similar to the \e
290
///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
291
///   operation mode when the asserts are enabled with \e
292
///   LEMON_ENABLE_ASSERTS.
293
/// - \e LEMON_ASSERT_ERROR The assert throws an \ref
294
///   lemon::AssertionFailedError "AssertionFailedError". If the \c
295
///   msg parameter is an exception, then the result of the \ref
296
///   lemon::Exception::what() "what()" member function is passed as
297
///   error message.
298
/// - \e LEMON_ASSERT_EXCEPTION If the specified \c msg is an
299
///   exception then it raised directly (solving that the exception
275
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
276
///   message to the standard error and continues the execution.
277
/// - \c LEMON_ASSERT_ABORT This mode is similar to the
278
///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
279
///   behaviour mode when the assertions are enabled with
280
///   \c LEMON_ENABLE_ASSERTS.
281
/// - \c LEMON_ASSERT_ERROR The assertion throws an
282
///   \ref lemon::AssertionFailedError "AssertionFailedError".
283
///   If the \c msg parameter is an exception, then the result of the
284
///   \ref lemon::Exception::what() "what()" member function is passed
285
///   as error message.
286
/// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
287
///   exception, then it raised directly (solving that the exception
300 288
///   can not be thrown polymorphically), otherwise an \ref
301 289
///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
302
///   the given parameter.
303
/// - \e LEMON_ASSERT_CUSTOM The user can define an own assertion
304
///   handler functions. Three overloaded functions should be defined
305
///   with the following parameter lists:
290
///   the given parameters.
291
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
292
///   functions. Three overloaded functions should be defined with the
293
///   following parameter lists:
306 294
///   \code
307
///     void custom_assert_handler(const char* file, int line, 
308
///                                const char* function, const char* message, const char* expression);
309
///     void custom_assert_handler(const char* file, int line, 
310
///                                const char* function, const std::string& message, const char* expression);
311
///     void custom_assert_handler(const char* file, int line, 
312
///                                const char* function, const std::exception& message, const char* expression);
295
///     void custom_assert_handler(const char* file, int line, const char* function,
296
///                                const char* message, const char* assertion);
297
///     void custom_assert_handler(const char* file, int line, const char* function,
298
///                                const std::string& message, const char* assertion);
299
///     void custom_assert_handler(const char* file, int line, const char* function,
300
///                                const std::exception& message, const char* assertion);
313 301
///   \endcode
314 302
///   The name of the functions should be defined as the \c
315 303
///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
316 304
///   \code
317 305
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
318 306
///   \endcode
319 307
///   Whenever an assertion is occured, one of the custom assertion
320
///   handler is called with appropiate parameters.
308
///   handlers is called with appropiate parameters.
321 309
///
322
/// The assertion mode can be changed within one compilation unit, if
323
/// the macros are redefined with other settings and the
324
/// lemon/assert.h file is reincluded then the behaviour is changed
325
/// appropiately to the new settings.
310
/// The assertion mode can also be changed within one compilation unit.
311
/// If the macros are redefined with other settings and the
312
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
313
/// behaviour is changed appropiately to the new settings.
326 314
#  define LEMON_ASSERT(exp, msg)					\
327 315
  (static_cast<void> (!!(exp) ? 0 : (					\
328 316
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
329 317
			 LEMON_FUNCTION_NAME,				\
330 318
			 msg, #exp), 0)))
331 319

	
332 320

	
333 321
/// \ingroup exceptions
334 322
///
335 323
/// \brief Macro for mark not yet implemented features.
336 324
///
337 325
/// Macro for mark not yet implemented features and outstanding bugs.
338 326
/// It is close to be the shortcut of the following code:
339 327
/// \code
340 328
///   LEMON_ASSERT(false, msg);
341 329
/// \endcode
342 330
#  define LEMON_FIXME(msg)						\
343 331
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
344 332
			     "FIXME: " msg, static_cast<const char*>(0)))
345 333

	
346 334
#else
347 335

	
348 336
#  ifndef LEMON_ASSERT_HANDLER
349
#    define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
337
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
350 338
#    define LEMON_FIXME(msg) (static_cast<void>(0))
351 339
#  else
352 340
#    define LEMON_ASSERT(exp, msg)                 \
353 341
       (static_cast<void> (!!(exp) ? 0 : (         \
354 342
         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
355 343
                              LEMON_FUNCTION_NAME, \
356 344
                              msg, #exp), 0)))
357 345
#    define LEMON_FIXME(msg) \
358 346
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
359 347
			     "FIXME: " msg,  static_cast<const char*>(0)))
360 348
#  endif
361 349

	
362 350
#endif
363 351

	
364 352

	
0 comments (0 inline)