diff --git a/kernel/src/Log.cpp b/kernel/src/Log.cpp index 44ea6bd4..cd153c12 100644 --- a/kernel/src/Log.cpp +++ b/kernel/src/Log.cpp @@ -4,6 +4,7 @@ #include "arch/Timer.h" #include "video/TextConsole.h" #include +#include static bool g_debug_enabled = true; static bool g_serial_enabled = true; @@ -117,13 +118,14 @@ bool log_text_console_enabled() static bool g_check_already_failed = false; -[[noreturn]] bool __check_failed(const char* file, const char* line, const char* func, const char* expr) +[[noreturn]] bool __check_failed(SourceLocation location, const char* expr) { CPU::disable_interrupts(); if (!g_check_already_failed) { // Avoid endlessly failing when trying to report a failed check. g_check_already_failed = true; - kerrorln("ERROR: Check failed at %s:%s, in %s: %s", file, line, func, expr); + kerrorln("ERROR: Check failed at %s:%d, in %s: %s", location.file(), location.line(), location.function(), + expr); CPU::print_stack_trace(); } CPU::efficient_halt(); diff --git a/luna/include/luna/Check.h b/luna/include/luna/Check.h index 9fb7a495..4adaca8b 100644 --- a/luna/include/luna/Check.h +++ b/luna/include/luna/Check.h @@ -1,6 +1,7 @@ #pragma once +#include -[[noreturn]] extern bool __check_failed(const char* file, const char* line, const char* func, const char* expr); +[[noreturn]] extern bool __check_failed(SourceLocation location, const char* expr); #ifndef STRINGIZE_VALUE_OF #define STRINGIZE(x) #x @@ -10,22 +11,15 @@ // Like check(), but with a custom error message. #define expect(expr, message) \ do { \ - if (!(expr)) [[unlikely]] \ - { \ - __check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, message); \ - } \ + if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), message); } \ } while (0) // Like assert(), but always enabled. #define check(expr) \ do { \ - if (!(expr)) [[unlikely]] \ - { \ - __check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, #expr); \ - } \ + if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), #expr); } \ } while (0) -#define unreachable() \ - __check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, "Reached unreachable code") +#define unreachable() __check_failed(SourceLocation::current(), "Reached unreachable code") -#define todo() __check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, "Reached a TODO!") +#define todo() __check_failed(SourceLocation::current(), "Reached a TODO!") diff --git a/luna/include/luna/SourceLocation.h b/luna/include/luna/SourceLocation.h new file mode 100644 index 00000000..6b3d2561 --- /dev/null +++ b/luna/include/luna/SourceLocation.h @@ -0,0 +1,42 @@ +#pragma once +#include + +#ifndef STRINGIZE_VALUE_OF +#define STRINGIZE(x) #x +#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) +#endif + +class SourceLocation +{ + public: + constexpr const char* file() + { + return m_file; + } + + constexpr u32 line() + { + return m_line; + } + + constexpr const char* function() + { + return m_function; + } + + constexpr static SourceLocation current(const char* file = __builtin_FILE(), u32 line = __builtin_LINE(), + const char* function = __builtin_FUNCTION()) + { + return SourceLocation { file, line, function }; + } + + private: + constexpr SourceLocation(const char* file, u32 line, const char* function) + : m_file(file), m_line(line), m_function(function) + { + } + + const char* m_file; + u32 m_line; + const char* m_function; +}; diff --git a/luna/src/Check.cpp b/luna/src/Check.cpp index 5d706837..b4d1bcb4 100644 --- a/luna/src/Check.cpp +++ b/luna/src/Check.cpp @@ -1,11 +1,12 @@ #include +#include #include #include -_weak [[noreturn]] bool __check_failed(const char* file, const char* line, const char* func, const char* expr) +_weak [[noreturn]] bool __check_failed(SourceLocation location, const char* expr) { // FIXME: Output to standard error instead of standard output. - printf("Check failed at %s:%s in %s: %s\n", file, line, func, expr); + printf("Check failed at %s:%d in %s: %s\n", location.file(), location.line(), location.function(), expr); abort(); }