use crate::util::AmoOnceRef;
use core::fmt;
pub trait LegacyStdio: Send + Sync {
fn getchar(&self) -> u8;
fn putchar(&self, ch: u8);
fn write_str(&self, s: &str) {
for byte in s.as_bytes() {
self.putchar(*byte)
}
}
}
static LEGACY_STDIO: AmoOnceRef<dyn LegacyStdio> = AmoOnceRef::new();
#[inline]
pub fn init_legacy_stdio(stdio: &'static dyn LegacyStdio) {
if !LEGACY_STDIO.try_call_once(stdio) {
panic!("load sbi module when already loaded")
}
}
#[inline]
pub fn legacy_stdio_putchar(ch: u8) {
if let Some(stdio) = LEGACY_STDIO.get() {
stdio.putchar(ch)
}
}
#[inline]
pub fn legacy_stdio_getchar() -> usize {
if let Some(stdio) = LEGACY_STDIO.get() {
stdio.getchar() as usize
} else {
usize::from_ne_bytes(isize::to_ne_bytes(-1))
}
}
#[inline]
pub(crate) fn probe_legacy_stdio() -> bool {
LEGACY_STDIO.get().is_some()
}
struct Stdout;
impl fmt::Write for Stdout {
#[inline]
fn write_str(&mut self, s: &str) -> fmt::Result {
if let Some(stdio) = LEGACY_STDIO.get() {
stdio.write_str(s);
}
Ok(())
}
}
#[inline]
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
use fmt::Write;
Stdout.write_fmt(args).unwrap();
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::legacy_stdio::_print(core::format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => ($crate::print!("\r\n"));
($($arg:tt)*) => {
$crate::legacy_stdio::_print(core::format_args!($($arg)*));
$crate::print!("\r\n");
}
}