Mercurial > octave
changeset 29335:3180f830d396 stable
line buffer input in terminal_reader class
* input.cc (terminal_reader::m_eof, terminal_reader::m_input_queue):
New data members.
(terminal_reader::get_input): Cache multi-line input in m_input_queue
and return buffered input one line at a time.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 27 Jan 2021 06:42:38 -0500 |
parents | 1ceeab926dc6 |
children | 036079c9ee12 |
files | libinterp/corefcn/input.cc |
diffstat | 1 files changed, 60 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/input.cc Wed Jan 27 13:32:04 2021 +0100 +++ b/libinterp/corefcn/input.cc Wed Jan 27 06:42:38 2021 -0500 @@ -36,6 +36,7 @@ #include <algorithm> #include <iostream> +#include <queue> #include <sstream> #include <string> @@ -796,7 +797,7 @@ public: terminal_reader (interpreter& interp) - : base_reader (interp) + : base_reader (interp), m_eof (false), m_input_queue () { } std::string get_input (const std::string& prompt, bool& eof); @@ -807,6 +808,9 @@ private: + bool m_eof; + std::queue<std::string> m_input_queue; + static const std::string s_in_src; }; @@ -869,6 +873,13 @@ const std::string terminal_reader::s_in_src ("terminal"); + // If octave_gets returns multiple lines, we cache the input and + // return it one line at a time. Multiple input lines may happen when + // using readline and bracketed paste mode is enabled, for example. + // Instead of queueing lines here, it might be better to modify the + // grammar in the parser to handle multiple lines when working + // interactively. See also bug #59938. + std::string terminal_reader::get_input (const std::string& prompt, bool& eof) { @@ -876,7 +887,54 @@ eof = false; - return octave_gets (prompt, eof); + if (m_input_queue.empty ()) + { + std::string input = octave_gets (prompt, m_eof); + + size_t len = input.size (); + + if (len == 0) + { + if (m_eof) + { + eof = m_eof; + return input; + } + else + { + // Can this happen, or will the string returned from + // octave_gets always end in a newline character? + + input = "\n"; + len = 1; + } + } + + size_t beg = 0; + while (beg < len) + { + size_t end = input.find ('\n', beg); + + if (end == std::string::npos) + { + m_input_queue.push (input.substr (beg)); + break; + } + else + { + m_input_queue.push (input.substr (beg, end-beg+1)); + beg = end + 1; + } + } + } + + std::string retval = m_input_queue.front (); + m_input_queue.pop (); + + if (m_input_queue.empty ()) + eof = m_eof; + + return retval; } const std::string file_reader::s_in_src ("file");