From 1363bfea3e74ccd549b58a7593c8b408d3c94fc2 Mon Sep 17 00:00:00 2001 From: stratact <stratact1@gmail.com> Date: Tue, 29 May 2018 14:21:31 -0700 Subject: [PATCH] Use slices instead of iterators for PipelineExecution without needing to allocate a Vec as done before the iterator migration --- src/lib/builtins/mod.rs | 2 +- src/lib/shell/binary/prompt.rs | 2 +- src/lib/shell/flow_control.rs | 9 ++---- src/lib/shell/fork_function.rs | 9 ++---- src/lib/shell/job.rs | 4 +-- src/lib/shell/mod.rs | 9 ++---- src/lib/shell/pipe_exec/mod.rs | 54 +++++++++++++--------------------- 7 files changed, 31 insertions(+), 58 deletions(-) diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs index 216f4add..e383294d 100644 --- a/src/lib/builtins/mod.rs +++ b/src/lib/builtins/mod.rs @@ -165,7 +165,7 @@ pub fn builtin_cd(args: &[&str], shell: &mut Shell) -> i32 { shell.set_var("OLDPWD", pwd); shell.set_var("PWD", current_dir); } - fork_function(shell, "CD_CHANGE", &mut ["ion"].iter()); + fork_function(shell, "CD_CHANGE", &["ion"]); } Err(_) => env::set_var("PWD", "?"), }; diff --git a/src/lib/shell/binary/prompt.rs b/src/lib/shell/binary/prompt.rs index 6f456098..3f7288e7 100644 --- a/src/lib/shell/binary/prompt.rs +++ b/src/lib/shell/binary/prompt.rs @@ -20,7 +20,7 @@ pub(crate) fn prompt_fn(shell: &mut Shell) -> Option<String> { let mut output = None; match shell.fork(Capture::StdoutThenIgnoreStderr, |child| unsafe { - let _ = function.read().execute(child, &mut ["ion"].iter()); + let _ = function.read().execute(child, &["ion"]); }) { Ok(result) => { let mut string = String::with_capacity(1024); diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs index bc5aaa8a..1bb37795 100644 --- a/src/lib/shell/flow_control.rs +++ b/src/lib/shell/flow_control.rs @@ -2,7 +2,6 @@ use super::{flow::FlowLogic, Shell}; use fnv::*; use parser::{assignments::*, pipelines::Pipeline}; use std::fmt::{self, Display, Formatter}; -use std::iter::ExactSizeIterator; use types::{Identifier, *}; #[derive(Debug, PartialEq, Clone)] @@ -168,11 +167,7 @@ impl Display for FunctionError { } impl Function { - pub(crate) fn execute<'a, I>(self, shell: &mut Shell, args: &mut I) -> Result<(), FunctionError> - where - I: ExactSizeIterator, - <I as Iterator>::Item: AsRef<str>, - { + pub(crate) fn execute<S: AsRef<str>>(self, shell: &mut Shell, args: &[S]) -> Result<(), FunctionError> { if args.len() - 1 != self.args.len() { return Err(FunctionError::InvalidArgumentCount); } @@ -183,7 +178,7 @@ impl Function { let mut arrays_backup: FnvHashMap<&str, Option<Array>> = FnvHashMap::with_capacity_and_hasher(64, Default::default()); - for (type_, value) in self.args.iter().zip(args.skip(1)) { + for (type_, value) in self.args.iter().zip(args.iter().skip(1)) { let value = match value_check(shell, value.as_ref(), type_.kind) { Ok(value) => value, Err(_) => { diff --git a/src/lib/shell/fork_function.rs b/src/lib/shell/fork_function.rs index 05321f6a..eac3684c 100644 --- a/src/lib/shell/fork_function.rs +++ b/src/lib/shell/fork_function.rs @@ -1,19 +1,14 @@ use super::{Capture, Function, Shell}; -use std::iter::ExactSizeIterator; use std::process; use sys; pub(crate) fn command_not_found(shell: &mut Shell, command: &str) -> bool { - fork_function(shell, "COMMAND_NOT_FOUND", &mut ["ion", &command].iter()) + fork_function(shell, "COMMAND_NOT_FOUND", &["ion", command]) } /// High-level function for executing a function programmatically. /// NOTE: Always add "ion" as a first argument in `args`. -pub fn fork_function<I>(shell: &mut Shell, fn_name: &str, args: &mut I) -> bool -where - I: ExactSizeIterator, - <I as Iterator>::Item: AsRef<str>, -{ +pub fn fork_function<S: AsRef<str>>(shell: &mut Shell, fn_name: &str, args: &[S]) -> bool { let function = match shell.functions.get(fn_name) { Some(func) => func as *const Function, None => return false, diff --git a/src/lib/shell/job.rs b/src/lib/shell/job.rs index 4287890f..fc482c8e 100644 --- a/src/lib/shell/job.rs +++ b/src/lib/shell/job.rs @@ -233,7 +233,7 @@ impl RefinedJob { ref stdout, ref stderr, } => { - shell.exec_external(&name, args[1..].iter().map(|s| s.as_ref()), stdin, stdout, stderr) + shell.exec_external(&name, &args[1..], stdin, stdout, stderr) } RefinedJob::Builtin { main, @@ -252,7 +252,7 @@ impl RefinedJob { ref stdout, ref stderr, } => { - shell.exec_function(name, &mut args.iter(), stdout, stderr, stdin) + shell.exec_function(name, args, stdout, stderr, stdin) } _ => panic!("exec job should not be able to be called on Cat or Tee jobs"), } diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs index 7187ca99..97c845ed 100644 --- a/src/lib/shell/mod.rs +++ b/src/lib/shell/mod.rs @@ -172,11 +172,7 @@ impl<'a> Shell { /// A method for executing a function with the given `name`, using `args` as the input. /// If the function does not exist, an `IonError::DoesNotExist` is returned. - pub fn execute_function<I>(&mut self, name: &str, args: &mut I) -> Result<i32, IonError> - where - I: ExactSizeIterator, - <I as Iterator>::Item: AsRef<str>, - { + pub fn execute_function<S: AsRef<str>>(&mut self, name: &str, args: &[S]) -> Result<i32, IonError> { self.functions .get_mut(name.into()) .ok_or(IonError::DoesNotExist) @@ -295,8 +291,7 @@ impl<'a> Shell { } else if let Some(function) = self.functions.get(&pipeline.items[0].job.command).cloned() { if !pipeline.requires_piping() { let args: &[String] = pipeline.items[0].job.args.deref(); - let mut args = args.iter(); - match function.execute(self, &mut args) { + match function.execute(self, args) { Ok(()) => None, Err(FunctionError::InvalidArgumentCount) => { eprintln!("ion: invalid number of function arguments supplied"); diff --git a/src/lib/shell/pipe_exec/mod.rs b/src/lib/shell/pipe_exec/mod.rs index 1932e3e7..22a12a21 100644 --- a/src/lib/shell/pipe_exec/mod.rs +++ b/src/lib/shell/pipe_exec/mod.rs @@ -22,7 +22,7 @@ use builtins::{self, BuiltinFunction}; use parser::pipelines::{Input, PipeItem, Pipeline, RedirectFrom, Redirection}; use smallvec::SmallVec; use std::{ - fs::{File, OpenOptions}, io::{self, Error, Write}, iter::{self, ExactSizeIterator}, + fs::{File, OpenOptions}, io::{self, Error, Write}, iter, os::unix::io::{AsRawFd, FromRawFd, RawFd}, path::Path, process::{self, exit}, }; use sys; @@ -388,28 +388,23 @@ pub(crate) trait PipelineExecution { stdin: &Option<File>, ) -> i32; - fn exec_external<'a, I>( + fn exec_external<'a, S: AsRef<str>>( &mut self, - name: &str, - args: I, + name: &'a str, + args: &'a [S], stdout: &Option<File>, stderr: &Option<File>, stdin: &Option<File>, - ) -> i32 - where I: Iterator, - I::Item: AsRef<str> + 'a, - Vec<&'a str>: ::std::iter::FromIterator<I::Item>; + ) -> i32; - fn exec_function<I>( + fn exec_function<S: AsRef<str>>( &mut self, name: &str, - args: &mut I, + args: &[S], stdout: &Option<File>, stderr: &Option<File>, stdin: &Option<File>, - ) -> i32 - where I: ExactSizeIterator, - <I as Iterator>::Item: AsRef<str>; + ) -> i32; /// For cat jobs fn exec_multi_in( @@ -431,21 +426,17 @@ pub(crate) trait PipelineExecution { } impl PipelineExecution for Shell { - fn exec_external<'a, I>( + fn exec_external<'a, S: AsRef<str>>( &mut self, - name: &str, - args: I, + name: &'a str, + args: &'a [S], stdin: &Option<File>, stdout: &Option<File>, stderr: &Option<File>, - ) -> i32 - where I: Iterator, - I::Item: AsRef<str> + 'a, - Vec<&'a str>: ::std::iter::FromIterator<I::Item>, - { + ) -> i32 { let result = sys::fork_and_exec( name, - &args.collect::<Vec<_>>(), + &args.iter().map(|s| s.as_ref()).collect::<Vec<_>>(), if let Some(ref f) = *stdin { Some(f.as_raw_fd()) } else { @@ -493,7 +484,8 @@ impl PipelineExecution for Shell { stderr: &Option<File>, stdin: &Option<File>, kind: JobKind, - ) -> i32 { + ) -> i32 + { if let Some(ref file) = *stdin { redir(file.as_raw_fd(), sys::STDIN_FILENO); } @@ -537,7 +529,8 @@ impl PipelineExecution for Shell { sources: &mut [File], stdout: &Option<File>, stdin: &mut Option<File>, - ) -> i32 { + ) -> i32 + { if let Some(ref file) = *stdin { redir(file.as_raw_fd(), sys::STDIN_FILENO) } @@ -573,18 +566,14 @@ impl PipelineExecution for Shell { SUCCESS } - fn exec_function<I>( + fn exec_function<S: AsRef<str>>( &mut self, name: &str, - args: &mut I, + args: &[S], stdout: &Option<File>, stderr: &Option<File>, stdin: &Option<File>, - ) -> i32 - where - I: ExactSizeIterator, - <I as Iterator>::Item: AsRef<str>, - { + ) -> i32 { if let Some(ref file) = *stdin { redir(file.as_raw_fd(), sys::STDIN_FILENO); } @@ -1015,11 +1004,10 @@ fn spawn_proc( ref stderr, ref stdin, } => { - let mut args = args.iter().map(|x| x as &str); match unsafe { sys::fork() } { Ok(0) => { prepare_child(block_child, pgid); - let ret = shell.exec_function(name, &mut args, stdout, stderr, stdin); + let ret = shell.exec_function(name, &args, stdout, stderr, stdin); close(stdout); close(stderr); close(stdin); -- GitLab