From a3edd38046663c3da5c5377a2fc712d4db7cec76 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 16 Mar 2019 15:44:57 +0800 Subject: [PATCH] fix VGA color on x86_64 --- kernel/Cargo.lock | 35 +++++++++ kernel/Cargo.toml | 1 + kernel/Makefile | 2 +- .../src/arch/aarch64/driver/console/color.rs | 28 +------ kernel/src/arch/aarch64/driver/console/mod.rs | 20 ++--- kernel/src/arch/aarch64/mod.rs | 1 + kernel/src/arch/aarch64/syscall.rs | 4 + kernel/src/arch/x86_64/driver/vga.rs | 73 +++++++++++++----- kernel/src/logging.rs | 74 +++++-------------- kernel/src/syscall/mod.rs | 1 + kernel/src/util/color.rs | 65 ++++++++++++++++ .../driver/console => util}/escape_parser.rs | 30 ++++---- kernel/src/{util.rs => util/mod.rs} | 3 + 13 files changed, 213 insertions(+), 124 deletions(-) create mode 100644 kernel/src/arch/aarch64/syscall.rs create mode 100644 kernel/src/util/color.rs rename kernel/src/{arch/aarch64/driver/console => util}/escape_parser.rs (87%) rename kernel/src/{util.rs => util/mod.rs} (91%) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 9ea4fbc..9c9d35c 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -137,6 +137,14 @@ name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "generic-array" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getopts" version = "0.2.18" @@ -145,6 +153,23 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hash32" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heapless" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "1.3.0" @@ -266,6 +291,7 @@ dependencies = [ "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "console-traits 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)", + "heapless 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -423,6 +449,11 @@ name = "tock-registers" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "typenum" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "uart_16550" version = "0.1.0" @@ -549,7 +580,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8107dafa78c80c848b71b60133954b4a58609a3a1a5f9af037ecc7f67280f369" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12d790435639c06a7b798af9e1e331ae245b7ef915b92f70a39b4cf8c00686af" +"checksum heapless 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "56b960caff1a46f1fb3c1eb05f0575ac21c6248364ebebde11b11116e099881c" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" "checksum linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "655d57c71827fe0891ce72231b6aa5e14033dae3f604609e6a6f807267c1678d" @@ -581,6 +615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tock-registers 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316" +"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index c978b56..66feb50 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -45,6 +45,7 @@ xmas-elf = "0.6" bitflags = "1.0" bit_field = "0.9" volatile = "0.2" +heapless = "0.4" console-traits = "0.3" linked_list_allocator = "0.6" device_tree = { git = "https://github.com/jiegec/device_tree-rs" } diff --git a/kernel/Makefile b/kernel/Makefile index 5c26af8..46f6023 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -207,7 +207,7 @@ debug: $(kernel) $(bin) build: $(bin) asm: - @$(objdump) -dS $(kernel) | less + @$(objdump) -d $(kernel) | less header: @$(objdump) -h $(kernel) diff --git a/kernel/src/arch/aarch64/driver/console/color.rs b/kernel/src/arch/aarch64/driver/console/color.rs index b5cdfe4..419df50 100644 --- a/kernel/src/arch/aarch64/driver/console/color.rs +++ b/kernel/src/arch/aarch64/driver/console/color.rs @@ -1,7 +1,9 @@ //! Frambuffer color +use crate::util::color::ConsoleColor; + pub trait FramebufferColor { - /// pack as 32-bit integer + /// pack as 16-bit integer fn pack16(&self) -> u16; /// pack as 32-bit integer @@ -12,34 +14,12 @@ pub trait FramebufferColor { #[derive(Debug, Clone, Copy, PartialEq)] pub struct RgbColor(u8, u8, u8); -#[repr(u8)] -#[allow(dead_code)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum ConsoleColor { - Black = 0, - Red = 1, - Green = 2, - Yellow = 3, - Blue = 4, - Magenta = 5, - Cyan = 6, - White = 7, - BrightBlack = 60, - BrightRed = 61, - BrightGreen = 62, - BrightYellow = 63, - BrightBlue = 64, - BrightMagenta = 65, - BrightCyan = 66, - BrightWhite = 67, -} -use self::ConsoleColor::*; - impl From for RgbColor { /// Convert `ConsoleColor` to `RgbColor`. /// use `CMD` color scheme. /// (ref: https://en.wikipedia.org/wiki/ANSI_escape_code) fn from(color: ConsoleColor) -> Self { + use self::ConsoleColor::*; match color { Black => RgbColor(0, 0, 0), Red => RgbColor(128, 0, 0), diff --git a/kernel/src/arch/aarch64/driver/console/mod.rs b/kernel/src/arch/aarch64/driver/console/mod.rs index 90fc38a..d66b3a7 100644 --- a/kernel/src/arch/aarch64/driver/console/mod.rs +++ b/kernel/src/arch/aarch64/driver/console/mod.rs @@ -1,21 +1,23 @@ //! Framebuffer console display driver for ARM64 -mod color; -mod escape_parser; -mod fonts; - -use self::color::FramebufferColor; -use self::escape_parser::{CharacterAttribute, EscapeParser}; -use self::fonts::{Font, Font8x16}; - -use super::fb::{ColorDepth::*, FramebufferInfo, FRAME_BUFFER}; use alloc::vec::Vec; use core::fmt; use core::marker::PhantomData; + use lazy_static::lazy_static; use log::*; use spin::Mutex; +use crate::util::escape_parser::{CharacterAttribute, EscapeParser}; + +use super::fb::{ColorDepth::*, FRAME_BUFFER, FramebufferInfo}; + +use self::color::FramebufferColor; +use self::fonts::{Font, Font8x16}; + +mod color; +mod fonts; + #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq)] pub struct ConsoleChar { diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index 84ede32..6a1753f 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -8,6 +8,7 @@ pub mod consts; pub mod cpu; pub mod driver; pub mod timer; +pub mod syscall; #[cfg(feature = "board_raspi3")] #[path = "board/raspi3/mod.rs"] diff --git a/kernel/src/arch/aarch64/syscall.rs b/kernel/src/arch/aarch64/syscall.rs new file mode 100644 index 0000000..68bf3f5 --- /dev/null +++ b/kernel/src/arch/aarch64/syscall.rs @@ -0,0 +1,4 @@ +pub fn translate(id: usize) -> usize { + // FIXME: translate syscall id on aarch64 + id +} diff --git a/kernel/src/arch/x86_64/driver/vga.rs b/kernel/src/arch/x86_64/driver/vga.rs index 1ea7e8e..2c0c9e0 100644 --- a/kernel/src/arch/x86_64/driver/vga.rs +++ b/kernel/src/arch/x86_64/driver/vga.rs @@ -1,18 +1,45 @@ use core::fmt; + +use console_traits::*; +use lazy_static::lazy_static; use spin::Mutex; use volatile::Volatile; -use lazy_static::lazy_static; use x86_64::instructions::port::Port; -use crate::logging::Color; + use crate::consts::KERNEL_OFFSET; -use console_traits::*; +use crate::util::color::ConsoleColor; +use crate::util::escape_parser::EscapeParser; #[derive(Debug, Clone, Copy)] struct ColorCode(u8); impl ColorCode { - const fn new(foreground: Color, background: Color) -> ColorCode { - ColorCode((background as u8) << 4 | (foreground as u8)) + fn new(foreground: ConsoleColor, background: ConsoleColor) -> ColorCode { + ColorCode(background.to_code() << 4 | foreground.to_code()) + } +} + +impl ConsoleColor { + fn to_code(&self) -> u8 { + use self::ConsoleColor::*; + match self { + Black => 0, + Blue => 1, + Green => 2, + Cyan => 3, + Red => 4, + Magenta => 5, + Yellow => 6, + White => 7, + BrightBlack => 8, + BrightBlue => 9, + BrightGreen => 10, + BrightCyan => 11, + BrightRed => 12, + BrightMagenta => 13, + BrightYellow => 14, + BrightWhite => 15, + } } } @@ -24,7 +51,7 @@ pub struct ScreenChar { } impl ScreenChar { - pub const fn new(ascii_char: u8, foreground_color: Color, background_color: Color) -> Self { + pub fn new(ascii_char: u8, foreground_color: ConsoleColor, background_color: ConsoleColor) -> Self { ScreenChar { ascii_char, color_code: ColorCode::new(foreground_color, background_color) @@ -41,7 +68,7 @@ pub struct VgaBuffer { impl VgaBuffer { pub fn clear(&mut self) { - let blank = ScreenChar::new(b' ', Color::LightGray, Color::Black); + let blank = ScreenChar::new(b' ', ConsoleColor::White, ConsoleColor::Black); for row in 0 .. BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { self.chars[row][col].write(blank); @@ -76,9 +103,10 @@ lazy_static! { pub struct VgaWriter { pos: Position, - color: Color, + color_code: ColorCode, ctrl_char_mode: ControlCharMode, esc_char_mode: EscapeCharMode, + escape_parser: EscapeParser, buffer: &'static mut VgaBuffer, } @@ -105,6 +133,7 @@ impl BaseConsole for VgaWriter { fn set_pos(&mut self, pos: Position) -> Result<(), Self::Error> { self.pos = pos; + self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); Ok(()) } @@ -135,24 +164,35 @@ impl BaseConsole for VgaWriter { self.buffer.write(row - 1, col, screen_char); } } - let blank = ScreenChar::new(b' ', self.color, Color::Black); + let blank = ScreenChar::new(b' ', ConsoleColor::White, ConsoleColor::Black); for col in 0..BUFFER_WIDTH { self.buffer.write(BUFFER_HEIGHT - 1, col, blank); } - self.buffer.set_cursor_at(BUFFER_HEIGHT - 1, 0); Ok(()) } } impl AsciiConsole for VgaWriter { fn write_char_at(&mut self, ch: u8, pos: Position) -> Result<(), Self::Error> { - self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, ScreenChar::new(ch, self.color, Color::Black)); - self.buffer.set_cursor_at(pos.row.0 as usize, pos.col.0 as usize); + let screen_char = ScreenChar { + ascii_char: ch, + color_code: self.color_code, + }; + self.buffer.write(pos.row.0 as usize, pos.col.0 as usize, screen_char); Ok(()) } fn handle_escape(&mut self, escaped_char: u8) -> bool { - true + if escaped_char == b'[' { + self.escape_parser.start_parse(); + } + self.escape_parser.parse(escaped_char); + let end = escaped_char == b'm'; + if end { + let attr = self.escape_parser.char_attribute(); + self.color_code = ColorCode::new(attr.foreground, attr.background); + } + end } } @@ -161,16 +201,13 @@ impl VgaWriter { buffer.clear(); VgaWriter { pos: Position::origin(), - color: Color::LightGray, + color_code: ColorCode::new(ConsoleColor::White, ConsoleColor::Black), ctrl_char_mode: ControlCharMode::Interpret, esc_char_mode: EscapeCharMode::Waiting, + escape_parser: EscapeParser::new(), buffer, } } - - pub fn set_color(&mut self, color: Color) { - self.color = color; - } } impl fmt::Write for VgaWriter { diff --git a/kernel/src/logging.rs b/kernel/src/logging.rs index 4e6bf39..4e58590 100644 --- a/kernel/src/logging.rs +++ b/kernel/src/logging.rs @@ -1,10 +1,13 @@ use core::fmt; + +use lazy_static::lazy_static; use log::{self, Level, LevelFilter, Log, Metadata, Record}; + use crate::sync::SpinNoIrqLock as Mutex; -use lazy_static::lazy_static; +use crate::util::color::ConsoleColor; lazy_static! { - static ref log_mutex: Mutex<()> = Mutex::new(()); + static ref LOG_LOCK: Mutex<()> = Mutex::new(()); } pub fn init() { @@ -37,20 +40,20 @@ macro_rules! println { /// Add escape sequence to print with color in Linux console macro_rules! with_color { ($args: ident, $color: ident) => {{ - let (show, code) = color_to_console_code($color); - format_args!("\u{1B}[{};{}m{}\u{1B}[0m", show.clone(), code + 30, $args) + let code = $color.to_console_code(); + format_args!("\u{1B}[{}m{}\u{1B}[0m", code as u8, $args) }}; } -fn print_in_color(args: fmt::Arguments, color: Color) { +fn print_in_color(args: fmt::Arguments, color: ConsoleColor) { use crate::arch::io; - let _guard = log_mutex.lock(); + let _guard = LOG_LOCK.lock(); io::putfmt(with_color!(args, color)); } pub fn print(args: fmt::Arguments) { use crate::arch::io; - let _guard = log_mutex.lock(); + let _guard = LOG_LOCK.lock(); io::putfmt(args); } @@ -66,63 +69,20 @@ impl Log for SimpleLogger { if self.enabled(record.metadata()) && !DISABLED_TARGET.contains(&record.target()) { // let target = record.target(); // let begin = target.as_bytes().iter().rposition(|&c| c == b':').map(|i| i + 1).unwrap_or(0); - print_in_color(format_args!("[{:>5}] {}\n", record.level(), record.args()), Color::from(record.level())); + print_in_color(format_args!("[{:>5}] {}\n", record.level(), record.args()), ConsoleColor::from(record.level())); } } fn flush(&self) {} } -impl From for Color { +impl From for ConsoleColor { fn from(level: Level) -> Self { match level { - Level::Error => Color::Red, - Level::Warn => Color::Yellow, - Level::Info => Color::Blue, - Level::Debug => Color::Green, - Level::Trace => Color::DarkGray, + Level::Error => ConsoleColor::Red, + Level::Warn => ConsoleColor::Yellow, + Level::Info => ConsoleColor::Blue, + Level::Debug => ConsoleColor::Green, + Level::Trace => ConsoleColor::BrightBlack, } } } - -fn color_to_console_code(color: Color) -> (u8, u8) { - match color { - Color::Black => (0, 0), - Color::Blue => (0, 4), - Color::Green => (0, 2), - Color::Cyan => (0, 6), - Color::Red => (0, 1), - Color::Magenta => (0, 5), - Color::Brown => (0, 3), - Color::LightGray => (1, 7), - Color::DarkGray => (0, 7), - Color::LightBlue => (1, 4), - Color::LightGreen => (1, 2), - Color::LightCyan => (1, 6), - Color::LightRed => (1, 1), - Color::Pink => (1, 5), - Color::Yellow => (1, 3), - Color::White => (1, 0), - } -} - -#[allow(dead_code)] -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -#[repr(u8)] -pub enum Color { - Black = 0, - Blue = 1, - Green = 2, - Cyan = 3, - Red = 4, - Magenta = 5, - Brown = 6, - LightGray = 7, - DarkGray = 8, - LightBlue = 9, - LightGreen = 10, - LightCyan = 11, - LightRed = 12, - Pink = 13, - Yellow = 14, - White = 15, -} \ No newline at end of file diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index bad01f1..e4ae899 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -301,6 +301,7 @@ pub enum SysError { #[allow(non_snake_case)] impl fmt::Display for SysError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::SysError::*; write!(f, "{}", match self { EPERM => "Operation not permitted", diff --git a/kernel/src/util/color.rs b/kernel/src/util/color.rs new file mode 100644 index 0000000..385c56b --- /dev/null +++ b/kernel/src/util/color.rs @@ -0,0 +1,65 @@ +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum ConsoleColor { + Black, + Red, + Green, + Yellow, + Blue, + Magenta, + Cyan, + White, + BrightBlack, + BrightRed, + BrightGreen, + BrightYellow, + BrightBlue, + BrightMagenta, + BrightCyan, + BrightWhite, +} + +impl ConsoleColor { + pub fn to_console_code(&self) -> u8 { + use self::ConsoleColor::*; + match self { + Black => 30, + Red => 31, + Green => 32, + Yellow => 33, + Blue => 34, + Magenta => 35, + Cyan => 36, + White => 37, + BrightBlack => 90, + BrightRed => 91, + BrightGreen => 92, + BrightYellow => 93, + BrightBlue => 94, + BrightMagenta => 95, + BrightCyan => 96, + BrightWhite => 97, + } + } + pub fn from_console_code(code: u8) -> Option { + use self::ConsoleColor::*; + match code { + 30 => Some(Black), + 31 => Some(Red), + 32 => Some(Green), + 33 => Some(Yellow), + 34 => Some(Blue), + 35 => Some(Magenta), + 36 => Some(Cyan), + 37 => Some(White), + 90 => Some(BrightBlack), + 91 => Some(BrightRed), + 92 => Some(BrightGreen), + 93 => Some(BrightYellow), + 94 => Some(BrightBlue), + 95 => Some(BrightMagenta), + 96 => Some(BrightCyan), + 97 => Some(BrightWhite), + _ => None, + } + } +} diff --git a/kernel/src/arch/aarch64/driver/console/escape_parser.rs b/kernel/src/util/escape_parser.rs similarity index 87% rename from kernel/src/arch/aarch64/driver/console/escape_parser.rs rename to kernel/src/util/escape_parser.rs index 5c308f2..97127e2 100644 --- a/kernel/src/arch/aarch64/driver/console/escape_parser.rs +++ b/kernel/src/util/escape_parser.rs @@ -1,16 +1,17 @@ //! ANSI escape sequences parser //! (ref: https://en.wikipedia.org/wiki/ANSI_escape_code) -use super::color::{ConsoleColor, ConsoleColor::*, FramebufferColor}; -use alloc::vec::Vec; +use heapless::Vec; +use heapless::consts::U8; +use super::color::ConsoleColor; #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq)] -pub struct CharacterAttribute { +pub struct CharacterAttribute { /// foreground color - pub foreground: C, + pub foreground: ConsoleColor, /// background color - pub background: C, + pub background: ConsoleColor, /// show underline pub underline: bool, /// swap foreground and background colors @@ -22,8 +23,8 @@ pub struct CharacterAttribute { impl Default for CharacterAttribute { fn default() -> Self { CharacterAttribute { - foreground: White, - background: Black, + foreground: ConsoleColor::White, + background: ConsoleColor::Black, underline: false, reverse: false, strikethrough: false, @@ -50,7 +51,7 @@ pub struct EscapeParser { status: ParseStatus, char_attr: CharacterAttribute, current_param: Option, - params: Vec, + params: Vec, } impl EscapeParser { @@ -69,14 +70,13 @@ impl EscapeParser { /// See an `ECS` character, start parsing escape sequence. pub fn start_parse(&mut self) { - assert!(self.status == ParseStatus::Text); + assert_eq!(self.status, ParseStatus::Text); self.status = ParseStatus::BeginEscapeSequence; self.current_param = None; } //// Parse SGR (Select Graphic Rendition) parameters. fn parse_sgr_params(&mut self) { - use core::mem::transmute; for param in &self.params { match param { 0 => self.char_attr = CharacterAttribute::default(), @@ -86,8 +86,8 @@ impl EscapeParser { 24 => self.char_attr.underline = false, 27 => self.char_attr.reverse = false, 29 => self.char_attr.strikethrough = false, - 30...37 | 90...97 => self.char_attr.foreground = unsafe { transmute(param - 30) }, - 40...47 | 100...107 => self.char_attr.background = unsafe { transmute(param - 40) }, + 30...37 | 90...97 => self.char_attr.foreground = ConsoleColor::from_console_code(*param).unwrap(), + 40...47 | 100...107 => self.char_attr.background = ConsoleColor::from_console_code(*param - 10).unwrap(), _ => { /* unimplemented!() */ } } } @@ -95,7 +95,7 @@ impl EscapeParser { /// See a character during parsing. pub fn parse(&mut self, byte: u8) -> bool { - assert!(self.status != ParseStatus::Text); + assert_ne!(self.status, ParseStatus::Text); match self.status { ParseStatus::BeginEscapeSequence => match byte { b'[' => { @@ -117,7 +117,7 @@ impl EscapeParser { } b';' => { if let Some(param) = self.current_param { - self.params.push(param); + self.params.push(param).unwrap(); } self.current_param = Some(0); return true; @@ -125,7 +125,7 @@ impl EscapeParser { // @A–Z[\]^_`a–z{|}~ 0x40...0x7E => { if let Some(param) = self.current_param { - self.params.push(param); + self.params.push(param).unwrap(); } match byte { b'm' => self.parse_sgr_params(), diff --git a/kernel/src/util.rs b/kernel/src/util/mod.rs similarity index 91% rename from kernel/src/util.rs rename to kernel/src/util/mod.rs index dc9ffa0..c36dc88 100644 --- a/kernel/src/util.rs +++ b/kernel/src/util/mod.rs @@ -1,3 +1,6 @@ +pub mod color; +pub mod escape_parser; + /// Convert C string to Rust string pub unsafe fn from_cstr(s: *const u8) -> &'static str { use core::{str, slice};