From 0b394ba3186de7aa5222a634540850ae5b95080f Mon Sep 17 00:00:00 2001 From: Lukasz Forynski Date: Tue, 17 Dec 2013 13:59:35 +0000 Subject: [PATCH] Added signal handling to the updated Catch (fetched from latest upstream) --- README.md | 2 +- include/internal/catch_default_main.hpp | 74 +++++++++++++++++++++++ include/internal/catch_version.hpp | 2 +- single_include/catch.hpp | 80 ++++++++++++++++++++++++- 4 files changed, 153 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4b321812..dba8e0c2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![catch logo](catch-logo-small.png) -*v1.0 build 19 (master branch)* +*v1.0 build 23 (master branch)* Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch) diff --git a/include/internal/catch_default_main.hpp b/include/internal/catch_default_main.hpp index b7b65a5b..1e89f43d 100644 --- a/include/internal/catch_default_main.hpp +++ b/include/internal/catch_default_main.hpp @@ -10,8 +10,82 @@ #ifndef __OBJC__ +#if !defined(DO_NOT_USE_SIGNALS) +#include +#include +void add_test_info(std::stringstream& s) { + // add info about current test + Catch::IContext& context = Catch::getCurrentContext(); + Catch::IResultCapture& result = context.getResultCapture(); + const Catch::AssertionResult* ar = result.getLastResult(); + if(ar) { + Catch::SourceLineInfo src = ar->getSourceInfo(); + s << "\n\nwhile executing test: \"" << result.getCurrentTestName() << "\"\n"; + s << "\n(last successful check was: \"" << ar->getExpression() << "\"\n"; + s << " in: " << src.file << ", "; + s << "line: " << static_cast(src.line) << ")\n\n"; + } + Catch::cleanUp(); +} +#endif + +#ifndef DO_NOT_USE_SIGNALS +static bool testing_finished = false; +#include + +// handler for signals +void handle_signal(int sig) { + std::stringstream s; + s << "\n\n=================\n\n"; + if(testing_finished) + { + std::cerr << s.str() << "received signal " << std::dec << sig; + std::cerr << " after testing was finished\n"; + exit(0); + } + + switch (sig) { + case SIGINT: + s << "Interactive attention"; + break; + case SIGILL: + s << "Illegal instruction"; + break; + case SIGFPE: + s << "Floating point error"; + break; + case SIGSEGV: + s << "Segmentation violation"; + break; + case SIGTERM: + s << "Termination request"; + break; + case SIGABRT: + s << "Abnormal termination (abort)"; + break; + default: + break; + } + + add_test_info(s); + std::cout << s.str(); + + exit(-sig); +} +#endif /*!DO_NOT_USE_SIGNALS*/ + // Standard C/C++ main entry point int main (int argc, char * const argv[]) { +#ifndef DO_NOT_USE_SIGNALS + testing_finished = false; + signal(SIGSEGV, handle_signal); + signal(SIGABRT, handle_signal); + signal(SIGTERM, handle_signal); + signal(SIGINT, handle_signal); + signal(SIGILL, handle_signal); + signal(SIGFPE, handle_signal); +#endif /*!DO_NOT_USE_SIGNALS*/ + return Catch::Session().run( argc, argv ); } diff --git a/include/internal/catch_version.hpp b/include/internal/catch_version.hpp index 62ce4115..f615b3ea 100644 --- a/include/internal/catch_version.hpp +++ b/include/internal/catch_version.hpp @@ -13,7 +13,7 @@ namespace Catch { // These numbers are maintained by a script - Version libraryVersion( 1, 0, 19, "master" ); + Version libraryVersion( 1, 0, 23, "master" ); } #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED diff --git a/single_include/catch.hpp b/single_include/catch.hpp index bc2644b4..e3e40cae 100644 --- a/single_include/catch.hpp +++ b/single_include/catch.hpp @@ -1,6 +1,6 @@ /* - * CATCH v1.0 build 19 (master branch) - * Generated: 2013-12-14 23:16:21.805565 + * CATCH v1.0 build 23 (master branch) + * Generated: 2013-12-17 13:44:13.801508 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -6166,7 +6166,7 @@ namespace Catch { namespace Catch { // These numbers are maintained by a script - Version libraryVersion( 1, 0, 19, "master" ); + Version libraryVersion( 1, 0, 23, "master" ); } // #included from: catch_text.hpp @@ -7904,8 +7904,82 @@ namespace Catch { #ifndef __OBJC__ +#if !defined(DO_NOT_USE_SIGNALS) +#include +#include +void add_test_info(std::stringstream& s) { + // add info about current test + Catch::IContext& context = Catch::getCurrentContext(); + Catch::IResultCapture& result = context.getResultCapture(); + const Catch::AssertionResult* ar = result.getLastResult(); + if(ar) { + Catch::SourceLineInfo src = ar->getSourceInfo(); + s << "\n\nwhile executing test: \"" << result.getCurrentTestName() << "\"\n"; + s << "\n(last successful check was: \"" << ar->getExpression() << "\"\n"; + s << " in: " << src.file << ", "; + s << "line: " << static_cast(src.line) << ")\n\n"; + } + Catch::cleanUp(); +} +#endif + +#ifndef DO_NOT_USE_SIGNALS +static bool testing_finished = false; +#include + +// handler for signals +void handle_signal(int sig) { + std::stringstream s; + s << "\n\n=================\n\n"; + if(testing_finished) + { + std::cerr << s.str() << "received signal " << std::dec << sig; + std::cerr << " after testing was finished\n"; + exit(0); + } + + switch (sig) { + case SIGINT: + s << "Interactive attention"; + break; + case SIGILL: + s << "Illegal instruction"; + break; + case SIGFPE: + s << "Floating point error"; + break; + case SIGSEGV: + s << "Segmentation violation"; + break; + case SIGTERM: + s << "Termination request"; + break; + case SIGABRT: + s << "Abnormal termination (abort)"; + break; + default: + break; + } + + add_test_info(s); + std::cout << s.str(); + + exit(-sig); +} +#endif /*!DO_NOT_USE_SIGNALS*/ + // Standard C/C++ main entry point int main (int argc, char * const argv[]) { +#ifndef DO_NOT_USE_SIGNALS + testing_finished = false; + signal(SIGSEGV, handle_signal); + signal(SIGABRT, handle_signal); + signal(SIGTERM, handle_signal); + signal(SIGINT, handle_signal); + signal(SIGILL, handle_signal); + signal(SIGFPE, handle_signal); +#endif /*!DO_NOT_USE_SIGNALS*/ + return Catch::Session().run( argc, argv ); }