$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55515 - in trunk/boost/test: . impl output
From: gennadiy.rozental_at_[hidden]
Date: 2009-08-10 20:29:40
Author: rogeeff
Date: 2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
New Revision: 55515
URL: http://svn.boost.org/trac/boost/changeset/55515
Log:
support for exception inception location added
support for boost::exception added
Text files modified: 
   trunk/boost/test/execution_monitor.hpp             |    19 +++-                                    
   trunk/boost/test/impl/compiler_log_formatter.ipp   |    12 +-                                      
   trunk/boost/test/impl/execution_monitor.ipp        |   153 ++++++++++++++++++++++++++++++++------- 
   trunk/boost/test/impl/unit_test_log.ipp            |     2                                         
   trunk/boost/test/impl/xml_log_formatter.ipp        |    12 ++                                      
   trunk/boost/test/output/compiler_log_formatter.hpp |     2                                         
   trunk/boost/test/output/xml_log_formatter.hpp      |     2                                         
   trunk/boost/test/unit_test_log_formatter.hpp       |     9 ++                                      
   8 files changed, 166 insertions(+), 45 deletions(-)
Modified: trunk/boost/test/execution_monitor.hpp
==============================================================================
--- trunk/boost/test/execution_monitor.hpp	(original)
+++ trunk/boost/test/execution_monitor.hpp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -113,18 +113,27 @@
         //  is unreasonable to continue execution.
     };
     
+    struct BOOST_TEST_DECL location {
+        explicit    location( char const* file_name = 0, size_t line_num = 0, char const* func = 0 );
+
+        const_string    m_file_name;
+        size_t          m_line_num;
+        const_string    m_function;
+    };
+
     // Constructor
-    execution_exception( error_code ec_, const_string what_msg_ ) // max length 256 inc '\0'
-    : m_error_code( ec_ ), m_what( what_msg_ ) {}
+    execution_exception( error_code ec_, const_string what_msg_, location const& location_ ); // max length 256 inc '\0'
 
-    // access methods
-    error_code      code() const { return m_error_code; }
-    const_string    what() const { return m_what; }
+    // Access methods
+    error_code      code() const    { return m_error_code; }
+    const_string    what() const    { return m_what; }
+    location const& where() const   { return m_location; }
 
 private:
     // Data members
     error_code      m_error_code;
     const_string    m_what;
+    location        m_location;
 }; // execution_exception
 
 // ************************************************************************** //
Modified: trunk/boost/test/impl/compiler_log_formatter.ipp
==============================================================================
--- trunk/boost/test/impl/compiler_log_formatter.ipp	(original)
+++ trunk/boost/test/impl/compiler_log_formatter.ipp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -108,16 +108,14 @@
 //____________________________________________________________________________//
 
 void
-compiler_log_formatter::log_exception( std::ostream& output, log_checkpoint_data const& checkpoint_data, const_string explanation )
+compiler_log_formatter::log_exception( std::ostream& output, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
 {
-    print_prefix( output, BOOST_TEST_L( "unknown location" ), 0 );
-    output << "fatal error in \"" << framework::current_test_case().p_name << "\": ";
+    execution_exception::location const& loc = ex.where();
+    print_prefix( output, loc.m_file_name, loc.m_line_num );
 
-    if( !explanation.is_empty() )
-        output << explanation;
-    else
-        output << "uncaught exception, system error or abort requested";
+    output << "fatal error in \"" << (loc.m_function.is_empty() ? framework::current_test_case().p_name.get() : loc.m_function ) << "\": ";
 
+    output << ex.what();
 
     if( !checkpoint_data.m_file_name.is_empty() ) {
         output << '\n';
Modified: trunk/boost/test/impl/execution_monitor.ipp
==============================================================================
--- trunk/boost/test/impl/execution_monitor.ipp	(original)
+++ trunk/boost/test/impl/execution_monitor.ipp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -33,6 +33,8 @@
 // Boost
 #include <boost/cstdlib.hpp>    // for exit codes
 #include <boost/config.hpp>     // for workarounds
+#include <boost/exception/get_error_info.hpp> // for get_error_info
+#include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
 
 // STL
 #include <string>               // for std::string
@@ -218,21 +220,56 @@
 #  define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
 #endif
 
+template <typename ErrorInfo>
+typename ErrorInfo::value_type
+extract( boost::exception const* ex )
+{
+    if( !ex )
+        return 0;
+
+    typename ErrorInfo::value_type const * val = boost::get_error_info<ErrorInfo>( *ex );
+
+    return val ? *val : 0;
+}
+
+//____________________________________________________________________________//
+
 static void
-report_error( execution_exception::error_code ec, char const* format, ... )
+report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, va_list* args )
 {
     static const int REPORT_ERROR_BUFFER_SIZE = 512;
     static char buf[REPORT_ERROR_BUFFER_SIZE];
 
+    BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, *args ); 
+    buf[sizeof(buf)-1] = 0;
+
+    va_end( *args );
+
+    throw execution_exception( ec, buf, execution_exception::location( extract<throw_file>( be ), 
+                                                                       extract<throw_line>( be ),
+                                                                       extract<throw_function>( be ) ) );
+}
+
+//____________________________________________________________________________//
+
+static void
+report_error( execution_exception::error_code ec, char const* format, ... )
+{
     va_list args;
     va_start( args, format );
 
-    BOOST_TEST_VSNPRINTF( buf, sizeof(buf)-1, format, args ); 
-    buf[sizeof(buf)-1] = 0;
+    report_error( ec, 0, format, &args );
+}
 
-    va_end( args );
+//____________________________________________________________________________//
+
+static void
+report_error( execution_exception::error_code ec, boost::exception const* be, char const* format, ... )
+{
+    va_list args;
+    va_start( args, format );
 
-    throw execution_exception( ec, buf );
+    report_error( ec, be, format, &args );
 }
 
 //____________________________________________________________________________//
@@ -1173,60 +1210,105 @@
     //  easier than answering questions about non-const usage.
 
     catch( char const* ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "C string: %s", ex ); }
