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