diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp index 350e1078890b2ebe0ccb963fad35421be3096a48..132e35203eb80dd7ecda30cdf4c0c18ac9b9d4db 100644 --- a/aql2/src/prompt/Prompt.cpp +++ b/aql2/src/prompt/Prompt.cpp @@ -7,11 +7,76 @@ #include "Prompt.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; +} + 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; + } } 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 ( ) ); }