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 |
|
---|