Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions firmware/qemu/src/bin/dbg.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TRACE x + 1 = 43
TRACE x - 1 = 41
INFO the answer is 41
TRACE x - 2 = 40
TRACE x + 2 = 44
TRACE
TRACE x = 42
1 change: 1 addition & 0 deletions firmware/qemu/src/bin/dbg.release.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INFO the answer is 41
42 changes: 42 additions & 0 deletions firmware/qemu/src/bin/dbg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use cortex_m_semihosting::debug;

use defmt::dbg;
use defmt_semihosting as _; // global logger

#[entry]
fn main() -> ! {
// return value
let x: i32 = 42;
foo(dbg!(x + 1));

// dbg! in log statement
defmt::info!("the answer is {}", dbg!(x - 1));

// dbg! with multiple arguments
let _: (i32, i32) = dbg!(x - 2, x + 2);

// dbg! with zero arguments
let _: () = dbg!();
Comment thread
jonas-schievink marked this conversation as resolved.

// dbg! with trailing comma
foo(dbg!(x,));

loop {
debug::exit(debug::EXIT_SUCCESS)
}
}

fn foo(_: i32) {}

// like `panic-semihosting` but doesn't print to stdout (that would corrupt the defmt stream)
#[cfg(target_os = "none")]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {
debug::exit(debug::EXIT_FAILURE)
}
}
40 changes: 40 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,46 @@ fn log(level: Level, log: FormatArgs) -> TokenStream2 {
})
}

struct DbgArgs {
exprs: Punctuated<Expr, Token![,]>,
}

impl Parse for DbgArgs {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
Ok(Self {
exprs: Punctuated::parse_terminated(input)?,
})
}
}

#[proc_macro]
pub fn dbg(input: TokenStream) -> TokenStream {
let inputs = parse_macro_input!(input as DbgArgs).exprs;

let outputs = inputs
.into_iter()
.map(|expr| {
let escaped_expr = escape_expr(&expr);
let format_string = format!("{} = {{}}", escaped_expr);

quote!(match #expr {
tmp => {
defmt::trace!(#format_string, tmp);
tmp
}
})
})
.collect::<Vec<_>>();

if outputs.is_empty() {
// for compatibility with `std::dbg!` we also emit a TRACE log in this case
quote!(defmt::trace!(""))
} else {
quote!((#(#outputs),*))
}
.into()
}

#[proc_macro]
pub fn trace(ts: TokenStream) -> TokenStream {
log_ts(Level::Trace, ts)
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ pub use defmt_macros::trace;
/// [the manual]: https://defmt.ferrous-systems.com/macros.html
pub use defmt_macros::warn;

/// Just like the [`std::dbg!`] macro but `defmt` is used to log the message at TRACE level
Comment thread
jonas-schievink marked this conversation as resolved.
Outdated
///
/// [`std::dbg!`]: https://doc.rust-lang.org/std/macro.dbg.html
pub use defmt_macros::dbg;

/// Writes formatted data to a [`Formatter`].
///
/// [`Formatter`]: struct.Formatter.html
Expand Down
1 change: 1 addition & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ fn test_snapshot() {
"unwrap",
"defmt-test",
"hints",
"dbg",
];

if rustc_is_nightly() {
Expand Down