1 use core::{
2 fmt::{self, Write},
3 sync::atomic::Ordering,
4 };
5
6 use alloc::string::ToString;
7
8 use super::lib_ui::textui::{textui_putstr, FontColor};
9
10 use crate::{
11 driver::tty::{
12 tty_driver::TtyOperation, tty_port::TTY_PORTS,
13 virtual_terminal::virtual_console::CURRENT_VCNUM,
14 },
15 filesystem::procfs::{
16 kmsg::KMSG,
17 log::{LogLevel, LogMessage},
18 },
19 time::TimeSpec,
20 };
21
22 #[macro_export]
23 macro_rules! print {
24 ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*)));
25 }
26
27 #[macro_export]
28 macro_rules! println {
29 () => {
30 $crate::print!("\n");
31 };
32 ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
33 }
34
35 #[macro_export]
36 macro_rules! kdebug {
37 ($($arg:tt)*) => {
38 $crate::libs::printk::Logger.log(7,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
39 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)))
40 }
41 }
42
43 #[macro_export]
44 macro_rules! kinfo {
45 ($($arg:tt)*) => {
46 $crate::libs::printk::Logger.log(6,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
47 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)))
48 }
49 }
50
51 #[macro_export]
52 macro_rules! kwarn {
53 ($($arg:tt)*) => {
54 $crate::libs::printk::Logger.log(4,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
55 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[1;33m[ WARN ] \x1B[0m"));
56 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
57 }
58 }
59
60 #[macro_export]
61 macro_rules! kerror {
62 ($($arg:tt)*) => {
63 $crate::libs::printk::Logger.log(3,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
64 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ ERROR ] \x1B[0m"));
65 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
66 }
67 }
68
69 #[macro_export]
70 macro_rules! kBUG {
71 ($($arg:tt)*) => {
72 $crate::libs::printk::Logger.log(1,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
73 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ BUG ] \x1B[0m"));
74 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
75 }
76 }
77
78 pub struct PrintkWriter;
79
80 impl PrintkWriter {
81 #[inline]
__write_fmt(&mut self, args: fmt::Arguments)82 pub fn __write_fmt(&mut self, args: fmt::Arguments) {
83 self.write_fmt(args).ok();
84 }
85
86 /// 并输出白底黑字
87 /// @param str: 要写入的字符
__write_string(&mut self, s: &str)88 pub fn __write_string(&mut self, s: &str) {
89 let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
90 if current_vcnum != -1 {
91 // tty已经初始化了之后才输出到屏幕
92 let port = TTY_PORTS[current_vcnum as usize].clone();
93 let tty = port.port_data().tty();
94 if tty.is_some() {
95 let tty = tty.unwrap();
96 let _ = tty.write(tty.core(), s.as_bytes(), s.len());
97 } else {
98 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
99 }
100 } else {
101 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
102 }
103 }
104 }
105
106 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出
107 impl fmt::Write for PrintkWriter {
write_str(&mut self, s: &str) -> fmt::Result108 fn write_str(&mut self, s: &str) -> fmt::Result {
109 self.__write_string(s);
110 Ok(())
111 }
112 }
113
114 #[doc(hidden)]
__printk(args: fmt::Arguments)115 pub fn __printk(args: fmt::Arguments) {
116 PrintkWriter.write_fmt(args).unwrap();
117 }
118
119 pub struct Logger;
120
121 impl Logger {
log(&self, log_level: usize, message: fmt::Arguments)122 pub fn log(&self, log_level: usize, message: fmt::Arguments) {
123 if unsafe { KMSG.is_some() } {
124 let timestamp: TimeSpec = TimeSpec::now();
125 let log_level = LogLevel::from(log_level.clone());
126
127 let log_message = LogMessage::new(timestamp, log_level, message.to_string());
128
129 unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) };
130 }
131 }
132 }
133