diff options
author | Howard Chu <hyc@symas.com> | 2017-08-21 12:55:06 +0100 |
---|---|---|
committer | Howard Chu <hyc@symas.com> | 2017-08-22 08:30:04 +0100 |
commit | c088d38a57f6be5c8399a8c2243b2862d9f67cbe (patch) | |
tree | e66c0e3f8a211f95cad796a51933af27aeb0d3d3 /contrib/epee/src/readline_buffer.cpp | |
parent | Merge pull request #2303 (diff) | |
download | monero-c088d38a57f6be5c8399a8c2243b2862d9f67cbe.tar.xz |
Simplify readline support
And don't use std::mutex
Diffstat (limited to '')
-rw-r--r-- | contrib/epee/src/readline_buffer.cpp | 191 |
1 files changed, 69 insertions, 122 deletions
diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index 42b474052..291bba94c 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -3,19 +3,15 @@ #include <readline/history.h> #include <sys/select.h> #include <unistd.h> -#include <mutex> -#include <condition_variable> #include <boost/thread.hpp> #include <boost/algorithm/string.hpp> -static int process_input(); static void install_line_handler(); static void remove_line_handler(); -static std::string last_line; -static std::string last_prompt; -static std::mutex line_mutex, sync_mutex, process_mutex; -static std::condition_variable have_line; +static boost::mutex sync_mutex; +static rdln::linestatus line_stat; +static char *the_line; namespace { @@ -55,7 +51,6 @@ rdln::readline_buffer::readline_buffer() void rdln::readline_buffer::start() { - std::unique_lock<std::mutex> lock(process_mutex); if(m_cout_buf != NULL) return; m_cout_buf = std::cout.rdbuf(); @@ -65,9 +60,6 @@ void rdln::readline_buffer::start() void rdln::readline_buffer::stop() { - std::unique_lock<std::mutex> lock_process(process_mutex); - std::unique_lock<std::mutex> lock_sync(sync_mutex); - have_line.notify_all(); if(m_cout_buf == NULL) return; std::cout.rdbuf(m_cout_buf); @@ -75,20 +67,26 @@ void rdln::readline_buffer::stop() remove_line_handler(); } -void rdln::readline_buffer::get_line(std::string& line) const +rdln::linestatus rdln::readline_buffer::get_line(std::string& line) const { - std::unique_lock<std::mutex> lock(line_mutex); - have_line.wait(lock); - line = last_line; + boost::lock_guard<boost::mutex> lock(sync_mutex); + line_stat = rdln::partial; + rl_callback_read_char(); + if (line_stat == rdln::full) + { + line = the_line; + free(the_line); + the_line = NULL; + } + return line_stat; } void rdln::readline_buffer::set_prompt(const std::string& prompt) { - last_prompt = prompt; if(m_cout_buf == NULL) return; - std::lock_guard<std::mutex> lock(sync_mutex); - rl_set_prompt(last_prompt.c_str()); + boost::lock_guard<boost::mutex> lock(sync_mutex); + rl_set_prompt(prompt.c_str()); rl_redisplay(); } @@ -104,126 +102,78 @@ const std::vector<std::string>& rdln::readline_buffer::get_completions() return completion_commands(); } -int rdln::readline_buffer::process() +int rdln::readline_buffer::sync() { - process_mutex.lock(); - if(m_cout_buf == NULL) + boost::lock_guard<boost::mutex> lock(sync_mutex); +#if RL_READLINE_VERSION < 0x0700 + char lbuf[2] = {0,0}; + char *line = NULL; + int end = 0, point = 0; +#endif + + if (rl_end || *rl_prompt) { - process_mutex.unlock(); - boost::this_thread::sleep_for(boost::chrono::milliseconds( 1 )); - return 0; +#if RL_READLINE_VERSION >= 0x0700 + rl_clear_visible_line(); +#else + line = rl_line_buffer; + end = rl_end; + point = rl_point; + rl_line_buffer = lbuf; + rl_end = 0; + rl_point = 0; + rl_save_prompt(); + rl_redisplay(); +#endif } - int count = process_input(); - process_mutex.unlock(); - boost::this_thread::sleep_for(boost::chrono::milliseconds( 1 )); - return count; -} -int rdln::readline_buffer::sync() -{ - std::lock_guard<std::mutex> lock(sync_mutex); - char* saved_line; - int saved_point; - - saved_point = rl_point; - saved_line = rl_copy_text(0, rl_end); - - rl_set_prompt(""); - rl_replace_line("", 0); - rl_redisplay(); - do { m_cout_buf->sputc( this->sgetc() ); } while ( this->snextc() != EOF ); - - rl_set_prompt(last_prompt.c_str()); - rl_replace_line(saved_line, 0); - rl_point = saved_point; - rl_redisplay(); - free(saved_line); - - return 0; -} -static int process_input() -{ - int count; - struct timeval t; - fd_set fds; - - t.tv_sec = 0; - t.tv_usec = 1000; - - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - count = select(STDIN_FILENO + 1, &fds, NULL, NULL, &t); - if (count < 1) +#if RL_READLINE_VERSION < 0x0700 + if (end || *rl_prompt) { - return count; + rl_restore_prompt(); + rl_line_buffer = line; + rl_end = end; + rl_point = point; } - rl_callback_read_char(); - return count; -} - -static void handle_line(char* line) -{ - free(line); - rl_done = 1; - return; -} - -static int handle_enter(int x, int y) -{ - std::lock_guard<std::mutex> lock(sync_mutex); - char* line = NULL; - - line = rl_copy_text(0, rl_end); - std::string test_line = line; - free(line); - boost::trim_right(test_line); - - rl_crlf(); +#endif rl_on_new_line(); - - if(test_line.empty()) - { - last_line = ""; - rl_set_prompt(last_prompt.c_str()); - rl_replace_line("", 1); - rl_redisplay(); - have_line.notify_one(); - return 0; - } - - rl_set_prompt(""); - rl_replace_line("", 1); rl_redisplay(); - - if (!test_line.empty()) - { - last_line = test_line; - add_history(test_line.c_str()); - history_set_pos(history_length); - } - if(last_line != "exit" && last_line != "q") - { - rl_set_prompt(last_prompt.c_str()); - rl_replace_line("", 1); - rl_redisplay(); - } - - have_line.notify_one(); return 0; } -static int startup_hook() +static void handle_line(char* line) { - rl_bind_key(RETURN, handle_enter); - rl_bind_key(NEWLINE, handle_enter); - return 0; + bool exit = false; + if (line) + { + line_stat = rdln::full; + the_line = line; + std::string test_line = line; + boost::trim_right(test_line); + if(!test_line.empty()) + { + add_history(test_line.c_str()); + history_set_pos(history_length); + if (test_line == "exit" || test_line == "q") + exit = true; + } + } else + /* EOF */ + { + line_stat = rdln::empty; + exit = true; + } + rl_done = 1; + if (exit) + rl_set_prompt(""); + return; } static char* completion_matches(const char* text, int state) @@ -258,7 +208,6 @@ static char** attempted_completion(const char* text, int start, int end) static void install_line_handler() { - rl_startup_hook = startup_hook; rl_attempted_completion_function = attempted_completion; rl_callback_handler_install("", handle_line); stifle_history(500); @@ -269,8 +218,6 @@ static void remove_line_handler() rl_replace_line("", 0); rl_set_prompt(""); rl_redisplay(); - rl_unbind_key(RETURN); - rl_unbind_key(NEWLINE); rl_callback_handler_remove(); } |