Skip to content

Commit f9a5746

Browse files
committed
parse extended terminfo format
1 parent bfd0487 commit f9a5746

File tree

4 files changed

+27
-20
lines changed

4 files changed

+27
-20
lines changed

src/libterm/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub fn stderr() -> Option<Box<StderrTerminal>> {
9191
#[allow(missing_docs)]
9292
pub mod color {
9393
/// Number for a terminal color
94-
pub type Color = u16;
94+
pub type Color = u32;
9595

9696
pub const BLACK: Color = 0;
9797
pub const RED: Color = 1;

src/libterm/terminfo/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub struct TermInfo {
2424
/// Map of capability name to boolean value
2525
pub bools: HashMap<String, bool>,
2626
/// Map of capability name to numeric value
27-
pub numbers: HashMap<String, u16>,
27+
pub numbers: HashMap<String, u32>,
2828
/// Map of capability name to raw (unexpanded) string
2929
pub strings: HashMap<String, Vec<u8>>,
3030
}
@@ -129,7 +129,7 @@ fn cap_for_attr(attr: Attr) -> &'static str {
129129
/// A Terminal that knows how many colors it supports, with a reference to its
130130
/// parsed Terminfo database record.
131131
pub struct TerminfoTerminal<T> {
132-
num_colors: u16,
132+
num_colors: u32,
133133
out: T,
134134
ti: TermInfo,
135135
}

src/libterm/terminfo/parser/compiled.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,16 @@ pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
159159

160160
fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
161161
let mut b = [0; 2];
162-
let mut amt = 0;
163-
while amt < b.len() {
164-
match r.read(&mut b[amt..])? {
165-
0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")),
166-
n => amt += n,
167-
}
168-
}
162+
r.read_exact(&mut b)?;
169163
Ok((b[0] as u16) | ((b[1] as u16) << 8))
170164
}
171165

166+
fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
167+
let mut b = [0; 4];
168+
r.read_exact(&mut b)?;
169+
Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
170+
}
171+
172172
fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
173173
match r.bytes().next() {
174174
Some(s) => s,
@@ -194,9 +194,12 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
194194

195195
// Check magic number
196196
let magic = t!(read_le_u16(file));
197-
if magic != 0x011A {
198-
return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A, magic));
199-
}
197+
198+
let extended = match magic {
199+
0o0432 => false,
200+
0o01036 => true,
201+
_ => return Err(format!("invalid magic number, found {:o}", magic)),
202+
};
200203

201204
// According to the spec, these fields must be >= -1 where -1 means that the feature is not
202205
// 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
258261
t!(read_byte(file)); // compensate for padding
259262
}
260263

261-
let numbers_map: HashMap<String, u16> = t! {
262-
(0..numbers_count).filter_map(|i| match read_le_u16(file) {
263-
Ok(0xFFFF) => None,
264-
Ok(n) => Some(Ok((nnames[i].to_string(), n))),
265-
Err(e) => Some(Err(e))
264+
let numbers_map: HashMap<String, u32> = t! {
265+
(0..numbers_count).filter_map(|i| {
266+
let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
267+
268+
match number {
269+
Ok(0xFFFF) => None,
270+
Ok(n) => Some(Ok((nnames[i].to_string(), n))),
271+
Err(e) => Some(Err(e))
272+
}
266273
}).collect()
267274
};
268275

@@ -318,7 +325,7 @@ pub fn msys_terminfo() -> TermInfo {
318325
strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
319326

320327
let mut numbers = HashMap::new();
321-
numbers.insert("colors".to_string(), 8u16);
328+
numbers.insert("colors".to_string(), 8);
322329

323330
TermInfo {
324331
names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version

src/libterm/win.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn bits_to_color(bits: u16) -> color::Color {
8989
_ => unreachable!(),
9090
};
9191

92-
color | (bits & 0x8) // copy the hi-intensity bit
92+
color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
9393
}
9494

9595
impl<T: Write + Send + 'static> WinConsole<T> {

0 commit comments

Comments
 (0)