1.1 --- a/lemon/Makefile.am Fri Mar 21 22:25:40 2008 +0000
1.2 +++ b/lemon/Makefile.am Tue Mar 25 16:36:44 2008 +0100
1.3 @@ -17,6 +17,7 @@
1.4
1.5 lemon_HEADERS += \
1.6 lemon/arg_parser.h \
1.7 + lemon/assert.h \
1.8 lemon/bfs.h \
1.9 lemon/bin_heap.h \
1.10 lemon/dfs.h \
2.1 --- a/lemon/arg_parser.h Fri Mar 21 22:25:40 2008 +0000
2.2 +++ b/lemon/arg_parser.h Tue Mar 25 16:36:44 2008 +0100
2.3 @@ -26,7 +26,7 @@
2.4 #include <iostream>
2.5 #include <sstream>
2.6 #include <algorithm>
2.7 -#include <lemon/error.h>
2.8 +#include <lemon/assert.h>
2.9
2.10 ///\ingroup misc
2.11 ///\file
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/lemon/assert.h Tue Mar 25 16:36:44 2008 +0100
3.3 @@ -0,0 +1,364 @@
3.4 +/* -*- C++ -*-
3.5 + *
3.6 + * This file is a part of LEMON, a generic C++ optimization library
3.7 + *
3.8 + * Copyright (C) 2003-2008
3.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
3.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
3.11 + *
3.12 + * Permission to use, modify and distribute this software is granted
3.13 + * provided that this copyright notice appears in all copies. For
3.14 + * precise terms see the accompanying LICENSE file.
3.15 + *
3.16 + * This software is provided "AS IS" with no warranty of any kind,
3.17 + * express or implied, and with no claim as to its suitability for any
3.18 + * purpose.
3.19 + *
3.20 + */
3.21 +
3.22 +#ifndef LEMON_ASSERT_H
3.23 +#define LEMON_ASSERT_H
3.24 +
3.25 +/// \ingroup exceptions
3.26 +/// \file
3.27 +/// \brief Extended assertion handling
3.28 +
3.29 +#include <lemon/error.h>
3.30 +
3.31 +namespace lemon {
3.32 +
3.33 + /// @{
3.34 +
3.35 + ///\e
3.36 + class AssertionFailedError : public LogicError {
3.37 + protected:
3.38 + const char *_assertion;
3.39 + const char *_file;
3.40 + int _line;
3.41 + const char *_function;
3.42 + const char *_message;
3.43 +
3.44 + mutable ExceptionMember<std::string> _message_holder;
3.45 + public:
3.46 + ///\e
3.47 + AssertionFailedError(const char *file, int line, const char *function,
3.48 + const char *msg, const char *assertion = 0) :
3.49 + _assertion(assertion), _file(file), _line(line),
3.50 + _function(function), _message(msg) {}
3.51 +
3.52 + ///\e
3.53 + const char* assertion() const { return _assertion; }
3.54 + ///\e
3.55 + const char* message() const { return _message; }
3.56 + ///\e
3.57 + const char* file() const { return _file; }
3.58 + ///\e
3.59 + const char* function() const { return _function; }
3.60 + ///\e
3.61 + int line() const { return _line; }
3.62 +
3.63 +
3.64 + virtual const char* what() const throw() {
3.65 + try {
3.66 + std::ostringstream ostr;
3.67 + ostr << _file << ":" << _line << ": ";
3.68 + if (_function)
3.69 + ostr << _function << ": ";
3.70 + ostr << _message;
3.71 + if (_assertion)
3.72 + ostr << " (assertion '" << _assertion << "' failed)";
3.73 + _message_holder.set(ostr.str());
3.74 + return ostr.str().c_str();
3.75 + }
3.76 + catch(...) {}
3.77 + if( _message_holder.valid() ) return _message_holder.get().c_str();
3.78 + return "lemon::AssertionFailedError";
3.79 + }
3.80 + virtual ~AssertionFailedError() throw() {}
3.81 + };
3.82 +
3.83 +
3.84 + inline void assert_fail_log(const char *file, int line,
3.85 + const char *function,
3.86 + const std::exception& exception,
3.87 + const char *assertion)
3.88 + {
3.89 + std::cerr << file << ":" << line << ": ";
3.90 + if (function)
3.91 + std::cerr << function << ": ";
3.92 + std::cerr << exception.what();
3.93 + if (assertion)
3.94 + std::cerr << " (assertion '" << assertion << "' failed)";
3.95 + std::cerr << std::endl;
3.96 + }
3.97 +
3.98 + inline void assert_fail_log(const char *file, int line, const char *function,
3.99 + const char *message, const char *assertion)
3.100 + {
3.101 + std::cerr << file << ":" << line << ": ";
3.102 + if (function)
3.103 + std::cerr << function << ": ";
3.104 + std::cerr << message;
3.105 + if (assertion)
3.106 + std::cerr << " (assertion '" << assertion << "' failed)";
3.107 + std::cerr << std::endl;
3.108 + }
3.109 +
3.110 + inline void assert_fail_log(const char *file, int line, const char *function,
3.111 + const std::string& message, const char *assertion)
3.112 + {
3.113 + assert_fail_log(file, line, function, message.c_str(), assertion);
3.114 + }
3.115 +
3.116 + inline void assert_fail_abort(const char *file, int line,
3.117 + const char *function,
3.118 + const std::exception& exception,
3.119 + const char *assertion)
3.120 + {
3.121 + std::cerr << file << ":" << line << ": ";
3.122 + if (function)
3.123 + std::cerr << function << ": ";
3.124 + std::cerr << exception.what();
3.125 + if (assertion)
3.126 + std::cerr << " (assertion '" << assertion << "' failed)";
3.127 + std::cerr << std::endl;
3.128 + std::abort();
3.129 + }
3.130 +
3.131 + inline void assert_fail_abort(const char *file, int line,
3.132 + const char *function, const char* message,
3.133 + const char *assertion)
3.134 + {
3.135 + std::cerr << file << ":" << line << ": ";
3.136 + if (function)
3.137 + std::cerr << function << ": ";
3.138 + std::cerr << message;
3.139 + if (assertion)
3.140 + std::cerr << " (assertion '" << assertion << "' failed)";
3.141 + std::cerr << std::endl;
3.142 + std::abort();
3.143 + }
3.144 +
3.145 + inline void assert_fail_abort(const char *file, int line,
3.146 + const char *function,
3.147 + const std::string& message,
3.148 + const char *assertion)
3.149 + {
3.150 + assert_fail_abort(file, line, function, message.c_str(), assertion);
3.151 + }
3.152 +
3.153 + inline void assert_fail_error(const char *file, int line,
3.154 + const char *function,
3.155 + const std::exception& exception,
3.156 + const char *assertion)
3.157 + {
3.158 + throw AssertionFailedError(file, line, function,
3.159 + exception.what(), assertion);
3.160 + }
3.161 +
3.162 + inline void assert_fail_error(const char *file, int line,
3.163 + const char *function, const char *message,
3.164 + const char *assertion)
3.165 + {
3.166 + throw AssertionFailedError(file, line, function, message, assertion);
3.167 + }
3.168 +
3.169 + inline void assert_fail_error(const char *file, int line,
3.170 + const char *function,
3.171 + const std::string& message,
3.172 + const char *assertion)
3.173 + {
3.174 + assert_fail_error(file, line, function, message.c_str(), assertion);
3.175 + }
3.176 +
3.177 + template <typename Exception>
3.178 + inline void assert_fail_exception(const char *, int, const char *,
3.179 + const Exception& exception,
3.180 + const char *, const std::exception* =
3.181 + static_cast<const Exception*>(0))
3.182 + {
3.183 + throw exception;
3.184 + }
3.185 +
3.186 + inline void assert_fail_exception(const char *file, int line,
3.187 + const char *function, const char *message,
3.188 + const char *assertion)
3.189 + {
3.190 + throw AssertionFailedError(file, line, function, message, assertion);
3.191 + }
3.192 +
3.193 + inline void assert_fail_exception(const char *file, int line,
3.194 + const char *function,
3.195 + const std::string& message,
3.196 + const char *assertion)
3.197 + {
3.198 + assert_fail_exception(file, line, function, message.c_str(), assertion);
3.199 + }
3.200 +
3.201 +/// @}
3.202 +
3.203 +}
3.204 +#endif // LEMON_ASSERT_H
3.205 +
3.206 +#undef LEMON_ASSERT
3.207 +#undef LEMON_FIXME
3.208 +
3.209 +#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \
3.210 + (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
3.211 + (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \
3.212 + (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \
3.213 + (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
3.214 +#error "Lemon assertion system is not set properly"
3.215 +#endif
3.216 +
3.217 +#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \
3.218 + (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
3.219 + (defined(LEMON_ASSERT_ERROR) ? 1 : 0) + \
3.220 + (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) + \
3.221 + (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \
3.222 + defined(LEMON_ENABLE_ASSERT)) && \
3.223 + defined(LEMON_DISABLE_ASSERTS)
3.224 +#error "Lemon assertion system is not set properly"
3.225 +#endif
3.226 +
3.227 +
3.228 +#if defined LEMON_ASSERT_LOG
3.229 +# undef LEMON_ASSERT_HANDLER
3.230 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
3.231 +#elif defined LEMON_ASSERT_ABORT
3.232 +# undef LEMON_ASSERT_HANDLER
3.233 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
3.234 +#elif defined LEMON_ASSERT_ERROR
3.235 +# undef LEMON_ASSERT_HANDLER
3.236 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
3.237 +#elif defined LEMON_ASSERT_EXCEPTION
3.238 +# undef LEMON_ASSERT_HANDLER
3.239 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
3.240 +#elif defined LEMON_ASSERT_CUSTOM
3.241 +# undef LEMON_ASSERT_HANDLER
3.242 +# ifndef LEMON_CUSTOM_ASSERT_HANDLER
3.243 +# error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
3.244 +# endif
3.245 +# define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
3.246 +#elif defined LEMON_ENABLE_ASSERTS
3.247 +# undef LEMON_ASSERT_HANDLER
3.248 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
3.249 +#else
3.250 +# undef LEMON_ASSERT_HANDLER
3.251 +#endif
3.252 +
3.253 +
3.254 +#ifndef LEMON_FUNCTION_NAME
3.255 +# define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
3.256 +#endif
3.257 +
3.258 +#ifdef DOXYGEN
3.259 +
3.260 +/// \ingroup exceptions
3.261 +///
3.262 +/// \brief Macro for assertions with customizable message
3.263 +///
3.264 +/// Macro for assertions with customizable message.
3.265 +/// \param exp An expression convertible to bool. If the expression is
3.266 +/// false, then an assertion is raised. The concrete behaviour depends
3.267 +/// on the settings of the assertion system.
3.268 +/// \param msg A \e const \e char*, a \e const std::string& or a \e
3.269 +/// const \e std::exception& parameter. The variable can be used to
3.270 +/// provide information about the circumstances of failed assertion.
3.271 +///
3.272 +/// The assertions are disabled in the default behaviour. You can
3.273 +/// enable the assertions with the following code:
3.274 +/// \code
3.275 +/// #define LEMON_ENABLE_ASSERTS
3.276 +/// \endcode
3.277 +/// or with compilation parameters:
3.278 +/// \code
3.279 +/// g++ -DLEMON_ENABLE_ASSERTS
3.280 +/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
3.281 +/// \endcode
3.282 +///
3.283 +/// The %lemon assertion system has a wide range of customization
3.284 +/// properties. As default behaviour the failed assertion prints a
3.285 +/// short log message to the standard ouput and aborts the execution.
3.286 +///
3.287 +/// The following modes can be used in the assertion system:
3.288 +///
3.289 +/// - \e LEMON_ASSERT_LOG The failed assert print a short convenient
3.290 +/// error message to the standard error and continues the
3.291 +/// execution.
3.292 +/// - \e LEMON_ASSERT_ABORT This mode is similar to the \e
3.293 +/// LEMON_ASSERT_LOG, but it aborts the program. It is the default
3.294 +/// operation mode when the asserts are enabled with \e
3.295 +/// LEMON_ENABLE_ASSERTS.
3.296 +/// - \e LEMON_ASSERT_ERROR The assert throws an \ref
3.297 +/// lemon::AssertionFailedError "AssertionFailedError". If the \c
3.298 +/// msg parameter is an exception, then the result of the \ref
3.299 +/// lemon::Exception::what() "what()" member function is passed as
3.300 +/// error message.
3.301 +/// - \e LEMON_ASSERT_EXCEPTION If the specified \c msg is an
3.302 +/// exception then it raised directly (solving that the exception
3.303 +/// can not be thrown polymorphically), otherwise an \ref
3.304 +/// lemon::AssertionFailedError "AssertionFailedError" is thrown with
3.305 +/// the given parameter.
3.306 +/// - \e LEMON_ASSERT_CUSTOM The user can define an own assertion
3.307 +/// handler functions. Three overloaded functions should be defined
3.308 +/// with the following parameter lists:
3.309 +/// \code
3.310 +/// void custom_assert_handler(const char* file, int line,
3.311 +/// const char* function, const char* message, const char* expression);
3.312 +/// void custom_assert_handler(const char* file, int line,
3.313 +/// const char* function, const std::string& message, const char* expression);
3.314 +/// void custom_assert_handler(const char* file, int line,
3.315 +/// const char* function, const std::exception& message, const char* expression);
3.316 +/// \endcode
3.317 +/// The name of the functions should be defined as the \c
3.318 +/// LEMON_CUSTOM_ASSERT_HANDLER macro name.
3.319 +/// \code
3.320 +/// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
3.321 +/// \endcode
3.322 +/// Whenever an assertion is occured, one of the custom assertion
3.323 +/// handler is called with appropiate parameters.
3.324 +///
3.325 +/// The assertion mode can be changed within one compilation unit, if
3.326 +/// the macros are redefined with other settings and the
3.327 +/// lemon/assert.h file is reincluded then the behaviour is changed
3.328 +/// appropiately to the new settings.
3.329 +# define LEMON_ASSERT(exp, msg) \
3.330 + (static_cast<void> (!!(exp) ? 0 : ( \
3.331 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
3.332 + LEMON_FUNCTION_NAME, \
3.333 + msg, #exp), 0)))
3.334 +
3.335 +
3.336 +/// \ingroup exceptions
3.337 +///
3.338 +/// \brief Macro for mark not yet implemented features.
3.339 +///
3.340 +/// Macro for mark not yet implemented features and outstanding bugs.
3.341 +/// It is close to be the shortcut of the following code:
3.342 +/// \code
3.343 +/// LEMON_ASSERT(false, msg);
3.344 +/// \endcode
3.345 +# define LEMON_FIXME(msg) \
3.346 + (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \
3.347 + "FIXME: " msg, static_cast<const char*>(0)))
3.348 +
3.349 +#else
3.350 +
3.351 +# ifndef LEMON_ASSERT_HANDLER
3.352 +# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
3.353 +# define LEMON_FIXME(msg) (static_cast<void>(0))
3.354 +# else
3.355 +# define LEMON_ASSERT(exp, msg) \
3.356 + (static_cast<void> (!!(exp) ? 0 : ( \
3.357 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
3.358 + LEMON_FUNCTION_NAME, \
3.359 + msg, #exp), 0)))
3.360 +# define LEMON_FIXME(msg) \
3.361 + (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \
3.362 + "FIXME: " msg, static_cast<const char*>(0)))
3.363 +# endif
3.364 +
3.365 +#endif
3.366 +
3.367 +
4.1 --- a/lemon/error.h Fri Mar 21 22:25:40 2008 +0000
4.2 +++ b/lemon/error.h Tue Mar 25 16:36:44 2008 +0100
4.3 @@ -93,7 +93,7 @@
4.4 std::auto_ptr<_Type> ptr;
4.5 };
4.6
4.7 - /// Exception-safe convenient "error message" class.
4.8 + /// Exception-safe convenient error message builder class.
4.9
4.10 /// Helper class which provides a convenient ostream-like (operator <<
4.11 /// based) interface to create a string message. Mostly useful in
4.12 @@ -413,263 +413,8 @@
4.13 virtual ~IoParameterError() throw() {}
4.14 };
4.15
4.16 -
4.17 - ///\e
4.18 - class AssertionFailedError : public LogicError {
4.19 - protected:
4.20 - const char *assertion;
4.21 - const char *file;
4.22 - int line;
4.23 - const char *function;
4.24 - const char *message;
4.25 -
4.26 - mutable ExceptionMember<std::string> _message_holder;
4.27 - public:
4.28 - ///\e
4.29 - AssertionFailedError(const char *_file, int _line, const char *func,
4.30 - const char *msg, const char *_assertion = 0) :
4.31 - assertion(_assertion), file(_file), line(_line), function(func),
4.32 - message(msg) {}
4.33 -
4.34 - ///\e
4.35 - const char* get_assertion() const { return assertion; }
4.36 - ///\e
4.37 - const char* get_message() const { return message; }
4.38 - ///\e
4.39 - const char* get_file() const { return file; }
4.40 - ///\e
4.41 - const char* get_function() const { return function; }
4.42 - ///\e
4.43 - int get_line() const { return line; }
4.44 -
4.45 -
4.46 - virtual const char* what() const throw() {
4.47 - try {
4.48 - std::ostringstream ostr;
4.49 - ostr << file << ":" << line << ": ";
4.50 - if( function )
4.51 - ostr << function << ": ";
4.52 - ostr << message;
4.53 - if( assertion )
4.54 - ostr << " (assertion '" << assertion << "' failed)";
4.55 - _message_holder.set(ostr.str());
4.56 - return ostr.str().c_str();
4.57 - }
4.58 - catch(...) {}
4.59 - if( _message_holder.valid() ) return _message_holder.get().c_str();
4.60 - return "lemon::AssertionFailedError";
4.61 - }
4.62 - virtual ~AssertionFailedError() throw() {}
4.63 - };
4.64 -
4.65 -
4.66 - /**************** Macros ****************/
4.67 -
4.68 -
4.69 - template <typename Exception>
4.70 - inline void assert_fail(const char *file, int line,
4.71 - const char *func,
4.72 - Exception exception,
4.73 - const char *assertion = 0,
4.74 - bool do_abort=true)
4.75 - {
4.76 - using namespace std;
4.77 - cerr << file << ":" << line << ": ";
4.78 - if (func)
4.79 - cerr << func << ": ";
4.80 - cerr << exception.what();
4.81 - if (assertion)
4.82 - cerr << " (assertion '" << assertion << "' failed)";
4.83 - cerr << endl;
4.84 - if (do_abort)
4.85 - abort();
4.86 - }
4.87 -
4.88 - template <>
4.89 - inline void assert_fail<const char *>(const char *file, int line,
4.90 - const char *func,
4.91 - const char *message,
4.92 - const char *assertion,
4.93 - bool do_abort)
4.94 - {
4.95 - using namespace std;
4.96 - cerr << file << ":" << line << ": ";
4.97 - if (func)
4.98 - cerr << func << ": ";
4.99 - cerr << message;
4.100 - if (assertion)
4.101 - cerr << " (assertion '" << assertion << "' failed)";
4.102 - cerr << endl;
4.103 - if (do_abort)
4.104 - abort();
4.105 - }
4.106 -
4.107 - template <>
4.108 - inline void assert_fail<std::string>(const char *file, int line,
4.109 - const char *func,
4.110 - std::string message,
4.111 - const char *assertion,
4.112 - bool do_abort)
4.113 - {
4.114 - assert_fail(file, line, func, message.c_str(), assertion, do_abort);
4.115 - }
4.116 -
4.117 - template <typename Exception>
4.118 - inline void assert_fail_failure(const char *file, int line, const char *func,
4.119 - Exception exception,
4.120 - const char *assertion = 0,
4.121 - bool = true)
4.122 - {
4.123 - throw AssertionFailedError(file, line, func, exception.what(), assertion);
4.124 - }
4.125 -
4.126 - template <>
4.127 - inline void assert_fail_failure<const char *>(const char *file, int line,
4.128 - const char *func,
4.129 - const char *message,
4.130 - const char *assertion,
4.131 - bool)
4.132 - {
4.133 - throw AssertionFailedError(file, line, func, message, assertion);
4.134 - }
4.135 -
4.136 - template <>
4.137 - inline void assert_fail_failure<std::string>(const char *file, int line,
4.138 - const char *func,
4.139 - std::string message,
4.140 - const char *assertion,
4.141 - bool)
4.142 - {
4.143 - assert_fail_failure(file, line, func, message.c_str(), assertion, true);
4.144 - }
4.145 -
4.146 - template <typename Exception>
4.147 - inline void assert_fail_exception(const char *file, int line, const char *func,
4.148 - Exception exception,
4.149 - const char *assertion = 0, bool = true)
4.150 - {
4.151 - throw exception;
4.152 - }
4.153 -
4.154 - template <>
4.155 - inline void assert_fail_exception<const char *>(const char *file, int line,
4.156 - const char *func,
4.157 - const char *message,
4.158 - const char *assertion,
4.159 - bool)
4.160 - {
4.161 - throw AssertionFailedError(file, line, func, message, assertion);
4.162 - }
4.163 -
4.164 - template <>
4.165 - inline void assert_fail_exception<std::string>(const char *file, int line,
4.166 - const char *func,
4.167 - std::string message,
4.168 - const char *assertion,
4.169 - bool)
4.170 - {
4.171 - assert_fail_exception(file, line, func, message.c_str(), assertion, true);
4.172 - }
4.173 -
4.174 -/// @}
4.175 + /// @}
4.176
4.177 }
4.178 +
4.179 #endif // LEMON_ERROR_H
4.180 -
4.181 -#undef LEMON_ASSERT
4.182 -#undef LEMON_FIXME
4.183 -
4.184 -#ifdef LEMON_ENABLE_ASSERTS
4.185 -# define LEMON_ASSERT_ABORT
4.186 -#endif
4.187 -
4.188 -#ifndef LEMON_ASSERT_DO_ABORT
4.189 -# define LEMON_ASSERT_DO_ABORT 1
4.190 -#endif
4.191 -
4.192 -#ifndef LEMON_ASSERT_HANDLER
4.193 -# if defined LEMON_ASSERT_EXCEPTION
4.194 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
4.195 -# elif defined LEMON_ASSERT_FAILURE
4.196 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
4.197 -# elif defined LEMON_ASSERT_ABORT
4.198 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
4.199 -# else
4.200 -# define LEMON_DISABLE_ASSERTS
4.201 -# endif
4.202 -#endif
4.203 -
4.204 -#ifdef DOXYGEN
4.205 -
4.206 -/// \brief Macro for assertions with customizable message
4.207 -///
4.208 -/// Macro for assertions with customizable message.
4.209 -///
4.210 -/// The assertions are disabled in the default behaviour. You can
4.211 -/// enable the assertions with the
4.212 -/// \code
4.213 -/// #define LEMON_ENABLE_ASSERTS
4.214 -/// \endcode
4.215 -/// Then an assert
4.216 -/// provides a log on the standard error about the assertion and aborts
4.217 -/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the
4.218 -/// program keeps on running).
4.219 -/// By defining LEMON_ASSERT_FAILURE or
4.220 -/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the
4.221 -/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT
4.222 -/// will always throw an \c AssertionFailedError exception with
4.223 -/// the \c msg error message. By using
4.224 -/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.
4.225 -///
4.226 -/// The LEMON_ASSERT macro should be called with the \c exp parameter
4.227 -/// which should be an expression convertible to bool. If the given
4.228 -/// parameter is false the assertion is raised and one of the assertion
4.229 -/// behaviour will be activated. The \c msg should be either a const
4.230 -/// char* message or an exception. When the \c msg is an exception the
4.231 -/// \ref lemon::Exception::what() "what()" function is called to retrieve and
4.232 -/// display the error message.
4.233 -///
4.234 -/// \todo We should provide some way to reset to the default behaviour,
4.235 -/// shouldn't we?
4.236 -///
4.237 -/// \todo This whole 'assert' business should be placed in a separate
4.238 -/// include file. The boost assert is not guarded by header sentries
4.239 -/// which may help to change the behaviour of the assertions in
4.240 -/// the files.
4.241 -///
4.242 -/// \todo __PRETTY_FUNCTION__ should be replaced by something
4.243 -/// compiler-independent, like BOOST_CURRENT_FUNCTION
4.244 -
4.245 -# define LEMON_ASSERT(exp, msg) \
4.246 - (static_cast<void> (!!(exp) ? 0 : ( \
4.247 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
4.248 - __PRETTY_FUNCTION__, \
4.249 - msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
4.250 -
4.251 -#else
4.252 -# if defined LEMON_DISABLE_ASSERTS
4.253 -
4.254 -# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
4.255 -
4.256 -# else
4.257 -# define LEMON_ASSERT(exp, msg) \
4.258 - (static_cast<void> (!!(exp) ? 0 : ( \
4.259 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
4.260 - __PRETTY_FUNCTION__, \
4.261 - msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
4.262 -# endif
4.263 -#endif
4.264 -
4.265 -/**
4.266 - * \brief Macro for mark not yet implemented features.
4.267 - *
4.268 - * \todo Is this the right place for this? It should be used only in
4.269 - * modules under development.
4.270 - *
4.271 - * \todo __PRETTY_FUNCTION__ should be replaced by something
4.272 - * compiler-independent, like BOOST_CURRENT_FUNCTION
4.273 - */
4.274 -
4.275 -#define LEMON_FIXME(msg) \
4.276 - (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
4.277 - "FIXME: " msg))
5.1 --- a/test/Makefile.am Fri Mar 21 22:25:40 2008 +0000
5.2 +++ b/test/Makefile.am Tue Mar 25 16:36:44 2008 +0100
5.3 @@ -12,6 +12,7 @@
5.4 test/dfs_test \
5.5 test/digraph_test \
5.6 test/dim_test \
5.7 + test/error_test \
5.8 test/graph_test \
5.9 test/kruskal_test \
5.10 test/maps_test \
5.11 @@ -28,7 +29,7 @@
5.12 test_dfs_test_SOURCES = test/dfs_test.cc
5.13 test_digraph_test_SOURCES = test/digraph_test.cc
5.14 test_dim_test_SOURCES = test/dim_test.cc
5.15 -#test_error_test_SOURCES = test/error_test.cc
5.16 +test_error_test_SOURCES = test/error_test.cc
5.17 test_graph_test_SOURCES = test/graph_test.cc
5.18 # test_heap_test_SOURCES = test/heap_test.cc
5.19 test_kruskal_test_SOURCES = test/kruskal_test.cc
6.1 --- a/test/error_test.cc Fri Mar 21 22:25:40 2008 +0000
6.2 +++ b/test/error_test.cc Tue Mar 25 16:36:44 2008 +0100
6.3 @@ -22,47 +22,242 @@
6.4 #include "test_tools.h"
6.5
6.6 using namespace lemon;
6.7 -using std::cout;
6.8 -using std::endl;
6.9
6.10 -void faulty_fn() {
6.11 - fault("This is a fault message");
6.12 +#ifdef LEMON_ENABLE_ASSERTS
6.13 +#undef LEMON_ENABLE_ASSERTS
6.14 +#endif
6.15 +
6.16 +#ifdef LEMON_DISABLE_ASSERTS
6.17 +#undef LEMON_DISABLE_ASSERTS
6.18 +#endif
6.19 +
6.20 +//checking disabled asserts
6.21 +#define LEMON_DISABLE_ASSERTS
6.22 +#include <lemon/assert.h>
6.23 +
6.24 +void no_assertion_text_disable() {
6.25 + LEMON_ASSERT(true, "This is a fault message");
6.26 }
6.27
6.28 -void exception_fn() {
6.29 - throw Exception("This is a function throwing exception with some args: ")
6.30 - << 5 << ", " << 18;
6.31 +void no_assertion_exception_disable() {
6.32 + LEMON_ASSERT(true, Exception());
6.33 }
6.34
6.35 -void unfinished_fn() {
6.36 - LEMON_FIXME("unfinished_fn() is unfinished!");
6.37 +void assertion_text_disable() {
6.38 + LEMON_ASSERT(false, "This is a fault message");
6.39 }
6.40
6.41 +void assertion_exception_disable() {
6.42 + LEMON_ASSERT(false, Exception());
6.43 +}
6.44
6.45 -int main() {
6.46 +void fixme_disable() {
6.47 + LEMON_FIXME("fixme_disable() is fixme!");
6.48 +}
6.49 +
6.50 +void check_assertion_disable() {
6.51 + no_assertion_text_disable();
6.52 + no_assertion_exception_disable();
6.53 + assertion_exception_disable();
6.54 + assertion_text_disable();
6.55 + fixme_disable();
6.56 +}
6.57 +#undef LEMON_DISABLE_ASSERTS
6.58 +
6.59 +
6.60 +#define LEMON_ASSERT_ERROR
6.61 +#include <lemon/assert.h>
6.62 +
6.63 +void no_assertion_text_error() {
6.64 + LEMON_ASSERT(true, "This is a fault message");
6.65 +}
6.66 +
6.67 +void no_assertion_exception_error() {
6.68 + LEMON_ASSERT(true, Exception());
6.69 +}
6.70 +
6.71 +void assertion_text_error() {
6.72 + LEMON_ASSERT(false, "This is a fault message");
6.73 +}
6.74 +
6.75 +void assertion_exception_error() {
6.76 + LEMON_ASSERT(false, Exception());
6.77 +}
6.78 +
6.79 +void fixme_error() {
6.80 + LEMON_FIXME("fixme_error() is fixme!");
6.81 +}
6.82 +
6.83 +void check_assertion_error() {
6.84 + no_assertion_text_error();
6.85 + no_assertion_exception_error();
6.86 try {
6.87 - faulty_fn();
6.88 - check(false, "A faulty function did not fail.");
6.89 - }
6.90 - catch(const Exception &e) {
6.91 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
6.92 + assertion_exception_error();
6.93 + check(false, "Assertion error");
6.94 + } catch (const AssertionFailedError& e) {
6.95 }
6.96
6.97 try {
6.98 - exception_fn();
6.99 - check(false, "The function did not throw Exception.");
6.100 - }
6.101 - catch(const Exception &e) {
6.102 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
6.103 + assertion_text_error();
6.104 + check(false, "Assertion error");
6.105 + } catch (const AssertionFailedError& e) {
6.106 }
6.107
6.108 try {
6.109 - unfinished_fn();
6.110 - check(false, "FIXME macro does not work.");
6.111 + fixme_error();
6.112 + check(false, "Assertion error");
6.113 + } catch (const AssertionFailedError& e) {
6.114 }
6.115 - catch(const Exception &e) {
6.116 - cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
6.117 +}
6.118 +#undef LEMON_ASSERT_ERROR
6.119 +
6.120 +#define LEMON_ASSERT_EXCEPTION
6.121 +#include <lemon/assert.h>
6.122 +
6.123 +void no_assertion_text_exception() {
6.124 + LEMON_ASSERT(true, "This is a fault message");
6.125 +}
6.126 +
6.127 +void no_assertion_exception_exception() {
6.128 + LEMON_ASSERT(true, Exception());
6.129 +}
6.130 +
6.131 +void assertion_text_exception() {
6.132 + LEMON_ASSERT(false, "This is a fault message");
6.133 +}
6.134 +
6.135 +void assertion_exception_exception() {
6.136 + LEMON_ASSERT(false, Exception());
6.137 +}
6.138 +
6.139 +void fixme_exception() {
6.140 + LEMON_FIXME("fixme_exception() is fixme!");
6.141 +}
6.142 +
6.143 +void check_assertion_exception() {
6.144 + no_assertion_text_exception();
6.145 + no_assertion_exception_exception();
6.146 + try {
6.147 + assertion_exception_exception();
6.148 + check(false, "Assertion error");
6.149 + } catch (const Exception& e) {
6.150 }
6.151
6.152 + try {
6.153 + assertion_text_exception();
6.154 + check(false, "Assertion error");
6.155 + } catch (const AssertionFailedError& e) {
6.156 + }
6.157 +
6.158 + try {
6.159 + assertion_text_exception();
6.160 + check(false, "Assertion error");
6.161 + } catch (const AssertionFailedError& e) {
6.162 + }
6.163 +
6.164 + try {
6.165 + fixme_exception();
6.166 + check(false, "Assertion error");
6.167 + } catch (const AssertionFailedError& e) {
6.168 + }
6.169 +}
6.170 +#undef LEMON_ASSERT_EXCEPTION
6.171 +
6.172 +#define LEMON_ASSERT_LOG
6.173 +
6.174 +#include <lemon/assert.h>
6.175 +
6.176 +void no_assertion_text_log() {
6.177 + LEMON_ASSERT(true, "This is a fault message");
6.178 +}
6.179 +
6.180 +void no_assertion_exception_log() {
6.181 + LEMON_ASSERT(true, Exception());
6.182 +}
6.183 +
6.184 +void assertion_text_log() {
6.185 + LEMON_ASSERT(false, "This is a fault message");
6.186 +}
6.187 +
6.188 +void assertion_exception_log() {
6.189 + LEMON_ASSERT(false, Exception());
6.190 +}
6.191 +
6.192 +void fixme_log() {
6.193 + LEMON_FIXME("fixme_log() is fixme!");
6.194 +}
6.195 +
6.196 +void check_assertion_log() {
6.197 + no_assertion_text_log();
6.198 + no_assertion_exception_log();
6.199 + std::cerr << "The next 3 failure messages are expected: " << std::endl;
6.200 + assertion_exception_log();
6.201 + assertion_text_log();
6.202 + fixme_log();
6.203 + std::cerr << "End of expected error messages" << std::endl;
6.204 +}
6.205 +#undef LEMON_ASSERT_LOG
6.206 +
6.207 +#define LEMON_ASSERT_CUSTOM
6.208 +
6.209 +static int cnt = 0;
6.210 +void my_assert_handler(const char*, int, const char*,
6.211 + const char*, const char*) {
6.212 + ++cnt;
6.213 +}
6.214 +
6.215 +void my_assert_handler(const char*, int, const char*,
6.216 + const std::exception&, const char*) {
6.217 + ++cnt;
6.218 +}
6.219 +
6.220 +void my_assert_handler(const char*, int, const char*,
6.221 + const std::string&, const char*) {
6.222 + ++cnt;
6.223 +}
6.224 +
6.225 +
6.226 +#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
6.227 +#include <lemon/assert.h>
6.228 +
6.229 +void no_assertion_text_custom() {
6.230 + LEMON_ASSERT(true, "This is a fault message");
6.231 +}
6.232 +
6.233 +void no_assertion_exception_custom() {
6.234 + LEMON_ASSERT(true, Exception());
6.235 +}
6.236 +
6.237 +void assertion_text_custom() {
6.238 + LEMON_ASSERT(false, "This is a fault message");
6.239 +}
6.240 +
6.241 +void assertion_exception_custom() {
6.242 + LEMON_ASSERT(false, Exception());
6.243 +}
6.244 +
6.245 +void fixme_custom() {
6.246 + LEMON_FIXME("fixme_custom() is fixme!");
6.247 +}
6.248 +
6.249 +void check_assertion_custom() {
6.250 + no_assertion_text_custom();
6.251 + no_assertion_exception_custom();
6.252 + assertion_exception_custom();
6.253 + assertion_text_custom();
6.254 + fixme_custom();
6.255 + check(cnt == 3, "The custom assert handler does not work");
6.256 +}
6.257 +
6.258 +#undef LEMON_ASSERT_CUSTOM
6.259 +
6.260 +
6.261 +int main() {
6.262 + check_assertion_disable();
6.263 + check_assertion_error();
6.264 + check_assertion_exception();
6.265 + check_assertion_log();
6.266 + check_assertion_custom();
6.267 +
6.268 return 0;
6.269 }