// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#[allow(non_uppercase_statics)];
+#![allow(non_uppercase_statics)]
-/// ncurses-compatible compiled terminfo format parsing (term(5))
+//! ncurses-compatible compiled terminfo format parsing (term(5))
-
-use std::{vec, str};
-use std::io;
use collections::HashMap;
+use std::io;
+use std::str;
use super::super::TermInfo;
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
assert!(names_bytes > 0);
- debug!("names_bytes = {}", names_bytes);
- debug!("bools_bytes = {}", bools_bytes);
- debug!("numbers_count = {}", numbers_count);
- debug!("string_offsets_count = {}", string_offsets_count);
- debug!("string_table_bytes = {}", string_table_bytes);
-
if (bools_bytes as uint) > boolnames.len() {
- error!("expected bools_bytes to be less than {} but found {}", boolnames.len(),
- bools_bytes);
- return Err(~"incompatible file: more booleans than expected");
+ return Err("incompatible file: more booleans than expected".to_owned());
}
if (numbers_count as uint) > numnames.len() {
- error!("expected numbers_count to be less than {} but found {}", numnames.len(),
- numbers_count);
- return Err(~"incompatible file: more numbers than expected");
+ return Err("incompatible file: more numbers than expected".to_owned());
}
if (string_offsets_count as uint) > stringnames.len() {
- error!("expected string_offsets_count to be less than {} but found {}", stringnames.len(),
- string_offsets_count);
- return Err(~"incompatible file: more string offsets than expected");
+ return Err("incompatible file: more string offsets than expected".to_owned());
}
// don't read NUL
- let bytes = try!(file.read_bytes(names_bytes as uint - 1));
- let names_str = match str::from_utf8_owned(bytes) {
- Some(s) => s, None => return Err(~"input not utf-8"),
+ let bytes = try!(file.read_exact(names_bytes as uint - 1));
+ let names_str = match str::from_utf8(bytes.as_slice()) {
+ Some(s) => s.to_owned(), None => return Err("input not utf-8".to_owned()),
};
- let term_names: ~[~str] = names_str.split('|').map(|s| s.to_owned()).collect();
+ let term_names: Vec<~str> = names_str.split('|').map(|s| s.to_owned()).collect();
try!(file.read_byte()); // consume NUL
- debug!("term names: {:?}", term_names);
-
let mut bools_map = HashMap::new();
if bools_bytes != 0 {
for i in range(0, bools_bytes) {
let b = try!(file.read_byte());
- if b < 0 {
- error!("EOF reading bools after {} entries", i);
- return Err(~"error: expected more bools but hit EOF");
- } else if b == 1 {
- debug!("{} set", bnames[i]);
- bools_map.insert(bnames[i].to_owned(), true);
+ if b == 1 {
+ bools_map.insert(bnames[i as uint].to_owned(), true);
}
}
}
- debug!("bools: {:?}", bools_map);
-
if (bools_bytes + names_bytes) % 2 == 1 {
- debug!("adjusting for padding between bools and numbers");
try!(file.read_byte()); // compensate for padding
}
for i in range(0, numbers_count) {
let n = try!(file.read_le_u16());
if n != 0xFFFF {
- debug!("{}\\#{}", nnames[i], n);
- numbers_map.insert(nnames[i].to_owned(), n);
+ numbers_map.insert(nnames[i as uint].to_owned(), n);
}
}
}
- debug!("numbers: {:?}", numbers_map);
-
let mut string_map = HashMap::new();
if string_offsets_count != 0 {
- let mut string_offsets = vec::with_capacity(10);
+ let mut string_offsets = Vec::with_capacity(10);
for _ in range(0, string_offsets_count) {
string_offsets.push(try!(file.read_le_u16()));
}
- debug!("offsets: {:?}", string_offsets);
-
- let string_table = try!(file.read_bytes(string_table_bytes as uint));
+ let string_table = try!(file.read_exact(string_table_bytes as uint));
if string_table.len() != string_table_bytes as uint {
- error!("EOF reading string table after {} bytes, wanted {}", string_table.len(),
- string_table_bytes);
- return Err(~"error: hit EOF before end of string table");
+ return Err("error: hit EOF before end of string table".to_owned());
}
for (i, v) in string_offsets.iter().enumerate() {
if offset == 0xFFFE {
// undocumented: FFFE indicates cap@, which means the capability is not present
// unsure if the handling for this is correct
- string_map.insert(name.to_owned(), ~[]);
+ string_map.insert(name.to_owned(), Vec::new());
continue;
}
match nulpos {
Some(len) => {
string_map.insert(name.to_owned(),
- string_table.slice(offset as uint,
- offset as uint + len).to_owned())
+ Vec::from_slice(
+ string_table.slice(offset as uint,
+ offset as uint + len)))
},
None => {
- return Err(~"invalid file: missing NUL in string_table");
+ return Err("invalid file: missing NUL in string_table".to_owned());
}
};
}
}
// And that's all there is to it
- Ok(~TermInfo {names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map })
+ Ok(box TermInfo {
+ names: term_names,
+ bools: bools_map,
+ numbers: numbers_map,
+ strings: string_map
+ })
}
/// Create a dummy TermInfo struct for msys terminals
pub fn msys_terminfo() -> ~TermInfo {
let mut strings = HashMap::new();
- strings.insert(~"sgr0", bytes!("\x1b[0m").to_owned());
- strings.insert(~"bold", bytes!("\x1b[1m").to_owned());
- strings.insert(~"setaf", bytes!("\x1b[3%p1%dm").to_owned());
- strings.insert(~"setab", bytes!("\x1b[4%p1%dm").to_owned());
- ~TermInfo {
- names: ~[~"cygwin"], // msys is a fork of an older cygwin version
+ strings.insert("sgr0".to_owned(), Vec::from_slice(bytes!("\x1b[0m")));
+ strings.insert("bold".to_owned(), Vec::from_slice(bytes!("\x1b[1m")));
+ strings.insert("setaf".to_owned(), Vec::from_slice(bytes!("\x1b[3%p1%dm")));
+ strings.insert("setab".to_owned(), Vec::from_slice(bytes!("\x1b[4%p1%dm")));
+ box TermInfo {
+ names: vec!("cygwin".to_owned()), // msys is a fork of an older cygwin version
bools: HashMap::new(),
numbers: HashMap::new(),
strings: strings