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