feat: add assertion library

This commit is contained in:
2026-05-21 13:09:29 -03:00
parent 4ee117cdb7
commit 39cbd6d096
2 changed files with 110 additions and 0 deletions
+59
View File
@@ -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
}
+51
View File
@@ -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);
}