diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-22 17:42:04 -0500 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-22 17:42:47 -0500 |
| commit | a06baa56b95674fc626b3c3fd680d6a65357fe60 (patch) | |
| tree | cd9d867c2ca3cff5c1d6b3bd73377c44649fb075 /src/libterm | |
| parent | 8eb7c58dbb7b32701af113bc58722d0d1fefb1eb (diff) | |
Format the world
Diffstat (limited to 'src/libterm')
| -rw-r--r-- | src/libterm/lib.rs | 16 | ||||
| -rw-r--r-- | src/libterm/terminfo/mod.rs | 53 | ||||
| -rw-r--r-- | src/libterm/terminfo/parm.rs | 246 | ||||
| -rw-r--r-- | src/libterm/terminfo/parm/tests.rs | 105 | ||||
| -rw-r--r-- | src/libterm/terminfo/parser/compiled.rs | 77 | ||||
| -rw-r--r-- | src/libterm/win.rs | 20 |
6 files changed, 261 insertions, 256 deletions
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index ad1a83316be..7318ced676a 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -30,15 +30,16 @@ //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx //! [ti]: https://en.wikipedia.org/wiki/Terminfo -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(deny(warnings))))] +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + test(attr(deny(warnings))) +)] #![deny(missing_docs)] - #![cfg_attr(windows, feature(libc))] use std::io::prelude::*; -use std::io::{self, Stdout, Stderr}; +use std::io::{self, Stderr, Stdout}; pub use terminfo::TerminfoTerminal; #[cfg(windows)] @@ -86,7 +87,6 @@ pub fn stderr() -> Option<Box<StderrTerminal>> { .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>)) } - /// Terminal color definitions #[allow(missing_docs)] pub mod color { @@ -192,5 +192,7 @@ pub trait Terminal: Write { fn get_mut(&mut self) -> &mut Self::Output; /// Returns the contained stream, destroying the `Terminal` - fn into_inner(self) -> Self::Output where Self: Sized; + fn into_inner(self) -> Self::Output + where + Self: Sized; } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index 09bea80c95a..5db1d5f4278 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -8,13 +8,13 @@ use std::fs::File; use std::io::{self, prelude::*, BufReader}; use std::path::Path; -use crate::Attr; use crate::color; +use crate::Attr; use crate::Terminal; +use parm::{expand, Param, Variables}; +use parser::compiled::{msys_terminfo, parse}; use searcher::get_dbpath_for_term; -use parser::compiled::{parse, msys_terminfo}; -use parm::{expand, Variables, Param}; /// A parsed terminfo database entry. #[derive(Debug)] @@ -112,7 +112,6 @@ pub mod parser { } pub mod parm; - fn cap_for_attr(attr: Attr) -> &'static str { match attr { Attr::Bold => "bold", @@ -178,18 +177,14 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> { fn reset(&mut self) -> io::Result<bool> { // are there any terminals that have color/attrs and not sgr0? // Try falling back to sgr, then op - let cmd = match ["sgr0", "sgr", "op"] - .iter() - .filter_map(|cap| self.ti.strings.get(*cap)) - .next() { - Some(op) => { - match expand(&op, &[], &mut Variables::new()) { + let cmd = + match ["sgr0", "sgr", "op"].iter().filter_map(|cap| self.ti.strings.get(*cap)).next() { + Some(op) => match expand(&op, &[], &mut Variables::new()) { Ok(cmd) => cmd, Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)), - } - } - None => return Ok(false), - }; + }, + None => return Ok(false), + }; self.out.write_all(&cmd).and(Ok(true)) } @@ -202,7 +197,8 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> { } fn into_inner(self) -> T - where Self: Sized + where + Self: Sized, { self.out } @@ -211,18 +207,14 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> { impl<T: Write + Send> TerminfoTerminal<T> { /// Creates a new TerminfoTerminal with the given TermInfo and Write. pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> { - let nc = if terminfo.strings.contains_key("setaf") && - terminfo.strings.contains_key("setab") { + let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab") + { terminfo.numbers.get("colors").map_or(0, |&n| n) } else { 0 }; - TerminfoTerminal { - out, - ti: terminfo, - num_colors: nc, - } + TerminfoTerminal { out, ti: terminfo, num_colors: nc } } /// Creates a new TerminfoTerminal for the current environment with the given Write. @@ -233,27 +225,20 @@ impl<T: Write + Send> TerminfoTerminal<T> { } fn dim_if_necessary(&self, color: color::Color) -> color::Color { - if color >= self.num_colors && color >= 8 && color < 16 { - color - 8 - } else { - color - } + if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color } } fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> { match self.ti.strings.get(cmd) { - Some(cmd) => { - match expand(&cmd, params, &mut Variables::new()) { - Ok(s) => self.out.write_all(&s).and(Ok(true)), - Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)), - } - } + Some(cmd) => match expand(&cmd, params, &mut Variables::new()) { + Ok(s) => self.out.write_all(&s).and(Ok(true)), + Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)), + }, None => Ok(false), } } } - impl<T: Write> Write for TerminfoTerminal<T> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.out.write(buf) diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index c7466daa2ba..2e4e917891e 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -53,16 +53,60 @@ impl Variables { pub fn new() -> Variables { Variables { sta_va: [ - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0) + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), ], dyn_va: [ - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0), Number(0), Number(0) + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), ], } } @@ -86,8 +130,17 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec< let mut stack: Vec<Param> = Vec::new(); // Copy parameters into a local vector for mutability - let mut mparams = [Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), - Number(0), Number(0), Number(0)]; + let mut mparams = [ + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + Number(0), + ]; for (dst, src) in mparams.iter_mut().zip(params.iter()) { *dst = (*src).clone(); } @@ -124,81 +177,67 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec< 'g' => state = GetVar, '\'' => state = CharConstant, '{' => state = IntConstant(0), - 'l' => { - match stack.pop() { - Some(Words(s)) => stack.push(Number(s.len() as i32)), - Some(_) => return Err("a non-str was used with %l".to_string()), - None => return Err("stack is empty".to_string()), - } - } + 'l' => match stack.pop() { + Some(Words(s)) => stack.push(Number(s.len() as i32)), + Some(_) => return Err("a non-str was used with %l".to_string()), + None => return Err("stack is empty".to_string()), + }, '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => { match (stack.pop(), stack.pop()) { - (Some(Number(y)), Some(Number(x))) => { - stack.push(Number(match cur { - '+' => x + y, - '-' => x - y, - '*' => x * y, - '/' => x / y, - '|' => x | y, - '&' => x & y, - '^' => x ^ y, - 'm' => x % y, - _ => unreachable!("All cases handled"), - })) - } + (Some(Number(y)), Some(Number(x))) => stack.push(Number(match cur { + '+' => x + y, + '-' => x - y, + '*' => x * y, + '/' => x / y, + '|' => x | y, + '&' => x & y, + '^' => x ^ y, + 'm' => x % y, + _ => unreachable!("All cases handled"), + })), (Some(_), Some(_)) => { - return Err(format!("non-numbers on stack with {}", cur)) + return Err(format!("non-numbers on stack with {}", cur)); } _ => return Err("stack is empty".to_string()), } } - '=' | '>' | '<' | 'A' | 'O' => { - match (stack.pop(), stack.pop()) { - (Some(Number(y)), Some(Number(x))) => { - stack.push(Number(if match cur { - '=' => x == y, - '<' => x < y, - '>' => x > y, - 'A' => x > 0 && y > 0, - 'O' => x > 0 || y > 0, - _ => unreachable!(), - } { - 1 - } else { - 0 - })) - } - (Some(_), Some(_)) => { - return Err(format!("non-numbers on stack with {}", cur)) - } - _ => return Err("stack is empty".to_string()), - } - } - '!' | '~' => { - match stack.pop() { - Some(Number(x)) => { - stack.push(Number(match cur { - '!' if x > 0 => 0, - '!' => 1, - '~' => !x, - _ => unreachable!(), - })) - } - Some(_) => return Err(format!("non-numbers on stack with {}", cur)), - None => return Err("stack is empty".to_string()), + '=' | '>' | '<' | 'A' | 'O' => match (stack.pop(), stack.pop()) { + (Some(Number(y)), Some(Number(x))) => stack.push(Number( + if match cur { + '=' => x == y, + '<' => x < y, + '>' => x > y, + 'A' => x > 0 && y > 0, + 'O' => x > 0 || y > 0, + _ => unreachable!(), + } { + 1 + } else { + 0 + }, + )), + (Some(_), Some(_)) => { + return Err(format!("non-numbers on stack with {}", cur)); } - } - 'i' => { - match (&mparams[0], &mparams[1]) { - (&Number(x), &Number(y)) => { - mparams[0] = Number(x + 1); - mparams[1] = Number(y + 1); - } - _ => { - return Err("first two params not numbers with %i".to_string()) - } + _ => return Err("stack is empty".to_string()), + }, + '!' | '~' => match stack.pop() { + Some(Number(x)) => stack.push(Number(match cur { + '!' if x > 0 => 0, + '!' => 1, + '~' => !x, + _ => unreachable!(), + })), + Some(_) => return Err(format!("non-numbers on stack with {}", cur)), + None => return Err("stack is empty".to_string()), + }, + 'i' => match (&mparams[0], &mparams[1]) { + (&Number(x), &Number(y)) => { + mparams[0] = Number(x + 1); + mparams[1] = Number(y + 1); } - } + _ => return Err("first two params not numbers with %i".to_string()), + }, // printf-style support for %doxXs 'd' | 'o' | 'x' | 'X' | 's' => { @@ -229,16 +268,12 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec< // conditionals '?' => (), - 't' => { - match stack.pop() { - Some(Number(0)) => state = SeekIfElse(0), - Some(Number(_)) => (), - Some(_) => { - return Err("non-number on stack with conditional".to_string()) - } - None => return Err("stack is empty".to_string()), - } - } + 't' => match stack.pop() { + Some(Number(0)) => state = SeekIfElse(0), + Some(Number(_)) => (), + Some(_) => return Err("non-number on stack with conditional".to_string()), + None => return Err("stack is empty".to_string()), + }, 'e' => state = SeekIfEnd(0), ';' => (), _ => return Err(format!("unrecognized format option {}", cur)), @@ -246,11 +281,13 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec< } PushParam => { // params are 1-indexed - stack.push(mparams[match cur.to_digit(10) { - Some(d) => d as usize - 1, - None => return Err("bad param number".to_string()), - }] - .clone()); + stack.push( + mparams[match cur.to_digit(10) { + Some(d) => d as usize - 1, + None => return Err("bad param number".to_string()), + }] + .clone(), + ); } SetVar => { if cur >= 'A' && cur <= 'Z' { @@ -419,14 +456,7 @@ struct Flags { impl Flags { fn new() -> Flags { - Flags { - width: 0, - precision: 0, - alternate: false, - left: false, - sign: false, - space: false, - } + Flags { width: 0, precision: 0, alternate: false, left: false, sign: false, space: false } } } @@ -503,18 +533,16 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> { } .into_bytes() } - Words(s) => { - match op { - FormatOp::String => { - let mut s = s.into_bytes(); - if flags.precision > 0 && flags.precision < s.len() { - s.truncate(flags.precision); - } - s + Words(s) => match op { + FormatOp::String => { + let mut s = s.into_bytes(); + if flags.precision > 0 && flags.precision < s.len() { + s.truncate(flags.precision); } - _ => return Err(format!("non-string on stack with %{}", op.to_char())), + s } - } + _ => return Err(format!("non-string on stack with %{}", op.to_char())), + }, }; if flags.width > s.len() { let n = flags.width - s.len(); diff --git a/src/libterm/terminfo/parm/tests.rs b/src/libterm/terminfo/parm/tests.rs index 4d38715424e..b975bd2d198 100644 --- a/src/libterm/terminfo/parm/tests.rs +++ b/src/libterm/terminfo/parm/tests.rs @@ -5,36 +5,43 @@ use std::result::Result::Ok; #[test] fn test_basic_setabf() { let s = b"\\E[48;5;%p1%dm"; - assert_eq!(expand(s, &[Number(1)], &mut Variables::new()).unwrap(), - "\\E[48;5;1m".bytes().collect::<Vec<_>>()); + assert_eq!( + expand(s, &[Number(1)], &mut Variables::new()).unwrap(), + "\\E[48;5;1m".bytes().collect::<Vec<_>>() + ); } #[test] fn test_multiple_int_constants() { - assert_eq!(expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(), - "21".bytes().collect::<Vec<_>>()); + assert_eq!( + expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(), + "21".bytes().collect::<Vec<_>>() + ); } #[test] fn test_op_i() { let mut vars = Variables::new(); - assert_eq!(expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", - &[Number(1), Number(2), Number(3)], - &mut vars), - Ok("123233".bytes().collect::<Vec<_>>())); - assert_eq!(expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars), - Ok("0011".bytes().collect::<Vec<_>>())); + assert_eq!( + expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", &[Number(1), Number(2), Number(3)], &mut vars), + Ok("123233".bytes().collect::<Vec<_>>()) + ); + assert_eq!( + expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars), + Ok("0011".bytes().collect::<Vec<_>>()) + ); } #[test] fn test_param_stack_failure_conditions() { let mut varstruct = Variables::new(); let vars = &mut varstruct; - fn get_res(fmt: &str, - cap: &str, - params: &[Param], - vars: &mut Variables) - -> Result<Vec<u8>, String> { + fn get_res( + fmt: &str, + cap: &str, + params: &[Param], + vars: &mut Variables, + ) -> Result<Vec<u8>, String> { let mut u8v: Vec<_> = fmt.bytes().collect(); u8v.extend(cap.as_bytes().iter().map(|&b| b)); expand(&u8v, params, vars) @@ -43,35 +50,19 @@ fn test_param_stack_failure_conditions() { let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"]; for &cap in caps.iter() { let res = get_res("", cap, &[], vars); - assert!(res.is_err(), - "Op {} succeeded incorrectly with 0 stack entries", - cap); - let p = if cap == "%s" || cap == "%l" { - Words("foo".to_string()) - } else { - Number(97) - }; + assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap); + let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) }; let res = get_res("%p1", cap, &[p], vars); - assert!(res.is_ok(), - "Op {} failed with 1 stack entry: {}", - cap, - res.unwrap_err()); + assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err()); } let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"]; for &cap in caps.iter() { let res = expand(cap.as_bytes(), &[], vars); - assert!(res.is_err(), - "Binop {} succeeded incorrectly with 0 stack entries", - cap); + assert!(res.is_err(), "Binop {} succeeded incorrectly with 0 stack entries", cap); let res = get_res("%{1}", cap, &[], vars); - assert!(res.is_err(), - "Binop {} succeeded incorrectly with 1 stack entry", - cap); + assert!(res.is_err(), "Binop {} succeeded incorrectly with 1 stack entry", cap); let res = get_res("%{1}%{2}", cap, &[], vars); - assert!(res.is_ok(), - "Binop {} failed with 2 stack entries: {}", - cap, - res.unwrap_err()); + assert!(res.is_ok(), "Binop {} failed with 2 stack entries: {}", cap, res.unwrap_err()); } } @@ -118,20 +109,30 @@ fn test_conditionals() { fn test_format() { let mut varstruct = Variables::new(); let vars = &mut varstruct; - assert_eq!(expand(b"%p1%s%p2%2s%p3%2s%p4%.2s", - &[Words("foo".to_string()), - Words("foo".to_string()), - Words("f".to_string()), - Words("foo".to_string())], - vars), - Ok("foofoo ffo".bytes().collect::<Vec<_>>())); - assert_eq!(expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars), - Ok("fo ".bytes().collect::<Vec<_>>())); + assert_eq!( + expand( + b"%p1%s%p2%2s%p3%2s%p4%.2s", + &[ + Words("foo".to_string()), + Words("foo".to_string()), + Words("f".to_string()), + Words("foo".to_string()) + ], + vars + ), + Ok("foofoo ffo".bytes().collect::<Vec<_>>()) + ); + assert_eq!( + expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars), + Ok("fo ".bytes().collect::<Vec<_>>()) + ); - assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars), - Ok("1001 1+1".bytes().collect::<Vec<_>>())); - assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", - &[Number(15), Number(27)], - vars), - Ok("17017 001b0X001B".bytes().collect::<Vec<_>>())); + assert_eq!( + expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars), + Ok("1001 1+1".bytes().collect::<Vec<_>>()) + ); + assert_eq!( + expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars), + Ok("17017 001b0X001B".bytes().collect::<Vec<_>>()) + ); } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index a8653a22f25..d36adb72c8e 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -2,10 +2,10 @@ //! ncurses-compatible compiled terminfo format parsing (term(5)) +use super::super::TermInfo; use std::collections::HashMap; use std::io; use std::io::prelude::*; -use super::super::TermInfo; #[cfg(test)] mod tests; @@ -195,9 +195,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin // Check magic number let magic = t!(read_le_u16(file)); if magic != 0x011A { - return Err(format!("invalid magic number: expected {:x}, found {:x}", - 0x011A, - magic)); + return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A, magic)); } // According to the spec, these fields must be >= -1 where -1 means that the feature is not @@ -209,7 +207,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin -1 => 0, _ => return Err("incompatible file: length fields must be >= -1".to_string()), } - }} + }}; } let names_bytes = read_nonneg!(); @@ -242,9 +240,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin Err(_) => return Err("input not utf-8".to_string()), }; - let term_names: Vec<String> = names_str.split('|') - .map(|s| s.to_string()) - .collect(); + let term_names: Vec<String> = names_str.split('|').map(|s| s.to_string()).collect(); // consume NUL if t!(read_byte(file)) != b'\0' { return Err("incompatible file: missing null terminator for names section".to_string()); @@ -271,49 +267,46 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin }; let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 { - let string_offsets: Vec<u16> = t!((0..string_offsets_count) - .map(|_| read_le_u16(file)) - .collect()); + let string_offsets: Vec<u16> = + t!((0..string_offsets_count).map(|_| read_le_u16(file)).collect()); let mut string_table = Vec::new(); t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table)); - t!(string_offsets.into_iter().enumerate().filter(|&(_, offset)| { - // non-entry - offset != 0xFFFF - }).map(|(i, offset)| { - let offset = offset as usize; - - let name = if snames[i] == "_" { - stringfnames[i] - } else { - snames[i] - }; - - if offset == 0xFFFE { - // undocumented: FFFE indicates cap@, which means the capability is not present - // unsure if the handling for this is correct - return Ok((name.to_string(), Vec::new())); - } - - // Find the offset of the NUL we want to go to - let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0); - match nulpos { - Some(len) => Ok((name.to_string(), string_table[offset..offset + len].to_vec())), - None => Err("invalid file: missing NUL in string_table".to_string()), - } - }).collect()) + t!(string_offsets + .into_iter() + .enumerate() + .filter(|&(_, offset)| { + // non-entry + offset != 0xFFFF + }) + .map(|(i, offset)| { + let offset = offset as usize; + + let name = if snames[i] == "_" { stringfnames[i] } else { snames[i] }; + + if offset == 0xFFFE { + // undocumented: FFFE indicates cap@, which means the capability is not present + // unsure if the handling for this is correct + return Ok((name.to_string(), Vec::new())); + } + + // Find the offset of the NUL we want to go to + let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0); + match nulpos { + Some(len) => { + Ok((name.to_string(), string_table[offset..offset + len].to_vec())) + } + None => Err("invalid file: missing NUL in string_table".to_string()), + } + }) + .collect()) } else { HashMap::new() }; // And that's all there is to it - Ok(TermInfo { - names: term_names, - bools: bools_map, - numbers: numbers_map, - strings: string_map, - }) + Ok(TermInfo { names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map }) } /// Creates a dummy TermInfo struct for msys terminals diff --git a/src/libterm/win.rs b/src/libterm/win.rs index e5911de8396..a789d739ab1 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -5,8 +5,8 @@ use std::io; use std::io::prelude::*; -use crate::Attr; use crate::color; +use crate::Attr; use crate::Terminal; /// A Terminal implementation that uses the Win32 Console API. @@ -73,11 +73,7 @@ fn color_to_bits(color: color::Color) -> u16 { _ => unreachable!(), }; - if color >= 8 { - bits | 0x8 - } else { - bits - } + if color >= 8 { bits | 0x8 } else { bits } } fn bits_to_color(bits: u16) -> color::Color { @@ -126,11 +122,10 @@ impl<T: Write + Send + 'static> WinConsole<T> { let bg; unsafe { let mut buffer_info = MaybeUninit::<CONSOLE_SCREEN_BUFFER_INFO>::uninit(); - if GetConsoleScreenBufferInfo( - GetStdHandle(-11i32 as DWORD), - buffer_info.as_mut_ptr() - ) != 0 { - let buffer_info = buffer_info.assume_init() ; + if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr()) + != 0 + { + let buffer_info = buffer_info.assume_init(); fg = bits_to_color(buffer_info.wAttributes); bg = bits_to_color(buffer_info.wAttributes >> 4); } else { @@ -217,7 +212,8 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> { } fn into_inner(self) -> T - where Self: Sized + where + Self: Sized, { self.buf } |
