Skip to content

Commit f89dc1c

Browse files
committed
add support for ncurses 6.1 terminfo files
fixes Stebalien#81
1 parent ef9dfb2 commit f89dc1c

File tree

5 files changed

+29
-23
lines changed

5 files changed

+29
-23
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ categories = ["command-line-interface"]
1717
travis-ci = { repository = "Stebalien/term" }
1818
appveyor = { repository = "Stebalien/term" }
1919

20+
[dependencies]
21+
byteorder = "1.2.1"
22+
2023
[target.'cfg(windows)'.dependencies]
2124
winapi = { version = "0.3", features = ["wincon", "handleapi", "fileapi"] }
2225

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
#![deny(missing_docs)]
6464
#![cfg_attr(test, deny(warnings))]
6565

66+
extern crate byteorder;
67+
6668
use std::io::prelude::*;
6769

6870
pub use terminfo::TerminfoTerminal;
@@ -118,7 +120,7 @@ pub fn stderr() -> Option<Box<StderrTerminal>> {
118120
#[allow(missing_docs)]
119121
pub mod color {
120122
/// Number for a terminal color
121-
pub type Color = u16;
123+
pub type Color = u32;
122124

123125
pub const BLACK: Color = 0;
124126
pub const RED: Color = 1;

src/terminfo/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub struct TermInfo {
6161
/// Map of capability name to boolean value
6262
pub bools: HashMap<&'static str, bool>,
6363
/// Map of capability name to numeric value
64-
pub numbers: HashMap<&'static str, u16>,
64+
pub numbers: HashMap<&'static str, u32>,
6565
/// Map of capability name to raw (unexpanded) string
6666
pub strings: HashMap<&'static str, Vec<u8>>,
6767
}
@@ -107,7 +107,7 @@ impl TermInfo {
107107
strings.insert("setab", b"\x1B[4%p1%dm".to_vec());
108108

109109
let mut numbers = HashMap::new();
110-
numbers.insert("colors", 8u16);
110+
numbers.insert("colors", 8);
111111

112112
Ok(TermInfo {
113113
names: vec![name.to_owned()],
@@ -181,7 +181,7 @@ impl TermInfo {
181181
pub enum Error {
182182
/// The "magic" number at the start of the file was wrong.
183183
///
184-
/// It should be `0x11A`
184+
/// It should be `0x11A` (16bit numbers) or `0x21e` (32bit numbers)
185185
BadMagic(u16),
186186
/// The names in the file were not valid UTF-8.
187187
///
@@ -278,7 +278,7 @@ fn cap_for_attr(attr: Attr) -> &'static str {
278278
/// parsed Terminfo database record.
279279
#[derive(Clone, Debug)]
280280
pub struct TerminfoTerminal<T> {
281-
num_colors: u16,
281+
num_colors: u32,
282282
out: T,
283283
ti: TermInfo,
284284
}
@@ -371,7 +371,7 @@ impl<T: Write> TerminfoTerminal<T> {
371371
TerminfoTerminal {
372372
out: out,
373373
ti: terminfo,
374-
num_colors: nc,
374+
num_colors: nc as u32,
375375
}
376376
}
377377

src/terminfo/parser/compiled.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use std::collections::HashMap;
1414
use std::io::prelude::*;
1515
use std::io;
1616

17+
use byteorder::{LittleEndian, ReadBytesExt};
18+
1719
use terminfo::Error::*;
1820
use terminfo::TermInfo;
1921
use Result;
@@ -23,16 +25,12 @@ pub use terminfo::parser::names::*;
2325
// These are the orders ncurses uses in its compiled format (as of 5.9). Not
2426
// sure if portable.
2527

26-
fn read_le_u16(r: &mut io::Read) -> io::Result<u16> {
27-
let mut b = [0; 2];
28-
let mut amt = 0;
29-
while amt < b.len() {
30-
match try!(r.read(&mut b[amt..])) {
31-
0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")),
32-
n => amt += n,
33-
}
34-
}
35-
Ok((b[0] as u16) | ((b[1] as u16) << 8))
28+
fn read_le_u16(r: &mut io::Read) -> io::Result<u32> {
29+
return r.read_u16::<LittleEndian>().map(|i| i as u32)
30+
}
31+
32+
fn read_le_u32(r: &mut io::Read) -> io::Result<u32> {
33+
return r.read_u32::<LittleEndian>()
3634
}
3735

3836
fn read_byte(r: &mut io::Read) -> io::Result<u8> {
@@ -52,10 +50,13 @@ pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo> {
5250
};
5351

5452
// Check magic number
55-
let magic = try!(read_le_u16(file));
56-
if magic != 0x011A {
57-
return Err(BadMagic(magic).into());
58-
}
53+
let magic = try!(file.read_u16::<LittleEndian>());
54+
55+
let read_number = match magic {
56+
0x011A => read_le_u16,
57+
0x021e => read_le_u32,
58+
_ => return Err(BadMagic(magic).into()),
59+
};
5960

6061
// According to the spec, these fields must be >= -1 where -1 means that the
6162
// feature is not
@@ -121,8 +122,8 @@ pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo> {
121122
try!(read_byte(file)); // compensate for padding
122123
}
123124

124-
let numbers_map: HashMap<&str, u16> = try! {
125-
(0..numbers_count).filter_map(|i| match read_le_u16(file) {
125+
let numbers_map: HashMap<&str, u32> = try! {
126+
(0..numbers_count).filter_map(|i| match read_number(file) {
126127
Ok(0xFFFF) => None,
127128
Ok(n) => Some(Ok((nnames[i], n))),
128129
Err(e) => Some(Err(e))
@@ -131,7 +132,7 @@ pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo> {
131132

132133
let string_map: HashMap<&str, Vec<u8>> = if string_offsets_count > 0 {
133134
let string_offsets: Vec<u16> = try!((0..string_offsets_count)
134-
.map(|_| read_le_u16(file))
135+
.map(|_| file.read_u16::<LittleEndian>())
135136
.collect());
136137

137138
let mut string_table = Vec::new();

tests/data/xterm-256color

251 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)