Chris@16: //Copyright (c) 2006-2010 Emil Dotchevski and Reverge Studios, Inc. Chris@16: Chris@16: //Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef UUID_0552D49838DD11DD90146B8956D89593 Chris@16: #define UUID_0552D49838DD11DD90146B8956D89593 Chris@16: #if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma GCC system_header Chris@16: #endif Chris@16: #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma warning(push,1) Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #ifndef BOOST_NO_RTTI Chris@101: #include Chris@101: #endif Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifndef BOOST_NO_EXCEPTIONS Chris@16: #include Chris@16: namespace Chris@16: boost Chris@16: { Chris@16: namespace Chris@16: exception_detail Chris@16: { Chris@16: std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool, bool ); Chris@16: } Chris@16: Chris@16: inline Chris@16: std::string Chris@16: current_exception_diagnostic_information( bool verbose=true) Chris@16: { Chris@16: boost::exception const * be=current_exception_cast(); Chris@16: std::exception const * se=current_exception_cast(); Chris@16: if( be || se ) Chris@16: return exception_detail::diagnostic_information_impl(be,se,true,verbose); Chris@16: else Chris@16: return "No diagnostic information available."; Chris@16: } Chris@16: } Chris@16: #endif Chris@16: Chris@16: namespace Chris@16: boost Chris@16: { Chris@16: namespace Chris@16: exception_detail Chris@16: { Chris@16: inline Chris@16: exception const * Chris@16: get_boost_exception( exception const * e ) Chris@16: { Chris@16: return e; Chris@16: } Chris@16: Chris@16: inline Chris@16: exception const * Chris@16: get_boost_exception( ... ) Chris@16: { Chris@16: return 0; Chris@16: } Chris@16: Chris@16: inline Chris@16: std::exception const * Chris@16: get_std_exception( std::exception const * e ) Chris@16: { Chris@16: return e; Chris@16: } Chris@16: Chris@16: inline Chris@16: std::exception const * Chris@16: get_std_exception( ... ) Chris@16: { Chris@16: return 0; Chris@16: } Chris@16: Chris@16: inline Chris@16: char const * Chris@16: get_diagnostic_information( exception const & x, char const * header ) Chris@16: { Chris@16: #ifndef BOOST_NO_EXCEPTIONS Chris@16: try Chris@16: { Chris@16: #endif Chris@16: error_info_container * c=x.data_.get(); Chris@16: if( !c ) Chris@16: x.data_.adopt(c=new exception_detail::error_info_container_impl); Chris@16: char const * di=c->diagnostic_information(header); Chris@16: BOOST_ASSERT(di!=0); Chris@16: return di; Chris@16: #ifndef BOOST_NO_EXCEPTIONS Chris@16: } Chris@16: catch(...) Chris@16: { Chris@16: return 0; Chris@16: } Chris@16: #endif Chris@16: } Chris@16: Chris@16: inline Chris@16: std::string Chris@16: diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what, bool verbose ) Chris@16: { Chris@16: if( !be && !se ) Chris@16: return "Unknown exception."; Chris@16: #ifndef BOOST_NO_RTTI Chris@16: if( !be ) Chris@16: be=dynamic_cast(se); Chris@16: if( !se ) Chris@16: se=dynamic_cast(be); Chris@16: #endif Chris@16: char const * wh=0; Chris@16: if( with_what && se ) Chris@16: { Chris@16: wh=se->what(); Chris@16: if( be && exception_detail::get_diagnostic_information(*be,0)==wh ) Chris@16: return wh; Chris@16: } Chris@16: std::ostringstream tmp; Chris@16: if( be && verbose ) Chris@16: { Chris@16: char const * const * f=get_error_info(*be); Chris@16: int const * l=get_error_info(*be); Chris@16: char const * const * fn=get_error_info(*be); Chris@16: if( !f && !l && !fn ) Chris@16: tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n"; Chris@16: else Chris@16: { Chris@16: if( f ) Chris@16: { Chris@16: tmp << *f; Chris@16: if( int const * l=get_error_info(*be) ) Chris@16: tmp << '(' << *l << "): "; Chris@16: } Chris@16: tmp << "Throw in function "; Chris@16: if( char const * const * fn=get_error_info(*be) ) Chris@16: tmp << *fn; Chris@16: else Chris@16: tmp << "(unknown)"; Chris@16: tmp << '\n'; Chris@16: } Chris@16: } Chris@16: #ifndef BOOST_NO_RTTI Chris@16: if ( verbose ) Chris@16: tmp << std::string("Dynamic exception type: ") << Chris@101: core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n'; Chris@16: #endif Chris@16: if( with_what && se && verbose ) Chris@16: tmp << "std::exception::what: " << wh << '\n'; Chris@16: if( be ) Chris@16: if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) ) Chris@16: if( *s ) Chris@16: return std::string(s); Chris@16: return tmp.str(); Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: std::string Chris@16: diagnostic_information( T const & e, bool verbose=true ) Chris@16: { Chris@16: return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true,verbose); Chris@16: } Chris@16: Chris@16: inline Chris@16: char const * Chris@16: diagnostic_information_what( exception const & e, bool verbose=true ) throw() Chris@16: { Chris@16: char const * w=0; Chris@16: #ifndef BOOST_NO_EXCEPTIONS Chris@16: try Chris@16: { Chris@16: #endif Chris@16: (void) exception_detail::diagnostic_information_impl(&e,0,false,verbose); Chris@16: if( char const * di=exception_detail::get_diagnostic_information(e,0) ) Chris@16: return di; Chris@16: else Chris@16: return "Failed to produce boost::diagnostic_information_what()"; Chris@16: #ifndef BOOST_NO_EXCEPTIONS Chris@16: } Chris@16: catch( Chris@16: ... ) Chris@16: { Chris@16: } Chris@16: #endif Chris@16: return w; Chris@16: } Chris@16: } Chris@16: Chris@16: #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: #endif