diff options
Diffstat (limited to 'contrib/epee')
-rw-r--r-- | contrib/epee/include/console_handler.h | 28 | ||||
-rw-r--r-- | contrib/epee/include/net/http_client.h | 3 | ||||
-rw-r--r-- | contrib/epee/include/readline_buffer.h | 20 | ||||
-rw-r--r-- | contrib/epee/include/string_tools.h | 12 | ||||
-rw-r--r-- | contrib/epee/src/readline_buffer.cpp | 206 |
5 files changed, 118 insertions, 151 deletions
diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index a3b2d30eb..b8336b270 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -52,11 +52,10 @@ namespace epee , m_has_read_request(false) , m_read_status(state_init) { - m_reader_thread = boost::thread(std::bind(&async_stdin_reader::reader_thread_func, this)); #ifdef HAVE_READLINE m_readline_buffer.start(); - m_readline_thread = boost::thread(std::bind(&async_stdin_reader::readline_thread_func, this)); #endif + m_reader_thread = boost::thread(std::bind(&async_stdin_reader::reader_thread_func, this)); } ~async_stdin_reader() @@ -115,7 +114,6 @@ namespace epee m_reader_thread.join(); #ifdef HAVE_READLINE m_readline_buffer.stop(); - m_readline_thread.join(); #endif } } @@ -193,16 +191,6 @@ namespace epee return true; } -#ifdef HAVE_READLINE - void readline_thread_func() - { - while (m_run.load(std::memory_order_relaxed)) - { - m_readline_buffer.process(); - } - } -#endif - void reader_thread_func() { while (true) @@ -212,12 +200,20 @@ namespace epee std::string line; bool read_ok = true; +#ifdef HAVE_READLINE +reread: +#endif if (wait_stdin_data()) { if (m_run.load(std::memory_order_relaxed)) { #ifdef HAVE_READLINE - m_readline_buffer.get_line(line); + switch (m_readline_buffer.get_line(line)) + { + case rdln::empty: goto eof; + case rdln::partial: goto reread; + case rdln::full: break; + } #else std::getline(std::cin, line); #endif @@ -229,6 +225,9 @@ namespace epee read_ok = false; } if (std::cin.eof()) { +#ifdef HAVE_READLINE +eof: +#endif m_read_status = state_eos; m_response_cv.notify_one(); break; @@ -263,7 +262,6 @@ namespace epee boost::thread m_reader_thread; std::atomic<bool> m_run; #ifdef HAVE_READLINE - boost::thread m_readline_thread; rdln::readline_buffer m_readline_buffer; #endif diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 67e63f7bf..8e099e2bc 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -293,6 +293,9 @@ using namespace std; , m_lock() {} + const std::string &get_host() const { return m_host_buff; }; + const std::string &get_port() const { return m_port; }; + bool set_server(const std::string& address, boost::optional<login> user) { http::url_content parsed{}; diff --git a/contrib/epee/include/readline_buffer.h b/contrib/epee/include/readline_buffer.h index 8dd082a70..cda7e34f9 100644 --- a/contrib/epee/include/readline_buffer.h +++ b/contrib/epee/include/readline_buffer.h @@ -8,36 +8,28 @@ namespace rdln { + typedef enum { empty, partial, full } linestatus; class readline_buffer : public std::stringbuf { public: readline_buffer(); void start(); void stop(); - int process(); bool is_running() const { return m_cout_buf != NULL; } - void get_line(std::string& line) const; + linestatus get_line(std::string& line) const; void set_prompt(const std::string& prompt); - static void add_completion(const std::string& command) - { - if(std::find(completion_commands.begin(), completion_commands.end(), command) != completion_commands.end()) - return; - completion_commands.push_back(command); - } - static const std::vector<std::string>& get_completions() - { - return completion_commands; - } + static void add_completion(const std::string& command); + static const std::vector<std::string>& get_completions(); protected: virtual int sync(); - + private: std::streambuf* m_cout_buf; - static std::vector<std::string> completion_commands; + static std::vector<std::string>& completion_commands(); }; class suspend_readline diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 258caa49e..ce7b2fb87 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -314,6 +314,18 @@ POP_WARNINGS return str; } //---------------------------------------------------------------------------- + inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false) + { + if (s.size() < n) + { + if (prepend) + s = std::string(n - s.size(), c) + s; + else + s.append(n - s.size(), c); + } + return s; + } + //---------------------------------------------------------------------------- template<class t_pod_type> std::string pod_to_hex(const t_pod_type& s) { diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index ce8260ef6..291bba94c 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -3,21 +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; -std::mutex line_mutex, sync_mutex, process_mutex; -std::condition_variable have_line; - -std::vector<std::string> rdln::readline_buffer::completion_commands = {"exit"}; +static boost::mutex sync_mutex; +static rdln::linestatus line_stat; +static char *the_line; namespace { @@ -43,6 +37,12 @@ rdln::suspend_readline::~suspend_readline() m_buffer->start(); } +std::vector<std::string>& rdln::readline_buffer::completion_commands() +{ + static std::vector<std::string> commands = {"exit"}; + return commands; +} + rdln::readline_buffer::readline_buffer() : std::stringbuf(), m_cout_buf(NULL) { @@ -51,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(); @@ -61,8 +60,6 @@ void rdln::readline_buffer::start() void rdln::readline_buffer::stop() { - std::unique_lock<std::mutex> lock(process_mutex); - have_line.notify_all(); if(m_cout_buf == NULL) return; std::cout.rdbuf(m_cout_buf); @@ -70,145 +67,113 @@ 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()); - rl_redisplay(); -} - -int rdln::readline_buffer::process() -{ - process_mutex.lock(); - if(m_cout_buf == NULL) - { - process_mutex.unlock(); - boost::this_thread::sleep_for(boost::chrono::milliseconds( 1 )); - return 0; - } - 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; + boost::lock_guard<boost::mutex> lock(sync_mutex); + rl_set_prompt(prompt.c_str()); rl_redisplay(); - free(saved_line); - - return 0; } -static int process_input() +void rdln::readline_buffer::add_completion(const std::string& command) { - 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) - { - return count; - } - rl_callback_read_char(); - return count; + if(std::find(completion_commands().begin(), completion_commands().end(), command) != completion_commands().end()) + return; + completion_commands().push_back(command); } -static void handle_line(char* line) +const std::vector<std::string>& rdln::readline_buffer::get_completions() { - // This function never gets called now as we are trapping newlines. - // However, it still needs to be present for readline to know we are - // manually handling lines. - rl_done = 1; - return; + return completion_commands(); } -static int handle_enter(int x, int y) +int rdln::readline_buffer::sync() { - std::lock_guard<std::mutex> lock(sync_mutex); - char* line = 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 - line = rl_copy_text(0, rl_end); - std::string test_line = line; - boost::trim_right(test_line); - - rl_crlf(); - rl_on_new_line(); - - if(test_line.empty()) + if (rl_end || *rl_prompt) { - last_line = ""; - rl_set_prompt(last_prompt.c_str()); - rl_replace_line("", 1); +#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(); - have_line.notify_one(); - return 0; +#endif } - rl_set_prompt(""); - rl_replace_line("", 1); - rl_redisplay(); - - if (!test_line.empty()) + do { - last_line = test_line; - add_history(test_line.c_str()); - history_set_pos(history_length); + m_cout_buf->sputc( this->sgetc() ); } - free(line); + while ( this->snextc() != EOF ); - if(last_line != "exit" && last_line != "q") +#if RL_READLINE_VERSION < 0x0700 + if (end || *rl_prompt) { - rl_set_prompt(last_prompt.c_str()); - rl_replace_line("", 1); - rl_redisplay(); + rl_restore_prompt(); + rl_line_buffer = line; + rl_end = end; + rl_point = point; } +#endif + rl_on_new_line(); + 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) @@ -243,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); @@ -254,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(); } |