diff --git a/lib.rs b/lib.rs index 756d67b..ba9860e 100644 --- a/lib.rs +++ b/lib.rs @@ -52,14 +52,15 @@ #![feature(box_syntax)] #![feature(collections)] +#![feature(fs)] #![feature(int_uint)] +#![feature(io)] #![feature(old_io)] -#![feature(old_path)] +#![feature(path)] #![feature(rustc_private)] #![feature(staged_api)] -#![feature(unicode)] #![feature(std_misc)] -#![feature(os)] +#![feature(unicode)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/terminfo/parser/compiled.rs b/terminfo/parser/compiled.rs index c147e6a..cc9a288 100644 --- a/terminfo/parser/compiled.rs +++ b/terminfo/parser/compiled.rs @@ -13,7 +13,8 @@ //! ncurses-compatible compiled terminfo format parsing (term(5)) use std::collections::HashMap; -use std::old_io; +use std::io::prelude::*; +use std::io; use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. @@ -158,7 +159,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 old_io::Reader, longnames: bool) +pub fn parse(file: &mut Read, longnames: bool) -> Result, String> { macro_rules! try { ($e:expr) => ( match $e { @@ -182,17 +183,17 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // Check magic number - let magic = try!(file.read_le_u16()); + let magic = try!(read_le_u16(file)); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A as usize, magic as usize)); } - let names_bytes = try!(file.read_le_i16()) as int; - let bools_bytes = try!(file.read_le_i16()) as int; - let numbers_count = try!(file.read_le_i16()) as int; - let string_offsets_count = try!(file.read_le_i16()) as int; - let string_table_bytes = try!(file.read_le_i16()) as int; + let names_bytes = try!(read_le_u16(file)) as int; + let bools_bytes = try!(read_le_u16(file)) as int; + let numbers_count = try!(read_le_u16(file)) as int; + let string_offsets_count = try!(read_le_u16(file)) as int; + let string_table_bytes = try!(read_le_u16(file)) as int; assert!(names_bytes > 0); @@ -212,7 +213,7 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } // don't read NUL - let bytes = try!(file.read_exact(names_bytes as uint - 1)); + let bytes = try!(read_exact(file, names_bytes as uint - 1)); let names_str = match String::from_utf8(bytes) { Ok(s) => s, Err(_) => return Err("input not utf-8".to_string()), @@ -222,12 +223,12 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) .map(|s| s.to_string()) .collect(); - try!(file.read_byte()); // consume NUL + try!(read_byte(file)); // consume NUL let mut bools_map = HashMap::new(); if bools_bytes != 0 { for i in 0..bools_bytes { - let b = try!(file.read_byte()); + let b = try!(read_byte(file)); if b == 1 { bools_map.insert(bnames[i as uint].to_string(), true); } @@ -235,13 +236,13 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) } if (bools_bytes + names_bytes) % 2 == 1 { - try!(file.read_byte()); // compensate for padding + try!(read_byte(file)); // compensate for padding } let mut numbers_map = HashMap::new(); if numbers_count != 0 { for i in 0..numbers_count { - let n = try!(file.read_le_u16()); + let n = try!(read_le_u16(file)); if n != 0xFFFF { numbers_map.insert(nnames[i as uint].to_string(), n); } @@ -253,10 +254,10 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) if string_offsets_count != 0 { let mut string_offsets = Vec::with_capacity(10); for _ in 0..string_offsets_count { - string_offsets.push(try!(file.read_le_u16())); + string_offsets.push(try!(read_le_u16(file))); } - let string_table = try!(file.read_exact(string_table_bytes as uint)); + let string_table = try!(read_exact(file, string_table_bytes as usize)); if string_table.len() != string_table_bytes as uint { return Err("error: hit EOF before end of string \ @@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool) }) } +fn read_le_u16(r: &mut R) -> io::Result { + let mut b = [0; 2]; + assert_eq!(try!(r.read(&mut b)), 2); + Ok((b[0] as u16) | ((b[1] as u16) << 8)) +} + +fn read_byte(r: &mut R) -> io::Result { + let mut b = [0; 1]; + assert_eq!(try!(r.read(&mut b)), 1); + Ok(b[0]) +} + +fn read_exact(r: &mut R, sz: usize) -> io::Result> { + let mut v = Vec::with_capacity(sz); + try!(r.take(sz as u64).read_to_end(&mut v)); + assert_eq!(v.len(), sz); + Ok(v) +} + /// Create a dummy TermInfo struct for msys terminals pub fn msys_terminfo() -> Box { let mut strings = HashMap::new(); diff --git a/terminfo/searcher.rs b/terminfo/searcher.rs index 15f7f38..f47921c 100644 --- a/terminfo/searcher.rs +++ b/terminfo/searcher.rs @@ -12,26 +12,27 @@ //! //! Does not support hashed database, only filesystem! -use std::old_io::File; -use std::old_io::fs::PathExtensions; use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::path::PathBuf; /// Return path to database entry for `term` #[allow(deprecated)] -pub fn get_dbpath_for_term(term: &str) -> Option> { +pub fn get_dbpath_for_term(term: &str) -> Option> { if term.len() == 0 { return None; } - let homedir = ::std::os::homedir(); + let homedir = env::home_dir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); // Find search directory - match env::var("TERMINFO") { - Ok(dir) => dirs_to_search.push(Path::new(dir)), - Err(..) => { + match env::var_os("TERMINFO") { + Some(dir) => dirs_to_search.push(PathBuf::new(&dir)), + None => { if homedir.is_some() { // ncurses compatibility; dirs_to_search.push(homedir.unwrap().join(".terminfo")) @@ -39,9 +40,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { match env::var("TERMINFO_DIRS") { Ok(dirs) => for i in dirs.split(':') { if i == "" { - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } else { - dirs_to_search.push(Path::new(i)); + dirs_to_search.push(PathBuf::new(i)); } }, // Found nothing in TERMINFO_DIRS, use the default paths: @@ -49,9 +50,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { // ~/.terminfo, ncurses will search /etc/terminfo, then // /lib/terminfo, and eventually /usr/share/terminfo. Err(..) => { - dirs_to_search.push(Path::new("/etc/terminfo")); - dirs_to_search.push(Path::new("/lib/terminfo")); - dirs_to_search.push(Path::new("/usr/share/terminfo")); + dirs_to_search.push(PathBuf::new("/etc/terminfo")); + dirs_to_search.push(PathBuf::new("/lib/terminfo")); + dirs_to_search.push(PathBuf::new("/usr/share/terminfo")); } } } @@ -61,13 +62,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { for p in &dirs_to_search { if p.exists() { let f = first_char.to_string(); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } // on some installations the dir is named after the hex of the char (e.g. OS X) let f = format!("{:x}", first_char as uint); - let newp = p.join_many(&[&f[..], term]); + let newp = p.join(&f).join(term); if newp.exists() { return Some(box newp); } @@ -100,7 +101,7 @@ fn test_get_dbpath_for_term() { // FIXME (#9639): This needs to handle non-utf8 paths fn x(t: &str) -> String { let p = get_dbpath_for_term(t).expect("no terminfo entry found"); - p.as_str().unwrap().to_string() + p.to_str().unwrap().to_string() }; assert!(x("screen") == "/usr/share/terminfo/s/screen"); assert!(get_dbpath_for_term("") == None);