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:
parent
c7832c39ab
commit
ac6faa15bc
@ -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, "");
|
||||||
|
@ -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(),
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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),
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user