Skip to content

Commit 77dc2fd

Browse files
Added macros print! and println! (#430)
1 parent 22d6974 commit 77dc2fd

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

uefi-services/src/lib.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern crate log;
2626
extern crate uefi;
2727

2828
use core::ffi::c_void;
29+
use core::fmt::Write;
2930
use core::ptr::NonNull;
3031

3132
use cfg_if::cfg_if;
@@ -93,6 +94,53 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result {
9394
}
9495
}
9596

97+
// Internal function for print macros.
98+
#[doc(hidden)]
99+
pub fn _print(args: core::fmt::Arguments) {
100+
unsafe {
101+
let st = SYSTEM_TABLE
102+
.as_mut()
103+
.expect("The system table handle is not available");
104+
105+
st.stdout()
106+
.write_fmt(args)
107+
.expect("Failed to write to stdout");
108+
}
109+
}
110+
111+
/// Prints to the standard output.
112+
///
113+
/// # Panics
114+
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
115+
///
116+
/// # Examples
117+
/// ```
118+
/// print!("");
119+
/// print!("Hello World\n");
120+
/// print!("Hello {}", "World");
121+
/// ```
122+
#[macro_export]
123+
macro_rules! print {
124+
($($arg:tt)*) => ($crate::_print(core::format_args!($($arg)*)));
125+
}
126+
127+
/// Prints to the standard output, with a newline.
128+
///
129+
/// # Panics
130+
/// Will panic if `SYSTEM_TABLE` is `None` (Before [init()] and after [uefi::prelude::SystemTable::exit_boot_services()]).
131+
///
132+
/// # Examples
133+
/// ```
134+
/// println!();
135+
/// println!("Hello World");
136+
/// println!("Hello {}", "World");
137+
/// ```
138+
#[macro_export]
139+
macro_rules! println {
140+
() => ($crate::print!("\n"));
141+
($($arg:tt)*) => ($crate::_print(core::format_args!("{}{}", core::format_args!($($arg)*), "\n")));
142+
}
143+
96144
/// Set up logging
97145
///
98146
/// This is unsafe because you must arrange for the logger to be reset with

uefi-test-runner/src/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use alloc::string::String;
1111
use uefi::prelude::*;
1212
use uefi::proto::console::serial::Serial;
1313
use uefi::table::boot::{OpenProtocolAttributes, OpenProtocolParams};
14+
use uefi_services::{print, println};
1415

1516
mod boot;
1617
mod proto;
@@ -28,6 +29,14 @@ fn efi_main(image: Handle, mut st: SystemTable<Boot>) -> Status {
2829
st.firmware_vendor().as_str_in_buf(&mut buf).unwrap();
2930
info!("Firmware Vendor: {}", buf.as_str());
3031

32+
// Test print! and println! macros.
33+
let (print, println) = ("print!", "println!"); // necessary for clippy to ignore
34+
print!("Testing {} macro with formatting: {:#010b} ", print, 155u8);
35+
println!(
36+
"Testing {} macro with formatting: {:#010b} ",
37+
println, 155u8
38+
);
39+
3140
// Reset the console before running all the other tests.
3241
st.stdout().reset(false).expect("Failed to reset stdout");
3342

0 commit comments

Comments
 (0)