[Lemon-commits] Balazs Dezso: Reworking assertions and moving to...

Lemon HG hg at lemon.cs.elte.hu
Wed Mar 26 17:33:17 CET 2008


details:   http://lemon.cs.elte.hu/hg/lemon/rev/889d0c289d19
changeset: 108:889d0c289d19
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Tue Mar 25 16:36:44 2008 +0100
description:
	Reworking assertions and moving to distinict file

diffstat:

6 files changed, 590 insertions(+), 284 deletions(-)
lemon/Makefile.am  |    1 
lemon/arg_parser.h |    2 
lemon/assert.h     |  364 ++++++++++++++++++++++++++++++++++++++++++++++++++++
lemon/error.h      |  261 -------------------------------------
test/Makefile.am   |    3 
test/error_test.cc |  243 +++++++++++++++++++++++++++++++---

diffs (truncated from 959 to 300 lines):

diff -r 31a2e6d28f61 -r 889d0c289d19 lemon/Makefile.am
--- a/lemon/Makefile.am	Fri Mar 21 22:25:40 2008 +0000
+++ b/lemon/Makefile.am	Tue Mar 25 16:36:44 2008 +0100
@@ -17,6 +17,7 @@
 
 lemon_HEADERS += \
         lemon/arg_parser.h \
+	lemon/assert.h \
         lemon/bfs.h \
         lemon/bin_heap.h \
         lemon/dfs.h \
diff -r 31a2e6d28f61 -r 889d0c289d19 lemon/arg_parser.h
--- a/lemon/arg_parser.h	Fri Mar 21 22:25:40 2008 +0000
+++ b/lemon/arg_parser.h	Tue Mar 25 16:36:44 2008 +0100
@@ -26,7 +26,7 @@
 #include <iostream>
 #include <sstream>
 #include <algorithm>
-#include <lemon/error.h>
+#include <lemon/assert.h>
 
 ///\ingroup misc
 ///\file
