// TODO: refactor this file // TODO: make STDOUT redirect to a socket owned // by the process named "stdout" use core::fmt::{Arguments, Error}; pub struct Stdout; impl Stdout { pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */ { let _ = core::fmt::Write::write_fmt(self, arg); // Ok(()) } } impl core::fmt::Write for Stdout { #[cfg(target_arch = "aarch64")] fn write_str(&mut self, s: &str) -> Result<(), Error> { // Don't actually print anything yet lmao Ok(()) } #[cfg(target_arch = "x86_64")] fn write_str(&mut self, s: &str) -> Result<(), Error> { // use mini_backtrace::Backtrace; // use crate::TERM; // Capture up to 16 frames. This is returned using an ArrayVec that doesn't // perform any dynamic memory allocation. /* let bt = Backtrace::<16>::capture(); trace!("Backtrace:"); for frame in bt.frames { trace!(" {:#x}", frame); } if bt.frames_omitted { trace!(" ... "); } */ trace!("printing"); trace!("PRINT: {}", s); // x86_64::instructions::interrupts::without_interrupts(|| { // let mut term = TERM.lock(); // term.set_dirty(true); // term.print(s); // drop(term); // }); // trace!("Finished printing"); Ok(()) } #[cfg(target_arch = "riscv64")] fn write_str(&mut self, s: &str) -> Result<(), Error> { Ok(()) } fn write_char(&mut self, c: char) -> core::fmt::Result { self.write_str(c.encode_utf8(&mut [0; 4])) } fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> core::fmt::Result { core::fmt::write(&mut self, args) } } #[macro_export] macro_rules! print { () => { ::core::writeln!($crate::print::Stdout, "") }; ($($tt:tt)*) => { ::core::write!($crate::print::Stdout, $($tt)*) }; } #[macro_export] macro_rules! println { ($($tt:tt)*) => { ::core::writeln!($crate::print::Stdout, $($tt)*) }; }