diff --git a/Cargo.toml b/Cargo.toml index 6709f7a..b688e20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ dwarf-expr = [] hide-trace = [] personality = [] personality-dummy = [] +print = ["libc"] system-alloc = [] default = ["dwarf-expr", "hide-trace", "fde-phdr", "fde-registry"] diff --git a/src/lib.rs b/src/lib.rs index e8b774d..c569acf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,10 @@ #![feature(c_unwind)] #![feature(naked_functions)] #![feature(asm)] -#![cfg_attr(any(feature = "personality", feature = "personality-dummy"), feature(lang_items))] +#![cfg_attr( + any(feature = "personality", feature = "personality-dummy"), + feature(lang_items) +)] #![warn(rust_2018_idioms)] #![warn(unsafe_op_in_unsafe_fn)] #![no_std] @@ -15,6 +18,9 @@ mod find_fde; mod frame; mod util; +#[cfg(feature = "print")] +pub mod print; + #[cfg(feature = "personality")] mod personality; #[cfg(feature = "personality-dummy")] diff --git a/src/print.rs b/src/print.rs new file mode 100644 index 0000000..b0ff76d --- /dev/null +++ b/src/print.rs @@ -0,0 +1,51 @@ +pub use crate::{eprint, eprintln, print, println}; + +#[doc(hidden)] +pub struct StdoutPrinter; +impl core::fmt::Write for StdoutPrinter { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + unsafe { libc::printf(b"%.*s\0".as_ptr() as _, s.len() as i32, s.as_ptr()) }; + Ok(()) + } +} + +#[doc(hidden)] +pub struct StderrPrinter; +impl core::fmt::Write for StderrPrinter { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + unsafe { libc::write(libc::STDERR_FILENO, s.as_ptr() as _, s.len() as _) }; + Ok(()) + } +} + +#[macro_export] +macro_rules! println { + ($($arg:tt)*) => ({ + use core::fmt::Write; + let _ = core::writeln!($crate::print::StdoutPrinter, $($arg)*); + }) +} + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ({ + use core::fmt::Write; + let _ = core::writeln!($crate::print::StdoutPrinter, $($arg)*); + }) +} + +#[macro_export] +macro_rules! eprintln { + ($($arg:tt)*) => ({ + use core::fmt::Write; + let _ = core::writeln!($crate::print::StderrPrinter, $($arg)*); + }) +} + +#[macro_export] +macro_rules! eprint { + ($($arg:tt)*) => ({ + use core::fmt::Write; + let _ = core::writeln!($crate::print::StderrPrinter, $($arg)*); + }) +}