luna: Add a new SourceLocation class and use that in check() and expect()
This commit is contained in:
parent
129297a0b0
commit
0126a8fb6e
@ -4,6 +4,7 @@
|
|||||||
#include "arch/Timer.h"
|
#include "arch/Timer.h"
|
||||||
#include "video/TextConsole.h"
|
#include "video/TextConsole.h"
|
||||||
#include <luna/Format.h>
|
#include <luna/Format.h>
|
||||||
|
#include <luna/SourceLocation.h>
|
||||||
|
|
||||||
static bool g_debug_enabled = true;
|
static bool g_debug_enabled = true;
|
||||||
static bool g_serial_enabled = true;
|
static bool g_serial_enabled = true;
|
||||||
@ -117,13 +118,14 @@ bool log_text_console_enabled()
|
|||||||
|
|
||||||
static bool g_check_already_failed = false;
|
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();
|
CPU::disable_interrupts();
|
||||||
if (!g_check_already_failed)
|
if (!g_check_already_failed)
|
||||||
{ // Avoid endlessly failing when trying to report a failed check.
|
{ // Avoid endlessly failing when trying to report a failed check.
|
||||||
g_check_already_failed = true;
|
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::print_stack_trace();
|
||||||
}
|
}
|
||||||
CPU::efficient_halt();
|
CPU::efficient_halt();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <luna/SourceLocation.h>
|
||||||
|
|
||||||
[[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
|
#ifndef STRINGIZE_VALUE_OF
|
||||||
#define STRINGIZE(x) #x
|
#define STRINGIZE(x) #x
|
||||||
@ -10,22 +11,15 @@
|
|||||||
// Like check(), but with a custom error message.
|
// Like check(), but with a custom error message.
|
||||||
#define expect(expr, message) \
|
#define expect(expr, message) \
|
||||||
do { \
|
do { \
|
||||||
if (!(expr)) [[unlikely]] \
|
if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), message); } \
|
||||||
{ \
|
|
||||||
__check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, message); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
// Like assert(), but always enabled.
|
// Like assert(), but always enabled.
|
||||||
#define check(expr) \
|
#define check(expr) \
|
||||||
do { \
|
do { \
|
||||||
if (!(expr)) [[unlikely]] \
|
if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), #expr); } \
|
||||||
{ \
|
|
||||||
__check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, #expr); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define unreachable() \
|
#define unreachable() __check_failed(SourceLocation::current(), "Reached unreachable code")
|
||||||
__check_failed(__FILE__, STRINGIZE_VALUE_OF(__LINE__), __PRETTY_FUNCTION__, "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!")
|
||||||
|
42
luna/include/luna/SourceLocation.h
Normal file
42
luna/include/luna/SourceLocation.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Types.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
@ -1,11 +1,12 @@
|
|||||||
#include <luna/Attributes.h>
|
#include <luna/Attributes.h>
|
||||||
|
#include <luna/SourceLocation.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
_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.
|
// 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();
|
abort();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user