From d31ab146da8162f4f43cc7aeff92e991451a052a Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sat, 26 Jan 2019 13:02:02 +0100 Subject: [PATCH] takeout history handling from Prompt --- aql2/src/prompt/Prompt.cpp | 71 +----------------- aql2/src/prompt/ReadlinePromptHistory.cpp | 13 ++++ aql2/src/prompt/ReadlinePromptHistory.h | 91 +++++++++++++++++++++++ 3 files changed, 107 insertions(+), 68 deletions(-) create mode 100644 aql2/src/prompt/ReadlinePromptHistory.cpp create mode 100644 aql2/src/prompt/ReadlinePromptHistory.h diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp index 02cc99bedc..ed66482e1a 100644 --- a/aql2/src/prompt/Prompt.cpp +++ b/aql2/src/prompt/Prompt.cpp @@ -7,81 +7,16 @@ #include "Prompt.h" #include "ReadlinePromptCompletion.h" - -char esc_char [] = { '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\' }; -char essc_str [] = { 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\' }; -size_t esc_char_size = sizeof ( esc_char ); - -char * descape ( const char * buffer ) { - size_t l = strlen ( buffer ); - - char * dest = ( char * ) malloc ( ( l + 1 ) * sizeof ( char ) ); - char * ptr = dest; - for ( size_t i = 0; i < l; ++ i ) { - if ( buffer [ i ] == '\\' ) { - ++ i; - size_t j = std::find ( essc_str, essc_str + esc_char_size, buffer [ i ] ) - essc_str; - if ( j == esc_char_size ) { - free ( dest ); - return strdup ( buffer ); - } - * ptr ++ = esc_char [ j ]; - } else { - * ptr ++ = buffer [ i ]; - } - } - * ptr = '\0'; - - return dest; -} - -char * escape ( const char * buffer){ - size_t l = strlen ( buffer ); - - char * dest = ( char * ) malloc ( ( l * 2 + 1 ) * sizeof ( char ) ); - char * ptr = dest; - for ( size_t i = 0; i < l; ++ i ) { - size_t j = std::find ( esc_char, esc_char + esc_char_size, buffer [ i ] ) - esc_char; - if ( j == esc_char_size ) { - * ptr ++ = buffer [ i ]; - } else { - * ptr ++ = '\\'; - * ptr ++ = essc_str [ j ]; - } - } - * ptr = '\0'; - - return dest; -} +#include "ReadlinePromptHistory.h" Prompt::Prompt ( cli::Environment environment ) : m_history_file ( std::string ( std::getenv ( "HOME" ) ) + "/.aql_history" ), m_environment ( std::move ( environment ) ) { - read_history ( m_history_file.c_str ( ) ); - - HIST_ENTRY ** history = history_list ( ); - int i = 0; - if ( history ) while ( * history ) { - char * tmp = descape ( ( * history )->line ); - replace_history_entry ( i, tmp, ( * history )->data ); - free ( tmp ); - ++ history; - ++ i; - } - + ReadlinePromptHistory::readHistory ( m_history_file.c_str ( ) ); // register readline completion function, pass environment rl_attempted_completion_function = ReadlinePromptCompletion::readline_completion; } Prompt::~Prompt ( ) { - HIST_ENTRY ** history = history_list ( ); - int i = 0; - if ( history ) while ( * history ) { - char * tmp = escape ( ( * history )->line ); - replace_history_entry ( i, tmp, ( * history )->data ); - free ( tmp ); - ++ history; - ++ i; - } - write_history ( m_history_file.c_str ( ) ); + ReadlinePromptHistory::writeHistory ( m_history_file.c_str ( ) ); } cli::Command::Result Prompt::run ( ) { diff --git a/aql2/src/prompt/ReadlinePromptHistory.cpp b/aql2/src/prompt/ReadlinePromptHistory.cpp new file mode 100644 index 0000000000..69de4c4ebb --- /dev/null +++ b/aql2/src/prompt/ReadlinePromptHistory.cpp @@ -0,0 +1,13 @@ +/* + * ReadlinePromptHistory.cpp + * + * Created on: 26. 1. 2019 + * Author: Jan Travnicek + */ + +#include "ReadlinePromptHistory.h" + +char ReadlinePromptHistory::esc_char [] = { '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\' }; +char ReadlinePromptHistory::essc_str [] = { 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\' }; +size_t ReadlinePromptHistory::esc_char_size = sizeof ( ReadlinePromptHistory::esc_char ); + diff --git a/aql2/src/prompt/ReadlinePromptHistory.h b/aql2/src/prompt/ReadlinePromptHistory.h new file mode 100644 index 0000000000..691fd99a0f --- /dev/null +++ b/aql2/src/prompt/ReadlinePromptHistory.h @@ -0,0 +1,91 @@ +/* + * ReadlinePromptCompletion.h + * + * Created on: 26. 1. 2019 + * Author: Jan Travnicek + */ + +#ifndef _READLINE_PROMPT_HISTORY_H +#define _READLINE_PROMPT_HISTORY_H + +#include <string.h> +#include <stdio.h> + +#include <alib/string> + +#include <readline/history.h> + +class ReadlinePromptHistory { + static char esc_char []; + static char essc_str []; + static size_t esc_char_size; + + static char * descape ( const char * buffer ) { + size_t l = strlen ( buffer ); + + char * dest = ( char * ) malloc ( ( l + 1 ) * sizeof ( char ) ); + char * ptr = dest; + for ( size_t i = 0; i < l; ++ i ) { + if ( buffer [ i ] == '\\' ) { + ++ i; + size_t j = std::find ( essc_str, essc_str + esc_char_size, buffer [ i ] ) - essc_str; + if ( j == esc_char_size ) { + free ( dest ); + return strdup ( buffer ); + } + * ptr ++ = esc_char [ j ]; + } else { + * ptr ++ = buffer [ i ]; + } + } + * ptr = '\0'; + + return dest; + } + + static char * escape ( const char * buffer){ + size_t l = strlen ( buffer ); + + char * dest = ( char * ) malloc ( ( l * 2 + 1 ) * sizeof ( char ) ); + char * ptr = dest; + for ( size_t i = 0; i < l; ++ i ) { + size_t j = std::find ( esc_char, esc_char + esc_char_size, buffer [ i ] ) - esc_char; + if ( j == esc_char_size ) { + * ptr ++ = buffer [ i ]; + } else { + * ptr ++ = '\\'; + * ptr ++ = essc_str [ j ]; + } + } + * ptr = '\0'; + + return dest; + } + + template < class Callable > + static void history_transform ( Callable callable ) { + HIST_ENTRY ** history = history_list ( ); + int i = 0; + if ( history ) while ( * history ) { + char * tmp = callable ( ( * history )->line ); + replace_history_entry ( i, tmp, ( * history )->data ); + free ( tmp ); + ++ history; + ++ i; + } + } + +public: + static void readHistory ( const std::string & history_file ) { + read_history ( history_file.c_str ( ) ); + ReadlinePromptHistory::history_transform ( ReadlinePromptHistory::descape ); + } + + static void writeHistory ( const std::string & history_file ) { + ReadlinePromptHistory::history_transform ( ReadlinePromptHistory::escape ); + write_history ( history_file.c_str ( ) ); + } + +}; + +#endif /* _READLINE_PROMPT_HISTORY_H */ -- GitLab