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(NOT APPLE)
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IF(NOT "$ENV{OPENSSL_ROOT_DIR}" STREQUAL "")
|
IF(NOT "$ENV{OPENSSL_ROOT_DIR}" STREQUAL "")
|
||||||
set(OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT_DIR} )
|
set(OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT_DIR} )
|
||||||
set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include)
|
set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include)
|
||||||
|
|
@ -123,6 +125,7 @@ set( fc_sources
|
||||||
src/interprocess/file_mapping.cpp
|
src/interprocess/file_mapping.cpp
|
||||||
src/interprocess/mmap_struct.cpp
|
src/interprocess/mmap_struct.cpp
|
||||||
src/rpc/json_connection.cpp
|
src/rpc/json_connection.cpp
|
||||||
|
src/rpc/cli.cpp
|
||||||
src/log/log_message.cpp
|
src/log/log_message.cpp
|
||||||
src/log/logger.cpp
|
src/log/logger.cpp
|
||||||
src/log/appender.cpp
|
src/log/appender.cpp
|
||||||
|
|
@ -195,6 +198,25 @@ add_subdirectory( vendor/udt4 )
|
||||||
|
|
||||||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY )
|
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)
|
IF(WIN32)
|
||||||
target_compile_definitions(fc PUBLIC WIN32 NOMINMAX _WIN32_WINNT=0x0501 _CRT_SECURE_NO_WARNINGS
|
target_compile_definitions(fc PUBLIC WIN32 NOMINMAX _WIN32_WINNT=0x0501 _CRT_SECURE_NO_WARNINGS
|
||||||
_SCL_SERCURE_NO_WARNINGS
|
_SCL_SERCURE_NO_WARNINGS
|
||||||
|
|
@ -221,6 +243,7 @@ target_include_directories(fc
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
${OPENSSL_INCLUDE_DIR}
|
${OPENSSL_INCLUDE_DIR}
|
||||||
|
"${readline_includes}"
|
||||||
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
#${CMAKE_CURRENT_SOURCE_DIR}/vendor/scrypt-jane
|
#${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 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(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(a|lib)$")
|
||||||
IF(WIN32)
|
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/rpc/api_connection.hpp>
|
||||||
#include <fc/thread/thread.hpp>
|
#include <fc/thread/thread.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace fc { namespace rpc {
|
namespace fc { namespace rpc {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,16 +50,24 @@ namespace fc { namespace rpc {
|
||||||
{
|
{
|
||||||
_result_formatters[method] = formatter;
|
_result_formatters[method] = formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void getline( const fc::string& prompt, fc::string& line );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
while( !fc::cin.eof() && !_run_complete.canceled() )
|
while( !_run_complete.canceled() )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
std::cout << ">>> ";
|
|
||||||
std::cout.flush();
|
|
||||||
std::string line;
|
std::string line;
|
||||||
fc::getline( fc::cin, line );
|
try
|
||||||
|
{
|
||||||
|
getline( ">>> ", line );
|
||||||
|
}
|
||||||
|
catch ( const fc::eof_exception& e )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
std::cout << line << "\n";
|
std::cout << line << "\n";
|
||||||
line += char(EOF);
|
line += char(EOF);
|
||||||
fc::variants args = fc::json::variants_from_string(line);;
|
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