1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-10 16:48:09 +00:00

feat(core): introduce uformat!, use it in print/println!

now that we have ufmt, this is just much nicer
This commit is contained in:
matejcik 2024-04-09 12:58:07 +02:00
parent c7832c39ab
commit ac6faa15bc
10 changed files with 80 additions and 12 deletions

View File

@ -51,9 +51,7 @@ fn panic_debug(panic_info: &core::panic::PanicInfo) -> ! {
if let Some(location) = panic_info.location() { if let Some(location) = panic_info.location() {
let file = location.file(); let file = location.file();
print!(file); println!("Panic at {}:{}:{}", file, location.line(), location.column());
print!(":");
println!(inttostr!(location.line()));
trezorhal::fatal_error::__fatal_error("", "rs", file, location.line(), ""); trezorhal::fatal_error::__fatal_error("", "rs", file, location.line(), "");
} else { } else {
trezorhal::fatal_error::__fatal_error("", "rs", "", 0, ""); trezorhal::fatal_error::__fatal_error("", "rs", "", 0, "");

View File

@ -20,7 +20,7 @@ use super::ffi;
/// The `off` field represents offset from the `ptr` and allows us to do /// The `off` field represents offset from the `ptr` and allows us to do
/// substring slices while keeping the head pointer as required by GC. /// substring slices while keeping the head pointer as required by GC.
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Copy, Clone)]
pub struct StrBuffer { pub struct StrBuffer {
ptr: *const u8, ptr: *const u8,
len: u16, len: u16,
@ -165,6 +165,18 @@ impl From<&'static str> for StrBuffer {
} }
} }
#[cfg(feature="debug")]
impl ufmt::uDebug for StrBuffer {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized {
f.write_str("StrBuffer(")?;
f.write_str(self.as_ref())?;
f.write_str(")")?;
Ok(())
}
}
fn get_buffer_info(obj: Obj, flags: u32) -> Result<ffi::mp_buffer_info_t, Error> { fn get_buffer_info(obj: Obj, flags: u32) -> Result<ffi::mp_buffer_info_t, Error> {
let mut bufinfo = ffi::mp_buffer_info_t { let mut bufinfo = ffi::mp_buffer_info_t {
buf: ptr::null_mut(), buf: ptr::null_mut(),

View File

@ -261,15 +261,35 @@ macro_rules! attr_tuple {
}); });
} }
// from https://docs.rs/ufmt/latest/ufmt/
// like `std::format!` it returns a `std::String` but uses `uwrite!` instead of
// `write!`
macro_rules! uformat {
// IMPORTANT use `tt` fragments instead of `expr` fragments (i.e. `$($exprs:expr),*`)
($len:expr, $($tt:tt)*) => {{
let mut s = heapless::String::<$len>::new();
match ufmt::uwrite!(&mut s, $($tt)*) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}};
}
/// Print arbitrary amounts of slices into a terminal. /// Print arbitrary amounts of slices into a terminal.
/// Does not include a newline at the end. /// Does not include a newline at the end.
/// Does not do anything when not in debugging mode. /// Does not do anything when not in debugging mode.
#[allow(unused_macros)] // Should be used only for debugging purposes #[allow(unused_macros)] // Should be used only for debugging purposes
macro_rules! print { macro_rules! print {
($($string:expr),+) => { ($($tt:tt)*) => {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
{ {
$(crate::micropython::print::print($string);)+ match uformat!(256, $($tt)*) {
Ok(u) => crate::micropython::print::print(&u),
Err(e) => {
crate::micropython::print::print("Error: ");
crate::micropython::print::print(&unwrap!(uformat!(256, "{:?}", e)));
}
};
} }
} }
} }
@ -279,8 +299,9 @@ macro_rules! print {
/// Does not do anything when not in debugging mode. /// Does not do anything when not in debugging mode.
#[allow(unused_macros)] // Should be used only for debugging purposes #[allow(unused_macros)] // Should be used only for debugging purposes
macro_rules! println { macro_rules! println {
($($string:expr),+) => { ($($tt:tt)*) => {
// Just delegating to print! and adding a newline // Just delegating to print! and adding a newline
print!($($string),+, "\n"); print!($($tt)*);
print!("\n");
} }
} }

View File

@ -195,3 +195,32 @@ impl<'a, 'b> PartialEq<TString<'a>> for TString<'b> {
} }
impl Eq for TString<'_> {} impl Eq for TString<'_> {}
#[cfg(feature="debug")]
impl ufmt::uDebug for TString<'_> {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized {
match self {
TString::Allocated(buf) => {
f.write_str("Allocated(")?;
buf.fmt(f)?;
f.write_str(")")?;
}
TString::Translation { tr, offset } => {
f.write_str("Translation(")?;
tr.fmt(f)?;
f.write_str(", ")?;
offset.fmt(f)?;
f.write_str(")")?;
}
TString::Str(s) => {
f.write_str("Str(")?;
f.write_str(s)?;
f.write_str(")")?;
}
}
Ok(())
}
}

