]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | #include <ostream> // for ostream | |
28 | ||
29 | # if defined(__BORLANDC__) && (__BORLANDC__ <= 0x0551) | |
30 | # define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT | |
31 | # endif | |
32 | ||
33 | #if defined(MPW_CPLUS) && (MPW_CPLUS <= 0x890) | |
34 | # define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT | |
35 | namespace std { class bad_typeid { }; } | |
36 | # endif | |
37 | ||
38 | namespace boost | |
39 | { | |
40 | ||
41 | namespace detail | |
42 | { | |
43 | // A separate reporting function was requested during formal review. | |
44 | inline void report_exception( std::ostream & os, | |
45 | const char * name, const char * info ) | |
46 | { os << "\n** uncaught exception: " << name << " " << info << std::endl; } | |
47 | } | |
48 | ||
49 | // catch_exceptions ------------------------------------------------------// | |
50 | ||
51 | template< class Generator > // Generator is function object returning int | |
52 | int catch_exceptions( Generator function_object, | |
53 | std::ostream & out, std::ostream & err ) | |
54 | { | |
55 | int result = 0; // quiet compiler warnings | |
56 | bool exception_thrown = true; // avoid setting result for each excptn type | |
57 | ||
58 | #ifndef BOOST_NO_EXCEPTIONS | |
59 | try | |
60 | { | |
61 | #endif | |
62 | result = function_object(); | |
63 | exception_thrown = false; | |
64 | #ifndef BOOST_NO_EXCEPTIONS | |
65 | } | |
66 | ||
67 | // As a result of hard experience with strangely interleaved output | |
68 | // under some compilers, there is a lot of use of endl in the code below | |
69 | // where a simple '\n' might appear to do. | |
70 | ||
71 | // The rules for catch & arguments are a bit different from function | |
72 | // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't | |
73 | // required, but it doesn't hurt and some programmers ask for it. | |
74 | ||
75 | catch ( const char * ex ) | |
76 | { detail::report_exception( out, "", ex ); } | |
77 | catch ( const std::string & ex ) | |
78 | { detail::report_exception( out, "", ex.c_str() ); } | |
79 | ||
80 | // std:: exceptions | |
81 | catch ( const std::bad_alloc & ex ) | |
82 | { detail::report_exception( out, "std::bad_alloc:", ex.what() ); } | |
83 | ||
84 | # ifndef BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT | |
85 | catch ( const std::bad_cast & ex ) | |
86 | { detail::report_exception( out, "std::bad_cast:", ex.what() ); } | |
87 | catch ( const std::bad_typeid & ex ) | |
88 | { detail::report_exception( out, "std::bad_typeid:", ex.what() ); } | |
89 | # else | |
90 | catch ( const std::bad_cast & ) | |
91 | { detail::report_exception( out, "std::bad_cast", "" ); } | |
92 | catch ( const std::bad_typeid & ) | |
93 | { detail::report_exception( out, "std::bad_typeid", "" ); } | |
94 | # endif | |
95 | ||
96 | catch ( const std::bad_exception & ex ) | |
97 | { detail::report_exception( out, "std::bad_exception:", ex.what() ); } | |
98 | catch ( const std::domain_error & ex ) | |
99 | { detail::report_exception( out, "std::domain_error:", ex.what() ); } | |
100 | catch ( const std::invalid_argument & ex ) | |
101 | { detail::report_exception( out, "std::invalid_argument:", ex.what() ); } | |
102 | catch ( const std::length_error & ex ) | |
103 | { detail::report_exception( out, "std::length_error:", ex.what() ); } | |
104 | catch ( const std::out_of_range & ex ) | |
105 | { detail::report_exception( out, "std::out_of_range:", ex.what() ); } | |
106 | catch ( const std::range_error & ex ) | |
107 | { detail::report_exception( out, "std::range_error:", ex.what() ); } | |
108 | catch ( const std::overflow_error & ex ) | |
109 | { detail::report_exception( out, "std::overflow_error:", ex.what() ); } | |
110 | catch ( const std::underflow_error & ex ) | |
111 | { detail::report_exception( out, "std::underflow_error:", ex.what() ); } | |
112 | catch ( const std::logic_error & ex ) | |
113 | { detail::report_exception( out, "std::logic_error:", ex.what() ); } | |
114 | catch ( const std::runtime_error & ex ) | |
115 | { detail::report_exception( out, "std::runtime_error:", ex.what() ); } | |
116 | catch ( const std::exception & ex ) | |
117 | { detail::report_exception( out, "std::exception:", ex.what() ); } | |
118 | ||
119 | catch ( ... ) | |
120 | { detail::report_exception( out, "unknown exception", "" ); } | |
121 | #endif // BOOST_NO_EXCEPTIONS | |
122 | ||
123 | if ( exception_thrown ) result = boost::exit_exception_failure; | |
124 | ||
125 | if ( result != 0 && result != exit_success ) | |
126 | { | |
127 | out << std::endl << "**** returning with error code " | |
128 | << result << std::endl; | |
129 | err | |
130 | << "********** errors detected; see stdout for details ***********" | |
131 | << std::endl; | |
132 | } | |
133 | #if !defined(BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE) | |
134 | else { out << std::flush << "no errors detected" << std::endl; } | |
135 | #endif | |
136 | return result; | |
137 | } // catch_exceptions | |
138 | ||
139 | } // boost | |
140 | ||
141 | #endif // BOOST_CATCH_EXCEPTIONS_HPP | |
142 |