Skip to content

Commit

Permalink
Further Public API Improveents
Browse files Browse the repository at this point in the history
The IonLibrary interface has been removed, and integrated directly
within the shell's main module.
  • Loading branch information
mmstick committed Nov 4, 2017
1 parent 6d1e422 commit fffdddc
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 195 deletions.
22 changes: 11 additions & 11 deletions src/builtins/exists.rs
Expand Up @@ -153,7 +153,7 @@ fn binary_is_in_path(binaryname: &str, shell: &Shell) -> bool {
// TODO: Right now they use an entirely different logic which means that it *might* be possible
// TODO: that `exists` reports a binary to be in the path, while the shell cannot find it or
// TODO: vice-versa
if let Some(path) = shell.variables.get_var("PATH") {
if let Some(path) = shell.get_var("PATH") {
for dir in path.split(":") {
let fname = format!("{}/{}", dir, binaryname);
if let Ok(metadata) = fs::metadata(&fname) {
Expand Down Expand Up @@ -197,7 +197,7 @@ fn array_var_is_not_empty(arrayvar: &str, shell: &Shell) -> bool {

/// Returns true if the variable is a string and the string is not empty
fn string_var_is_not_empty(stringvar: &str, shell: &Shell) -> bool {
match shell.variables.get_var(stringvar) {
match shell.get_var(stringvar) {
Some(string) => !string.is_empty(),
None => false,
}
Expand Down Expand Up @@ -250,16 +250,16 @@ fn test_evaluate_arguments() {
// TODO: see test_binary_is_in_path()
// no argument means we treat it as a string
assert_eq!(evaluate_arguments(&["-b"], &mut sink, &shell), Ok(true));
let oldpath = shell.variables.get_var("PATH").unwrap_or("/usr/bin".to_owned());
shell.variables.set_var("PATH", "testing/");
let oldpath = shell.get_var("PATH").unwrap_or("/usr/bin".to_owned());
shell.set_var("PATH", "testing/");

assert_eq!(evaluate_arguments(&["-b", "executable_file"], &mut sink, &shell), Ok(true));
assert_eq!(evaluate_arguments(&["-b", "empty_file"], &mut sink, &shell), Ok(false));
assert_eq!(evaluate_arguments(&["-b", "file_does_not_exist"], &mut sink, &shell), Ok(false));

// restore original PATH. Not necessary for the currently defined test cases but this might
// change in the future? Better safe than sorry!
shell.variables.set_var("PATH", &oldpath);
shell.set_var("PATH", &oldpath);

// check `exists -d`
// no argument means we treat it as a string
Expand All @@ -278,9 +278,9 @@ fn test_evaluate_arguments() {
// check `exists -s`
// no argument means we treat it as a string
assert_eq!(evaluate_arguments(&["-s"], &mut sink, &shell), Ok(true));
shell.variables.set_var("emptyvar", "");
shell.set_var("emptyvar", "");
assert_eq!(evaluate_arguments(&["-s", "emptyvar"], &mut sink, &shell), Ok(false));
shell.variables.set_var("testvar", "foobar");
shell.set_var("testvar", "foobar");
assert_eq!(evaluate_arguments(&["-s", "testvar"], &mut sink, &shell), Ok(true));
shell.variables.unset_var("testvar");
assert_eq!(evaluate_arguments(&["-s", "testvar"], &mut sink, &shell), Ok(false));
Expand Down Expand Up @@ -362,7 +362,7 @@ fn test_binary_is_in_path() {
// TODO: PATH containing directories without read permission (for user)
// TODO: PATH containing directories without execute ("enter") permission (for user)
// TODO: empty PATH?
shell.variables.set_var("PATH", "testing/");
shell.set_var("PATH", "testing/");

assert_eq!(binary_is_in_path("executable_file", &shell), true);
assert_eq!(binary_is_in_path("empty_file", &shell), false);
Expand Down Expand Up @@ -400,18 +400,18 @@ fn test_array_var_is_not_empty() {
assert_eq!(array_var_is_not_empty("NOT_EMPTY_ARRAY", &shell), false);

// array_var_is_not_empty should NOT match for non-array variables with the same name
shell.variables.set_var("VARIABLE", "notempty-variable");
shell.set_var("VARIABLE", "notempty-variable");
assert_eq!(array_var_is_not_empty("VARIABLE", &shell), false);
}

#[test]
fn test_string_var_is_not_empty() {
let mut shell = Shell::new();

shell.variables.set_var("EMPTY", "");
shell.set_var("EMPTY", "");
assert_eq!(string_var_is_not_empty("EMPTY", &shell), false);

shell.variables.set_var("NOT_EMPTY", "notempty");
shell.set_var("NOT_EMPTY", "notempty");
assert_eq!(string_var_is_not_empty("NOT_EMPTY", &shell), true);

// string_var_is_not_empty should NOT match for arrays with the same name
Expand Down
2 changes: 1 addition & 1 deletion src/builtins/ion.rs
Expand Up @@ -12,7 +12,7 @@ pub(crate) fn ion_docs(_: &[&str], shell: &mut Shell) -> i32 {
return FAILURE;
}

if let Some(cmd) = shell.variables.get_var("BROWSER".into()) {
if let Some(cmd) = shell.get_var("BROWSER".into()) {
if let Ok(_) = Command::new(&cmd).arg(DOCPATH).spawn() {
return SUCCESS;
}
Expand Down
8 changes: 4 additions & 4 deletions src/shell/assignments.rs
Expand Up @@ -96,9 +96,9 @@ impl VariableStore for Shell {

match value_check(self, &expression, key.kind) {
Ok(ReturnValue::Str(value)) => {
let lhs = self.variables.get_var_or_empty(&key.name);
let lhs = self.get_var_or_empty(&key.name);
match math(&lhs, key.kind, operator, &value) {
Ok(value) => self.variables.set_var(&key.name, &value),
Ok(value) => self.set_var(&key.name, &value),
Err(why) => {
eprintln!("ion: assignment error: {}", why);
return FAILURE;
Expand All @@ -125,7 +125,7 @@ impl VariableStore for Shell {
fn export(&mut self, action: ExportAction) -> i32 {
let actions = match action {
ExportAction::Assign(ref keys, op, ref vals) => AssignmentActions::new(keys, op, vals),
ExportAction::LocalExport(ref key) => match self.variables.get_var(key) {
ExportAction::LocalExport(ref key) => match self.get_var(key) {
Some(var) => {
env::set_var(key, &var);
return SUCCESS;
Expand Down Expand Up @@ -166,7 +166,7 @@ impl VariableStore for Shell {
Ok(Action::UpdateString(key, operator, expression)) => {
match value_check(self, &expression, key.kind) {
Ok(ReturnValue::Str(value)) => {
let lhs = self.variables.get_var_or_empty(&key.name);
let lhs = self.get_var_or_empty(&key.name);
match math(&lhs, key.kind, operator, &value) {
Ok(value) => {
let value = OsStr::from_bytes(&value.as_bytes());
Expand Down
7 changes: 3 additions & 4 deletions src/shell/binary/mod.rs
Expand Up @@ -10,7 +10,6 @@ use self::terminate::{terminate_quotes, terminate_script_quotes};
use super::{FlowLogic, JobControl, Shell, ShellHistory};
use super::flags::*;
use super::flow_control::Statement;
use super::library::IonLibrary;
use super::status::*;
use liner::{Buffer, Context};
use smallvec::SmallVec;
Expand Down Expand Up @@ -90,8 +89,8 @@ impl Binary for Shell {
self.context = Some({
let mut context = Context::new();
context.word_divider_fn = Box::new(word_divide);
if "1" == self.variables.get_var_or_empty("HISTFILE_ENABLED") {
let path = self.variables.get_var("HISTFILE").expect("shell didn't set HISTFILE");
if "1" == self.get_var_or_empty("HISTFILE_ENABLED") {
let path = self.get_var("HISTFILE").expect("shell didn't set HISTFILE");
context.history.set_file_name(Some(path.clone()));
if !Path::new(path.as_str()).exists() {
eprintln!("ion: creating history file at \"{}\"", path);
Expand All @@ -104,7 +103,7 @@ impl Binary for Shell {
// pass
}
Err(ref err) if err.kind() == ErrorKind::NotFound => {
let history_filename = self.variables.get_var_or_empty("HISTFILE");
let history_filename = self.get_var_or_empty("HISTFILE");
eprintln!("ion: failed to find history file {}: {}", history_filename, err);
}
Err(err) => {
Expand Down
27 changes: 24 additions & 3 deletions src/shell/binary/prompt.rs
@@ -1,11 +1,13 @@
use super::super::{Function, Shell};
use parser::shell_expand::expand_string;
use std::io::Read;
use sys;

pub(crate) fn prompt(shell: &mut Shell) -> String {
if shell.flow_control.level == 0 {
let rprompt = match prompt_fn(shell) {
Some(prompt) => prompt,
None => shell.variables.get_var_or_empty("PROMPT"),
None => shell.get_var_or_empty("PROMPT"),
};
expand_string(&rprompt, shell, false).join(" ")
} else {
Expand All @@ -19,7 +21,26 @@ pub(crate) fn prompt_fn(shell: &mut Shell) -> Option<String> {
None => return None,
};

shell.fork_and_output(|child| unsafe {
let mut output = None;

match shell.fork(|child| unsafe {
let _ = function.read().execute(child, &["ion"]);
})
}) {
Ok(mut result) => {
let mut string = String::new();
match result.stdout.read_to_string(&mut string) {
Ok(_) => output = Some(string),
Err(why) => {
eprintln!("ion: error reading stdout of child: {}", why);
}
}
}
Err(why) => {
eprintln!("ion: fork error: {}", why);
}
}

// Ensure that the parent retains ownership of the terminal before exiting.
let _ = sys::tcsetpgrp(sys::STDIN_FILENO, sys::getpid().unwrap());
output
}
20 changes: 9 additions & 11 deletions src/shell/flow.rs
Expand Up @@ -290,9 +290,8 @@ impl FlowLogic for Shell {
.map(|x| ReturnValue::Vector(x.clone()));
self.variables.set_array(&bind, value.clone());
} else {
previous_bind =
self.variables.get_var(bind).map(|x| ReturnValue::Str(x));
self.variables.set_var(&bind, &value.join(" "));
previous_bind = self.get_var(bind).map(|x| ReturnValue::Str(x));
self.set_var(&bind, &value.join(" "));
}
}

Expand All @@ -308,7 +307,7 @@ impl FlowLogic for Shell {
if let Some(ref bind) = case.binding {
if let Some(value) = previous_bind {
match value {
ReturnValue::Str(value) => self.variables.set_var(bind, &value),
ReturnValue::Str(value) => self.set_var(bind, &value),
ReturnValue::Vector(values) => {
self.variables.set_array(bind, values)
}
Expand All @@ -327,9 +326,8 @@ impl FlowLogic for Shell {
.map(|x| ReturnValue::Vector(x.clone()));
self.variables.set_array(&bind, value.clone());
} else {
previous_bind =
self.variables.get_var(bind).map(|x| ReturnValue::Str(x));
self.variables.set_var(&bind, &value.join(" "));
previous_bind = self.get_var(bind).map(|x| ReturnValue::Str(x));
self.set_var(&bind, &value.join(" "));
}
}

Expand All @@ -345,7 +343,7 @@ impl FlowLogic for Shell {
if let Some(ref bind) = case.binding {
if let Some(value) = previous_bind {
match value {
ReturnValue::Str(value) => self.variables.set_var(bind, &value),
ReturnValue::Str(value) => self.set_var(bind, &value),
ReturnValue::Vector(values) => {
self.variables.set_array(bind, values)
}
Expand Down Expand Up @@ -549,7 +547,7 @@ impl FlowLogic for Shell {
}
},
ForExpression::Multiple(values) => for value in values.iter() {
self.variables.set_var(variable, &value);
self.set_var(variable, &value);
match self.execute_statements(statements.clone()) {
Condition::Break => break,
Condition::SigInt => return Condition::SigInt,
Expand All @@ -564,7 +562,7 @@ impl FlowLogic for Shell {
}
},
ForExpression::Normal(values) => for value in values.lines() {
self.variables.set_var(variable, &value);
self.set_var(variable, &value);
match self.execute_statements(statements.clone()) {
Condition::Break => break,
Condition::SigInt => return Condition::SigInt,
Expand All @@ -579,7 +577,7 @@ impl FlowLogic for Shell {
}
},
ForExpression::Range(start, end) => for value in (start..end).map(|x| x.to_string()) {
self.variables.set_var(variable, &value);
self.set_var(variable, &value);
match self.execute_statements(statements.clone()) {
Condition::Break => break,
Condition::SigInt => return Condition::SigInt,
Expand Down
6 changes: 3 additions & 3 deletions src/shell/flow_control.rs
Expand Up @@ -191,8 +191,8 @@ impl Function {
shell.variables.set_array(&type_.name, vector);
}
ReturnValue::Str(string) => {
variables_backup.insert(&type_.name, shell.variables.get_var(&type_.name));
shell.variables.set_var(&type_.name, &string);
variables_backup.insert(&type_.name, shell.get_var(&type_.name));
shell.set_var(&type_.name, &string);
}
}
}
Expand All @@ -201,7 +201,7 @@ impl Function {

for (name, value_option) in &variables_backup {
match *value_option {
Some(ref value) => shell.variables.set_var(name, value),
Some(ref value) => shell.set_var(name, value),
None => {
shell.variables.unset_var(name);
}
Expand Down
10 changes: 5 additions & 5 deletions src/shell/history.rs
Expand Up @@ -85,17 +85,17 @@ impl ShellHistory for Shell {

fn set_context_history_from_vars(&mut self) {
let context = self.context.as_mut().unwrap();
let max_history_size =
self.variables.get_var_or_empty("HISTORY_SIZE").parse().unwrap_or(1000);
let variables = &self.variables;
let max_history_size = variables.get_var_or_empty("HISTORY_SIZE").parse().unwrap_or(1000);

context.history.set_max_size(max_history_size);

if &*self.variables.get_var_or_empty("HISTFILE_ENABLED") == "1" {
let file_name = self.variables.get_var("HISTFILE");
if &*variables.get_var_or_empty("HISTFILE_ENABLED") == "1" {
let file_name = variables.get_var("HISTFILE");
context.history.set_file_name(file_name.map(|f| f.into()));

let max_histfile_size =
self.variables.get_var_or_empty("HISTFILE_SIZE").parse().unwrap_or(1000);
variables.get_var_or_empty("HISTFILE_SIZE").parse().unwrap_or(1000);
context.history.set_max_file_size(max_histfile_size);
} else {
context.history.set_file_name(None);
Expand Down

0 comments on commit fffdddc

Please sign in to comment.