diff --git a/lemon/error.h b/lemon/error.h --- a/lemon/error.h +++ b/lemon/error.h @@ -93,7 +93,7 @@ std::auto_ptr<_Type> ptr; }; - /// Exception-safe convenient "error message" class. + /// Exception-safe convenient error message builder class. /// Helper class which provides a convenient ostream-like (operator << /// based) interface to create a string message. Mostly useful in @@ -413,263 +413,8 @@ virtual ~IoParameterError() throw() {} }; - - ///\e - class AssertionFailedError : public LogicError { - protected: - const char *assertion; - const char *file; - int line; - const char *function; - const char *message; - - mutable ExceptionMember _message_holder; - public: - ///\e - AssertionFailedError(const char *_file, int _line, const char *func, - const char *msg, const char *_assertion = 0) : - assertion(_assertion), file(_file), line(_line), function(func), - message(msg) {} - - ///\e - const char* get_assertion() const { return assertion; } - ///\e - const char* get_message() const { return message; } - ///\e - const char* get_file() const { return file; } - ///\e - const char* get_function() const { return function; } - ///\e - int get_line() const { return line; } - - - virtual const char* what() const throw() { - try { - std::ostringstream ostr; - ostr << file << ":" << line << ": "; - if( function ) - ostr << function << ": "; - ostr << message; - if( assertion ) - ostr << " (assertion '" << assertion << "' failed)"; - _message_holder.set(ostr.str()); - return ostr.str().c_str(); - } - catch(...) {} - if( _message_holder.valid() ) return _message_holder.get().c_str(); - return "lemon::AssertionFailedError"; - } - virtual ~AssertionFailedError() throw() {} - }; - - - /**************** Macros ****************/ - - - template - inline void assert_fail(const char *file, int line, - const char *func, - Exception exception, - const char *assertion = 0, - bool do_abort=true) - { - using namespace std; - cerr << file << ":" << line << ": "; - if (func) - cerr << func << ": "; - cerr << exception.what(); - if (assertion) - cerr << " (assertion '" << assertion << "' failed)"; - cerr << endl; - if (do_abort) - abort(); - } - - template <> - inline void assert_fail(const char *file, int line, - const char *func, - const char *message, - const char *assertion, - bool do_abort) - { - using namespace std; - cerr << file << ":" << line << ": "; - if (func) - cerr << func << ": "; - cerr << message; - if (assertion) - cerr << " (assertion '" << assertion << "' failed)"; - cerr << endl; - if (do_abort) - abort(); - } - - template <> - inline void assert_fail(const char *file, int line, - const char *func, - std::string message, - const char *assertion, - bool do_abort) - { - assert_fail(file, line, func, message.c_str(), assertion, do_abort); - } - - template - inline void assert_fail_failure(const char *file, int line, const char *func, - Exception exception, - const char *assertion = 0, - bool = true) - { - throw AssertionFailedError(file, line, func, exception.what(), assertion); - } - - template <> - inline void assert_fail_failure(const char *file, int line, - const char *func, - const char *message, - const char *assertion, - bool) - { - throw AssertionFailedError(file, line, func, message, assertion); - } - - template <> - inline void assert_fail_failure(const char *file, int line, - const char *func, - std::string message, - const char *assertion, - bool) - { - assert_fail_failure(file, line, func, message.c_str(), assertion, true); - } - - template - inline void assert_fail_exception(const char *file, int line, const char *func, - Exception exception, - const char *assertion = 0, bool = true) - { - throw exception; - } - - template <> - inline void assert_fail_exception(const char *file, int line, - const char *func, - const char *message, - const char *assertion, - bool) - { - throw AssertionFailedError(file, line, func, message, assertion); - } - - template <> - inline void assert_fail_exception(const char *file, int line, - const char *func, - std::string message, - const char *assertion, - bool) - { - assert_fail_exception(file, line, func, message.c_str(), assertion, true); - } - -/// @} + /// @} } + #endif // LEMON_ERROR_H - -#undef LEMON_ASSERT -#undef LEMON_FIXME - -#ifdef LEMON_ENABLE_ASSERTS -# define LEMON_ASSERT_ABORT -#endif - -#ifndef LEMON_ASSERT_DO_ABORT -# define LEMON_ASSERT_DO_ABORT 1 -#endif - -#ifndef LEMON_ASSERT_HANDLER -# if defined LEMON_ASSERT_EXCEPTION -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception -# elif defined LEMON_ASSERT_FAILURE -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure -# elif defined LEMON_ASSERT_ABORT -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail -# else -# define LEMON_DISABLE_ASSERTS -# endif -#endif - -#ifdef DOXYGEN - -/// \brief Macro for assertions with customizable message -/// -/// Macro for assertions with customizable message. -/// -/// The assertions are disabled in the default behaviour. You can -/// enable the assertions with the -/// \code -/// #define LEMON_ENABLE_ASSERTS -/// \endcode -/// Then an assert -/// provides a log on the standard error about the assertion and aborts -/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the -/// program keeps on running). -/// By defining LEMON_ASSERT_FAILURE or -/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the -/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT -/// will always throw an \c AssertionFailedError exception with -/// the \c msg error message. By using -/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown. -/// -/// The LEMON_ASSERT macro should be called with the \c exp parameter -/// which should be an expression convertible to bool. If the given -/// parameter is false the assertion is raised and one of the assertion -/// behaviour will be activated. The \c msg should be either a const -/// char* message or an exception. When the \c msg is an exception the -/// \ref lemon::Exception::what() "what()" function is called to retrieve and -/// display the error message. -/// -/// \todo We should provide some way to reset to the default behaviour, -/// shouldn't we? -/// -/// \todo This whole 'assert' business should be placed in a separate -/// include file. The boost assert is not guarded by header sentries -/// which may help to change the behaviour of the assertions in -/// the files. -/// -/// \todo __PRETTY_FUNCTION__ should be replaced by something -/// compiler-independent, like BOOST_CURRENT_FUNCTION - -# define LEMON_ASSERT(exp, msg) \ - (static_cast (!!(exp) ? 0 : ( \ - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ - __PRETTY_FUNCTION__, \ - msg, #exp, LEMON_ASSERT_DO_ABORT), 0))) - -#else -# if defined LEMON_DISABLE_ASSERTS - -# define LEMON_ASSERT(exp, msg) (static_cast (0)) - -# else -# define LEMON_ASSERT(exp, msg) \ - (static_cast (!!(exp) ? 0 : ( \ - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ - __PRETTY_FUNCTION__, \ - msg, #exp, LEMON_ASSERT_DO_ABORT), 0))) -# endif -#endif - -/** - * \brief Macro for mark not yet implemented features. - * - * \todo Is this the right place for this? It should be used only in - * modules under development. - * - * \todo __PRETTY_FUNCTION__ should be replaced by something - * compiler-independent, like BOOST_CURRENT_FUNCTION - */ - -#define LEMON_FIXME(msg) \ - (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - "FIXME: " msg))