feat: add assertion library
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// from: WinUser.h
|
||||||
|
#ifndef MB_ICONHAND
|
||||||
|
#define MB_ICONHAND 0x00000010L
|
||||||
|
#define MB_ICONERROR MB_ICONHAND
|
||||||
|
|
||||||
|
#define MB_SYSTEMMODAL 0x00001000L
|
||||||
|
|
||||||
|
#define MB_OK 0x00000000L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
__declspec(dllimport) void* __stdcall GetModuleHandleA(const char* lpModuleName);
|
||||||
|
__declspec(dllimport) void* __stdcall LoadLibraryA(const char* lpLibFileName);
|
||||||
|
__declspec(dllimport) int(__stdcall* __stdcall GetProcAddress(void* hModule, const char* lpProcName))();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#include <cstdlib>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string safeShellEscape(const std::string& input)
|
||||||
|
{
|
||||||
|
std::string escaped;
|
||||||
|
for (char c : input)
|
||||||
|
{
|
||||||
|
if (c == '"' || c == '\\' || c == '`' || c == '$') escaped += '\\';
|
||||||
|
escaped += c;
|
||||||
|
}
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
|
void seallib::displayError(const char* msg, const char* file, int line)
|
||||||
|
{
|
||||||
|
std::string fullError = std::string(msg) + "\n\nFile: " + file + "\nLine: " + std::to_string(line);
|
||||||
|
std::cerr << "[FATAL ERROR] " << fullError << std::endl;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef int(__stdcall * fnMessageBoxA)(void*, const char*, const char*, unsigned int);
|
||||||
|
if (void* hUser32 = GetModuleHandleA("user32.dll") ? GetModuleHandleA("user32.dll") : LoadLibraryA("user32.dll"))
|
||||||
|
{
|
||||||
|
auto msgBoxA = reinterpret_cast<fnMessageBoxA>(GetProcAddress(hUser32, "MessageBoxA"));
|
||||||
|
if (msgBoxA) msgBoxA(nullptr, fullError.c_str(), "Fatal Error Occurred", MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
|
||||||
|
}
|
||||||
|
#elif __linux__
|
||||||
|
std::string safeMsg = safeShellEscape(fullError);
|
||||||
|
if (std::system("which zenity > /dev/null 2>&1") == 0)
|
||||||
|
std::system(("zenity --error --text=\"" + safeMsg + "\" --title=\"Fatal Error\" 2>/dev/null").c_str());
|
||||||
|
else if (std::system("which kdialog > /dev/null 2>&1") == 0)
|
||||||
|
std::system(("kdialog --error \"" + safeMsg + "\" 2>/dev/null").c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define SEALLIB_DEBUGBREAK() __debugbreak()
|
||||||
|
#define SEALLIB_ASSUME(cond) __assume(cond)
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define SEALLIB_DEBUGBREAK() __builtin_trap()
|
||||||
|
#define SEALLIB_ASSUME(cond) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!(cond)) __builtin_unreachable(); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define SEALLIB_DEBUGBREAK() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#define SEALLIB_ASSUME(cond) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define ASSERT(cond, msg) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!(cond)) \
|
||||||
|
{ \
|
||||||
|
seallib::displayError(msg, __FILE__, __LINE__); \
|
||||||
|
SEALLIB_DEBUGBREAK(); \
|
||||||
|
std::exit(EXIT_FAILURE); \
|
||||||
|
} \
|
||||||
|
SEALLIB_ASSUME(cond); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define ASSERT(cond, msg) SEALLIB_ASSUME(cond)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PANIC(msg) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
seallib::displayError(msg, __FILE__, __LINE__); \
|
||||||
|
SEALLIB_DEBUGBREAK(); \
|
||||||
|
std::exit(EXIT_FAILURE); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
namespace seallib
|
||||||
|
{
|
||||||
|
void displayError(const char* msg, const char* file, int line);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user