1 /*
2  *  Created by Phil on 20/04/2011.
3  *  Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 #include "catch_exception_translator_registry.h"
10 #include "catch_assertionhandler.h"
11 #include "catch_compiler_capabilities.h"
12 #include "catch_enforce.h"
13 
14 #ifdef __OBJC__
15 #import "Foundation/Foundation.h"
16 #endif
17 
18 namespace Catch {
19 
~ExceptionTranslatorRegistry()20     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
21     }
22 
registerTranslator(const IExceptionTranslator * translator)23     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
24         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
25     }
26 
27 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
translateActiveException() const28     std::string ExceptionTranslatorRegistry::translateActiveException() const {
29         try {
30 #ifdef __OBJC__
31             // In Objective-C try objective-c exceptions first
32             @try {
33                 return tryTranslators();
34             }
35             @catch (NSException *exception) {
36                 return Catch::Detail::stringify( [exception description] );
37             }
38 #else
39             // Compiling a mixed mode project with MSVC means that CLR
40             // exceptions will be caught in (...) as well. However, these
41             // do not fill-in std::current_exception and thus lead to crash
42             // when attempting rethrow.
43             // /EHa switch also causes structured exceptions to be caught
44             // here, but they fill-in current_exception properly, so
45             // at worst the output should be a little weird, instead of
46             // causing a crash.
47             if (std::current_exception() == nullptr) {
48                 return "Non C++ exception. Possibly a CLR exception.";
49             }
50             return tryTranslators();
51 #endif
52         }
53         catch( TestFailureException& ) {
54             std::rethrow_exception(std::current_exception());
55         }
56         catch( std::exception& ex ) {
57             return ex.what();
58         }
59         catch( std::string& msg ) {
60             return msg;
61         }
62         catch( const char* msg ) {
63             return msg;
64         }
65         catch(...) {
66             return "Unknown exception";
67         }
68     }
69 
tryTranslators() const70     std::string ExceptionTranslatorRegistry::tryTranslators() const {
71         if (m_translators.empty()) {
72             std::rethrow_exception(std::current_exception());
73         } else {
74             return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
75         }
76     }
77 
78 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
translateActiveException() const79     std::string ExceptionTranslatorRegistry::translateActiveException() const {
80         CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
81     }
82 
tryTranslators() const83     std::string ExceptionTranslatorRegistry::tryTranslators() const {
84         CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
85     }
86 #endif
87 
88 
89 }
90