12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- #ifndef SUPPORT_ASSERT_CHECKPOINT_H
- #define SUPPORT_ASSERT_CHECKPOINT_H
- #include <csignal>
- #include <iostream>
- #include <cstdlib>
- struct Checkpoint {
- const char* file;
- const char* func;
- int line;
- const char* msg;
- Checkpoint() : file(nullptr), func(nullptr), line(-1), msg(nullptr) {}
- Checkpoint(const char* xfile, const char* xfunc, int xline, const char* xmsg)
- : file(xfile), func(xfunc), line(xline), msg(xmsg)
- {}
- template <class Stream>
- void print(Stream& s) const {
- if (!file) {
- s << "NO CHECKPOINT\n";
- return;
- }
- s << file << ":" << line << " " << func << ": Checkpoint";
- if (msg)
- s << " '" << msg << "'";
- s << std::endl;
- }
- };
- inline Checkpoint& globalCheckpoint() {
- static Checkpoint C;
- return C;
- }
- inline void clearCheckpoint() {
- globalCheckpoint() = Checkpoint();
- }
- #if defined(__GNUC__)
- #define CHECKPOINT_FUNCTION_NAME __PRETTY_FUNCTION__
- #else
- #define CHECKPOINT_FUNCTION_NAME __func__
- #endif
- #define CHECKPOINT(msg) globalCheckpoint() = Checkpoint(__FILE__, CHECKPOINT_FUNCTION_NAME, __LINE__, msg);
- inline void checkpointSignalHandler(int signal) {
- if (signal == SIGABRT) {
- globalCheckpoint().print(std::cerr);
- } else {
- std::cerr << "Unexpected signal " << signal << " received\n";
- }
- std::_Exit(EXIT_FAILURE);
- }
- inline bool initCheckpointHandler() {
- typedef void(*HandlerT)(int);
- static bool isInit = false;
- if (isInit) return true;
- HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler);
- if (prev_h == SIG_ERR) {
- std::cerr << "Setup failed.\n";
- std::_Exit(EXIT_FAILURE);
- }
- isInit = true;
- return false;
- }
- static bool initDummy = initCheckpointHandler();
- #endif
|