/*
* Created by Phil on 20/04/2011.
* Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include "catch_exception_translator_registry.h"
#include "catch_assertionhandler.h"
#include "catch_compiler_capabilities.h"
#include "catch_enforce.h"
#ifdef __OBJC__
#import "Foundation/Foundation.h"
#endif
namespace Catch {
ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
}
void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
}
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
std::string ExceptionTranslatorRegistry::translateActiveException() const {
try {
#ifdef __OBJC__
// In Objective-C try objective-c exceptions first
@try {
return tryTranslators();
}
@catch (NSException *exception) {
return Catch::Detail::stringify( [exception description] );
}
#else
// Compiling a mixed mode project with MSVC means that CLR
// exceptions will be caught in (...) as well. However, these
// do not fill-in std::current_exception and thus lead to crash
// when attempting rethrow.
// /EHa switch also causes structured exceptions to be caught
// here, but they fill-in current_exception properly, so
// at worst the output should be a little weird, instead of
// causing a crash.
if (std::current_exception() == nullptr) {
return "Non C++ exception. Possibly a CLR exception.";
}
return tryTranslators();
#endif
}
catch( TestFailureException& ) {
std::rethrow_exception(std::current_exception());
}
catch( std::exception& ex ) {
return ex.what();
}
catch( std::string& msg ) {
return msg;
}
catch( const char* msg ) {
return msg;
}
catch(...) {
return "Unknown exception";
}
}
std::string ExceptionTranslatorRegistry::tryTranslators() const {
if (m_translators.empty()) {
std::rethrow_exception(std::current_exception());
} else {
return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
}
}
#else // ^^ Exceptions are enabled // Exceptions are disabled vv
std::string ExceptionTranslatorRegistry::translateActiveException() const {
CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
}
std::string ExceptionTranslatorRegistry::tryTranslators() const {
CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
}
#endif
}