parent
34536e2a63
commit
9348207ffb
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Created by Brett on 23/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef BLT_ASSERT_H
|
||||
#define BLT_ASSERT_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define BLT_STACK_TRACE(number) void* ptrs[number]; \
|
||||
int size = backtrace(ptrs, number); \
|
||||
char** messages = backtrace_symbols(ptrs, size);
|
||||
|
||||
#define BLT_FREE_STACK_TRACE() free(messages);
|
||||
#else
|
||||
#define BLT_STACK_TRACE(number) void();
|
||||
#define BLT_FREE_STACK_TRACE() void();
|
||||
#endif
|
||||
|
||||
namespace blt
|
||||
{
|
||||
void printStacktrace(char** messages, int size, const char* path, int line);
|
||||
|
||||
void b_assert_failed(const char* expression, const char* path, int line);
|
||||
|
||||
void b_throw(const char* what, const char* path, int line);
|
||||
}
|
||||
|
||||
// prints error with stack trace if assertion fails. Does not stop execution.
|
||||
#define blt_assert(expr) static_cast<bool>(expr) ? void(0) : blt::b_assert_failed(#expr, __FILE__, __LINE__)
|
||||
// prints error with stack trace then exits with failure.
|
||||
#define BLT_ASSERT(expr) {static_cast<bool>(expr) ? void(0) : blt::b_assert_failed(#expr, __FILE__, __LINE__); std::exit(EXIT_FAILURE); }
|
||||
#define blt_throw(throwable) {blt::b_throw(throwable.what(), __FILE__, __LINE__); throw throwable;}
|
||||
|
||||
|
||||
#endif //BLT_ASSERT_H
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Created by Brett on 23/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <blt/std/assert.h>
|
||||
#include <blt/std/logging.h>
|
||||
#include <blt/std/string.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace blt {
|
||||
|
||||
static inline std::string _macro_filename(const std::string& path){
|
||||
auto paths = blt::string::split(path, "/");
|
||||
auto final = paths[paths.size()-1];
|
||||
if (final == "/")
|
||||
return paths[paths.size()-2];
|
||||
return final;
|
||||
}
|
||||
|
||||
void b_throw(const char* what, const char* path, int line)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
BLT_STACK_TRACE(50);
|
||||
|
||||
BLT_ERROR("An exception '%s' has occurred in file '%s:%d'", what, path, line);
|
||||
BLT_ERROR("Stack Trace:");
|
||||
printStacktrace(messages, size, path, line);
|
||||
|
||||
BLT_FREE_STACK_TRACE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void b_assert_failed(const char* expression, const char* path, int line)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
BLT_STACK_TRACE(50);
|
||||
|
||||
BLT_ERROR("The assertion '%s' has failed in file '%s:%d'", expression, path, line);
|
||||
BLT_ERROR("Stack Trace:");
|
||||
|
||||
backtrace_symbols(ptrs, size);
|
||||
|
||||
printStacktrace(messages, size, path, line);
|
||||
|
||||
BLT_FREE_STACK_TRACE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void printStacktrace(char** messages, int size, const char* path, int line)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
for (int i = 1; i < size; i++){
|
||||
int tabs = i - 1;
|
||||
std::string buffer;
|
||||
for (int j = 0; j < tabs; j++)
|
||||
buffer += '\t';
|
||||
if (i != 1)
|
||||
buffer += "⮡";
|
||||
|
||||
std::string message(messages[i]);
|
||||
|
||||
auto f = message.find('(');
|
||||
|
||||
auto mes = message.substr(f + 1, message.size());
|
||||
std::string loc;
|
||||
|
||||
buffer += message.substr(0, f);
|
||||
if (i == 1)
|
||||
{
|
||||
loc = '\'';
|
||||
loc += _macro_filename(path);
|
||||
loc += ':';
|
||||
loc += std::to_string(line);
|
||||
loc += '\'';
|
||||
} else
|
||||
loc = mes.substr(0, mes.find('+'));
|
||||
|
||||
if (!loc.empty())
|
||||
buffer += " in ";
|
||||
buffer += loc;
|
||||
|
||||
|
||||
BLT_ERROR(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue