Merge pull request #3059 from pmikkelsen/raw-input

Don't use "readline" input functionality for certain builtins
This commit is contained in:
Mark Thom
2025-08-26 23:09:18 -07:00
committed by GitHub
2 changed files with 46 additions and 3 deletions

View 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,

View File

@@ -107,6 +107,28 @@ fn get_prompt() -> &'static str {
}
}
thread_local! {
static RAW_READ: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
}
pub struct RawReadGuard;
impl RawReadGuard {
pub fn new() -> RawReadGuard {
if RAW_READ.get() {
panic!("Nested RawReadGuards");
}
RAW_READ.set(true);
RawReadGuard
}
}
impl Drop for RawReadGuard {
fn drop(&mut self) {
RAW_READ.set(false);
}
}
#[derive(Debug)]
pub struct ReadlineStream {
#[cfg(feature = "repl")]
@@ -172,7 +194,22 @@ impl ReadlineStream {
#[cfg(feature = "repl")]
fn call_readline(&mut self) -> std::io::Result<usize> {
match self.rl.readline(get_prompt()) {
let text = if RAW_READ.get() {
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 +232,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),
}
}