]> Repositorios git - scryer-prolog.git/commitdiff
fix stream position and term comparison bugs (#1472)
authorMark Thom <[email protected]>
Sun, 22 May 2022 20:15:56 +0000 (14:15 -0600)
committerMark Thom <[email protected]>
Sun, 22 May 2022 20:16:14 +0000 (14:16 -0600)
src/machine/machine_state_impl.rs
src/machine/streams.rs
src/parser/char_reader.rs

index a2940ecee25c5fa734c178b4e462ab22704375b6..be7edd3390f005fb2b289b80a6361ac37354392d 100644 (file)
@@ -1546,7 +1546,10 @@ impl MachineState {
                                         }
                                     } else {
                                         self.pdl.clear();
-                                        return Some(n1.chars().next().cmp(&Some(c2)));
+                                        return Some(
+                                            n1.chars().next().cmp(&Some(c2))
+                                              .then(Ordering::Greater)
+                                        );
                                     }
                                 }
                                 _ => {
@@ -1564,7 +1567,10 @@ impl MachineState {
                                         }
                                     } else {
                                         self.pdl.clear();
-                                        return Some(Some(c1).cmp(&n2.chars().next()));
+                                        return Some(
+                                            Some(c1).cmp(&n2.chars().next())
+                                                    .then(Ordering::Less)
+                                        );
                                     }
                                 }
                                 (HeapCellValueTag::Char, c2) => {
index 1a5ae76ec0cb6747ccbed9ff3d680fc24b8efe06..298c34414c5993c4b770bb86f51b3f32a3713ce8 100644 (file)
@@ -139,6 +139,17 @@ impl Read for InputFileStream {
     }
 }
 
+impl StreamLayout<CharReader<InputFileStream>> {
+    #[inline]
+    fn position(&mut self) -> Option<u64> {
+        // stream is the internal CharReader. subtract
+        // its pending buffer length from position.
+        self.get_mut().file.seek(SeekFrom::Current(0))
+            .map(|pos| pos  - self.stream.rem_buf_len() as u64)
+            .ok()
+    }
+}
+
 #[derive(Debug)]
 pub struct OutputFileStream {
     file_name: Atom,
@@ -813,8 +824,8 @@ impl Stream {
     pub(crate) fn position(&mut self) -> Option<(u64, usize)> {
         // returns lines_read, position.
         let result = match self {
-            Stream::InputFile(ref mut file_stream) => {
-                file_stream.get_mut().file.seek(SeekFrom::Current(0)).ok()
+            Stream::InputFile(file_stream) => {
+                file_stream.position()
             }
             Stream::NamedTcp(..)
             | Stream::NamedTls(..)
@@ -838,6 +849,7 @@ impl Stream {
                 } = &mut **stream_layout;
 
                 stream.get_mut().file.seek(SeekFrom::Start(position)).unwrap();
+                stream.reset_buffer(); // flush the internal buffer.
 
                 if let Ok(metadata) = stream.get_ref().file.metadata() {
                     *past_end_of_stream = position > metadata.len();
@@ -853,7 +865,6 @@ impl Stream {
             Stream::Byte(stream) => stream.past_end_of_stream,
             Stream::InputFile(stream) => stream.past_end_of_stream,
             Stream::OutputFile(stream) => stream.past_end_of_stream,
-            // Stream::PausedProlog(stream) => stream.paused_stream.past_end_of_stream(),
             Stream::StaticString(stream) => stream.past_end_of_stream,
             Stream::NamedTcp(stream) => stream.past_end_of_stream,
             Stream::NamedTls(stream) => stream.past_end_of_stream,
@@ -894,6 +905,8 @@ impl Stream {
         }
 
         if let Stream::InputFile(stream_layout) = self {
+            let position = stream_layout.position();
+
             let StreamLayout {
                 past_end_of_stream,
                 stream,
@@ -902,7 +915,7 @@ impl Stream {
 
             match stream.get_ref().file.metadata() {
                 Ok(metadata) => {
-                    if let Ok(position) = stream.get_mut().file.seek(SeekFrom::Current(0)) {
+                    if let Some(position) = position {
                         return match position.cmp(&metadata.len()) {
                             Ordering::Equal => AtEndOfStream::At,
                             Ordering::Less => AtEndOfStream::Not,
@@ -1057,7 +1070,7 @@ impl Stream {
                     http_stream.set_tag(ArenaHeaderTag::Dropped);
                     std::ptr::drop_in_place(&mut http_stream.inner_mut().body_reader as *mut _);
                 }
-                
+
                 Ok(())
             }
             Stream::InputFile(mut file_stream) => {
index dc4d277d5d7d87d345187282e35dcf69192511ed..dddabb190bdb36c9b46ba54bf3b49544ca292b91 100644 (file)
@@ -61,6 +61,14 @@ impl<R> CharReader<R> {
     pub fn inner_mut(&mut self) -> &mut R {
         &mut self.inner
     }
+
+    // Return the number of bytes remaining to be read.  Useful for,
+    // e.g., determining the position relative to the end of the
+    // owning stream.
+    #[inline]
+    pub fn rem_buf_len(&self) -> usize {
+        self.buf.len() - self.pos
+    }
 }
 
 pub trait CharRead {
@@ -96,7 +104,7 @@ impl<R> CharReader<R> {
         self.inner
     }
 
-    fn reset_buffer(&mut self) {
+    pub fn reset_buffer(&mut self) {
         self.buf.clear();
         self.pos = 0;
     }