| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //====================================================================================================================== | ||
| 2 | //! @file | ||
| 3 | /* | ||
| 4 | TTS - Tiny Test System | ||
| 5 | Copyright : TTS Contributors & Maintainers | ||
| 6 | SPDX-License-Identifier: BSL-1.0 | ||
| 7 | */ | ||
| 8 | //====================================================================================================================== | ||
| 9 | #pragma once | ||
| 10 | |||
| 11 | #include <tts/engine/deps.hpp> | ||
| 12 | #include <tts/tools/erased.hpp> | ||
| 13 | |||
| 14 | namespace tts::_ | ||
| 15 | { | ||
| 16 | using abort_handler = erased<void(int)>; | ||
| 17 | |||
| 18 | inline callable abort_epilogue = {}; // NOSONAR - the driver sets it once it is ready | ||
| 19 | inline abort_handler abort_action = {}; // NOSONAR - set_abort_handler replaces it | ||
| 20 | |||
| 21 | inline int abort_exit_code = 1; // NOSONAR - report_abort sets it once it has summed up | ||
| 22 | |||
| 23 | ✗ | [[noreturn]] inline void exit_now() | |
| 24 | { | ||
| 25 | // No atexit handler and no static destructor may run on a half-finished case, and _Exit | ||
| 26 | // flushes nothing. | ||
| 27 | ✗ | fflush(stdout); | |
| 28 | ✗ | fflush(stderr); | |
| 29 | ✗ | std::_Exit(abort_exit_code); | |
| 30 | } | ||
| 31 | |||
| 32 | ✗ | [[noreturn]] inline void perform_abort(int reason) | |
| 33 | { | ||
| 34 | ✗ | if(abort_epilogue) abort_epilogue(); | |
| 35 | ✗ | if(abort_action) abort_action(reason); | |
| 36 | ✗ | exit_now(); | |
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | namespace tts | ||
| 41 | { | ||
| 42 | //==================================================================================================================== | ||
| 43 | /** | ||
| 44 | @brief Run termination customization point | ||
| 45 | @ingroup customization-points | ||
| 46 | |||
| 47 | Runs just before **TTS** exits a crashed or timed out run, with the signal that brought it down | ||
| 48 | or `0` when nothing did. **TTS** exits once it returns, with 1, or with 0 when the case that | ||
| 49 | brought the run down was tagged @ref TTS_XFAIL or @ref TTS_MAYFAIL. | ||
| 50 | |||
| 51 | Useful when a test binary has to handle an abrupt stop in its own way. | ||
| 52 | |||
| 53 | @param h Any callable taking an `int`. | ||
| 54 | |||
| 55 | @return The handler installed before this call, empty if there was none. | ||
| 56 | |||
| 57 | @see TTS_CUSTOM_DRIVER_FUNCTION | ||
| 58 | |||
| 59 | @groupheader{Example} | ||
| 60 | @snippet doc/abort_handler.cpp snippet | ||
| 61 | **/ | ||
| 62 | //==================================================================================================================== | ||
| 63 | 1 | template<typename Handler> inline _::abort_handler set_abort_handler(Handler h) | |
| 64 | { | ||
| 65 | 1 | _::abort_handler previous = TTS_MOVE(_::abort_action); | |
| 66 |
1/1✓ Branch 1 taken 1 times.
|
1 | _::abort_action = _::abort_handler {TTS_MOVE(h)}; |
| 67 | 1 | return previous; | |
| 68 | ✗ | } | |
| 69 | } | ||
| 70 |