Add readline support for the "repl" command

fixes #8091
This commit is contained in:
Gunnar Beutner 2014-12-16 12:22:02 +01:00
parent afe4919169
commit d82defe6a9
8 changed files with 57 additions and 6 deletions

View File

@ -152,6 +152,7 @@ check_function_exists(pipe2 HAVE_PIPE2)
check_function_exists(nice HAVE_NICE) check_function_exists(nice HAVE_NICE)
check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR) check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR)
check_library_exists(execinfo backtrace_symbols "" HAVE_LIBEXECINFO) check_library_exists(execinfo backtrace_symbols "" HAVE_LIBEXECINFO)
check_library_exists(readline readline "" HAVE_LIBREADLINE)
check_include_file_cxx(cxxabi.h HAVE_CXXABI_H) check_include_file_cxx(cxxabi.h HAVE_CXXABI_H)
if(HAVE_LIBEXECINFO) if(HAVE_LIBEXECINFO)

View File

@ -9,6 +9,7 @@
#cmakedefine HAVE_LIBEXECINFO #cmakedefine HAVE_LIBEXECINFO
#cmakedefine HAVE_CXXABI_H #cmakedefine HAVE_CXXABI_H
#cmakedefine HAVE_NICE #cmakedefine HAVE_NICE
#cmakedefine HAVE_LIBREADLINE
#cmakedefine ICINGA2_UNITY_BUILD #cmakedefine ICINGA2_UNITY_BUILD

1
debian/control vendored
View File

@ -20,6 +20,7 @@ Build-Depends: bison,
libpq-dev, libpq-dev,
libssl-dev, libssl-dev,
libyajl-dev, libyajl-dev,
libreadline-dev,
make (>= 3.81), make (>= 3.81),
po-debconf po-debconf
Standards-Version: 3.9.5 Standards-Version: 3.9.5

View File

@ -98,6 +98,12 @@ BuildRequires: flex >= 2.5.35
BuildRequires: bison BuildRequires: bison
BuildRequires: make BuildRequires: make
%if "%{_vendor}" == "suse"
BuildRequires: libreadline-devel
%else
BuildRequires: readline-devel
%endif
%if "%{_vendor}" == "redhat" && (0%{?el5} || 0%{?rhel} == 5 || "%{?dist}" == ".el5") %if "%{_vendor}" == "redhat" && (0%{?el5} || 0%{?rhel} == 5 || "%{?dist}" == ".el5")
# el5 requires packages.icinga.org # el5 requires packages.icinga.org
BuildRequires: boost153-devel BuildRequires: boost153-devel

View File

@ -28,13 +28,17 @@ INITIALIZE_ONCE(&Console::DetectType);
static ConsoleType l_ConsoleType = Console_Dumb; static ConsoleType l_ConsoleType = Console_Dumb;
ConsoleColorTag::ConsoleColorTag(int color) 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) std::ostream& icinga::operator<<(std::ostream& fp, const ConsoleColorTag& cct)
{ {
#ifndef _WIN32 #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); Console::PrintVT100ColorCode(fp, cct.m_Color);
#else /* _WIN32 */ #else /* _WIN32 */
if (Console::GetType(fp) == Console_Windows) { if (Console::GetType(fp) == Console_Windows) {

View File

@ -68,11 +68,13 @@ class I2_BASE_API ConsoleColorTag
{ {
public: public:
ConsoleColorTag(int color); ConsoleColorTag(int color);
ConsoleColorTag(int color, ConsoleType consoleType);
friend I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct); friend I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);
private: private:
int m_Color; int m_Color;
int m_ConsoleType;
}; };
I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct); I2_BASE_API std::ostream& operator<<(std::ostream& fp, const ConsoleColorTag& cct);

View File

@ -35,7 +35,7 @@ endif()
add_library(cli SHARED ${cli_SOURCES}) 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 ( set_target_properties (
cli PROPERTIES cli PROPERTIES

View File

@ -25,6 +25,13 @@
#include "base/application.hpp" #include "base/application.hpp"
#include <iostream> #include <iostream>
#ifdef HAVE_LIBREADLINE
extern "C" {
#include <readline/readline.h>
#include <readline/history.h>
}
#endif /* HAVE_LIBREADLINE */
using namespace icinga; using namespace icinga;
namespace po = boost::program_options; 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) + ">"; String fileName = "<" + Convert::ToString(next_line) + ">";
next_line++; next_line++;
std::cout << ConsoleColorTag(Console_ForegroundCyan) #ifdef HAVE_LIBREADLINE
<< fileName << ConsoleColorTag(Console_ForegroundRed) << " => " ConsoleType type = Console::GetType(std::cout);
<< ConsoleColorTag(Console_Normal);
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)
<< " => "
<< 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::string line;
std::getline(std::cin, line); std::getline(std::cin, line);
#endif /* HAVE_LIBREADLINE */
Expression *expr; Expression *expr;