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