diff --git a/src/shell/binary/mod.rs b/src/shell/binary/mod.rs index f2b6f0e3cb06e4f635e530d0b10f40103b28c00e..55e7cae29772ff24e06a7932404ac5d0a3b2c541 100644 --- a/src/shell/binary/mod.rs +++ b/src/shell/binary/mod.rs @@ -1,16 +1,17 @@ //! Contains the binary logic of Ion. mod prompt; mod readln; +mod terminate; use self::prompt::{prompt, prompt_fn}; use self::readln::readln; +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 parser::QuoteTerminator; use smallvec::SmallVec; use std::env; use std::fs::File; @@ -49,50 +50,12 @@ impl Binary for Shell { fn readln(&mut self) -> Option<String> { readln(self) } - fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, mut lines: I) -> i32 { - while let Some(command) = lines.next() { - let mut buffer = QuoteTerminator::new(command); - while !buffer.check_termination() { - loop { - if let Some(command) = lines.next() { - buffer.append(command); - break; - } else { - let stderr = io::stderr(); - let _ = writeln!(stderr.lock(), "ion: unterminated quote in script"); - return FAILURE; - } - } - } - self.on_command(&buffer.consume()); - } - - // The flow control level being non zero means that we have a statement that has - // only been partially parsed. - if self.flow_control.level != 0 { - eprintln!( - "ion: unexpected end of script: expected end block for `{}`", - self.flow_control.current_statement.short() - ); - return FAILURE; - } - - SUCCESS + fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, lines: I) -> i32 { + terminate_script_quotes(self, lines) } fn terminate_quotes(&mut self, command: String) -> Result<String, ()> { - let mut buffer = QuoteTerminator::new(command); - self.flow_control.level += 1; - while !buffer.check_termination() { - if let Some(command) = self.readln() { - buffer.append(command); - } else { - return Err(()); - } - } - self.flow_control.level -= 1; - let terminated = buffer.consume(); - Ok(terminated) + terminate_quotes(self, command) } fn execute_arguments<A: Iterator<Item = String>>(&mut self, mut args: A) { diff --git a/src/shell/binary/terminate.rs b/src/shell/binary/terminate.rs new file mode 100644 index 0000000000000000000000000000000000000000..2da0894122d5690c0f4c604564d28794ccca19f4 --- /dev/null +++ b/src/shell/binary/terminate.rs @@ -0,0 +1,51 @@ +use super::super::{Binary, FlowLogic, Shell}; +use super::super::status::*; +use parser::QuoteTerminator; + +pub(crate) fn terminate_script_quotes<I: Iterator<Item = String>>( + shell: &mut Shell, + mut lines: I, +) -> i32 { + while let Some(command) = lines.next() { + let mut buffer = QuoteTerminator::new(command); + while !buffer.check_termination() { + loop { + if let Some(command) = lines.next() { + buffer.append(command); + break; + } else { + eprintln!("ion: unterminated quote in script"); + return FAILURE; + } + } + } + shell.on_command(&buffer.consume()); + } + + // The flow control level being non zero means that we have a statement that has + // only been partially parsed. + if shell.flow_control.level != 0 { + eprintln!( + "ion: unexpected end of script: expected end block for `{}`", + shell.flow_control.current_statement.short() + ); + return FAILURE; + } + + SUCCESS +} + +pub(crate) fn terminate_quotes(shell: &mut Shell, command: String) -> Result<String, ()> { + let mut buffer = QuoteTerminator::new(command); + shell.flow_control.level += 1; + while !buffer.check_termination() { + if let Some(command) = shell.readln() { + buffer.append(command); + } else { + return Err(()); + } + } + shell.flow_control.level -= 1; + let terminated = buffer.consume(); + Ok(terminated) +}