View File

@ -6,7 +6,8 @@
#[cfg(feature = "micropython")] #[cfg(feature = "micropython")]
use crate::micropython::qstr::Qstr; use crate::micropython::qstr::Qstr;
#[derive(Debug, Copy, Clone, FromPrimitive, PartialEq, Eq)] #[derive(Copy, Clone, FromPrimitive, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
#[repr(u16)] #[repr(u16)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum TranslatedString { pub enum TranslatedString {

View File

@ -35,7 +35,8 @@ en_data = json.loads(en_file.read_text())["translations"]
#[cfg(feature = "micropython")] #[cfg(feature = "micropython")]
use crate::micropython::qstr::Qstr; use crate::micropython::qstr::Qstr;
#[derive(Debug, Copy, Clone, FromPrimitive, PartialEq, Eq)] #[derive(Copy, Clone, FromPrimitive, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
#[repr(u16)] #[repr(u16)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum TranslatedString { pub enum TranslatedString {

View File

@ -416,6 +416,7 @@ where
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub enum Event { pub enum Event {
#[cfg(feature = "button")] #[cfg(feature = "button")]
Button(ButtonEvent), Button(ButtonEvent),
@ -436,6 +437,7 @@ pub enum Event {
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub struct TimerToken(u32); pub struct TimerToken(u32);
impl TimerToken { impl TimerToken {

View File

@ -2,12 +2,14 @@ use crate::{error, ui::geometry::Point};
use core::convert::TryInto; use core::convert::TryInto;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub enum PhysicalButton { pub enum PhysicalButton {
Left, Left,
Right, Right,
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub enum ButtonEvent { pub enum ButtonEvent {
/// Button pressed down. /// Button pressed down.
/// ▼ * | * ▼ /// ▼ * | * ▼
@ -36,6 +38,7 @@ impl ButtonEvent {
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub enum TouchEvent { pub enum TouchEvent {
/// A person has started touching the screen at given absolute coordinates. /// A person has started touching the screen at given absolute coordinates.
/// `TouchMove` will usually follow, and `TouchEnd` should finish the /// `TouchMove` will usually follow, and `TouchEnd` should finish the
@ -61,6 +64,7 @@ impl TouchEvent {
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub enum USBEvent { pub enum USBEvent {
/// USB host has connected/disconnected. /// USB host has connected/disconnected.
Connected(bool), Connected(bool),

View File

@ -137,6 +137,7 @@ impl From<Point> for Offset {
/// A point in 2D space defined by the the `x` and `y` coordinate. Relative /// A point in 2D space defined by the the `x` and `y` coordinate. Relative
/// coordinates, vectors, and offsets are represented by the `Offset` type. /// coordinates, vectors, and offsets are represented by the `Offset` type.
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))]
pub struct Point { pub struct Point {
pub x: i16, pub x: i16,
pub y: i16, pub y: i16,

View File

@ -21,8 +21,7 @@ impl<T, E> ResultExt for Result<T, E> {
fn assert_if_debugging_ui(self, #[allow(unused)] message: &str) { fn assert_if_debugging_ui(self, #[allow(unused)] message: &str) {
#[cfg(feature = "ui_debug")] #[cfg(feature = "ui_debug")]
if self.is_err() { if self.is_err() {
print!("Panic from assert_if_debugging_ui: "); println!("Panic from assert_if_debugging_ui: {}", message);
println!(message);
panic!("{}", message); panic!("{}", message);
} }
} }