// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! ncurses-compatible database discovery //! //! Does not support hashed database, only filesystem! use std::env; use std::fs; use std::path::PathBuf; /// Return path to database entry for `term` #[allow(deprecated)] pub fn get_dbpath_for_term(term: &str) -> Option { let mut dirs_to_search = Vec::new(); let first_char = match term.chars().next() { Some(c) => c, None => return None, }; // Find search directory match env::var_os("TERMINFO") { Some(dir) => dirs_to_search.push(PathBuf::from(dir)), None => { if let Some(mut homedir) = env::home_dir() { // ncurses compatibility; homedir.push(".terminfo"); dirs_to_search.push(homedir) } match env::var("TERMINFO_DIRS") { Ok(dirs) => { for i in dirs.split(':') { if i == "" { dirs_to_search.push(PathBuf::from("/usr/share/terminfo")); } else { dirs_to_search.push(PathBuf::from(i)); } } } // Found nothing in TERMINFO_DIRS, use the default paths: // According to /etc/terminfo/README, after looking at // ~/.terminfo, ncurses will search /etc/terminfo, then // /lib/terminfo, and eventually /usr/share/terminfo. Err(..) => { dirs_to_search.push(PathBuf::from("/etc/terminfo")); dirs_to_search.push(PathBuf::from("/lib/terminfo")); dirs_to_search.push(PathBuf::from("/usr/share/terminfo")); } } } }; // Look for the terminal in all of the search directories for mut p in dirs_to_search { if fs::metadata(&p).is_ok() { p.push(&first_char.to_string()); p.push(&term); if fs::metadata(&p).is_ok() { return Some(p); } p.pop(); p.pop(); // on some installations the dir is named after the hex of the char // (e.g. OS X) p.push(&format!("{:x}", first_char as usize)); p.push(term); if fs::metadata(&p).is_ok() { return Some(p); } } } None } #[test] #[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")] fn test_get_dbpath_for_term() { // woefully inadequate test coverage // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's) use std::env; // 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.to_str().unwrap().to_string() } assert!(x("screen") == "/usr/share/terminfo/s/screen"); assert!(get_dbpath_for_term("") == None); env::set_var("TERMINFO_DIRS", ":"); assert!(x("screen") == "/usr/share/terminfo/s/screen"); env::remove_var("TERMINFO_DIRS"); }