Rollup merge of #68036 - euclio:libterm-ncurses6-fix, r=KodrAus
libterm: parse extended terminfo format Fixes #45728. Modifies libterm to parse the extended terminfo format introduced in ncurses 6.1. This fixes the lack of color in test output for users with newer ncurses versions. The ideal fix for this would be to migrate libtest to use `termcolor` (https://github.com/rust-lang/rust/issues/60349), but that's blocked for the foreseeable future.
This commit is contained in:
commit
974b69927b
4 changed files with 27 additions and 20 deletions
|
|
@ -91,7 +91,7 @@ pub fn stderr() -> Option<Box<StderrTerminal>> {
|
|||
#[allow(missing_docs)]
|
||||
pub mod color {
|
||||
/// Number for a terminal color
|
||||
pub type Color = u16;
|
||||
pub type Color = u32;
|
||||
|
||||
pub const BLACK: Color = 0;
|
||||
pub const RED: Color = 1;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ pub struct TermInfo {
|
|||
/// Map of capability name to boolean value
|
||||
pub bools: HashMap<String, bool>,
|
||||
/// Map of capability name to numeric value
|
||||
pub numbers: HashMap<String, u16>,
|
||||
pub numbers: HashMap<String, u32>,
|
||||
/// Map of capability name to raw (unexpanded) string
|
||||
pub strings: HashMap<String, Vec<u8>>,
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ fn cap_for_attr(attr: Attr) -> &'static str {
|
|||
/// A Terminal that knows how many colors it supports, with a reference to its
|
||||
/// parsed Terminfo database record.
|
||||
pub struct TerminfoTerminal<T> {
|
||||
num_colors: u16,
|
||||
num_colors: u32,
|
||||
out: T,
|
||||
ti: TermInfo,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,16 +159,16 @@ pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
|
|||
|
||||
fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
|
||||
let mut b = [0; 2];
|
||||
let mut amt = 0;
|
||||
while amt < b.len() {
|
||||
match r.read(&mut b[amt..])? {
|
||||
0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")),
|
||||
n => amt += n,
|
||||
}
|
||||
}
|
||||
r.read_exact(&mut b)?;
|
||||
Ok((b[0] as u16) | ((b[1] as u16) << 8))
|
||||
}
|
||||
|
||||
fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
|
||||
let mut b = [0; 4];
|
||||
r.read_exact(&mut b)?;
|
||||
Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
|
||||
}
|
||||
|
||||
fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
|
||||
match r.bytes().next() {
|
||||
Some(s) => s,
|
||||
|
|
@ -194,9 +194,12 @@ 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));
|
||||
}
|
||||
|
||||
let extended = match magic {
|
||||
0o0432 => false,
|
||||
0o01036 => true,
|
||||
_ => return Err(format!("invalid magic number, found {:o}", magic)),
|
||||
};
|
||||
|
||||
// According to the spec, these fields must be >= -1 where -1 means that the feature is not
|
||||
// supported. Using 0 instead of -1 works because we skip sections with length 0.
|
||||
|
|
@ -258,11 +261,15 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
|
|||
t!(read_byte(file)); // compensate for padding
|
||||
}
|
||||
|
||||
let numbers_map: HashMap<String, u16> = t! {
|
||||
(0..numbers_count).filter_map(|i| match read_le_u16(file) {
|
||||
Ok(0xFFFF) => None,
|
||||
Ok(n) => Some(Ok((nnames[i].to_string(), n))),
|
||||
Err(e) => Some(Err(e))
|
||||
let numbers_map: HashMap<String, u32> = t! {
|
||||
(0..numbers_count).filter_map(|i| {
|
||||
let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
|
||||
|
||||
match number {
|
||||
Ok(0xFFFF) => None,
|
||||
Ok(n) => Some(Ok((nnames[i].to_string(), n))),
|
||||
Err(e) => Some(Err(e))
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
|
||||
|
|
@ -318,7 +325,7 @@ pub fn msys_terminfo() -> TermInfo {
|
|||
strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
|
||||
|
||||
let mut numbers = HashMap::new();
|
||||
numbers.insert("colors".to_string(), 8u16);
|
||||
numbers.insert("colors".to_string(), 8);
|
||||
|
||||
TermInfo {
|
||||
names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ fn bits_to_color(bits: u16) -> color::Color {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
color | (bits & 0x8) // copy the hi-intensity bit
|
||||
color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
|
||||
}
|
||||
|
||||
impl<T: Write + Send + 'static> WinConsole<T> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue