From ff420f1e67bb9b93df47fa3187b7314c73e9d094 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sat, 9 May 2020 01:34:56 -0600 Subject: [PATCH] carry past_end_of_stream in WrappedStreamInstance --- src/prolog/machine/machine_state.rs | 2 +- src/prolog/machine/streams.rs | 81 +++++++++++++++++------------ src/prolog/machine/system_calls.rs | 20 +++---- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index b16389d1..6f6c5365 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -627,7 +627,7 @@ impl MachineState { 3, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { diff --git a/src/prolog/machine/streams.rs b/src/prolog/machine/streams.rs index 305c0a20..66ad2b32 100644 --- a/src/prolog/machine/streams.rs +++ b/src/prolog/machine/streams.rs @@ -14,6 +14,7 @@ use std::fs::File; use std::io::{stdout, Cursor, ErrorKind, Read, Seek, SeekFrom, Write}; use std::hash::{Hash, Hasher}; use std::net::{Shutdown, TcpStream}; +use std::ops::DerefMut; use std::rc::Rc; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -125,12 +126,14 @@ impl fmt::Debug for StreamInstance { } #[derive(Debug, Clone)] -struct WrappedStreamInstance(Rc>); +struct WrappedStreamInstance(Rc>); impl WrappedStreamInstance { #[inline] fn new(stream_inst: StreamInstance) -> Self { - WrappedStreamInstance(Rc::new(RefCell::new(stream_inst))) + WrappedStreamInstance( + Rc::new(RefCell::new((false, stream_inst))) + ) } } @@ -220,7 +223,6 @@ impl Default for StreamOptions { #[derive(Debug, Clone, Hash)] pub struct Stream { - pub past_end_of_stream: bool, pub options: StreamOptions, stream_inst: WrappedStreamInstance, } @@ -284,7 +286,7 @@ impl Stream { #[inline] pub(crate) fn position(&mut self) -> Option { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::InputFile(_, ref mut file) => { file.seek(SeekFrom::Current(0)).ok() } @@ -294,15 +296,27 @@ impl Stream { } } + #[inline] + pub(crate) + fn past_end_of_stream(&self) -> bool { + self.stream_inst.0.borrow_mut().0 + } + + #[inline] + pub(crate) + fn set_past_end_of_stream(&mut self) { + self.stream_inst.0.borrow_mut().0 = true; + } + #[inline] pub(crate) fn position_relative_to_end(&mut self) -> AtEndOfStream { - if self.past_end_of_stream { + if self.past_end_of_stream() { return AtEndOfStream::Past; } - match *self.stream_inst.0.borrow_mut() { - StreamInstance::InputFile(_, ref mut file) => { + match self.stream_inst.0.borrow_mut().deref_mut() { + (past_end_of_stream, StreamInstance::InputFile(_, ref mut file)) => { match file.metadata() { Ok(metadata) => { if let Ok(position) = file.seek(SeekFrom::Current(0)) { @@ -314,17 +328,17 @@ impl Stream { AtEndOfStream::Not } Ordering::Greater => { - self.past_end_of_stream = true; + *past_end_of_stream = true; //self.set_past_end_of_stream(); AtEndOfStream::Past } }; } else { - self.past_end_of_stream = true; + *past_end_of_stream = true; //self.set_past_end_of_stream(); AtEndOfStream::Past } } _ => { - self.past_end_of_stream = true; + *past_end_of_stream = true; //self.set_past_end_of_stream(); AtEndOfStream::Past } } @@ -338,7 +352,7 @@ impl Stream { #[inline] pub(crate) fn file_name(&self) -> Option { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { StreamInstance::InputFile(ref name, _) => { Some(name.clone()) } @@ -357,7 +371,7 @@ impl Stream { #[inline] pub(crate) fn mode(&self) -> &'static str { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { StreamInstance::Bytes(_) | StreamInstance::ReadlineStream(_) | StreamInstance::DynReadSource(_) | @@ -383,7 +397,6 @@ impl Stream { #[inline] fn from_inst(stream_inst: StreamInstance) -> Self { Stream { - past_end_of_stream: false, options: StreamOptions::default(), stream_inst: WrappedStreamInstance::new(stream_inst) } @@ -419,7 +432,7 @@ impl Stream { #[inline] pub(crate) fn is_stdout(&self) -> bool { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { StreamInstance::Stdout => { true } @@ -432,7 +445,7 @@ impl Stream { #[inline] pub(crate) fn is_stdin(&self) -> bool { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { //StreamInstance::Stdin | StreamInstance::ReadlineStream(_) => { true @@ -446,14 +459,13 @@ impl Stream { #[inline] pub(crate) fn close(&mut self) { - *self.stream_inst.0.borrow_mut() = StreamInstance::Null; - self.past_end_of_stream = true; + self.stream_inst.0.borrow_mut().1 = StreamInstance::Null; } #[inline] pub(crate) fn is_null_stream(&self) -> bool { - if let StreamInstance::Null = *self.stream_inst.0.borrow() { + if let StreamInstance::Null = self.stream_inst.0.borrow().1 { true } else { false @@ -463,7 +475,7 @@ impl Stream { #[inline] pub(crate) fn is_input_stream(&self) -> bool { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { // StreamInstance::Stdin | StreamInstance::TcpStream(..) | StreamInstance::Bytes(_) | @@ -481,7 +493,7 @@ impl Stream { #[inline] pub(crate) fn is_output_stream(&self) -> bool { - match *self.stream_inst.0.borrow() { + match self.stream_inst.0.borrow().1 { StreamInstance::Stdout | StreamInstance::TcpStream(..) | StreamInstance::Bytes(_) @@ -497,7 +509,7 @@ impl Stream { // returns true on success. #[inline] fn reset(&mut self) -> bool { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::Bytes(ref mut cursor) => { cursor.set_position(0); true @@ -519,7 +531,7 @@ impl Stream { #[inline] pub(crate) fn peek_byte(&mut self) -> std::io::Result { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::Bytes(ref mut cursor) => { let mut b = [0u8; 1]; let pos = cursor.position(); @@ -575,7 +587,7 @@ impl Stream { fn peek_char(&mut self) -> std::io::Result { use unicode_reader::CodePoints; - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::InputFile(_, ref mut file) => { let c = { let mut iter = CodePoints::from(&*file); @@ -638,7 +650,7 @@ impl MachineState { ) -> CallResult { match stream.options.eof_action { EOFAction::Error => { - stream.past_end_of_stream = true; + stream.set_past_end_of_stream(); return Err(self.open_past_eos_error(stream.clone(), caller, arity)); } EOFAction::EOFCode => { @@ -646,12 +658,15 @@ impl MachineState { HeapCellValue::Atom(clause_name!("end_of_file"), None) ); - stream.past_end_of_stream = true; + stream.set_past_end_of_stream(); Ok(self.unify(result, end_of_stream)) } EOFAction::Reset => { - stream.past_end_of_stream = !stream.reset(); - Ok(self.fail = stream.past_end_of_stream) + if !stream.reset() { + stream.set_past_end_of_stream(); + } + + Ok(self.fail = stream.past_end_of_stream()) } } } @@ -752,10 +767,10 @@ impl MachineState { Addr::Con(h) if self.heap.atom_at(h) => { if let HeapCellValue::Atom(ref atom, ref spec) = self.heap.clone(h) { match indices.stream_aliases.get(atom) { - Some(stream) => { + Some(stream) if !stream.is_null_stream() => { stream.clone() } - None => { + _ => { let stub = MachineError::functor_stub(clause_name!(caller), arity); let addr = self.heap.to_unifiable( @@ -959,7 +974,7 @@ impl MachineState { } if let Some(input) = input { - if stream.past_end_of_stream { + if stream.past_end_of_stream() { self.eof_action( input, stream, @@ -975,7 +990,7 @@ impl MachineState { impl Read for Stream { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::InputFile(_, ref mut file) => { file.read(buf) } @@ -1008,7 +1023,7 @@ impl Read for Stream { impl Write for Stream { fn write(&mut self, buf: &[u8]) -> std::io::Result { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::OutputFile(_, ref mut file, _) => { file.write(buf) } @@ -1032,7 +1047,7 @@ impl Write for Stream { } fn flush(&mut self) -> std::io::Result<()> { - match *self.stream_inst.0.borrow_mut() { + match self.stream_inst.0.borrow_mut().1 { StreamInstance::OutputFile(_, ref mut file, _) => { file.flush() } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 73c62e49..43bfba86 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1183,7 +1183,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -1280,7 +1280,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -1378,7 +1378,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -2069,7 +2069,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -2164,7 +2164,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -2266,7 +2266,7 @@ impl MachineState { 2, )?; - if stream.past_end_of_stream { + if stream.past_end_of_stream() { if EOFAction::Reset != stream.options.eof_action { return return_from_clause!(self.last_call, self); } else if self.fail { @@ -2594,10 +2594,12 @@ impl MachineState { indices.streams.insert(current_output_stream.clone()); } - stream.close(); + if !stream.is_stdin() && !stream.is_stdout() { + stream.close(); - if let Some(alias) = stream.options.alias { - indices.stream_aliases.remove(&alias); + if let Some(alias) = stream.options.alias { + indices.stream_aliases.remove(&alias); + } } } &SystemClauseType::CopyToLiftedHeap => { -- 2.54.0