Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support octal display hint #857

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- [#859]: `defmt`: Satisfy clippy
- [#858]: `defmt`: Implement "passthrough" trait impls for *2Format wrappers
- [#857]: Add an octal display hint (`:o`)
- [#855]: `defmt-print`: Now uses tokio to make tcp and stdin reads async (in preparation for a `watch elf` flag)
- [#852]: `CI`: Update mdbook to v0.4.40
- [#847]: `decoder`: Fix log format width specifier not working as expected
Expand All @@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

[#859]: https://github.com/knurling-rs/defmt/pull/859
[#858]: https://github.com/knurling-rs/defmt/pull/858
[#857]: https://github.com/knurling-rs/defmt/pull/857
[#855]: https://github.com/knurling-rs/defmt/pull/855
[#852]: https://github.com/knurling-rs/defmt/pull/852
[#847]: https://github.com/knurling-rs/defmt/pull/847
Expand Down
10 changes: 7 additions & 3 deletions book/src/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The following display hints are currently supported:
| `:X` | uppercase hexadecimal |
| `:?` | `core::fmt::Debug`-like |
| `:b` | binary |
| `:o` | octal |
| `:a` | ASCII |
| `:ms` | timestamp in seconds (input in milliseconds) |
| `:us` | timestamp in seconds (input in microseconds) |
Expand Down Expand Up @@ -45,13 +46,16 @@ defmt::info!("{=[u8]:a}", bytes); // -> INFO b"he\xffllo"

## Alternate printing

Adding `#` in front of a binary and hexadecimal display hints, precedes these numbers with a base indicator.
Adding `#` in front of a binary, octal, and hexadecimal display hints, precedes these numbers with a base indicator.

``` rust
# extern crate defmt;
defmt::info!("{=u8:b}", 42); // -> INFO 101010
defmt::info!("{=u8:#b}", 42); // -> INFO 0b101010

defmt::info!("{=u8:o}", 42); // -> INFO 52
defmt::info!("{=u8:#o}", 42); // -> INFO 0o52

defmt::info!("{=u8:x}", 42); // -> INFO 2a
defmt::info!("{=u8:#x}", 42); // -> INFO 0x2a

Expand All @@ -72,11 +76,11 @@ defmt::info!("{=u8:08X}", 42); // -> INFO 0000002A
defmt::info!("{=u8:#08X}", 42); // -> INFO 0x00002A
```

When the alternate form is used for hex and binary, the `0x`/`0b` length is subtracted from the leading zeros. This matches [`core::fmt` behavior](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b11809759f975e266251f7968e542756).
When the alternate form is used for hex, octal, and binary, the `0x`/`0o`/`0b` length is subtracted from the leading zeros. This matches [`core::fmt` behavior](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b11809759f975e266251f7968e542756).

## Display hints for byte slice and byte array elements

Besides ASCII hints, byte slice and array elements can be formatted using hexadecimal or binary hints:
Besides ASCII hints, byte slice and array elements can be formatted using hexadecimal, octal, or binary hints:

```rust
# extern crate defmt;
Expand Down
18 changes: 17 additions & 1 deletion decoder/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,13 @@ impl<'t> Frame<'t> {
true => write!(buf, "{x:#0zero_pad$b}")?,
false => write!(buf, "{x:0zero_pad$b}")?,
},
Some(DisplayHint::Octal {
alternate,
zero_pad,
}) => match alternate {
true => write!(buf, "{x:#0zero_pad$o}")?,
false => write!(buf, "{x:0zero_pad$o}")?,
},
Some(DisplayHint::Hexadecimal {
uppercase,
alternate,
Expand Down Expand Up @@ -319,6 +326,13 @@ impl<'t> Frame<'t> {
true => write!(buf, "{x:#0zero_pad$b}")?,
false => write!(buf, "{x:0zero_pad$b}")?,
},
Some(DisplayHint::Octal {
alternate,
zero_pad,
}) => match alternate {
true => write!(buf, "{x:#0zero_pad$o}")?,
false => write!(buf, "{x:0zero_pad$o}")?,
},
Some(DisplayHint::Hexadecimal {
uppercase,
alternate,
Expand Down Expand Up @@ -368,7 +382,9 @@ impl<'t> Frame<'t> {
}
buf.push('\"');
}
Some(DisplayHint::Hexadecimal { .. }) | Some(DisplayHint::Binary { .. }) => {
Some(DisplayHint::Hexadecimal { .. })
| Some(DisplayHint::Octal { .. })
| Some(DisplayHint::Binary { .. }) => {
// `core::write!` doesn't quite produce the output we want, for example
// `write!("{:#04x?}", bytes)` produces a multi-line output
// `write!("{:02x?}", bytes)` is single-line but each byte doesn't include the "0x" prefix
Expand Down
130 changes: 70 additions & 60 deletions firmware/qemu/src/bin/hints.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,74 @@
0.000002 INFO hex alt 0x2a
0.000003 INFO HEX 2A
0.000004 INFO HEX alt 0x2A
0.000005 INFO binary 101010
0.000006 INFO binary alt 0b101010
0.000007 INFO ASCII 42
0.000008 INFO Debug 42
0.000009 INFO ----
0.000010 INFO no-hint 42
0.000011 INFO hex 2a
0.000012 INFO hex alt 0x2a
0.000013 INFO HEX 2A
0.000014 INFO HEX alt 0x2A
0.000015 INFO binary 101010
0.000016 INFO binary alt 0b101010
0.000017 INFO ASCII 42
0.000018 INFO Debug 42
0.000019 INFO ----
0.000020 INFO no hint 42
0.000021 INFO hex 2a
0.000022 INFO hex alt 0x2a
0.000023 INFO HEX 2A
0.000024 INFO HEX alt 0x2A
0.000025 INFO binary 101010
0.000026 INFO binary alt 0b101010
0.000027 INFO ASCII 42
0.000028 INFO Debug 42
0.000029 INFO ----
0.000030 INFO S1 > S2 101010
0.000031 INFO ----
0.000032 INFO no hint [72, 101, 127, 108, 108, 111]
0.000033 INFO hex [48, 65, 7f, 6c, 6c, 6f]
0.000034 INFO hex alt [0x48, 0x65, 0x7f, 0x6c, 0x6c, 0x6f]
0.000035 INFO HEX [48, 65, 7F, 6C, 6C, 6F]
0.000036 INFO HEX alt [0x48, 0x65, 0x7F, 0x6C, 0x6C, 0x6F]
0.000037 INFO binary [1001000, 1100101, 1111111, 1101100, 1101100, 1101111]
0.000038 INFO binary alt [0b1001000, 0b1100101, 0b1111111, 0b1101100, 0b1101100, 0b1101111]
0.000039 INFO ASCII b"He\x7fllo"
0.000040 INFO Debug [72, 101, 127, 108, 108, 111]
0.000041 INFO ----
0.000042 INFO b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
0.000043 INFO b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
0.000044 INFO ----
0.000045 INFO no hint Hello
0.000046 INFO Debug "Hello"
0.000047 INFO no hint world
0.000048 INFO Debug "world"
0.000005 INFO octal 52
0.000006 INFO octal alt 0o52
0.000007 INFO binary 101010
0.000008 INFO binary alt 0b101010
0.000009 INFO ASCII 42
0.000010 INFO Debug 42
0.000011 INFO ----
0.000012 INFO no-hint 42
0.000013 INFO hex 2a
0.000014 INFO hex alt 0x2a
0.000015 INFO HEX 2A
0.000016 INFO HEX alt 0x2A
0.000017 INFO octal 52
0.000018 INFO octal alt 0o52
0.000019 INFO binary 101010
0.000020 INFO binary alt 0b101010
0.000021 INFO ASCII 42
0.000022 INFO Debug 42
0.000023 INFO ----
0.000024 INFO no hint 42
0.000025 INFO hex 2a
0.000026 INFO hex alt 0x2a
0.000027 INFO HEX 2A
0.000028 INFO HEX alt 0x2A
0.000029 INFO octal 52
0.000030 INFO octal alt 0o52
0.000031 INFO binary 101010
0.000032 INFO binary alt 0b101010
0.000033 INFO ASCII 42
0.000034 INFO Debug 42
0.000035 INFO ----
0.000036 INFO S1 > S2 101010
0.000037 INFO ----
0.000038 INFO no hint [72, 101, 127, 108, 108, 111]
0.000039 INFO hex [48, 65, 7f, 6c, 6c, 6f]
0.000040 INFO hex alt [0x48, 0x65, 0x7f, 0x6c, 0x6c, 0x6f]
0.000041 INFO HEX [48, 65, 7F, 6C, 6C, 6F]
0.000042 INFO HEX alt [0x48, 0x65, 0x7F, 0x6C, 0x6C, 0x6F]
0.000043 INFO octal [110, 145, 177, 154, 154, 157]
0.000044 INFO octal alt [0o110, 0o145, 0o177, 0o154, 0o154, 0o157]
0.000045 INFO binary [1001000, 1100101, 1111111, 1101100, 1101100, 1101111]
0.000046 INFO binary alt [0b1001000, 0b1100101, 0b1111111, 0b1101100, 0b1101100, 0b1101111]
0.000047 INFO ASCII b"He\x7fllo"
0.000048 INFO Debug [72, 101, 127, 108, 108, 111]
0.000049 INFO ----
0.000050 INFO no hint 10
0.000051 INFO hex a
0.000052 INFO hex 0xa
0.000053 INFO HEX A
0.000054 INFO HEX 0xA
0.000055 INFO binary 1010
0.000056 INFO binary 0b1010
0.000057 INFO ASCII b"\n"
0.000058 INFO Debug 10
0.000059 INFO ISO8601 2021-04-20T09:23:44.804Z
0.000060 INFO ISO8601 +53271-03-27T11:46:44Z
0.000061 INFO Sec ms 1234.567
0.000062 INFO Sec us 1.234567
0.000063 INFO Time s 14:06:56:07
0.000064 INFO Time ms 00:20:34.567
0.000065 INFO Time us 00:00:01.234567
0.000050 INFO b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
0.000051 INFO b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
0.000052 INFO ----
0.000053 INFO no hint Hello
0.000054 INFO Debug "Hello"
0.000055 INFO no hint world
0.000056 INFO Debug "world"
0.000057 INFO ----
0.000058 INFO no hint 10
0.000059 INFO hex a
0.000060 INFO hex 0xa
0.000061 INFO HEX A
0.000062 INFO HEX 0xA
0.000063 INFO octal 12
0.000064 INFO octal 0o12
0.000065 INFO binary 1010
0.000066 INFO binary 0b1010
0.000067 INFO ASCII b"\n"
0.000068 INFO Debug 10
0.000069 INFO ISO8601 2021-04-20T09:23:44.804Z
0.000070 INFO ISO8601 +53271-03-27T11:46:44Z
0.000071 INFO Sec ms 1234.567
0.000072 INFO Sec us 1.234567
0.000073 INFO Time s 14:06:56:07
0.000074 INFO Time ms 00:20:34.567
0.000075 INFO Time us 00:00:01.234567
10 changes: 10 additions & 0 deletions firmware/qemu/src/bin/hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ fn main() -> ! {
defmt::info!("hex alt {=u8:#x}", x);
defmt::info!("HEX {=u8:X}", x);
defmt::info!("HEX alt {=u8:#X}", x);
defmt::info!("octal {=u8:o}", x);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add the tests at the end, to minimise the diff on the expected output file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, actually, that probably isn't going to help. Never mind.

defmt::info!("octal alt {=u8:#o}", x);
defmt::info!("binary {=u8:b}", x);
defmt::info!("binary alt {=u8:#b}", x);
defmt::info!("ASCII {=u8:a}", x);
Expand All @@ -30,6 +32,8 @@ fn main() -> ! {
defmt::info!("hex alt {=i8:#x}", x);
defmt::info!("HEX {=i8:X}", x);
defmt::info!("HEX alt {=i8:#X}", x);
defmt::info!("octal {=i8:o}", x);
defmt::info!("octal alt {=i8:#o}", x);
defmt::info!("binary {=i8:b}", x);
defmt::info!("binary alt {=i8:#b}", x);
defmt::info!("ASCII {=i8:a}", x);
Expand All @@ -45,6 +49,8 @@ fn main() -> ! {
defmt::info!("hex alt {:#x}", x);
defmt::info!("HEX {:X}", x);
defmt::info!("HEX alt {:#X}", x);
defmt::info!("octal {:o}", x);
defmt::info!("octal alt {:#o}", x);
defmt::info!("binary {:b}", x);
defmt::info!("binary alt {:#b}", x);
defmt::info!("ASCII {:a}", x);
Expand Down Expand Up @@ -83,6 +89,8 @@ fn main() -> ! {
defmt::info!("hex alt {=[u8]:#x}", *x);
defmt::info!("HEX {=[u8]:X}", *x);
defmt::info!("HEX alt {=[u8]:#X}", *x);
defmt::info!("octal {=[u8]:o}", *x);
defmt::info!("octal alt {=[u8]:#o}", *x);
defmt::info!("binary {=[u8]:b}", *x);
defmt::info!("binary alt {=[u8]:#b}", *x);
defmt::info!("ASCII {=[u8]:a}", *x);
Expand Down Expand Up @@ -118,6 +126,8 @@ fn main() -> ! {
defmt::info!("hex {=0..4:#x}", x);
defmt::info!("HEX {=0..4:X}", x);
defmt::info!("HEX {=0..4:#X}", x);
defmt::info!("octal {=0..4:o}", x);
defmt::info!("octal {=0..4:#o}", x);
defmt::info!("binary {=0..4:b}", x);
defmt::info!("binary {=0..4:#b}", x);
defmt::info!("ASCII {=0..4:a}", x);
Expand Down
9 changes: 9 additions & 0 deletions parser/src/display_hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ pub enum DisplayHint {
uppercase: bool,
zero_pad: usize,
},
/// `:o`
Octal {
alternate: bool,
zero_pad: usize,
},
/// `:b`
Binary {
alternate: bool,
Expand Down Expand Up @@ -87,6 +92,10 @@ impl DisplayHint {
alternate,
zero_pad,
},
"o" => DisplayHint::Octal {
alternate,
zero_pad,
},
"x" => DisplayHint::Hexadecimal {
alternate,
uppercase: false,
Expand Down
2 changes: 2 additions & 0 deletions parser/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ fn all_parse_param_cases(
#[case(":a", DisplayHint::Ascii)]
#[case(":b", DisplayHint::Binary { alternate: false, zero_pad: 0 })]
#[case(":#b", DisplayHint::Binary { alternate: true, zero_pad: 0 })]
#[case(":o", DisplayHint::Octal { alternate: false, zero_pad: 0 })]
#[case(":#o", DisplayHint::Octal { alternate: true, zero_pad: 0 })]
#[case(":x", DisplayHint::Hexadecimal { alternate: false, uppercase: false, zero_pad: 0 })]
#[case(":02x", DisplayHint::Hexadecimal { alternate: false, uppercase: false, zero_pad: 2 })]
#[case(":#x", DisplayHint::Hexadecimal { alternate: true, uppercase: false, zero_pad: 0 })]
Expand Down
Loading