Skip to content

Commit

Permalink
Create PID Variable To Store Shell's PID
Browse files Browse the repository at this point in the history
  • Loading branch information
mmstick committed Jul 27, 2017
1 parent 16097c6 commit 4cea578
Showing 1 changed file with 65 additions and 84 deletions.
149 changes: 65 additions & 84 deletions src/shell/variables.rs
Expand Up @@ -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()),
}
}
}
Expand All @@ -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());
}
}
}
Expand All @@ -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();
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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()));
}
}
}
Expand All @@ -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() {
Expand All @@ -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);
}

Expand Down

0 comments on commit 4cea578

Please sign in to comment.