+      { detail::report_error( execution_exception::cpp_exception_error,
+                              "C string: %s", ex ); }
     catch( std::string const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::string: %s", ex.c_str() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              "std::string: %s", ex.c_str() ); }
 
     //  std:: exceptions
 
     catch( std::bad_alloc const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_alloc: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_alloc: %s", ex.what() ); }
 
 #if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
     catch( std::bad_cast const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast" ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_cast" ); }
     catch( std::bad_typeid const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid" ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_typeid" ); }
 #else
     catch( std::bad_cast const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_cast: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_cast: %s", ex.what() ); }
     catch( std::bad_typeid const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_typeid: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_typeid: %s", ex.what() ); }
 #endif
 
     catch( std::bad_exception const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::bad_exception: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::bad_exception: %s", ex.what() ); }
     catch( std::domain_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::domain_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::domain_error: %s", ex.what() ); }
     catch( std::invalid_argument const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::invalid_argument: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::invalid_argument: %s", ex.what() ); }
     catch( std::length_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::length_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::length_error: %s", ex.what() ); }
     catch( std::out_of_range const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::out_of_range: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::out_of_range: %s", ex.what() ); }
     catch( std::range_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::range_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::range_error: %s", ex.what() ); }
     catch( std::overflow_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::overflow_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::overflow_error: %s", ex.what() ); }
     catch( std::underflow_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::underflow_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::underflow_error: %s", ex.what() ); }
     catch( std::logic_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::logic_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::logic_error: %s", ex.what() ); }
     catch( std::runtime_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::runtime_error: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::runtime_error: %s", ex.what() ); }
     catch( std::exception const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "std::exception: %s", ex.what() ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              current_exception_cast<boost::exception const>(),
+                              "std::exception: %s", ex.what() ); }
+
+    catch( boost::exception const& ex )
+    { detail::report_error( execution_exception::cpp_exception_error, 
+                            &ex,
+                            "unknown boost::exception" ); }
+
+    // system errors
     catch( system_error const& ex )
-      { detail::report_error( execution_exception::cpp_exception_error, "system_error produced by: %s: %s", 
-                              ex.p_failed_exp.get(), 
-                              std::strerror( ex.p_errno ) ); }
+      { detail::report_error( execution_exception::cpp_exception_error, 
+                              "system_error produced by: %s: %s", ex.p_failed_exp.get(), std::strerror( ex.p_errno ) ); }
     catch( detail::system_signal_exception const& ex )
       { ex.report(); }
+
+    // not an error
     catch( execution_aborted const& )
       { return 0; }
+
+    // just forward
     catch( execution_exception const& )
       { throw; }
 
+    // unknown error
     catch( ... )
       { detail::report_error( execution_exception::cpp_exception_error, "unknown type" ); }
 
@@ -1248,13 +1330,30 @@
 , p_failed_exp( exp )
 {}
 
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// **************              execution_exception             ************** //
+// ************************************************************************** //
+
+execution_exception::execution_exception( error_code ec_, const_string what_msg_, location const& location_ )
+: m_error_code( ec_ )
+, m_what( what_msg_.empty() ? BOOST_TEST_L( "uncaught exception, system error or abort requested" ) : what_msg_ )
+, m_location( location_ )
+{}
 
 //____________________________________________________________________________//
 
-} // namespace boost
+execution_exception::location::location( char const* file_name, size_t line_num, char const* func )
+: m_file_name( file_name ? file_name : "unknown location" )
+, m_line_num( line_num )
+, m_function( func )
+{}
 
 //____________________________________________________________________________//
 
+} // namespace boost
+
 #include <boost/test/detail/enable_warnings.hpp>
 
 #endif // BOOST_TEST_EXECUTION_MONITOR_IPP_012205GER
Modified: trunk/boost/test/impl/unit_test_log.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_log.ipp	(original)
+++ trunk/boost/test/impl/unit_test_log.ipp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -238,7 +238,7 @@
         if( s_log_impl().m_entry_in_progress )
             *this << log::end();
 
-        s_log_impl().m_log_formatter->log_exception( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex.what() );
+        s_log_impl().m_log_formatter->log_exception( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex );
     }
 }
 
Modified: trunk/boost/test/impl/xml_log_formatter.ipp
==============================================================================
--- trunk/boost/test/impl/xml_log_formatter.ipp	(original)
+++ trunk/boost/test/impl/xml_log_formatter.ipp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -110,9 +110,17 @@
 //____________________________________________________________________________//
 
 void
-xml_log_formatter::log_exception( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, const_string explanation )
+xml_log_formatter::log_exception( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
 {
-    ostr << "<Exception>" << pcdata() << explanation;
+    execution_exception::location const& loc = ex.where();
+
+    ostr << "<Exception file" << attr_value() << loc.m_file_name
+         << " line"           << attr_value() << loc.m_line_num;
+
+    if( !loc.m_function.is_empty() )
+        ostr << " function"   << attr_value() << loc.m_function;
+
+    ostr << ">" << pcdata() << ex.what();
 
     if( !checkpoint_data.m_file_name.is_empty() ) {
         ostr << "<LastCheckpoint file" << attr_value() << checkpoint_data.m_file_name
Modified: trunk/boost/test/output/compiler_log_formatter.hpp
==============================================================================
--- trunk/boost/test/output/compiler_log_formatter.hpp	(original)
+++ trunk/boost/test/output/compiler_log_formatter.hpp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -44,7 +44,7 @@
     void    test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
     void    test_unit_skipped( std::ostream&, test_unit const& tu );
 
-    void    log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation );
+    void    log_exception( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
 
     void    log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
     void    log_entry_value( std::ostream&, const_string value );
Modified: trunk/boost/test/output/xml_log_formatter.hpp
==============================================================================
--- trunk/boost/test/output/xml_log_formatter.hpp	(original)
+++ trunk/boost/test/output/xml_log_formatter.hpp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -47,7 +47,7 @@
     void    test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
     void    test_unit_skipped( std::ostream&, test_unit const& tu );
 
-    void    log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation );
+    void    log_exception( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
 
     void    log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
     using   unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
Modified: trunk/boost/test/unit_test_log_formatter.hpp
==============================================================================
--- trunk/boost/test/unit_test_log_formatter.hpp	(original)
+++ trunk/boost/test/unit_test_log_formatter.hpp	2009-08-10 20:29:39 EDT (Mon, 10 Aug 2009)
@@ -20,6 +20,8 @@
 #include <boost/test/detail/log_level.hpp>
 #include <boost/test/detail/fwd_decl.hpp>
 
+#include <boost/test/execution_monitor.hpp>
+
 // STL
 #include <iosfwd>
 #include <string> // for std::string
@@ -96,7 +98,12 @@
     virtual void        test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) = 0;
     virtual void        test_unit_skipped( std::ostream&, test_unit const& ) = 0;
 
-    virtual void        log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation ) = 0;
+    virtual void        log_exception( std::ostream& os, log_checkpoint_data const& cd, execution_exception const& ex )
+    {
+        // for backward compatibility
+        log_exception( os, cd, ex.what() );
+    }
+    virtual void        log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation ) {}
 
     virtual void        log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) = 0;
     virtual void        log_entry_value( std::ostream&, const_string value ) = 0;