os/arch/riscv/lib/
console.rs

1use core::fmt::{self, Write};
2
3use alloc::string::String;
4
5use crate::arch::lib::sbi::console_putchar;
6
7pub struct Stdout;
8pub struct Stdin;
9
10impl Write for Stdout {
11    fn write_str(&mut self, s: &str) -> fmt::Result {
12        for c in s.chars() {
13            console_putchar(c as usize);
14        }
15        Ok(())
16    }
17}
18
19impl Stdin {
20    // pub fn read_char(&mut self) -> char {
21    //     let c = crate::arch::lib::sbi::console_getchar();
22    //     c as u8 as char
23    // }
24    pub fn read_char(&mut self) -> char {
25        let c = crate::arch::lib::sbi::console_getchar();
26        // 立即回显字符(如果是可打印字符)
27        if (c as u8) >= 0x20 && (c as u8) <= 0x7E {
28            crate::arch::lib::sbi::console_putchar(c);
29        } else if (c as u8) == b'\n' || (c as u8) == b'\r' {
30            crate::arch::lib::sbi::console_putchar(b'\n' as usize);
31        }
32        c as u8 as char
33    }
34
35    pub fn read_line(&mut self, buf: &mut String) {
36        loop {
37            let c = self.read_char();
38            if c == '\n' || c == '\r' {
39                break;
40            }
41            buf.push(c);
42        }
43    }
44}
45
46pub(crate) fn print(args: fmt::Arguments) {
47    Stdout.write_fmt(args).unwrap();
48}
49
50pub fn stdin() -> Stdin {
51    Stdin
52}
53
54/// 打印格式化文本到控制台
55///
56/// 这个宏类似于标准库的 `print!` 宏,但使用 SBI 调用将文本输出到控制台。
57/// 它不会在末尾添加换行符。
58///
59/// # Examples
60///
61/// ```ignore
62/// print!("Hello, world!");
63/// print!("The answer is {}", 42);
64/// ```
65#[macro_export]
66macro_rules! earlyprint {
67    ($fmt: literal $(, $($arg: tt)+)?) => {
68        $crate::arch::lib::console::print(format_args!($fmt $(, $($arg)+)?))
69    }
70}
71
72/// 打印格式化文本到控制台并添加换行符
73///
74/// 这个宏类似于标准库的 `println!` 宏,但使用 SBI 调用将文本输出到控制台。
75/// 它会在末尾自动添加换行符。
76///
77/// # Examples
78///
79/// ```ignore
80/// println!("Hello, world!");
81/// println!("The answer is {}", 42);
82/// ```
83#[macro_export]
84macro_rules! earlyprintln {
85    ($fmt: literal $(, $($arg: tt)+)?) => {
86        $crate::arch::lib::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?))
87    }
88}