From 4cea5782acbedeebee768b6b4b3eafddb4f1ce7b Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy <mmstickman@gmail.com> Date: Thu, 27 Jul 2017 11:49:51 -0400 Subject: [PATCH] Create PID Variable To Store Shell's PID --- src/shell/variables.rs | 149 ++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 84 deletions(-) diff --git a/src/shell/variables.rs b/src/shell/variables.rs index 8d8f32f4..959b278c 100644 --- a/src/shell/variables.rs +++ b/src/shell/variables.rs @@ -2,68 +2,76 @@ use fnv::FnvHashMap; use std::env; use std::process; -use app_dirs::{AppDataType, AppInfo, app_root}; use super::directory_stack::DirectoryStack; +use super::status::{FAILURE, SUCCESS}; +use app_dirs::{AppDataType, AppInfo, app_root}; use liner::Context; -use super::status::{SUCCESS, FAILURE}; -use types::{ - HashMapVariableContext, - ArrayVariableContext, - VariableContext, - Identifier, - Key, - Value, - Array, - HashMap, -}; - -use ::sys::variables as self_sys; +use types::{Array, ArrayVariableContext, HashMap, HashMapVariableContext, Identifier, Key, Value, VariableContext}; + +#[cfg(target_os = "redox")] +use sys::getpid; + +#[cfg(all(unix, not(target_os = "unix")))] +use sys::getpid; + +use sys::variables as self_sys; #[derive(Debug)] pub struct Variables { - pub hashmaps: HashMapVariableContext, - pub arrays: ArrayVariableContext, + pub hashmaps: HashMapVariableContext, + pub arrays: ArrayVariableContext, pub variables: VariableContext, - pub aliases: VariableContext, + pub aliases: VariableContext, } impl Default for Variables { fn default() -> Variables { - let mut map = FnvHashMap::with_capacity_and_hasher( - 64, - Default::default(), - ); + let mut map = FnvHashMap::with_capacity_and_hasher(64, Default::default()); map.insert("DIRECTORY_STACK_SIZE".into(), "1000".into()); map.insert("HISTORY_SIZE".into(), "1000".into()); map.insert("HISTORY_FILE_SIZE".into(), "1000".into()); map.insert("PROMPT".into(), "\x1B\']\'0;${USER}: ${PWD}\x07\x1B\'[\'0m\x1B\'[\'1;38;5;85m${USER}\x1B\'[\'37m:\x1B\'[\'38;5;75m${PWD}\x1B\'[\'37m#\x1B\'[\'0m ".into()); + // Set the PID variable to the PID of the shell + let pid = getpid().map(|p| p.to_string()).unwrap_or_else( + |e| e.to_string(), + ); + map.insert("PID".into(), pid.into()); // Initialize the HISTORY_FILE variable - if let Ok(mut home_path) = app_root(AppDataType::UserData, &AppInfo{ name: "ion", author: "Redox OS Developers" }) { + if let Ok(mut home_path) = + app_root( + AppDataType::UserData, + &AppInfo { + name: "ion", + author: "Redox OS Developers", + }, + ) + { home_path.push("history"); map.insert("HISTORY_FILE".into(), home_path.to_str().unwrap_or("?").into()); map.insert("HISTORY_FILE_ENABLED".into(), "1".into()); } // Initialize the PWD (Present Working Directory) variable - env::current_dir().ok().map_or_else(|| env::set_var("PWD", "?"), |path| env::set_var("PWD", path.to_str().unwrap_or("?"))); + env::current_dir().ok().map_or_else( + || env::set_var("PWD", "?"), + |path| { + env::set_var("PWD", path.to_str().unwrap_or("?")) + }, + ); // Initialize the HOME variable - env::home_dir().map_or_else(|| env::set_var("HOME", "?"), |path| env::set_var("HOME", path.to_str().unwrap_or("?"))); + env::home_dir().map_or_else( + || env::set_var("HOME", "?"), + |path| { + env::set_var("HOME", path.to_str().unwrap_or("?")) + }, + ); Variables { - hashmaps: FnvHashMap::with_capacity_and_hasher( - 64, - Default::default(), - ), - arrays: FnvHashMap::with_capacity_and_hasher( - 64, - Default::default(), - ), + hashmaps: FnvHashMap::with_capacity_and_hasher(64, Default::default()), + arrays: FnvHashMap::with_capacity_and_hasher(64, Default::default()), variables: map, - aliases: FnvHashMap::with_capacity_and_hasher( - 64, - Default::default(), - ) + aliases: FnvHashMap::with_capacity_and_hasher(64, Default::default()), } } } @@ -87,10 +95,7 @@ impl Variables { if value.is_empty() { self.variables.remove(name); } else { - self.variables.insert( - name.into(), - value.into(), - ); + self.variables.insert(name.into(), value.into()); } } } @@ -109,56 +114,42 @@ impl Variables { if !name.is_empty() { if let Some(map) = self.hashmaps.get_mut(name) { map.insert(key.into(), value.into()); - return + return; } - let mut map = HashMap::with_capacity_and_hasher( - 4, - Default::default() - ); + let mut map = HashMap::with_capacity_and_hasher(4, Default::default()); map.insert(key.into(), value.into()); self.hashmaps.insert(name.into(), map); } } - pub fn get_map(&self, name: &str) -> Option<&HashMap>{ - self.hashmaps.get(name) - } + pub fn get_map(&self, name: &str) -> Option<&HashMap> { self.hashmaps.get(name) } - pub fn get_array(&self, name: &str) -> Option<&Array> { - self.arrays.get(name) - } + pub fn get_array(&self, name: &str) -> Option<&Array> { self.arrays.get(name) } - pub fn unset_array(&mut self, name: &str) -> Option<Array> { - self.arrays.remove(name) - } + pub fn unset_array(&mut self, name: &str) -> Option<Array> { self.arrays.remove(name) } pub fn get_var(&self, name: &str) -> Option<Value> { - self.variables.get(name).cloned() - .or_else(|| env::var(name).map(Into::into).ok()) + self.variables.get(name).cloned().or_else(|| { + env::var(name).map(Into::into).ok() + }) } - pub fn get_var_or_empty(&self, name: &str) -> Value { - self.get_var(name).unwrap_or_default() - } + pub fn get_var_or_empty(&self, name: &str) -> Value { self.get_var(name).unwrap_or_default() } - pub fn unset_var(&mut self, name: &str) -> Option<Value> { - self.variables.remove(name) - } + pub fn unset_var(&mut self, name: &str) -> Option<Value> { self.variables.remove(name) } pub fn get_vars(&self) -> Vec<Identifier> { - self.variables.keys().cloned() + self.variables + .keys() + .cloned() .chain(env::vars().map(|(k, _)| k.into())) .collect() } - pub fn is_valid_variable_character(c: char) -> bool { - c.is_alphanumeric() || c == '_' || c == '?' - } + pub fn is_valid_variable_character(c: char) -> bool { c.is_alphanumeric() || c == '_' || c == '?' } - pub fn is_valid_variable_name(name: &str) -> bool { - name.chars().all(Variables::is_valid_variable_character) - } + pub fn is_valid_variable_name(name: &str) -> bool { name.chars().all(Variables::is_valid_variable_character) } pub fn tilde_expansion(&self, word: &str, dir_stack: &DirectoryStack) -> Option<String> { let mut chars = word.char_indices(); @@ -215,11 +206,7 @@ impl Variables { match tilde_num.parse() { Ok(num) => { - let res = if neg { - dir_stack.dir_from_top(num) - } else { - dir_stack.dir_from_bottom(num) - }; + let res = if neg { dir_stack.dir_from_top(num) } else { dir_stack.dir_from_bottom(num) }; if let Some(path) = res { return Some(path.to_str().unwrap().to_string()); @@ -261,7 +248,7 @@ impl Variables { if inner_key.ends_with(']') { inner_key = inner_key.split(']').next().unwrap_or(""); inner_key = inner_key.trim_matches(|c| c == '\'' || c == '\"'); - return Some((map_name.into(), inner_key.into())) + return Some((map_name.into(), inner_key.into())); } } } @@ -273,12 +260,10 @@ impl Variables { #[cfg(test)] mod tests { use super::*; + use parser::{ExpanderFunctions, Select, expand_string}; use shell::directory_stack::DirectoryStack; - use parser::{expand_string, ExpanderFunctions, Select}; - fn new_dir_stack() -> DirectoryStack { - DirectoryStack::new() - } + fn new_dir_stack() -> DirectoryStack { DirectoryStack::new() } #[test] fn undefined_variable_expands_to_empty_string() { @@ -291,11 +276,7 @@ mod tests { fn set_var_and_expand_a_variable() { let mut variables = Variables::default(); variables.set_var("FOO", "BAR"); - let expanded = expand_string( - "$FOO", - &get_expanders!(&variables, &new_dir_stack()), - false - ).join(""); + let expanded = expand_string("$FOO", &get_expanders!(&variables, &new_dir_stack()), false).join(""); assert_eq!("BAR", &expanded); } -- GitLab