diff --git a/src/main.rs b/src/main.rs index 62c0a4d9ab0d7b5013fedbac458d208a70e52a8e..d8435f7c1cfe52d438d17cad47b29dc9a8dd9f3d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,11 +18,12 @@ mod parser; mod shell; use std::io::{stderr, Write, ErrorKind}; - +use builtins::Builtin; use shell::Shell; fn main() { - let mut shell = Shell::default(); + let builtins = Builtin::map(); + let mut shell = Shell::new(&builtins); shell.evaluate_init_file(); if "1" == shell.variables.get_var_or_empty("HISTORY_FILE_ENABLED") { diff --git a/src/shell/flow.rs b/src/shell/flow.rs index 10e5032710e04246110b7d8aec17656ae3dffb33..80a1abf54a9e15ceadf58197b098a51feccd7170 100644 --- a/src/shell/flow.rs +++ b/src/shell/flow.rs @@ -18,7 +18,7 @@ pub trait FlowLogic { fn execute_statements(&mut self, statements: Vec<Statement>) -> bool; } -impl FlowLogic for Shell { +impl<'a> FlowLogic for Shell<'a> { fn on_command(&mut self, command_string: &str) { let mut iterator = StatementSplitter::new(command_string).map(parse); diff --git a/src/shell/history.rs b/src/shell/history.rs index 25e322df598fe36379c0cbd9e00c587dc95659bf..b2a41c7427f8c8beaf0fcf2a7ffd584b4098fc1a 100644 --- a/src/shell/history.rs +++ b/src/shell/history.rs @@ -20,7 +20,7 @@ pub trait ShellHistory { fn set_context_history_from_vars(&mut self); } -impl ShellHistory for Shell { +impl<'a> ShellHistory for Shell<'a> { fn print_history(&self, _arguments: &[String]) -> i32 { let mut buffer = Vec::with_capacity(8*1024); for command in &self.context.history.buffers { diff --git a/src/shell/mod.rs b/src/shell/mod.rs index ce9e6ba77d4e7325ce40765461df2dd850a4402d..9b76840be7bbe7d338db25c0f58a6dad5f8911ef 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -30,7 +30,8 @@ use parser::peg::{parse, Pipeline}; /// This struct will contain all of the data structures related to this /// instance of the shell. -pub struct Shell { +pub struct Shell<'a> { + pub builtins: &'a HashMap<&'static str, Builtin>, pub context: Context, pub variables: Variables, flow_control: FlowControl, @@ -39,10 +40,11 @@ pub struct Shell { pub previous_status: i32, } -impl Default for Shell { +impl<'a> Shell<'a> { /// Panics if DirectoryStack construction fails - fn default() -> Shell { + pub fn new(builtins: &'a HashMap<&'static str, Builtin>) -> Shell<'a> { Shell { + builtins: builtins, context: Context::new(), variables: Variables::default(), flow_control: FlowControl::default(), @@ -51,13 +53,11 @@ impl Default for Shell { previous_status: 0, } } -} - -impl Shell { fn readln(&mut self) -> Option<String> { let prompt = self.prompt(); let funcs = &self.functions; let vars = &self.variables; + let builtins = self.builtins; // Collects the current list of values from history for completion. let history = &self.context.history.buffers.iter() @@ -108,9 +108,9 @@ impl Shell { // Creates a list of definitions from the shell environment that will be used // in the creation of a custom completer. - let words = Builtin::map().into_iter() + let words = builtins.iter() // Add built-in commands to the completer's definitions. - .map(|(s, _)| String::from(s)) + .map(|(&s, _)| String::from(s)) // Add the history list to the completer's definitions. .chain(history.iter().cloned()) // Add the aliases to the completer's definitions. @@ -283,6 +283,7 @@ impl Shell { let mut exit_status = None; let mut branched = false; + let builtins = self.builtins; if !noalias { if let Some(mut alias) = self.variables.aliases.get(pipeline.jobs[0].command.as_str()).cloned() { @@ -311,7 +312,7 @@ impl Shell { if !branched { // Branch if -> input == shell command i.e. echo - exit_status = if let Some(command) = Builtin::map().get(pipeline.jobs[0].command.as_str()) { + exit_status = if let Some(command) = builtins.get(pipeline.jobs[0].command.as_str()) { // Run the 'main' of the command and set exit_status Some((*command.main)(pipeline.jobs[0].args.as_slice(), self)) // Branch else if -> input == shell function and set the exit_status