#include #include #include #include #include #include namespace kapi::system { namespace { auto panic_write(kstd::error_code error) -> void { kstd::print(kstd::print_sink::stderr, " ({}) ", error); } } // namespace namespace detail { panic_buffer::~panic_buffer() { flush(); } void panic_buffer::append(char character) { m_buffer[m_written++] = character; if (m_written == m_buffer.size()) { flush(); } } void panic_buffer::flush() { if (m_written > 0) { panic_write(std::string_view{m_buffer.data(), m_written}); m_written = 0; } } panic_iterator::panic_iterator(panic_buffer & buffer) : m_buffer(&buffer) {} auto panic_iterator::operator*() noexcept -> panic_iterator & { return *this; } auto panic_iterator::operator=(char character) -> panic_iterator & { m_buffer->append(character); return *this; } auto panic_iterator::operator++() -> panic_iterator & { return *this; } auto panic_iterator::operator++(int) -> panic_iterator { return *this; } } // namespace detail [[gnu::weak]] auto panic(std::string_view message, std::source_location location) -> void { panic_start(location); panic_write(message); panic_finish(location); } [[gnu::weak]] auto panic(std::string_view message, kstd::error_code error, std::source_location location) -> void { panic_start(location); panic_write(message); panic_write(error); panic_finish(location); } auto panic_start(std::source_location location) -> void { kstd::print(kstd::print_sink::stderr, "[PANIC] in '{}': ", location.function_name()); } auto panic_write(std::string_view message) -> void { kstd::print(kstd::print_sink::stderr, "{}", message); } auto panic_finish(std::source_location location) -> void { kstd::println(kstd::print_sink::stderr, " @ {}:{}", location.file_name(), location.line()); cpu::halt(); } } // namespace kapi::system