use core::{
ffi::{CStr, c_int},
fmt::{self, Write},
panic::PanicInfo,
};
use crate::app_log;
const LOG_MSG_LEN: usize = 88;
pub fn panic_halt(_: &PanicInfo) -> ! {
unsafe {
core::arch::asm!("udf 0", options(noreturn));
};
}
fn location<'a>(info: &'a PanicInfo) -> (&'a CStr, c_int) {
info.location().map_or((c"unknown_file", 0), |loc| {
(loc.file_as_c_str(), loc.line() as c_int)
})
}
struct LogBuf {
buf: [u8; LOG_MSG_LEN],
len: usize,
}
impl Write for LogBuf {
#[inline(never)]
fn write_str(&mut self, s: &str) -> fmt::Result {
let free = &mut self.buf[self.len.min(LOG_MSG_LEN)..];
let n = s.len().min(free.len());
free[..n].copy_from_slice(&s.as_bytes()[..n]);
self.len += n;
Ok(())
}
}
pub fn panic_fmt(info: &PanicInfo) -> ! {
let (src_filename, src_line_number) = location(info);
let mut msg = LogBuf {
buf: [0; LOG_MSG_LEN],
len: 0,
};
let _ = write!(msg, "{}", info.message());
unsafe {
app_log(
crate::sys_raw::AppLogLevel_APP_LOG_LEVEL_ERROR,
src_filename.as_ptr(),
src_line_number,
c"Panic! %.*s".as_ptr(),
msg.len as c_int,
msg.buf.as_ptr(),
);
};
panic_halt(info)
}