Add readline support to fc::rpc::cli
This commit is contained in:
parent
35d4893069
commit
80de0987d7
4 changed files with 154 additions and 5 deletions
|
|
@ -76,6 +76,8 @@ ELSE(WIN32)
|
|||
ENDIF(NOT APPLE)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
||||
|
||||
IF(NOT "$ENV{OPENSSL_ROOT_DIR}" STREQUAL "")
|
||||
set(OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT_DIR} )
|
||||
set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include)
|
||||
|
|
@ -123,6 +125,7 @@ set( fc_sources
|
|||
src/interprocess/file_mapping.cpp
|
||||
src/interprocess/mmap_struct.cpp
|
||||
src/rpc/json_connection.cpp
|
||||
src/rpc/cli.cpp
|
||||
src/log/log_message.cpp
|
||||
src/log/logger.cpp
|
||||
src/log/appender.cpp
|
||||
|
|
@ -195,6 +198,25 @@ add_subdirectory( vendor/udt4 )
|
|||
|
||||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY )
|
||||
|
||||
# begin readline stuff
|
||||
find_package(Curses)
|
||||
find_package(Readline)
|
||||
|
||||
file(GLOB HEADERS "include/bts/cli/*.hpp")
|
||||
|
||||
if (READLINE_FOUND)
|
||||
target_compile_definitions (fc PRIVATE HAVE_READLINE)
|
||||
set(readline_libraries ${Readline_LIBRARY})
|
||||
if (CURSES_FOUND)
|
||||
list(APPEND readline_libraries ${CURSES_LIBRARY})
|
||||
endif()
|
||||
set(readline_includes ${Readline_INCLUDE_DIR})
|
||||
endif()
|
||||
if(WIN32)
|
||||
target_compile_definitions( fc PRIVATE _CRT_NONSTDC_NO_DEPRECATE )
|
||||
endif(WIN32)
|
||||
# end readline stuff
|
||||
|
||||
IF(WIN32)
|
||||
target_compile_definitions(fc PUBLIC WIN32 NOMINMAX _WIN32_WINNT=0x0501 _CRT_SECURE_NO_WARNINGS
|
||||
_SCL_SERCURE_NO_WARNINGS
|
||||
|
|
@ -221,6 +243,7 @@ target_include_directories(fc
|
|||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${Boost_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
"${readline_includes}"
|
||||
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/vendor/scrypt-jane
|
||||
|
|
@ -233,7 +256,7 @@ target_include_directories(fc
|
|||
)
|
||||
|
||||
#target_link_libraries( fc PUBLIC easylzma_static scrypt udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library})
|
||||
target_link_libraries( fc PUBLIC easylzma_static udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library})
|
||||
target_link_libraries( fc PUBLIC easylzma_static udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries})
|
||||
|
||||
IF(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(a|lib)$")
|
||||
IF(WIN32)
|
||||
|
|
|
|||
47
CMakeModules/FindReadline.cmake
Normal file
47
CMakeModules/FindReadline.cmake
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# - Try to find readline include dirs and libraries
|
||||
#
|
||||
# Usage of this module as follows:
|
||||
#
|
||||
# find_package(Readline)
|
||||
#
|
||||
# Variables used by this module, they can change the default behaviour and need
|
||||
# to be set before calling find_package:
|
||||
#
|
||||
# Readline_ROOT_DIR Set this variable to the root installation of
|
||||
# readline if the module has problems finding the
|
||||
# proper installation path.
|
||||
#
|
||||
# Variables defined by this module:
|
||||
#
|
||||
# READLINE_FOUND System has readline, include and lib dirs found
|
||||
# Readline_INCLUDE_DIR The readline include directories.
|
||||
# Readline_LIBRARY The readline library.
|
||||
|
||||
find_path(Readline_ROOT_DIR
|
||||
NAMES include/readline/readline.h
|
||||
)
|
||||
|
||||
find_path(Readline_INCLUDE_DIR
|
||||
NAMES readline/readline.h
|
||||
HINTS ${Readline_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
find_library(Readline_LIBRARY
|
||||
NAMES readline
|
||||
HINTS ${Readline_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
set(READLINE_FOUND TRUE)
|
||||
else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
FIND_LIBRARY(Readline_LIBRARY NAMES readline)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
|
||||
MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
|
||||
endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
|
||||
mark_as_advanced(
|
||||
Readline_ROOT_DIR
|
||||
Readline_INCLUDE_DIR
|
||||
Readline_LIBRARY
|
||||
)
|
||||
|
|
@ -6,6 +6,8 @@
|
|||
#include <fc/rpc/api_connection.hpp>
|
||||
#include <fc/thread/thread.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
/**
|
||||
|
|
@ -48,16 +50,24 @@ namespace fc { namespace rpc {
|
|||
{
|
||||
_result_formatters[method] = formatter;
|
||||
}
|
||||
|
||||
virtual void getline( const fc::string& prompt, fc::string& line );
|
||||
|
||||
private:
|
||||
void run()
|
||||
{
|
||||
while( !fc::cin.eof() && !_run_complete.canceled() )
|
||||
while( !_run_complete.canceled() )
|
||||
{
|
||||
try {
|
||||
std::cout << ">>> ";
|
||||
std::cout.flush();
|
||||
std::string line;
|
||||
fc::getline( fc::cin, line );
|
||||
try
|
||||
{
|
||||
getline( ">>> ", line );
|
||||
}
|
||||
catch ( const fc::eof_exception& e )
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::cout << line << "\n";
|
||||
line += char(EOF);
|
||||
fc::variants args = fc::json::variants_from_string(line);;
|
||||
|
|
|
|||
69
src/rpc/cli.cpp
Normal file
69
src/rpc/cli.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
#include <fc/rpc/cli.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
// I don't know exactly what version of readline we need. I know the 4.2 version that ships on some macs is
|
||||
// missing some functions we require. We're developing against 6.3, but probably anything in the 6.x
|
||||
// series is fine
|
||||
# if RL_VERSION_MAJOR < 6
|
||||
# ifdef _MSC_VER
|
||||
# pragma message("You have an old version of readline installed that might not support some of the features we need")
|
||||
# pragma message("Readline support will not be compiled in")
|
||||
# else
|
||||
# warning "You have an old version of readline installed that might not support some of the features we need"
|
||||
# warning "Readline support will not be compiled in"
|
||||
# endif
|
||||
# undef HAVE_READLINE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
void cli::getline(
|
||||
const fc::string& prompt,
|
||||
fc::string& line
|
||||
)
|
||||
{
|
||||
// getting file descriptor for C++ streams is near impossible
|
||||
// so we just assume it's the same as the C stream...
|
||||
#ifdef HAVE_READLINE
|
||||
#ifndef WIN32
|
||||
if( isatty( fileno( stdin ) ) )
|
||||
#else
|
||||
// it's implied by
|
||||
// https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx
|
||||
// that this is the proper way to do this on Windows, but I have
|
||||
// no access to a Windows compiler and thus,
|
||||
// no idea if this actually works
|
||||
if( _isatty( _fileno( stdin ) ) )
|
||||
#endif
|
||||
{
|
||||
char* line_read = nullptr;
|
||||
std::cout.flush(); //readline doesn't use cin, so we must manually flush _out
|
||||
line_read = readline(prompt.c_str());
|
||||
if( line_read == nullptr )
|
||||
FC_THROW_EXCEPTION( fc::eof_exception, "" );
|
||||
if( *line_read )
|
||||
add_history(line_read);
|
||||
line = line_read;
|
||||
free(line_read);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
std::cout << prompt;
|
||||
// sync_call( cin_thread, [&](){ std::getline( *input_stream, line ); }, "getline");
|
||||
fc::getline( fc::cin, line );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} }
|
||||
Loading…
Reference in a new issue