[857] | 1 | // boost/catch_exceptions.hpp -----------------------------------------------//
|
---|
| 2 |
|
---|
| 3 | // Copyright Beman Dawes 1995-2001. Distributed under the Boost
|
---|
| 4 | // Software License, Version 1.0. (See accompanying file
|
---|
| 5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
---|
| 6 |
|
---|
| 7 | // See http://www.boost.org/libs/test for documentation.
|
---|
| 8 |
|
---|
| 9 | // Revision History
|
---|
| 10 | // 13 Jun 01 report_exception() made inline. (John Maddock, Jesse Jones)
|
---|
| 11 | // 26 Feb 01 Numerous changes suggested during formal review. (Beman)
|
---|
| 12 | // 25 Jan 01 catch_exceptions.hpp code factored out of cpp_main.cpp.
|
---|
| 13 | // 22 Jan 01 Remove test_tools dependencies to reduce coupling.
|
---|
| 14 | // 5 Nov 00 Initial boost version (Beman Dawes)
|
---|
| 15 |
|
---|
| 16 | #ifndef BOOST_CATCH_EXCEPTIONS_HPP
|
---|
| 17 | #define BOOST_CATCH_EXCEPTIONS_HPP
|
---|
| 18 |
|
---|
| 19 | // header dependencies are deliberately restricted to the standard library
|
---|
| 20 | // to reduce coupling to other boost libraries.
|
---|
| 21 | #include <string> // for string
|
---|
| 22 | #include <new> // for bad_alloc
|
---|
| 23 | #include <typeinfo> // for bad_cast, bad_typeid
|
---|
| 24 | #include <exception> // for exception, bad_exception
|
---|
| 25 | #include <stdexcept> // for std exception hierarchy
|
---|
| 26 | #include <boost/cstdlib.hpp> // for exit codes
|
---|
| 27 | # if __GNUC__ != 2 || __GNUC_MINOR__ > 96
|
---|
| 28 | # include <ostream> // for ostream
|
---|
| 29 | # else
|
---|
| 30 | # include <iostream> // workaround GNU missing ostream header
|
---|
| 31 | # endif
|
---|
| 32 |
|
---|
| 33 | # if defined(__BORLANDC__) && (__BORLANDC__ <= 0x0551)
|
---|
| 34 | # define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT
|
---|
| 35 | # endif
|
---|
| 36 |
|
---|
| 37 | #if defined(MPW_CPLUS) && (MPW_CPLUS <= 0x890)
|
---|
| 38 | # define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT
|
---|
| 39 | namespace std { class bad_typeid { }; }
|
---|
| 40 | # endif
|
---|
| 41 |
|
---|
| 42 | namespace boost
|
---|
| 43 | {
|
---|
| 44 |
|
---|
| 45 | namespace detail
|
---|
| 46 | {
|
---|
| 47 | // A separate reporting function was requested during formal review.
|
---|
| 48 | inline void report_exception( std::ostream & os,
|
---|
| 49 | const char * name, const char * info )
|
---|
| 50 | { os << "\n** uncaught exception: " << name << " " << info << std::endl; }
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | // catch_exceptions ------------------------------------------------------//
|
---|
| 54 |
|
---|
| 55 | template< class Generator > // Generator is function object returning int
|
---|
| 56 | int catch_exceptions( Generator function_object,
|
---|
| 57 | std::ostream & out, std::ostream & err )
|
---|
| 58 | {
|
---|
| 59 | int result = 0; // quiet compiler warnings
|
---|
| 60 | bool exception_thrown = true; // avoid setting result for each excptn type
|
---|
| 61 |
|
---|
| 62 | #ifndef BOOST_NO_EXCEPTIONS
|
---|
| 63 | try
|
---|
| 64 | {
|
---|
| 65 | #endif
|
---|
| 66 | result = function_object();
|
---|
| 67 | exception_thrown = false;
|
---|
| 68 | #ifndef BOOST_NO_EXCEPTIONS
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | // As a result of hard experience with strangely interleaved output
|
---|
| 72 | // under some compilers, there is a lot of use of endl in the code below
|
---|
| 73 | // where a simple '\n' might appear to do.
|
---|
| 74 |
|
---|
| 75 | // The rules for catch & arguments are a bit different from function
|
---|
| 76 | // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't
|
---|
| 77 | // required, but it doesn't hurt and some programmers ask for it.
|
---|
| 78 |
|
---|
| 79 | catch ( const char * ex )
|
---|
| 80 | { detail::report_exception( out, "", ex ); }
|
---|
| 81 | catch ( const std::string & ex )
|
---|
| 82 | { detail::report_exception( out, "", ex.c_str() ); }
|
---|
| 83 |
|
---|
| 84 | // std:: exceptions
|
---|
| 85 | catch ( const std::bad_alloc & ex )
|
---|
| 86 | { detail::report_exception( out, "std::bad_alloc:", ex.what() ); }
|
---|
| 87 |
|
---|
| 88 | # ifndef BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT
|
---|
| 89 | catch ( const std::bad_cast & ex )
|
---|
| 90 | { detail::report_exception( out, "std::bad_cast:", ex.what() ); }
|
---|
| 91 | catch ( const std::bad_typeid & ex )
|
---|
| 92 | { detail::report_exception( out, "std::bad_typeid:", ex.what() ); }
|
---|
| 93 | # else
|
---|
| 94 | catch ( const std::bad_cast & )
|
---|
| 95 | { detail::report_exception( out, "std::bad_cast", "" ); }
|
---|
| 96 | catch ( const std::bad_typeid & )
|
---|
| 97 | { detail::report_exception( out, "std::bad_typeid", "" ); }
|
---|
| 98 | # endif
|
---|
| 99 |
|
---|
| 100 | catch ( const std::bad_exception & ex )
|
---|
| 101 | { detail::report_exception( out, "std::bad_exception:", ex.what() ); }
|
---|
| 102 | catch ( const std::domain_error & ex )
|
---|
| 103 | { detail::report_exception( out, "std::domain_error:", ex.what() ); }
|
---|
| 104 | catch ( const std::invalid_argument & ex )
|
---|
| 105 | { detail::report_exception( out, "std::invalid_argument:", ex.what() ); }
|
---|
| 106 | catch ( const std::length_error & ex )
|
---|
| 107 | { detail::report_exception( out, "std::length_error:", ex.what() ); }
|
---|
| 108 | catch ( const std::out_of_range & ex )
|
---|
| 109 | { detail::report_exception( out, "std::out_of_range:", ex.what() ); }
|
---|
| 110 | catch ( const std::range_error & ex )
|
---|
| 111 | { detail::report_exception( out, "std::range_error:", ex.what() ); }
|
---|
| 112 | catch ( const std::overflow_error & ex )
|
---|
| 113 | { detail::report_exception( out, "std::overflow_error:", ex.what() ); }
|
---|
| 114 | catch ( const std::underflow_error & ex )
|
---|
| 115 | { detail::report_exception( out, "std::underflow_error:", ex.what() ); }
|
---|
| 116 | catch ( const std::logic_error & ex )
|
---|
| 117 | { detail::report_exception( out, "std::logic_error:", ex.what() ); }
|
---|
| 118 | catch ( const std::runtime_error & ex )
|
---|
| 119 | { detail::report_exception( out, "std::runtime_error:", ex.what() ); }
|
---|
| 120 | catch ( const std::exception & ex )
|
---|
| 121 | { detail::report_exception( out, "std::exception:", ex.what() ); }
|
---|
| 122 |
|
---|
| 123 | catch ( ... )
|
---|
| 124 | { detail::report_exception( out, "unknown exception", "" ); }
|
---|
| 125 | #endif // BOOST_NO_EXCEPTIONS
|
---|
| 126 |
|
---|
| 127 | if ( exception_thrown ) result = boost::exit_exception_failure;
|
---|
| 128 |
|
---|
| 129 | if ( result != 0 && result != exit_success )
|
---|
| 130 | {
|
---|
| 131 | out << std::endl << "**** returning with error code "
|
---|
| 132 | << result << std::endl;
|
---|
| 133 | err
|
---|
| 134 | << "********** errors detected; see stdout for details ***********"
|
---|
| 135 | << std::endl;
|
---|
| 136 | }
|
---|
| 137 | #if !defined(BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE)
|
---|
| 138 | else { out << std::flush << "no errors detected" << std::endl; }
|
---|
| 139 | #endif
|
---|
| 140 | return result;
|
---|
| 141 | } // catch_exceptions
|
---|
| 142 |
|
---|
| 143 | } // boost
|
---|
| 144 |
|
---|
| 145 | #endif // BOOST_CATCH_EXCEPTIONS_HPP
|
---|
| 146 |
|
---|