]> Repositorios git - scryer-prolog.git/commitdiff
carry past_end_of_stream in WrappedStreamInstance
authorMark Thom <[email protected]>
Sat, 9 May 2020 07:34:56 +0000 (01:34 -0600)
committerMark Thom <[email protected]>
Sat, 9 May 2020 07:34:56 +0000 (01:34 -0600)
src/prolog/machine/machine_state.rs
src/prolog/machine/streams.rs
src/prolog/machine/system_calls.rs

index b16389d1905b1e6d975f26fbb6cc9a442871faf2..6f6c53654bafdc8c6a56a74f88ab5eafbe2e08c2 100644 (file)
@@ -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 {
index 305c0a20abda6a2f2ccc9903d2891887b432cc85..66ad2b3259d202a728fbf5c9b7dced64196d8884 100644 (file)
@@ -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<RefCell<StreamInstance>>);
+struct WrappedStreamInstance(Rc<RefCell<(bool, StreamInstance)>>);
 
 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<u64> {
-        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<ClauseName> {
-        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<u8> {
-        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<char> {
         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<usize> {
-        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<usize> {
-        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()
             }
index 73c62e49d052d8463d645586d8877033c7cebab3..43bfba86c8eb1e99483795694964a514030a975b 100644 (file)
@@ -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 => {