diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 99bbd951766c6..f33530f93d111 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -63,8 +63,12 @@ #![feature(str_char)] #![feature(vec_push_all)] #![cfg_attr(windows, feature(libc))] +// Handle rustfmt skips +#![feature(custom_attribute)] +#![allow(unused_attributes)] -#[macro_use] extern crate log; +#[macro_use] +extern crate log; pub use terminfo::TerminfoTerminal; #[cfg(windows)] @@ -100,26 +104,18 @@ impl Write for WriterWrapper { /// Return a Terminal wrapping stdout, or None if a terminal couldn't be /// opened. pub fn stdout() -> Option + Send>> { - TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stdout(), - }) + TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() }) } #[cfg(windows)] /// Return a Terminal wrapping stdout, or None if a terminal couldn't be /// opened. pub fn stdout() -> Option + Send>> { - let ti = TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stdout(), - }); + let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() }); match ti { Some(t) => Some(t), - None => { - WinConsole::new(WriterWrapper { - wrapped: box std::io::stdout(), - }) - } + None => WinConsole::new(WriterWrapper { wrapped: box std::io::stdout() }), } } @@ -127,26 +123,18 @@ pub fn stdout() -> Option + Send>> { /// Return a Terminal wrapping stderr, or None if a terminal couldn't be /// opened. pub fn stderr() -> Option + Send>> { - TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stderr(), - }) + TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() }) } #[cfg(windows)] /// Return a Terminal wrapping stderr, or None if a terminal couldn't be /// opened. pub fn stderr() -> Option + Send>> { - let ti = TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stderr(), - }); + let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() }); match ti { Some(t) => Some(t), - None => { - WinConsole::new(WriterWrapper { - wrapped: box std::io::stderr(), - }) - } + None => WinConsole::new(WriterWrapper { wrapped: box std::io::stderr() }), } } @@ -157,23 +145,23 @@ pub mod color { /// Number for a terminal color pub type Color = u16; - pub const BLACK: Color = 0; - pub const RED: Color = 1; - pub const GREEN: Color = 2; - pub const YELLOW: Color = 3; - pub const BLUE: Color = 4; + pub const BLACK: Color = 0; + pub const RED: Color = 1; + pub const GREEN: Color = 2; + pub const YELLOW: Color = 3; + pub const BLUE: Color = 4; pub const MAGENTA: Color = 5; - pub const CYAN: Color = 6; - pub const WHITE: Color = 7; - - pub const BRIGHT_BLACK: Color = 8; - pub const BRIGHT_RED: Color = 9; - pub const BRIGHT_GREEN: Color = 10; - pub const BRIGHT_YELLOW: Color = 11; - pub const BRIGHT_BLUE: Color = 12; + pub const CYAN: Color = 6; + pub const WHITE: Color = 7; + + pub const BRIGHT_BLACK: Color = 8; + pub const BRIGHT_RED: Color = 9; + pub const BRIGHT_GREEN: Color = 10; + pub const BRIGHT_YELLOW: Color = 11; + pub const BRIGHT_BLUE: Color = 12; pub const BRIGHT_MAGENTA: Color = 13; - pub const BRIGHT_CYAN: Color = 14; - pub const BRIGHT_WHITE: Color = 15; + pub const BRIGHT_CYAN: Color = 14; + pub const BRIGHT_WHITE: Color = 15; } /// Terminal attributes @@ -206,7 +194,7 @@ pub mod attr { /// Convenience attribute to set the foreground color ForegroundColor(super::color::Color), /// Convenience attribute to set the background color - BackgroundColor(super::color::Color) + BackgroundColor(super::color::Color), } } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index ffe896b93a718..89c22e555ca95 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -28,13 +28,13 @@ use self::parm::{expand, Number, Variables}; #[derive(Debug)] pub struct TermInfo { /// Names for the terminal - pub names: Vec , + pub names: Vec, /// Map of capability name to boolean value pub bools: HashMap, /// Map of capability name to numeric value pub numbers: HashMap, /// Map of capability name to raw (unexpanded) string - pub strings: HashMap > + pub strings: HashMap>, } pub mod searcher; @@ -49,19 +49,19 @@ pub mod parm; fn cap_for_attr(attr: attr::Attr) -> &'static str { match attr { - attr::Bold => "bold", - attr::Dim => "dim", - attr::Italic(true) => "sitm", - attr::Italic(false) => "ritm", - attr::Underline(true) => "smul", - attr::Underline(false) => "rmul", - attr::Blink => "blink", - attr::Standout(true) => "smso", - attr::Standout(false) => "rmso", - attr::Reverse => "rev", - attr::Secure => "invis", + attr::Bold => "bold", + attr::Dim => "dim", + attr::Italic(true) => "sitm", + attr::Italic(false) => "ritm", + attr::Underline(true) => "smul", + attr::Underline(false) => "rmul", + attr::Blink => "blink", + attr::Standout(true) => "smso", + attr::Standout(false) => "rmso", + attr::Reverse => "rev", + attr::Secure => "invis", attr::ForegroundColor(_) => "setaf", - attr::BackgroundColor(_) => "setab" + attr::BackgroundColor(_) => "setab", } } @@ -70,7 +70,7 @@ fn cap_for_attr(attr: attr::Attr) -> &'static str { pub struct TerminfoTerminal { num_colors: u16, out: T, - ti: Box + ti: Box, } impl Terminal for TerminfoTerminal { @@ -80,12 +80,12 @@ impl Terminal for TerminfoTerminal { let s = expand(self.ti .strings .get("setaf") - .unwrap() - , - &[Number(color as isize)], &mut Variables::new()); + .unwrap(), + &[Number(color as isize)], + &mut Variables::new()); if s.is_ok() { try!(self.out.write_all(&s.unwrap())); - return Ok(true) + return Ok(true); } } Ok(false) @@ -97,12 +97,12 @@ impl Terminal for TerminfoTerminal { let s = expand(self.ti .strings .get("setab") - .unwrap() - , - &[Number(color as isize)], &mut Variables::new()); + .unwrap(), + &[Number(color as isize)], + &mut Variables::new()); if s.is_ok() { try!(self.out.write_all(&s.unwrap())); - return Ok(true) + return Ok(true); } } Ok(false) @@ -116,12 +116,10 @@ impl Terminal for TerminfoTerminal { let cap = cap_for_attr(attr); let parm = self.ti.strings.get(cap); if parm.is_some() { - let s = expand(parm.unwrap(), - &[], - &mut Variables::new()); + let s = expand(parm.unwrap(), &[], &mut Variables::new()); if s.is_ok() { try!(self.out.write_all(&s.unwrap())); - return Ok(true) + return Ok(true); } } Ok(false) @@ -131,9 +129,7 @@ impl Terminal for TerminfoTerminal { fn supports_attr(&self, attr: attr::Attr) -> bool { match attr { - attr::ForegroundColor(_) | attr::BackgroundColor(_) => { - self.num_colors > 0 - } + attr::ForegroundColor(_) | attr::BackgroundColor(_) => self.num_colors > 0, _ => { let cap = cap_for_attr(attr); self.ti.strings.get(cap).is_some() @@ -151,28 +147,33 @@ impl Terminal for TerminfoTerminal { cap = self.ti.strings.get("op"); } } - let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_owned()), |op| { - expand(op, &[], &mut Variables::new()) - }); + let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_owned()), + |op| expand(op, &[], &mut Variables::new())); if s.is_ok() { - return self.out.write_all(&s.unwrap()) + return self.out.write_all(&s.unwrap()); } Ok(()) } - fn get_ref<'a>(&'a self) -> &'a T { &self.out } + fn get_ref<'a>(&'a self) -> &'a T { + &self.out + } - fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out } + fn get_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.out + } } impl UnwrappableTerminal for TerminfoTerminal { - fn unwrap(self) -> T { self.out } + fn unwrap(self) -> T { + self.out + } } impl TerminfoTerminal { /// Returns `None` whenever the terminal cannot be created for some /// reason. - pub fn new(out: T) -> Option+Send+'static>> { + pub fn new(out: T) -> Option + Send + 'static>> { let term = match env::var("TERM") { Ok(t) => t, Err(..) => { @@ -183,20 +184,22 @@ impl TerminfoTerminal { let mut file = match open(&term[..]) { Ok(f) => f, - Err(err) => return match env::var("MSYSCON") { - Ok(ref val) if &val[..] == "mintty.exe" => { - // msys terminal - Some(box TerminfoTerminal{ - out: out, - ti: msys_terminfo(), - num_colors: 8, - }) - }, - _ => { - debug!("error finding terminfo entry: {:?}", err); - None - }, - }, + Err(err) => { + return match env::var("MSYSCON") { + Ok(ref val) if &val[..] == "mintty.exe" => { + // msys terminal + Some(box TerminfoTerminal { + out: out, + ti: msys_terminfo(), + num_colors: 8, + }) + } + _ => { + debug!("error finding terminfo entry: {:?}", err); + None + } + }; + } }; let ti = parse(&mut file, false); @@ -206,20 +209,25 @@ impl TerminfoTerminal { } let inf = ti.unwrap(); - let nc = if inf.strings.get("setaf").is_some() - && inf.strings.get("setab").is_some() { - inf.numbers.get("colors").map_or(0, |&n| n) - } else { 0 }; - - Some(box TerminfoTerminal {out: out, - ti: inf, - num_colors: nc}) + let nc = if inf.strings.get("setaf").is_some() && inf.strings.get("setab").is_some() { + inf.numbers.get("colors").map_or(0, |&n| n) + } else { + 0 + }; + + Some(box TerminfoTerminal { + out: out, + ti: inf, + num_colors: nc, + }) } fn dim_if_necessary(&self, color: color::Color) -> color::Color { if color >= self.num_colors && color >= 8 && color < 16 { - color-8 - } else { color } + color - 8 + } else { + color + } } } diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 9110be33907b0..49db096ce7332 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -32,14 +32,14 @@ enum States { SeekIfElse(isize), SeekIfElsePercent(isize), SeekIfEnd(isize), - SeekIfEndPercent(isize) + SeekIfEndPercent(isize), } #[derive(Copy, Clone, PartialEq)] enum FormatState { FormatStateFlags, FormatStateWidth, - FormatStatePrecision + FormatStatePrecision, } /// Types of parameters a capability can use @@ -47,7 +47,7 @@ enum FormatState { #[derive(Clone)] pub enum Param { Words(String), - Number(isize) + Number(isize), } /// Container for static and dynamic variable arrays @@ -55,29 +55,21 @@ pub struct Variables { /// Static variables A-Z sta: [Param; 26], /// Dynamic variables a-z - dyn: [Param; 26] + dyn: [Param; 26], } impl Variables { /// Return a new zero-initialized Variables pub fn new() -> Variables { Variables { - sta: [ - 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: [ - 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), - ], + sta: [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: [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)], } } } @@ -91,8 +83,7 @@ impl Variables { /// /// To be compatible with ncurses, `vars` should be the same between calls to `expand` for /// multiple capabilities for the same terminal. -pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) - -> Result , String> { +pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result, String> { let mut state = Nothing; // expanded cap will only rarely be larger than the cap itself @@ -101,10 +92,8 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) let mut stack: Vec = 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) { *dst = (*src).clone(); } @@ -119,147 +108,241 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) } else { output.push(c); } - }, + } Percent => { match cur { - '%' => { output.push(c); state = Nothing }, - 'c' => if !stack.is_empty() { - match stack.pop().unwrap() { - // if c is 0, use 0200 (128) for ncurses compatibility - Number(c) => { - output.push(if c == 0 { - 128 - } else { - c as u8 - }) + '%' => { + output.push(c); + state = Nothing + } + 'c' => { + if !stack.is_empty() { + match stack.pop().unwrap() { + // if c is 0, use 0200 (128) for ncurses compatibility + Number(c) => { + output.push(if c == 0 { + 128 + } else { + c as u8 + }) + } + _ => return Err("a non-char was used with %c".to_owned()), } - _ => return Err("a non-char was used with %c".to_owned()) + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, + } 'p' => state = PushParam, 'P' => state = SetVar, 'g' => state = GetVar, '\'' => state = CharConstant, '{' => state = IntConstant(0), - 'l' => if !stack.is_empty() { - match stack.pop().unwrap() { - Words(s) => stack.push(Number(s.len() as isize)), - _ => return Err("a non-str was used with %l".to_owned()) + 'l' => { + if !stack.is_empty() { + match stack.pop().unwrap() { + Words(s) => stack.push(Number(s.len() as isize)), + _ => return Err("a non-str was used with %l".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '+' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x + y)), - _ => return Err("non-numbers on stack with +".to_owned()) + } + '+' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x + y)), + _ => return Err("non-numbers on stack with +".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '-' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x - y)), - _ => return Err("non-numbers on stack with -".to_owned()) + } + '-' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x - y)), + _ => return Err("non-numbers on stack with -".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '*' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x * y)), - _ => return Err("non-numbers on stack with *".to_owned()) + } + '*' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x * y)), + _ => return Err("non-numbers on stack with *".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '/' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x / y)), - _ => return Err("non-numbers on stack with /".to_owned()) + } + '/' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x / y)), + _ => return Err("non-numbers on stack with /".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - 'm' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x % y)), - _ => return Err("non-numbers on stack with %".to_owned()) + } + 'm' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x % y)), + _ => return Err("non-numbers on stack with %".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '&' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x & y)), - _ => return Err("non-numbers on stack with &".to_owned()) + } + '&' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x & y)), + _ => return Err("non-numbers on stack with &".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '|' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x | y)), - _ => return Err("non-numbers on stack with |".to_owned()) + } + '|' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x | y)), + _ => return Err("non-numbers on stack with |".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '^' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(x ^ y)), - _ => return Err("non-numbers on stack with ^".to_owned()) + } + '^' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => stack.push(Number(x ^ y)), + _ => return Err("non-numbers on stack with ^".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '=' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(if x == y { 1 } - else { 0 })), - _ => return Err("non-numbers on stack with =".to_owned()) + } + '=' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => { + stack.push(Number(if x == y { + 1 + } else { + 0 + })) + } + _ => return Err("non-numbers on stack with =".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '>' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(if x > y { 1 } - else { 0 })), - _ => return Err("non-numbers on stack with >".to_owned()) + } + '>' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => { + stack.push(Number(if x > y { + 1 + } else { + 0 + })) + } + _ => return Err("non-numbers on stack with >".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '<' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(y), Number(x)) => stack.push(Number(if x < y { 1 } - else { 0 })), - _ => return Err("non-numbers on stack with <".to_owned()) + } + '<' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(y), Number(x)) => { + stack.push(Number(if x < y { + 1 + } else { + 0 + })) + } + _ => return Err("non-numbers on stack with <".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - 'A' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(0), Number(_)) => stack.push(Number(0)), - (Number(_), Number(0)) => stack.push(Number(0)), - (Number(_), Number(_)) => stack.push(Number(1)), - _ => return Err("non-numbers on stack with logical and".to_owned()) + } + 'A' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(0), Number(_)) => stack.push(Number(0)), + (Number(_), Number(0)) => stack.push(Number(0)), + (Number(_), Number(_)) => stack.push(Number(1)), + _ => return Err("non-numbers on stack with logical and".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - 'O' => if stack.len() > 1 { - match (stack.pop().unwrap(), stack.pop().unwrap()) { - (Number(0), Number(0)) => stack.push(Number(0)), - (Number(_), Number(_)) => stack.push(Number(1)), - _ => return Err("non-numbers on stack with logical or".to_owned()) + } + 'O' => { + if stack.len() > 1 { + match (stack.pop().unwrap(), stack.pop().unwrap()) { + (Number(0), Number(0)) => stack.push(Number(0)), + (Number(_), Number(_)) => stack.push(Number(1)), + _ => return Err("non-numbers on stack with logical or".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '!' => if !stack.is_empty() { - match stack.pop().unwrap() { - Number(0) => stack.push(Number(1)), - Number(_) => stack.push(Number(0)), - _ => return Err("non-number on stack with logical not".to_owned()) + } + '!' => { + if !stack.is_empty() { + match stack.pop().unwrap() { + Number(0) => stack.push(Number(1)), + Number(_) => stack.push(Number(0)), + _ => return Err("non-number on stack with logical not".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); + } + } + '~' => { + if !stack.is_empty() { + match stack.pop().unwrap() { + Number(x) => stack.push(Number(!x)), + _ => return Err("non-number on stack with %~".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, - '~' => if !stack.is_empty() { - match stack.pop().unwrap() { - Number(x) => stack.push(Number(!x)), - _ => return Err("non-number on stack with %~".to_owned()) + } + 'i' => { + match (mparams[0].clone(), mparams[1].clone()) { + (Number(x), Number(y)) => { + mparams[0] = Number(x + 1); + mparams[1] = Number(y + 1); + } + (_, _) => return Err("first two params not numbers with %i".to_owned()), } - } else { return Err("stack is empty".to_owned()) }, - 'i' => match (mparams[0].clone(), mparams[1].clone()) { - (Number(x), Number(y)) => { - mparams[0] = Number(x+1); - mparams[1] = Number(y+1); - }, - (_, _) => return Err("first two params not numbers with %i".to_owned()) - }, + } // printf-style support for %doxXs - 'd'|'o'|'x'|'X'|'s' => if !stack.is_empty() { - let flags = Flags::new(); - let res = format(stack.pop().unwrap(), FormatOp::from_char(cur), flags); - if res.is_err() { return res } - output.push_all(&res.unwrap()) - } else { return Err("stack is empty".to_owned()) }, - ':'|'#'|' '|'.'|'0'...'9' => { + 'd' | 'o' | 'x' | 'X' | 's' => { + if !stack.is_empty() { + let flags = Flags::new(); + let res = format(stack.pop().unwrap(), FormatOp::from_char(cur), flags); + if res.is_err() { + return res; + } + output.push_all(&res.unwrap()) + } else { + return Err("stack is empty".to_owned()); + } + } + ':' | '#' | ' ' | '.' | '0'...'9' => { let mut flags = Flags::new(); let mut fstate = FormatStateFlags; match cur { @@ -271,51 +354,57 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) flags.width = cur as usize - '0' as usize; fstate = FormatStateWidth; } - _ => unreachable!() + _ => unreachable!(), } state = FormatPattern(flags, fstate); } // conditionals '?' => (), - 't' => if !stack.is_empty() { - match stack.pop().unwrap() { - Number(0) => state = SeekIfElse(0), - Number(_) => (), - _ => return Err("non-number on stack \ - with conditional".to_owned()) + 't' => { + if !stack.is_empty() { + match stack.pop().unwrap() { + Number(0) => state = SeekIfElse(0), + Number(_) => (), + _ => return Err("non-number on stack with conditional".to_owned()), + } + } else { + return Err("stack is empty".to_owned()); } - } else { return Err("stack is empty".to_owned()) }, + } 'e' => state = SeekIfEnd(0), ';' => (), - _ => { - return Err(format!("unrecognized format option {:?}", cur)) - } + _ => return Err(format!("unrecognized format option {:?}", cur)), } - }, + } 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_owned()) - }].clone()); - }, + Some(d) => d as usize - 1, + None => return Err("bad param number".to_owned()), + }] + .clone()); + } SetVar => { if cur >= 'A' && cur <= 'Z' { if !stack.is_empty() { let idx = (cur as u8) - b'A'; vars.sta[idx as usize] = stack.pop().unwrap(); - } else { return Err("stack is empty".to_owned()) } + } else { + return Err("stack is empty".to_owned()); + } } else if cur >= 'a' && cur <= 'z' { if !stack.is_empty() { let idx = (cur as u8) - b'a'; vars.dyn[idx as usize] = stack.pop().unwrap(); - } else { return Err("stack is empty".to_owned()) } + } else { + return Err("stack is empty".to_owned()); + } } else { return Err("bad variable name in %P".to_owned()); } - }, + } GetVar => { if cur >= 'A' && cur <= 'Z' { let idx = (cur as u8) - b'A'; @@ -326,16 +415,16 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) } else { return Err("bad variable name in %g".to_owned()); } - }, + } CharConstant => { stack.push(Number(c as isize)); state = CharClose; - }, + } CharClose => { if cur != '\'' { return Err("malformed character constant".to_owned()); } - }, + } IntConstant(i) => { match cur { '}' => { @@ -343,57 +432,67 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) state = Nothing; } '0'...'9' => { - state = IntConstant(i*10 + (cur as isize - '0' as isize)); + state = IntConstant(i * 10 + (cur as isize - '0' as isize)); old_state = Nothing; } - _ => return Err("bad isize constant".to_owned()) + _ => return Err("bad isize constant".to_owned()), } } FormatPattern(ref mut flags, ref mut fstate) => { old_state = Nothing; match (*fstate, cur) { - (_,'d')|(_,'o')|(_,'x')|(_,'X')|(_,'s') => if !stack.is_empty() { - let res = format(stack.pop().unwrap(), FormatOp::from_char(cur), *flags); - if res.is_err() { return res } - output.push_all(&res.unwrap()); - // will cause state to go to Nothing - old_state = FormatPattern(*flags, *fstate); - } else { return Err("stack is empty".to_owned()) }, - (FormatStateFlags,'#') => { + (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => { + if !stack.is_empty() { + let res = format(stack.pop().unwrap(), + FormatOp::from_char(cur), + *flags); + if res.is_err() { + return res; + } + output.push_all(&res.unwrap()); + // will cause state to go to Nothing + old_state = FormatPattern(*flags, *fstate); + } else { + return Err("stack is empty".to_owned()); + } + } + (FormatStateFlags, '#') => { flags.alternate = true; } - (FormatStateFlags,'-') => { + (FormatStateFlags, '-') => { flags.left = true; } - (FormatStateFlags,'+') => { + (FormatStateFlags, '+') => { flags.sign = true; } - (FormatStateFlags,' ') => { + (FormatStateFlags, ' ') => { flags.space = true; } - (FormatStateFlags,'0'...'9') => { + (FormatStateFlags, '0'...'9') => { flags.width = cur as usize - '0' as usize; *fstate = FormatStateWidth; } - (FormatStateFlags,'.') => { + (FormatStateFlags, '.') => { *fstate = FormatStatePrecision; } - (FormatStateWidth,'0'...'9') => { + (FormatStateWidth, '0'...'9') => { let old = flags.width; flags.width = flags.width * 10 + (cur as usize - '0' as usize); - if flags.width < old { return Err("format width overflow".to_owned()) } + if flags.width < old { + return Err("format width overflow".to_owned()); + } } - (FormatStateWidth,'.') => { + (FormatStateWidth, '.') => { *fstate = FormatStatePrecision; } - (FormatStatePrecision,'0'...'9') => { + (FormatStatePrecision, '0'...'9') => { let old = flags.precision; flags.precision = flags.precision * 10 + (cur as usize - '0' as usize); if flags.precision < old { - return Err("format precision overflow".to_owned()) + return Err("format precision overflow".to_owned()); } } - _ => return Err("invalid format specifier".to_owned()) + _ => return Err("invalid format specifier".to_owned()), } } SeekIfElse(level) => { @@ -407,12 +506,12 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) if level == 0 { state = Nothing; } else { - state = SeekIfElse(level-1); + state = SeekIfElse(level - 1); } } else if cur == 'e' && level == 0 { state = Nothing; } else if cur == '?' { - state = SeekIfElse(level+1); + state = SeekIfElse(level + 1); } else { state = SeekIfElse(level); } @@ -428,10 +527,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) if level == 0 { state = Nothing; } else { - state = SeekIfEnd(level-1); + state = SeekIfEnd(level - 1); } } else if cur == '?' { - state = SeekIfEnd(level+1); + state = SeekIfEnd(level + 1); } else { state = SeekIfEnd(level); } @@ -451,13 +550,19 @@ struct Flags { alternate: bool, left: bool, sign: bool, - space: bool + space: bool, } 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, + } } } @@ -467,7 +572,7 @@ enum FormatOp { FormatOctal, FormatHex, FormatHEX, - FormatString + FormatString, } impl FormatOp { @@ -478,7 +583,7 @@ impl FormatOp { 'x' => FormatHex, 'X' => FormatHEX, 's' => FormatString, - _ => panic!("bad FormatOp char") + _ => panic!("bad FormatOp char"), } } fn to_char(self) -> char { @@ -487,23 +592,21 @@ impl FormatOp { FormatOctal => 'o', FormatHex => 'x', FormatHEX => 'X', - FormatString => 's' + FormatString => 's', } } } -fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { +fn format(val: Param, op: FormatOp, flags: Flags) -> Result, String> { let mut s = match val { Number(d) => { let s = match (op, flags.sign) { - (FormatDigit, true) => format!("{:+}", d).into_bytes(), + (FormatDigit, true) => format!("{:+}", d).into_bytes(), (FormatDigit, false) => format!("{}", d).into_bytes(), - (FormatOctal, _) => format!("{:o}", d).into_bytes(), - (FormatHex, _) => format!("{:x}", d).into_bytes(), - (FormatHEX, _) => format!("{:X}", d).into_bytes(), - (FormatString, _) => { - return Err("non-number on stack with %s".to_owned()) - } + (FormatOctal, _) => format!("{:o}", d).into_bytes(), + (FormatHex, _) => format!("{:x}", d).into_bytes(), + (FormatHEX, _) => format!("{:X}", d).into_bytes(), + (FormatString, _) => return Err("non-number on stack with %s".to_owned()), }; let mut s: Vec = s.into_iter().collect(); if flags.precision > s.len() { @@ -516,7 +619,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { assert!(!s.is_empty(), "string conversion produced empty result"); match op { FormatDigit => { - if flags.space && !(s[0] == b'-' || s[0] == b'+' ) { + if flags.space && !(s[0] == b'-' || s[0] == b'+') { s.insert(0, b' '); } } @@ -527,18 +630,18 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { } FormatHex => { if flags.alternate { - let s_ = replace(&mut s, vec!(b'0', b'x')); + let s_ = replace(&mut s, vec![b'0', b'x']); s.extend(s_); } } FormatHEX => { s = s.to_ascii_uppercase(); if flags.alternate { - let s_ = replace(&mut s, vec!(b'0', b'X')); + let s_ = replace(&mut s, vec![b'0', b'X']); s.extend(s_); } } - FormatString => unreachable!() + FormatString => unreachable!(), } s } @@ -551,10 +654,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { } s } - _ => { - return Err(format!("non-string on stack with %{:?}", - op.to_char())) - } + _ => return Err(format!("non-string on stack with %{:?}", op.to_char())), } } }; @@ -574,7 +674,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { #[cfg(test)] mod tests { - use super::{expand,Param,Words,Variables,Number}; + use super::{expand, Param, Words, Variables, Number}; use std::result::Result::Ok; #[test] @@ -594,7 +694,8 @@ mod tests { 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), + &[Number(1), Number(2), Number(3)], + &mut vars), Ok("123233".bytes().collect::>())); assert_eq!(expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars), Ok("0011".bytes().collect::>())); @@ -604,9 +705,11 @@ mod tests { 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, String> - { + fn get_res(fmt: &str, + cap: &str, + params: &[Param], + vars: &mut Variables) + -> Result, String> { let mut u8v: Vec<_> = fmt.bytes().collect(); u8v.extend(cap.bytes()); expand(&u8v, params, vars) @@ -616,7 +719,8 @@ mod tests { for &cap in &caps { let res = get_res("", cap, &[], vars); assert!(res.is_err(), - "Op {} succeeded incorrectly with 0 stack entries", cap); + "Op {} succeeded incorrectly with 0 stack entries", + cap); let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { @@ -624,19 +728,25 @@ mod tests { }; let res = get_res("%p1", cap, &[p], vars); assert!(res.is_ok(), - "Op {} failed with 1 stack entry: {}", cap, res.err().unwrap()); + "Op {} failed with 1 stack entry: {}", + cap, + res.err().unwrap()); } let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"]; for &cap in &caps { let res = expand(cap.as_bytes(), &[], vars); assert!(res.is_err(), - "Binop {} succeeded incorrectly with 0 stack entries", cap); + "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); + "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.err().unwrap()); + "Binop {} failed with 2 stack entries: {:?}", + cap, + res.err().unwrap()); } } @@ -670,16 +780,13 @@ mod tests { let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"; let res = expand(s, &[Number(1)], &mut vars); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), - "\\E[31m".bytes().collect::>()); + assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::>()); let res = expand(s, &[Number(8)], &mut vars); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), - "\\E[90m".bytes().collect::>()); + assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::>()); let res = expand(s, &[Number(42)], &mut vars); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), - "\\E[38;5;42m".bytes().collect::>()); + assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::>()); } #[test] @@ -690,14 +797,17 @@ mod tests { &[Words("foo".to_string()), Words("foo".to_string()), Words("f".to_string()), - Words("foo".to_string())], vars), + Words("foo".to_string())], + vars), Ok("foofoo ffo".bytes().collect::>())); assert_eq!(expand(b"%p1%:-4.2s", &[Words("foo".to_owned())], vars), Ok("fo ".bytes().collect::>())); assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars), Ok("1001 1+1".bytes().collect::>())); - assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars), + assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", + &[Number(15), Number(27)], + vars), Ok("17017 001b0X001B".bytes().collect::>())); } } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index d29042ae5e762..7c8d9983e78f5 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -19,6 +19,7 @@ use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. +#[rustfmt_skip] #[allow(missing_docs)] pub static boolfnames: &'static[&'static str] = &["auto_left_margin", "auto_right_margin", "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type", @@ -32,12 +33,14 @@ pub static boolfnames: &'static[&'static str] = &["auto_left_margin", "auto_righ "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs", "return_does_clr_eol"]; +#[rustfmt_skip] #[allow(missing_docs)] pub static boolnames: &'static[&'static str] = &["bw", "am", "xsb", "xhp", "xenl", "eo", "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon", "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy", "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"]; +#[rustfmt_skip] #[allow(missing_docs)] pub static numfnames: &'static[&'static str] = &[ "columns", "init_tabs", "lines", "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal", @@ -49,12 +52,14 @@ pub static numfnames: &'static[&'static str] = &[ "columns", "init_tabs", "lines "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay", "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"]; +#[rustfmt_skip] #[allow(missing_docs)] pub static numnames: &'static[&'static str] = &[ "cols", "it", "lines", "lm", "xmc", "pb", "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv", "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs", "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"]; +#[rustfmt_skip] #[allow(missing_docs)] pub static stringfnames: &'static[&'static str] = &[ "back_tab", "bell", "carriage_return", "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos", @@ -129,6 +134,7 @@ pub static stringfnames: &'static[&'static str] = &[ "back_tab", "bell", "carria "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline", "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"]; +#[rustfmt_skip] #[allow(missing_docs)] pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear", "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1", @@ -165,8 +171,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb "box1"]; /// Parse a compiled terminfo entry, using long capability names if `longnames` is true -pub fn parse(file: &mut Read, longnames: bool) - -> Result, String> { +pub fn parse(file: &mut Read, longnames: bool) -> Result, String> { macro_rules! try { ($e:expr) => ( match $e { Ok(e) => e, @@ -192,36 +197,34 @@ pub fn parse(file: &mut Read, longnames: bool) let magic = try!(read_le_u16(file)); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x}, found {:x}", - 0x011A_usize, magic as usize)); + 0x011A_usize, + magic as usize)); } - let names_bytes = try!(read_le_u16(file)) as isize; - let bools_bytes = try!(read_le_u16(file)) as isize; - let numbers_count = try!(read_le_u16(file)) as isize; + let names_bytes = try!(read_le_u16(file)) as isize; + let bools_bytes = try!(read_le_u16(file)) as isize; + let numbers_count = try!(read_le_u16(file)) as isize; let string_offsets_count = try!(read_le_u16(file)) as isize; - let string_table_bytes = try!(read_le_u16(file)) as isize; + let string_table_bytes = try!(read_le_u16(file)) as isize; - assert!(names_bytes > 0); + assert!(names_bytes > 0); if (bools_bytes as usize) > boolnames.len() { - return Err("incompatible file: more booleans than \ - expected".to_owned()); + return Err("incompatible file: more booleans than expected".to_owned()); } if (numbers_count as usize) > numnames.len() { - return Err("incompatible file: more numbers than \ - expected".to_owned()); + return Err("incompatible file: more numbers than expected".to_owned()); } if (string_offsets_count as usize) > stringnames.len() { - return Err("incompatible file: more string offsets than \ - expected".to_owned()); + return Err("incompatible file: more string offsets than expected".to_owned()); } // don't read NUL let bytes = try!(read_exact(file, names_bytes as usize - 1)); let names_str = match String::from_utf8(bytes) { - Ok(s) => s, + Ok(s) => s, Err(_) => return Err("input not utf-8".to_owned()), }; @@ -266,13 +269,13 @@ pub fn parse(file: &mut Read, longnames: bool) let string_table = try!(read_exact(file, string_table_bytes as usize)); if string_table.len() != string_table_bytes as usize { - return Err("error: hit EOF before end of string \ - table".to_owned()); + return Err("error: hit EOF before end of string table".to_owned()); } for (i, v) in string_offsets.iter().enumerate() { let offset = *v; - if offset == 0xFFFF { // non-entry + if offset == 0xFFFF { + // non-entry continue; } @@ -291,17 +294,17 @@ pub fn parse(file: &mut Read, longnames: bool) // Find the offset of the NUL we want to go to - let nulpos = string_table[offset as usize .. string_table_bytes as usize] - .iter().position(|&b| b == 0); + let nulpos = string_table[offset as usize..string_table_bytes as usize] + .iter() + .position(|&b| b == 0); match nulpos { Some(len) => { string_map.insert(name.to_string(), - string_table[offset as usize .. - (offset as usize + len)].to_vec()) - }, + string_table[offset as usize..(offset as usize + len)] + .to_vec()) + } None => { - return Err("invalid file: missing NUL in \ - string_table".to_owned()); + return Err("invalid file: missing NUL in string_table".to_owned()); } }; } @@ -312,7 +315,7 @@ pub fn parse(file: &mut Read, longnames: bool) names: term_names, bools: bools_map, numbers: numbers_map, - strings: string_map + strings: string_map, }) } @@ -343,10 +346,10 @@ pub fn msys_terminfo() -> Box { strings.insert("setaf".to_owned(), b"\x1B[3%p1%dm".to_vec()); strings.insert("setab".to_owned(), b"\x1B[4%p1%dm".to_vec()); box TermInfo { - names: vec!("cygwin".to_owned()), // msys is a fork of an older cygwin version + names: vec!["cygwin".to_owned()], // msys is a fork of an older cygwin version bools: HashMap::new(), numbers: HashMap::new(), - strings: strings + strings: strings, } } diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index 0e05ac53bc878..397e7aa22546c 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -38,13 +38,15 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { dirs_to_search.push(homedir.unwrap().join(".terminfo")) } match env::var("TERMINFO_DIRS") { - Ok(dirs) => for i in dirs.split(':') { - if i == "" { - dirs_to_search.push(PathBuf::from("/usr/share/terminfo")); - } else { - dirs_to_search.push(PathBuf::from(i)); + Ok(dirs) => { + for i in dirs.split(':') { + if i == "" { + dirs_to_search.push(PathBuf::from("/usr/share/terminfo")); + } else { + dirs_to_search.push(PathBuf::from(i)); + } } - }, + } // Found nothing in TERMINFO_DIRS, use the default paths: // According to /etc/terminfo/README, after looking at // ~/.terminfo, ncurses will search /etc/terminfo, then @@ -86,9 +88,7 @@ pub fn open(term: &str) -> Result { Err(e) => Err(format!("error opening file: {:?}", e)), } } - None => { - Err(format!("could not find terminfo entry for {:?}", term)) - } + None => Err(format!("could not find terminfo entry for {:?}", term)), } } diff --git a/src/libterm/win.rs b/src/libterm/win.rs index 28ddc56793832..fa53d783194c8 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -19,7 +19,7 @@ use std::io::prelude::*; use attr; use color; -use {Terminal,UnwrappableTerminal}; +use {Terminal, UnwrappableTerminal}; /// A Terminal implementation which uses the Win32 Console API. pub struct WinConsole { @@ -50,23 +50,22 @@ struct CONSOLE_SCREEN_BUFFER_INFO { extern "system" { fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL; fn GetStdHandle(which: DWORD) -> HANDLE; - fn GetConsoleScreenBufferInfo(handle: HANDLE, - info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL; + fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL; } fn color_to_bits(color: color::Color) -> u16 { // magic numbers from mingw-w64's wincon.h let bits = match color % 8 { - color::BLACK => 0, - color::BLUE => 0x1, - color::GREEN => 0x2, - color::RED => 0x4, - color::YELLOW => 0x2 | 0x4, + color::BLACK => 0, + color::BLUE => 0x1, + color::GREEN => 0x2, + color::RED => 0x4, + color::YELLOW => 0x2 | 0x4, color::MAGENTA => 0x1 | 0x4, - color::CYAN => 0x1 | 0x2, - color::WHITE => 0x1 | 0x2 | 0x4, - _ => unreachable!() + color::CYAN => 0x1 | 0x2, + color::WHITE => 0x1 | 0x2 | 0x4, + _ => unreachable!(), }; if color >= 8 { @@ -86,7 +85,7 @@ fn bits_to_color(bits: u16) -> color::Color { 0x5 => color::MAGENTA, 0x3 => color::CYAN, 0x7 => color::WHITE, - _ => unreachable!() + _ => unreachable!(), }; color | (bits & 0x8) // copy the hi-intensity bit @@ -116,13 +115,12 @@ impl WinConsole { /// Returns `None` whenever the terminal cannot be created for some /// reason. - pub fn new(out: T) -> Option+Send+'static>> { + pub fn new(out: T) -> Option + Send + 'static>> { let fg; let bg; unsafe { let mut buffer_info = ::std::mem::uninitialized(); - if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), - &mut buffer_info) != 0 { + if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), &mut buffer_info) != 0 { fg = bits_to_color(buffer_info.wAttributes); bg = bits_to_color(buffer_info.wAttributes >> 4); } else { @@ -130,9 +128,13 @@ impl WinConsole { bg = color::BLACK; } } - Some(box WinConsole { buf: out, - def_foreground: fg, def_background: bg, - foreground: fg, background: bg }) + Some(box WinConsole { + buf: out, + def_foreground: fg, + def_background: bg, + foreground: fg, + background: bg, + }) } } @@ -167,13 +169,13 @@ impl Terminal for WinConsole { self.foreground = f; self.apply(); Ok(true) - }, + } attr::BackgroundColor(b) => { self.background = b; self.apply(); Ok(true) - }, - _ => Ok(false) + } + _ => Ok(false), } } @@ -182,7 +184,7 @@ impl Terminal for WinConsole { // it to do anything -cmr match attr { attr::ForegroundColor(_) | attr::BackgroundColor(_) => true, - _ => false + _ => false, } } @@ -194,11 +196,17 @@ impl Terminal for WinConsole { Ok(()) } - fn get_ref<'a>(&'a self) -> &'a T { &self.buf } + fn get_ref<'a>(&'a self) -> &'a T { + &self.buf + } - fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf } + fn get_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.buf + } } impl UnwrappableTerminal for WinConsole { - fn unwrap(self) -> T { self.buf } + fn unwrap(self) -> T { + self.buf + } }