strat9_kernel/shell/
output.rs1use crate::sync::SpinLock;
8use alloc::vec::Vec;
9
10static CAPTURE_BUF: SpinLock<Option<Vec<u8>>> = SpinLock::new(None);
11static PIPE_INPUT: SpinLock<Option<Vec<u8>>> = SpinLock::new(None);
12
13pub fn start_capture() {
15 *CAPTURE_BUF.lock() = Some(Vec::new());
16}
17
18pub fn take_capture() -> Vec<u8> {
20 CAPTURE_BUF.lock().take().unwrap_or_default()
21}
22
23pub fn is_capturing() -> bool {
25 CAPTURE_BUF.lock().is_some()
26}
27
28pub fn capture_write_bytes(data: &[u8]) {
30 if let Some(buf) = CAPTURE_BUF.lock().as_mut() {
31 buf.extend_from_slice(data);
32 }
33}
34
35pub fn set_pipe_input(data: Vec<u8>) {
37 *PIPE_INPUT.lock() = Some(data);
38}
39
40pub fn take_pipe_input() -> Option<Vec<u8>> {
45 PIPE_INPUT.lock().take()
46}
47
48pub fn has_pipe_input() -> bool {
50 PIPE_INPUT.lock().is_some()
51}
52
53pub fn clear_pipe_input() {
55 PIPE_INPUT.lock().take();
56}
57
58#[macro_export]
60macro_rules! shell_print {
61 ($($arg:tt)*) => {{
62 if $crate::shell::output::is_capturing() {
63 use core::fmt::Write;
64 let mut __tmp = alloc::string::String::new();
65 let _ = write!(__tmp, $($arg)*);
66 $crate::shell::output::capture_write_bytes(__tmp.as_bytes());
67 } else {
68 $crate::serial_print!($($arg)*);
69 if $crate::arch::x86_64::vga::is_available() {
70 use core::fmt::Write;
71 let _ = write!($crate::arch::x86_64::vga::VGA_WRITER.lock(), $($arg)*);
72 }
73 }
74 }};
75}
76
77#[macro_export]
79macro_rules! shell_println {
80 () => ($crate::shell_print!("\n"));
81 ($($arg:tt)*) => {{
82 if $crate::shell::output::is_capturing() {
83 use core::fmt::Write;
84 let mut __tmp = alloc::string::String::new();
85 let _ = writeln!(__tmp, $($arg)*);
86 $crate::shell::output::capture_write_bytes(__tmp.as_bytes());
87 } else {
88 $crate::serial_println!($($arg)*);
89 if $crate::arch::x86_64::vga::is_available() {
90 use core::fmt::Write;
91 let _ = writeln!($crate::arch::x86_64::vga::VGA_WRITER.lock(), $($arg)*);
92 }
93 }
94 }};
95}
96
97pub fn clear_screen() {
99 if crate::arch::x86_64::vga::is_available() {
100 crate::arch::x86_64::vga::VGA_WRITER.lock().clear();
101 }
102}
103
104pub fn print_prompt() {
106 shell_print!(">>> ");
107}
108
109pub fn print_char(ch: char) {
111 if crate::arch::x86_64::vga::is_available() {
112 use core::fmt::Write;
113 let _ = write!(crate::arch::x86_64::vga::VGA_WRITER.lock(), "{}", ch);
114 } else {
115 crate::serial_print!("{}", ch);
116 }
117}
118
119pub fn format_bytes(bytes: usize) -> (usize, &'static str) {
121 const KB: usize = 1024;
122 const MB: usize = KB * 1024;
123 const GB: usize = MB * 1024;
124
125 if bytes >= GB {
126 (bytes / GB, "GB")
127 } else if bytes >= MB {
128 (bytes / MB, "MB")
129 } else if bytes >= KB {
130 (bytes / KB, "KB")
131 } else {
132 (bytes, "B")
133 }
134}