]> granicus.if.org Git - icinga2/commitdiff
Add readline support for the "repl" command
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 16 Dec 2014 11:22:02 +0000 (12:22 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 16 Dec 2014 12:26:26 +0000 (13:26 +0100)
fixes #8091

CMakeLists.txt
config.h.cmake
debian/control
icinga2.spec
lib/base/console.cpp
lib/base/console.hpp
lib/cli/CMakeLists.txt
lib/cli/replcommand.cpp

index 93358fc5750aaf9402bb0a9d3a187d763d8f2c8f..20067a5dedf9bd4a67f7b49a64013e5e1dfb406b 100644 (file)
@@ -152,6 +152,7 @@ check_function_exists(pipe2 HAVE_PIPE2)
 check_function_exists(nice HAVE_NICE)
 check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR)
 check_library_exists(execinfo backtrace_symbols "" HAVE_LIBEXECINFO)
+check_library_exists(readline readline "" HAVE_LIBREADLINE)
 check_include_file_cxx(cxxabi.h HAVE_CXXABI_H)
 
 if(HAVE_LIBEXECINFO)
index 24c38ef27258c9d12469b3c7b0642bfb3b0a269b..bf4ed8b1b8a7766b256cc987cc32dd5d6d20334c 100644 (file)
@@ -9,6 +9,7 @@
 #cmakedefine HAVE_LIBEXECINFO
 #cmakedefine HAVE_CXXABI_H
 #cmakedefine HAVE_NICE
+#cmakedefine HAVE_LIBREADLINE
 
 #cmakedefine ICINGA2_UNITY_BUILD
 
index b5817b509390b24e8e5de0b0f6f45b599809e09d..3d31cad94e9e7ece049ef65ad64a2040778944e0 100644 (file)
@@ -20,6 +20,7 @@ Build-Depends: bison,
                libpq-dev,
                libssl-dev,
                libyajl-dev,
+               libreadline-dev,
                make (>= 3.81),
                po-debconf
 Standards-Version: 3.9.5
index 6328821cf9a4de9e451619b24ddd32de9e56f2cf..d7e577c1275c5a3e3dacb8b76b0fc09d1f591049 100644 (file)
@@ -98,6 +98,12 @@ BuildRequires: flex >= 2.5.35
 BuildRequires: bison
 BuildRequires: make
 
+%if "%{_vendor}" == "suse"
+BuildRequires: libreadline-devel
+%else
+BuildRequires: readline-devel
+%endif
+
 %if "%{_vendor}" == "redhat" && (0%{?el5} || 0%{?rhel} == 5 || "%{?dist}" == ".el5")
 # el5 requires packages.icinga.org
 BuildRequires: boost153-devel
index 72b923f2cfd58d8dd5da62475fe7cca39ad7eae3..caca79a6e5e30be097b65f6da4217e68a466e8ba 100644 (file)
@@ -28,13 +28,17 @@ INITIALIZE_ONCE(&Console::DetectType);
 static ConsoleType l_ConsoleType = Console_Dumb;
 
 ConsoleColorTag::ConsoleColorTag(int color)
-       : m_Color(color)
+       : m_Color(color), m_ConsoleType(-1)
+{ }
+
+ConsoleColorTag::ConsoleColorTag(int color, ConsoleType consoleType)
+       : m_Color(color), m_ConsoleType(consoleType)
 { }
 
 std::ostream& icinga::operator<<(std::ostream& fp, const ConsoleColorTag& cct)
 {
 #ifndef _WIN32
-       if (Console::GetType(fp) == Console_VT100)
+       if (cct.m_ConsoleType == Console_VT100 || Console::GetType(fp) == Console_VT100)
                Console::PrintVT100ColorCode(fp, cct.m_Color);
 #else /* _WIN32 */
        if (Console::GetType(fp) == Console_Windows) {
index 3cf9a802a045bc225d80df7f8724309cf1a950e7..8fb4c4c864fa52acc5082e15bbaf18adecf9ca50 100644 (file)
@@ -68,11 +68,13 @@ class I2_BASE_API ConsoleColorTag
 {
 public:
        ConsoleColorTag(int color);
+       ConsoleColorTag(int color, ConsoleType consoleType);
 
        friend I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);
 
 private:
        int m_Color;
+       int m_ConsoleType;
 };
 
 I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);
index 4eb5d72869322d474822989eecae6cf61bdb8a8f..57b6ae3686d8617d4822cc8dd900797d5c9b0d06 100644 (file)
@@ -35,7 +35,7 @@ endif()
 
 add_library(cli SHARED ${cli_SOURCES})
 
-target_link_libraries(cli ${Boost_LIBRARIES} base config remote)
+target_link_libraries(cli ${Boost_LIBRARIES} readline base config remote)
 
 set_target_properties (
   cli PROPERTIES
index 4c1cfcec19ac96c32a8741de173f0e6eed0adb3e..b1b0c94a47d37d9f4b1f42b502455a145be1dc85 100644 (file)
 #include "base/application.hpp"
 #include <iostream>
 
+#ifdef HAVE_LIBREADLINE
+extern "C" {
+#include <readline/readline.h>
+#include <readline/history.h>
+}
+#endif /* HAVE_LIBREADLINE */
+
 using namespace icinga;
 namespace po = boost::program_options;
 
@@ -72,12 +79,41 @@ int ReplCommand::Run(const po::variables_map& vm, const std::vector<std::string>
                String fileName = "<" + Convert::ToString(next_line) + ">";
                next_line++;
 
+#ifdef HAVE_LIBREADLINE
+               ConsoleType type = Console::GetType(std::cout);
+
+               std::stringstream prompt_sbuf;
+
+               prompt_sbuf << RL_PROMPT_START_IGNORE << ConsoleColorTag(Console_ForegroundCyan, type)
+                   << RL_PROMPT_END_IGNORE << fileName
+                   << RL_PROMPT_START_IGNORE << ConsoleColorTag(Console_ForegroundRed, type)
+                   << RL_PROMPT_END_IGNORE << " => "
+                   << RL_PROMPT_START_IGNORE << ConsoleColorTag(Console_Normal, type);
+#else /* HAVE_LIBREADLINE */
                std::cout << ConsoleColorTag(Console_ForegroundCyan)
-                   << fileName << ConsoleColorTag(Console_ForegroundRed) << " => "
+                   << fileName
+                   << ConsoleColorTag(Console_ForegroundRed)
+                   << " => "
                    << ConsoleColorTag(Console_Normal);
+#endif /* HAVE_LIBREADLINE */
+
+#ifdef HAVE_LIBREADLINE
+               String prompt = prompt_sbuf.str();
+
+               char *rline = readline(prompt.CStr());
+
+               if (!rline)
+                       break;
+
+               if (*rline)
+                       add_history(rline);
 
+               String line = rline;
+               free(rline);
+#else /* HAVE_LIBREADLINE */
                std::string line;
                std::getline(std::cin, line);
+#endif /* HAVE_LIBREADLINE */
 
                Expression *expr;