]> Repositorios git - scryer-prolog.git/commitdiff
Don't use "readline" input functionality for the following builtins:
authorPeter Mikkelsen <[email protected]>
Fri, 22 Aug 2025 09:02:59 +0000 (11:02 +0200)
committerPeter Mikkelsen <[email protected]>
Fri, 22 Aug 2025 09:02:59 +0000 (11:02 +0200)
* peek_byte
* peek_char
* peek_code
* get_byte
* get_char
* get_code
* get_n_chars

src/machine/system_calls.rs
src/read.rs

index 60a4a515ecdefff9c0575bc9e74997cf015366db..06bf481e5426fb090cfd639c835d871f4ea59012 100644 (file)
@@ -2600,6 +2600,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn peek_byte(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let stub_gen = || functor_stub(atom!("peek_byte"), 2);
 
         let mut stream = self.machine_st.get_stream_or_alias(
@@ -2690,6 +2691,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn peek_char(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let stub_gen = || functor_stub(atom!("peek_char"), 2);
 
         let mut stream = self.machine_st.get_stream_or_alias(
@@ -2784,6 +2786,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn peek_code(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let stub_gen = || functor_stub(atom!("peek_code"), 2);
 
         let mut stream = self.machine_st.get_stream_or_alias(
@@ -3437,6 +3440,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn get_byte(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let mut stream = self.machine_st.get_stream_or_alias(
             self.machine_st.registers[1],
             &self.indices,
@@ -3521,6 +3525,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn get_char(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let mut stream = self.machine_st.get_stream_or_alias(
             self.machine_st.registers[1],
             &self.indices,
@@ -3616,6 +3621,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn get_n_chars(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let stream = self.machine_st.get_stream_or_alias(
             self.machine_st.registers[1],
             &self.indices,
@@ -3688,6 +3694,7 @@ impl Machine {
 
     #[inline(always)]
     pub(crate) fn get_code(&mut self) -> CallResult {
+        let _guard = RawReadGuard::new();
         let mut stream = self.machine_st.get_stream_or_alias(
             self.machine_st.registers[1],
             &self.indices,
index 4c6b033cc48b1ef4644d03aed5c71d2844c83ecb..636a6f491d28d272db91233f7495c12e14d4990e 100644 (file)
@@ -107,6 +107,30 @@ fn get_prompt() -> &'static str {
     }
 }
 
+static mut RAW_READ: bool = false;
+
+pub struct RawReadGuard;
+
+impl RawReadGuard {
+    pub fn new() -> RawReadGuard {
+        unsafe {
+            if RAW_READ {
+                panic!("Nested RawReadGuards");
+            }
+            RAW_READ = true;
+        }
+        RawReadGuard
+    }
+}
+
+impl Drop for RawReadGuard {
+    fn drop(&mut self) {
+        unsafe {
+            RAW_READ = false;
+        }
+    }
+}
+
 #[derive(Debug)]
 pub struct ReadlineStream {
     #[cfg(feature = "repl")]
@@ -172,7 +196,23 @@ impl ReadlineStream {
 
     #[cfg(feature = "repl")]
     fn call_readline(&mut self) -> std::io::Result<usize> {
-        match self.rl.readline(get_prompt()) {
+        let raw = unsafe { RAW_READ };
+        let text = if raw {
+            let mut buffer = String::new();
+            let stdin = std::io::stdin();
+            match stdin.read_line(&mut buffer) {
+                Ok(_) => Ok(buffer),
+                Err(e) => Err(e),
+            }
+        } else {
+            match self.rl.readline(get_prompt()) {
+                Ok(text) => Ok(text),
+                Err(ReadlineError::Eof) => Err(Error::from(ErrorKind::UnexpectedEof)),
+                Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
+            }
+        };
+
+        match text {
             Ok(text) => {
                 self.pending_input.reset_buffer();
 
@@ -195,8 +235,7 @@ impl ReadlineStream {
 
                 Ok(self.pending_input.get_ref().get_ref().len())
             }
-            Err(ReadlineError::Eof) => Err(Error::from(ErrorKind::UnexpectedEof)),
-            Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
+            Err(e) => Err(e)
         }
     }