Don't use "readline" input functionality for the following builtins:
* peek_byte * peek_char * peek_code * get_byte * get_char * get_code * get_n_chars
This commit is contained in:
@@ -2600,6 +2600,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn peek_byte(&mut self) -> CallResult {
|
pub(crate) fn peek_byte(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let stub_gen = || functor_stub(atom!("peek_byte"), 2);
|
let stub_gen = || functor_stub(atom!("peek_byte"), 2);
|
||||||
|
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
@@ -2690,6 +2691,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn peek_char(&mut self) -> CallResult {
|
pub(crate) fn peek_char(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let stub_gen = || functor_stub(atom!("peek_char"), 2);
|
let stub_gen = || functor_stub(atom!("peek_char"), 2);
|
||||||
|
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
@@ -2784,6 +2786,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn peek_code(&mut self) -> CallResult {
|
pub(crate) fn peek_code(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let stub_gen = || functor_stub(atom!("peek_code"), 2);
|
let stub_gen = || functor_stub(atom!("peek_code"), 2);
|
||||||
|
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
@@ -3437,6 +3440,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_byte(&mut self) -> CallResult {
|
pub(crate) fn get_byte(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
self.machine_st.registers[1],
|
self.machine_st.registers[1],
|
||||||
&self.indices,
|
&self.indices,
|
||||||
@@ -3521,6 +3525,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_char(&mut self) -> CallResult {
|
pub(crate) fn get_char(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
self.machine_st.registers[1],
|
self.machine_st.registers[1],
|
||||||
&self.indices,
|
&self.indices,
|
||||||
@@ -3616,6 +3621,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_n_chars(&mut self) -> CallResult {
|
pub(crate) fn get_n_chars(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let stream = self.machine_st.get_stream_or_alias(
|
let stream = self.machine_st.get_stream_or_alias(
|
||||||
self.machine_st.registers[1],
|
self.machine_st.registers[1],
|
||||||
&self.indices,
|
&self.indices,
|
||||||
@@ -3688,6 +3694,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn get_code(&mut self) -> CallResult {
|
pub(crate) fn get_code(&mut self) -> CallResult {
|
||||||
|
let _guard = RawReadGuard::new();
|
||||||
let mut stream = self.machine_st.get_stream_or_alias(
|
let mut stream = self.machine_st.get_stream_or_alias(
|
||||||
self.machine_st.registers[1],
|
self.machine_st.registers[1],
|
||||||
&self.indices,
|
&self.indices,
|
||||||
|
|||||||
45
src/read.rs
45
src/read.rs
@@ -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)]
|
#[derive(Debug)]
|
||||||
pub struct ReadlineStream {
|
pub struct ReadlineStream {
|
||||||
#[cfg(feature = "repl")]
|
#[cfg(feature = "repl")]
|
||||||
@@ -172,7 +196,23 @@ impl ReadlineStream {
|
|||||||
|
|
||||||
#[cfg(feature = "repl")]
|
#[cfg(feature = "repl")]
|
||||||
fn call_readline(&mut self) -> std::io::Result<usize> {
|
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) => {
|
Ok(text) => {
|
||||||
self.pending_input.reset_buffer();
|
self.pending_input.reset_buffer();
|
||||||
|
|
||||||
@@ -195,8 +235,7 @@ impl ReadlineStream {
|
|||||||
|
|
||||||
Ok(self.pending_input.get_ref().get_ref().len())
|
Ok(self.pending_input.get_ref().get_ref().len())
|
||||||
}
|
}
|
||||||
Err(ReadlineError::Eof) => Err(Error::from(ErrorKind::UnexpectedEof)),
|
Err(e) => Err(e)
|
||||||
Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user