diff -r 31a2e6d28f61 -r 889d0c289d19 lemon/assert.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/assert.h	Tue Mar 25 16:36:44 2008 +0100
@@ -0,0 +1,364 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_ASSERT_H
+#define LEMON_ASSERT_H
+
+/// \ingroup exceptions
+/// \file
+/// \brief Extended assertion handling
+
+#include <lemon/error.h>
+
+namespace lemon {
+
+  /// @{
+
+  ///\e
+  class AssertionFailedError : public LogicError {
+  protected:
+    const char *_assertion;
+    const char *_file;
+    int _line;
+    const char *_function;
+    const char *_message;
+
+    mutable ExceptionMember<std::string> _message_holder;
+  public:
+    ///\e
+    AssertionFailedError(const char *file, int line, const char *function,
+			 const char *msg, const char *assertion = 0) :
+      _assertion(assertion), _file(file), _line(line), 
+      _function(function), _message(msg) {}
+
+    ///\e
+    const char* assertion() const { return _assertion; }
+    ///\e
+    const char* message() const { return _message; }
+    ///\e
+    const char* file() const { return _file; }
+    ///\e
+    const char* function() const { return _function; }
+    ///\e
+    int 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() {}
+  };
+
+
+  inline void assert_fail_log(const char *file, int line,
+			      const char *function,
+			      const std::exception& exception, 
+			      const char *assertion)
+  {
+    std::cerr << file << ":" << line << ": ";
+    if (function)
+      std::cerr << function << ": ";
+    std::cerr << exception.what();
+    if (assertion)
+      std::cerr << " (assertion '" << assertion << "' failed)";
+    std::cerr << std::endl;
+  }
+
+  inline void assert_fail_log(const char *file, int line, const char *function,
+			      const char *message, const char *assertion)
+  {
+    std::cerr << file << ":" << line << ": ";
+    if (function)
+      std::cerr << function << ": ";
+    std::cerr << message;
+    if (assertion)
+      std::cerr << " (assertion '" << assertion << "' failed)";
+    std::cerr << std::endl;
+  }
+
+  inline void assert_fail_log(const char *file, int line, const char *function, 
+			      const std::string& message, const char *assertion)
+  {
+    assert_fail_log(file, line, function, message.c_str(), assertion);
+  }
+
+  inline void assert_fail_abort(const char *file, int line, 
+				const char *function,
+				const std::exception& exception,
+				const char *assertion)
+  {
+    std::cerr << file << ":" << line << ": ";
+    if (function)
+      std::cerr << function << ": ";
+    std::cerr << exception.what();
+    if (assertion)
+      std::cerr << " (assertion '" << assertion << "' failed)";
+    std::cerr << std::endl;
+    std::abort();
+  }
+
+  inline void assert_fail_abort(const char *file, int line,
+				const char *function, const char* message,
+				const char *assertion)
+  {
+    std::cerr << file << ":" << line << ": ";
+    if (function)
+      std::cerr << function << ": ";
+    std::cerr << message;
+    if (assertion)
+      std::cerr << " (assertion '" << assertion << "' failed)";
+    std::cerr << std::endl;
+    std::abort();
+  }
+
+  inline void assert_fail_abort(const char *file, int line, 
+				const char *function, 
+				const std::string& message,
+				const char *assertion)
+  {
+    assert_fail_abort(file, line, function, message.c_str(), assertion);
+  }
+
+  inline void assert_fail_error(const char *file, int line, 
+				  const char *function,
+				  const std::exception& exception,
+				  const char *assertion)
+  {
+    throw AssertionFailedError(file, line, function, 
+			       exception.what(), assertion);
+  }
+
+  inline void assert_fail_error(const char *file, int line,
+				  const char *function, const char *message,
+				  const char *assertion)
+  {
+    throw AssertionFailedError(file, line, function, message, assertion);
+  }
+
+  inline void assert_fail_error(const char *file, int line,
+				  const char *function, 
+				  const std::string& message,
+				  const char *assertion)
+  {
+    assert_fail_error(file, line, function, message.c_str(), assertion);
+  }
+
+  template <typename Exception>
+  inline void assert_fail_exception(const char *, int, const char *,
+				    const Exception& exception,
+				    const char *, const std::exception* = 
+				    static_cast<const Exception*>(0))
+  {
+    throw exception;
+  }
+
+  inline void assert_fail_exception(const char *file, int line,
+				    const char *function, const char *message,
+				    const char *assertion)
+  {
+    throw AssertionFailedError(file, line, function, message, assertion);
+  }
+
+  inline void assert_fail_exception(const char *file, int line, 
+				    const char *function, 
+				    const std::string& message,
+				    const char *assertion)
+  {
+    assert_fail_exception(file, line, function, message.c_str(), assertion);
+  }
+
+/// @}
+
+}
+#endif // LEMON_ASSERT_H
+
+#undef LEMON_ASSERT
+#undef LEMON_FIXME
+
+#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
+  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
+  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
+  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
+  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
+#error "Lemon assertion system is not set properly"
+#endif
+
+#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
+     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
+     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
+     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
+     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
+     defined(LEMON_ENABLE_ASSERT)) &&			\
+  defined(LEMON_DISABLE_ASSERTS)
+#error "Lemon assertion system is not set properly"
+#endif
+
+
+#if defined LEMON_ASSERT_LOG
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
+#elif defined LEMON_ASSERT_ABORT
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
+#elif defined LEMON_ASSERT_ERROR
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
+#elif defined LEMON_ASSERT_EXCEPTION
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
+#elif defined LEMON_ASSERT_CUSTOM
+#  undef LEMON_ASSERT_HANDLER
+#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
+#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
+#  endif
+#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
+#elif defined LEMON_ENABLE_ASSERTS
+#  undef LEMON_ASSERT_HANDLER
+#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
+#else
+#  undef LEMON_ASSERT_HANDLER
+#endif
+
+
+#ifndef LEMON_FUNCTION_NAME
+#  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
+#endif
+
+#ifdef DOXYGEN
+
+/// \ingroup exceptions
+///
+/// \brief Macro for assertions with customizable message
+///
+/// Macro for assertions with customizable message.  
+/// \param exp An expression convertible to bool. If the expression is
+/// false, then an assertion is raised. The concrete behaviour depends
+/// on the settings of the assertion system.
+/// \param msg A \e const \e char*, a \e const std::string& or a \e
+/// const \e std::exception& parameter. The variable can be used to
+/// provide information about the circumstances of failed assertion.
+///
+/// The assertions are disabled in the default behaviour. You can
+/// enable the assertions with the following code:
+/// \code
+/// #define LEMON_ENABLE_ASSERTS
+/// \endcode



More information about the Lemon-commits mailing list