mirror of https://gitee.com/bigwinds/arangodb
added better readline support for control-C
This commit is contained in:
parent
29b03e854d
commit
3029891405
|
@ -1,6 +1,8 @@
|
||||||
v2.7.0 (XXXX-XX-XX)
|
v2.7.0 (XXXX-XX-XX)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* added better control-C support in arangosh
|
||||||
|
|
||||||
* increased default value collection-specific `indexBuckets` value from 1 to 16
|
* increased default value collection-specific `indexBuckets` value from 1 to 16
|
||||||
|
|
||||||
Collections created from 2.7 on will use the new default if not overriden on
|
Collections created from 2.7 on will use the new default if not overriden on
|
||||||
|
|
|
@ -711,6 +711,10 @@ void ArangoServer::buildApplicationServer () {
|
||||||
// disable certain options in unittest or script mode
|
// disable certain options in unittest or script mode
|
||||||
OperationMode::server_operation_mode_e mode = OperationMode::determineMode(_applicationServer->programOptions());
|
OperationMode::server_operation_mode_e mode = OperationMode::determineMode(_applicationServer->programOptions());
|
||||||
|
|
||||||
|
if (mode == OperationMode::MODE_CONSOLE) {
|
||||||
|
_applicationScheduler->disableControlCHandler();
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == OperationMode::MODE_SCRIPT || mode == OperationMode::MODE_UNITTESTS) {
|
if (mode == OperationMode::MODE_SCRIPT || mode == OperationMode::MODE_UNITTESTS) {
|
||||||
// testing disables authentication
|
// testing disables authentication
|
||||||
_disableAuthentication = true;
|
_disableAuthentication = true;
|
||||||
|
|
|
@ -71,8 +71,8 @@ ConsoleThread::ConsoleThread (ApplicationServer* applicationServer,
|
||||||
_vocbase(vocbase),
|
_vocbase(vocbase),
|
||||||
_done(0),
|
_done(0),
|
||||||
_userAborted(false) {
|
_userAborted(false) {
|
||||||
allowAsynchronousCancelation();
|
|
||||||
|
|
||||||
|
allowAsynchronousCancelation();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -184,12 +184,6 @@ static vector<string> JsLint;
|
||||||
|
|
||||||
static uint64_t GcInterval = 10;
|
static uint64_t GcInterval = 10;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief console object
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static triagens::V8LineEditor* Console = nullptr;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief voice mode
|
/// @brief voice mode
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1503,26 +1497,6 @@ static std::string BuildPrompt () {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief signal handler for CTRL-C
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void SignalHandler (int signal) {
|
|
||||||
if (Console != nullptr) {
|
|
||||||
Console->close();
|
|
||||||
Console = nullptr;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
TRI_EXIT_FUNCTION(EXIT_SUCCESS, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief executes the shell
|
/// @brief executes the shell
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1531,25 +1505,8 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
||||||
v8::Context::Scope contextScope(context);
|
v8::Context::Scope contextScope(context);
|
||||||
v8::Local<v8::String> name(TRI_V8_ASCII_STRING(TRI_V8_SHELL_COMMAND_NAME));
|
v8::Local<v8::String> name(TRI_V8_ASCII_STRING(TRI_V8_SHELL_COMMAND_NAME));
|
||||||
|
|
||||||
Console = new triagens::V8LineEditor(context, ".arangosh.history");
|
triagens::V8LineEditor console(context, ".arangosh.history");
|
||||||
Console->open(BaseClient.autoComplete());
|
console.open(BaseClient.autoComplete());
|
||||||
|
|
||||||
// install signal handler for CTRL-C
|
|
||||||
#ifdef _WIN32
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct sigaction sa;
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_handler = &SignalHandler;
|
|
||||||
|
|
||||||
int res = sigaction(SIGINT, &sa, 0);
|
|
||||||
|
|
||||||
if (res != 0) {
|
|
||||||
LOG_ERROR("unable to install signal handler");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t nrCommands = 0;
|
uint64_t nrCommands = 0;
|
||||||
|
|
||||||
|
@ -1573,17 +1530,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
||||||
string badPrompt;
|
string badPrompt;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#if _WIN32
|
||||||
|
|
||||||
// ........................................................................................
|
|
||||||
// MacOS uses libedit, which does not support ignoring of non-printable characters in the prompt
|
|
||||||
// using non-printable characters in the prompt will lead to wrong prompt lengths being calculated
|
|
||||||
// we will therefore disable colorful prompts for MacOS.
|
|
||||||
// ........................................................................................
|
|
||||||
|
|
||||||
goodPrompt = badPrompt = dynamicPrompt;
|
|
||||||
|
|
||||||
#elif _WIN32
|
|
||||||
|
|
||||||
// ........................................................................................
|
// ........................................................................................
|
||||||
// Windows console is not coloured by escape sequences. So the method given below will not
|
// Windows console is not coloured by escape sequences. So the method given below will not
|
||||||
|
@ -1637,7 +1584,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* input = Console->prompt(promptError ? badPrompt.c_str() : goodPrompt.c_str());
|
char* input = console.prompt(promptError ? badPrompt.c_str() : goodPrompt.c_str());
|
||||||
|
|
||||||
if (input == nullptr) {
|
if (input == nullptr) {
|
||||||
break;
|
break;
|
||||||
|
@ -1666,7 +1613,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console->addHistory(input);
|
console.addHistory(input);
|
||||||
|
|
||||||
v8::TryCatch tryCatch;
|
v8::TryCatch tryCatch;
|
||||||
|
|
||||||
|
@ -1712,10 +1659,6 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Console->close();
|
|
||||||
delete Console;
|
|
||||||
Console = nullptr;
|
|
||||||
|
|
||||||
BaseClient.printLine("");
|
BaseClient.printLine("");
|
||||||
|
|
||||||
BaseClient.printByeBye();
|
BaseClient.printByeBye();
|
||||||
|
|
160
configure.ac
160
configure.ac
|
@ -206,7 +206,165 @@ dnl ----------------------------------------------------------------------------
|
||||||
dnl READLINE
|
dnl READLINE
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
m4_include([m4/external.readline])
|
AC_MSG_NOTICE([--------------------------------------------------------------------------------])
|
||||||
|
AC_MSG_NOTICE([CHECKING FOR READLINE])
|
||||||
|
AC_MSG_NOTICE([--------------------------------------------------------------------------------])
|
||||||
|
|
||||||
|
AC_LANG(C)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(readline,
|
||||||
|
AS_HELP_STRING([--enable-readline], [enable readline support (default: yes)]),
|
||||||
|
tr_READLINE="$enableval",
|
||||||
|
tr_READLINE="maybe"
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "x$tr_DARWIN" = xyes; then
|
||||||
|
READLINE=/usr/local/opt/readline
|
||||||
|
READLINE_CPPFLAGS="-I$READLINE/include"
|
||||||
|
READLINE_LDFLAGS="-L$READLINE/lib"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_WITH(readline,
|
||||||
|
AS_HELP_STRING([--with-readline=DIR], [where the readline library and includes are located]),
|
||||||
|
[READLINE_CPPFLAGS="-I$withval/include"
|
||||||
|
READLINE_LDFLAGS="-L$withval/lib"
|
||||||
|
READLINE="$withval"]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_ARG_WITH(readline-lib,
|
||||||
|
AS_HELP_STRING([--with-readline-lib=DIR], [where the readline library is located]),
|
||||||
|
[READLINE_LDFLAGS="-L$withval"]
|
||||||
|
)
|
||||||
|
|
||||||
|
dnl checks for the READLINE library
|
||||||
|
|
||||||
|
if test "x$READLINE_CPPFLAGS" != x; then
|
||||||
|
TR_INCLUDE([READLINE_CPPFLAGS])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl save flags
|
||||||
|
|
||||||
|
SAVE_CPPFLAGS="$CPPFLAGS"
|
||||||
|
CPPFLAGS="$CPPFLAGS $READLINE_CPPFLAGS"
|
||||||
|
|
||||||
|
SAVE_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS $READLINE_LDFLAGS"
|
||||||
|
|
||||||
|
SAVE_LIBS="$LIBS"
|
||||||
|
|
||||||
|
dnl check for header and library
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes -o "x$tr_READLINE" = xmaybe; then
|
||||||
|
ch_READLINE="$tr_READLINE"
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS(readline/readline.h, [tr_READLINE="yes"], [tr_READLINE="no"])
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes; then
|
||||||
|
AC_CHECK_LIB([readline], [readline], [READLINE_LIBS="-lreadline" tr_READLINE="yes"], [tr_READLINE="no"])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([READLINE support])
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" != xyes; then
|
||||||
|
AC_MSG_RESULT([not found])
|
||||||
|
|
||||||
|
if test "x$ch_READLINE" = xyes; then
|
||||||
|
AC_MSG_ERROR([Please install readline support])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([readline])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_CHECKING([READLINE support])
|
||||||
|
AC_MSG_RESULT([disabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl grep readline version number
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes; then
|
||||||
|
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <readline/readline.h>
|
||||||
|
|
||||||
|
main () {
|
||||||
|
#if defined(RL_VERSION_MAJOR) && defined(RL_VERSION_MINOR)
|
||||||
|
long sdnhg36ed = RL_VERSION_MAJOR RL_VERSION_MINOR ;
|
||||||
|
#else
|
||||||
|
long sdnhg36ed = RL_READLINE_VERSION hex ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([READLINE version])
|
||||||
|
eval "$ac_cpp conftest.$ac_ext" | fgrep "long sdnhg36ed" | awk '{print $4 "." $5}' > conftest.output
|
||||||
|
READLINE_VERSION=`cat conftest.output`
|
||||||
|
|
||||||
|
if test -z "$READLINE_VERSION"; then
|
||||||
|
AC_MSG_ERROR([Readline support is not working. Please re-install readline support])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$READLINE_VERSION])
|
||||||
|
rm -f conftest*
|
||||||
|
|
||||||
|
if test "x$tr_DARWIN" = xyes; then
|
||||||
|
case "$READLINE_VERSION" in
|
||||||
|
6.*|5.*)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR([Please install readline 6 from brew. If you have a non-standard brew location, use "--with-readline".])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl restore flags and set readline flags
|
||||||
|
|
||||||
|
LIBS="$SAVE_LIBS"
|
||||||
|
LDFLAGS="$SAVE_LDFLAGS"
|
||||||
|
CPPFLAGS="$SAVE_CPPFLAGS"
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes; then
|
||||||
|
CPPFLAGS="$CPPFLAGS -DHAVE_READLINE=1"
|
||||||
|
READLINE_CPPFLAGS="${READLINE_CPPFLAGS} -DTRI_READLINE_VERSION='\"${READLINE_VERSION}\"'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(ENABLE_READLINE, test "x$tr_READLINE" = xyes)
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes; then
|
||||||
|
AC_DEFINE_UNQUOTED(TRI_HAVE_READLINE, 1, [true if readline is used])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl add substitutions
|
||||||
|
|
||||||
|
AC_SUBST(READLINE_VERSION)
|
||||||
|
AC_SUBST(READLINE_CPPFLAGS)
|
||||||
|
AC_SUBST(READLINE_LDFLAGS)
|
||||||
|
AC_SUBST(READLINE_LIBS)
|
||||||
|
|
||||||
|
dnl informational output
|
||||||
|
|
||||||
|
if test "x$tr_READLINE" = xyes; then
|
||||||
|
LIB_INFO="$LIB_INFO|READLINE VERSION: ${READLINE_VERSION}"
|
||||||
|
|
||||||
|
LIB_INFO="$LIB_INFO|READLINE_CPPFLAGS: ${READLINE_CPPFLAGS}"
|
||||||
|
LIB_INFO="$LIB_INFO|READLINE_LDLIBS: ${READLINE_LDLIBS}"
|
||||||
|
LIB_INFO="$LIB_INFO|READLINE_LIBS: ${READLINE_LIBS}"
|
||||||
|
|
||||||
|
elif test "x$tr_READLINE" = xlinenoise; then
|
||||||
|
LIB_INFO="$LIB_INFO|LINENOISE VERSION: ${READLINE_VERSION}"
|
||||||
|
|
||||||
|
LIB_INFO="$LIB_INFO|LINENOISE_CPPFLAGS: ${READLINE_CPPFLAGS}"
|
||||||
|
LIB_INFO="$LIB_INFO|LINENOISE_LDLIBS: ${READLINE_LDLIBS}"
|
||||||
|
LIB_INFO="$LIB_INFO|LINENOISE_LIBS: ${READLINE_LIBS}"
|
||||||
|
|
||||||
|
else
|
||||||
|
LIB_INFO="$LIB_INFO|READLINE VERSION: disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIB_INFO="$LIB_INFO|."
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl OPENSSL
|
dnl OPENSSL
|
||||||
|
|
|
@ -104,20 +104,11 @@ if ENABLE_READLINE
|
||||||
lib_libarango_a_SOURCES += \
|
lib_libarango_a_SOURCES += \
|
||||||
lib/Utilities/ReadlineShell.cpp
|
lib/Utilities/ReadlineShell.cpp
|
||||||
|
|
||||||
else
|
|
||||||
if ENABLE_LINENOISE
|
|
||||||
|
|
||||||
lib_libarango_a_SOURCES += \
|
|
||||||
lib/Utilities/LinenoiseShell.cpp \
|
|
||||||
3rdParty/linenoise/linenoise.c \
|
|
||||||
3rdParty/linenoise/utf8.c
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
lib_libarango_a_SOURCES += \
|
lib_libarango_a_SOURCES += \
|
||||||
lib/Utilities/DummyShell.cpp
|
lib/Utilities/DummyShell.cpp
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
### @brief library "libarango.a", client part
|
### @brief library "libarango.a", client part
|
||||||
|
|
|
@ -341,7 +341,8 @@ ApplicationScheduler::ApplicationScheduler (ApplicationServer* applicationServer
|
||||||
_multiSchedulerAllowed(true),
|
_multiSchedulerAllowed(true),
|
||||||
_nrSchedulerThreads(4),
|
_nrSchedulerThreads(4),
|
||||||
_backend(0),
|
_backend(0),
|
||||||
_descriptorMinimum(256) {
|
_descriptorMinimum(256),
|
||||||
|
_disableControlCHandler(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -416,6 +417,14 @@ void ApplicationScheduler::setProcessorAffinity (const vector<size_t>& cores) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief disables CTRL-C handling (because taken over by console input)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ApplicationScheduler::disableControlCHandler () {
|
||||||
|
_disableControlCHandler = true;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- ApplicationFeature methods
|
// --SECTION-- ApplicationFeature methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -557,9 +566,7 @@ void ApplicationScheduler::stop () {
|
||||||
static size_t const MAX_TRIES = 10;
|
static size_t const MAX_TRIES = 10;
|
||||||
|
|
||||||
// remove all helper tasks
|
// remove all helper tasks
|
||||||
for (vector<Task*>::iterator i = _tasks.begin(); i != _tasks.end(); ++i) {
|
for (auto& task : _tasks) {
|
||||||
Task* task = *i;
|
|
||||||
|
|
||||||
_scheduler->destroyTask(task);
|
_scheduler->destroyTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +617,7 @@ void ApplicationScheduler::buildSchedulerReporter () {
|
||||||
Task* reporter = new SchedulerReporterTask(_scheduler, _reportInterval);
|
Task* reporter = new SchedulerReporterTask(_scheduler, _reportInterval);
|
||||||
|
|
||||||
_scheduler->registerTask(reporter);
|
_scheduler->registerTask(reporter);
|
||||||
_tasks.push_back(reporter);
|
_tasks.emplace_back(reporter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,23 +630,25 @@ void ApplicationScheduler::buildControlCHandler () {
|
||||||
LOG_FATAL_AND_EXIT("no scheduler is known, cannot create control-c handler");
|
LOG_FATAL_AND_EXIT("no scheduler is known, cannot create control-c handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
// control C handler
|
if (! _disableControlCHandler) {
|
||||||
Task* controlC = new ControlCTask(_applicationServer);
|
// control C handler
|
||||||
|
Task* controlC = new ControlCTask(_applicationServer);
|
||||||
|
|
||||||
_scheduler->registerTask(controlC);
|
_scheduler->registerTask(controlC);
|
||||||
_tasks.push_back(controlC);
|
_tasks.emplace_back(controlC);
|
||||||
|
}
|
||||||
|
|
||||||
// hangup handler
|
// hangup handler
|
||||||
Task* hangup = new HangupTask();
|
Task* hangup = new HangupTask();
|
||||||
|
|
||||||
_scheduler->registerTask(hangup);
|
_scheduler->registerTask(hangup);
|
||||||
_tasks.push_back(hangup);
|
_tasks.emplace_back(hangup);
|
||||||
|
|
||||||
// sigusr handler
|
// sigusr handler
|
||||||
Task* sigusr = new Sigusr1Task(this);
|
Task* sigusr = new Sigusr1Task(this);
|
||||||
|
|
||||||
_scheduler->registerTask(sigusr);
|
_scheduler->registerTask(sigusr);
|
||||||
_tasks.push_back(sigusr);
|
_tasks.emplace_back(sigusr);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -112,6 +112,12 @@ namespace triagens {
|
||||||
|
|
||||||
void setProcessorAffinity (const std::vector<size_t>& cores);
|
void setProcessorAffinity (const std::vector<size_t>& cores);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief disables CTRL-C handling (because taken over by console input)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void disableControlCHandler ();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- ApplicationFeature methods
|
// --SECTION-- ApplicationFeature methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -257,6 +263,12 @@ namespace triagens {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint32_t _descriptorMinimum;
|
uint32_t _descriptorMinimum;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief disables CTRL-C handling (because taken over by console input)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool _disableControlCHandler;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,8 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "LineEditor.h"
|
#include "LineEditor.h"
|
||||||
#include "ShellImplementation.h"
|
#include "Utilities/ShellImplementation.h"
|
||||||
#include "Completer.h"
|
#include "Utilities/Completer.h"
|
||||||
|
|
||||||
#include "Basics/tri-strings.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace triagens;
|
using namespace triagens;
|
||||||
|
@ -50,7 +48,7 @@ using namespace triagens;
|
||||||
|
|
||||||
LineEditor::LineEditor (std::string const& history)
|
LineEditor::LineEditor (std::string const& history)
|
||||||
: _history(history) {
|
: _history(history) {
|
||||||
_shellImpl = 0;
|
_shellImpl = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -121,6 +119,14 @@ bool LineEditor::writeHistory () {
|
||||||
return _shellImpl->writeHistory();
|
return _shellImpl->writeHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief send a signal to the shell implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void LineEditor::signal () {
|
||||||
|
_shellImpl->signal();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief sort the alternatives results vector
|
/// @brief sort the alternatives results vector
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -41,66 +41,67 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor
|
/// @brief line editor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
class ShellImplementation;
|
class ShellImplementation;
|
||||||
|
|
||||||
class LineEditor {
|
class LineEditor {
|
||||||
LineEditor(LineEditor const&);
|
LineEditor(LineEditor const&);
|
||||||
LineEditor& operator= (LineEditor const&);
|
LineEditor& operator= (LineEditor const&);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public constants
|
// --SECTION-- public constants
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief number of history entries
|
/// @brief number of history entries
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const int MAX_HISTORY_ENTRIES = 1000;
|
static const int MAX_HISTORY_ENTRIES = 1000;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors and destructors
|
// --SECTION-- constructors and destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief constructor
|
/// @brief constructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
LineEditor (std::string const& history);
|
LineEditor (std::string const& history);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destructor
|
/// @brief destructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual ~LineEditor ();
|
virtual ~LineEditor ();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor open
|
/// @brief line editor open
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool open (bool autoComplete);
|
bool open (bool autoComplete);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor shutdown
|
/// @brief line editor shutdown
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool close ();
|
bool close ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor prompt
|
/// @brief line editor prompt
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
char* prompt (char const*);
|
char* prompt (char const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the history file path
|
/// @brief get the history file path
|
||||||
|
@ -109,57 +110,60 @@ namespace triagens {
|
||||||
/// the local file _historyFilename.
|
/// the local file _historyFilename.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::string historyPath ();
|
std::string historyPath ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief add to history
|
/// @brief add to history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void addHistory (const char*);
|
void addHistory (const char*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief save the history
|
/// @brief save the history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool writeHistory ();
|
bool writeHistory ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief send a signal to the shell implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void signal ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief sort the alternatives results vector
|
/// @brief sort the alternatives results vector
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void sortAlternatives (std::vector<std::string>&);
|
static void sortAlternatives (std::vector<std::string>&);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- protected methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @brief arranges for the correct creation of the the ShellImplementation
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
void prepareShell ();
|
||||||
// --SECTION-- protected methods
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief arranges for the correct creation of the the ShellImplementation
|
/// @brief creates a concrete Shell with the correct parameter (Completer!!)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void prepareShell ();
|
virtual void initializeShell () = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
/// @brief creates a concrete Shell with the correct parameter (Completer!!)
|
// --SECTION-- protected variables
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
virtual void initializeShell () = 0;
|
protected:
|
||||||
|
|
||||||
protected:
|
ShellImplementation* _shellImpl;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
std::string _history;
|
||||||
// --SECTION-- protected variables
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ShellImplementation * _shellImpl;
|
|
||||||
|
|
||||||
std::string _history;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,19 +27,13 @@
|
||||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
#include "ReadlineShell.h"
|
#include "ReadlineShell.h"
|
||||||
|
#include "Basics/tri-strings.h"
|
||||||
#include "Utilities/Completer.h"
|
#include "Utilities/Completer.h"
|
||||||
#include "Utilities/LineEditor.h"
|
#include "Utilities/LineEditor.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
#include "Basics/tri-strings.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -97,17 +91,76 @@ namespace {
|
||||||
// --SECTION-- class ReadlineShell
|
// --SECTION-- class ReadlineShell
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief callback function that readline calls periodically while waiting
|
||||||
|
/// for input and being idle
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static int ReadlineIdle () {
|
||||||
|
auto instance = ReadlineShell::instance();
|
||||||
|
|
||||||
|
if (instance != nullptr &&
|
||||||
|
instance->getLoopState() == 2) {
|
||||||
|
rl_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief callback function that readline calls when the input is completed
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void ReadlineInputCompleted (char* value) {
|
||||||
|
// if we don't clear the prompt here, readline will display it instantly
|
||||||
|
// the user pressed the return key. this is not desired because when we
|
||||||
|
// wait for input afterwards, readline will display the prompt again
|
||||||
|
rl_set_prompt("");
|
||||||
|
|
||||||
|
auto instance = ReadlineShell::instance();
|
||||||
|
|
||||||
|
if (instance == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->getLoopState() == 2) {
|
||||||
|
// CTRL-C received
|
||||||
|
rl_done = 1;
|
||||||
|
// replace current input with nothing
|
||||||
|
rl_replace_line("", 0);
|
||||||
|
|
||||||
|
if (value != nullptr) {
|
||||||
|
// avoid memleak
|
||||||
|
TRI_SystemFree(value);
|
||||||
|
}
|
||||||
|
instance->setLastInput(nullptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instance->setLoopState(1);
|
||||||
|
instance->setLastInput(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors and destructors
|
// --SECTION-- constructors and destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief (sole) instance of a ReadlineShell
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::atomic<ReadlineShell*> ReadlineShell::_instance(nullptr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief constructs a new editor
|
/// @brief constructs a new editor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ReadlineShell::ReadlineShell (std::string const& history,
|
ReadlineShell::ReadlineShell (std::string const& history,
|
||||||
Completer* completer)
|
Completer* completer)
|
||||||
: ShellImplementation(history, completer) {
|
: ShellImplementation(history, completer),
|
||||||
|
_loopState(0),
|
||||||
|
_lastInput(nullptr),
|
||||||
|
_lastInputWasEmpty(false) {
|
||||||
|
|
||||||
COMPLETER = completer;
|
COMPLETER = completer;
|
||||||
|
|
||||||
|
@ -116,11 +169,19 @@ ReadlineShell::ReadlineShell (std::string const& history,
|
||||||
rl_attempted_completion_function = AttemptedCompletion;
|
rl_attempted_completion_function = AttemptedCompletion;
|
||||||
rl_completer_word_break_characters = WordBreakCharacters;
|
rl_completer_word_break_characters = WordBreakCharacters;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
// register ourselves
|
||||||
rl_catch_signals = 0;
|
TRI_ASSERT(_instance == nullptr);
|
||||||
#endif
|
_instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destructor
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ReadlineShell::~ReadlineShell () {
|
||||||
|
// unregister ourselves
|
||||||
|
_instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
|
@ -188,11 +249,6 @@ bool ReadlineShell::close () {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
// reset state of the terminal to what it was before readline()
|
|
||||||
rl_cleanup_after_signal();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,8 +308,46 @@ bool ReadlineShell::writeHistory () {
|
||||||
return (write_history(historyPath().c_str()) == 0);
|
return (write_history(historyPath().c_str()) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char * ReadlineShell::getLine (char const * input) {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
return readline(input);
|
/// @brief read a line from the input
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* ReadlineShell::getLine (char const* prompt) {
|
||||||
|
setLoopState(0);
|
||||||
|
rl_event_hook = ReadlineIdle;
|
||||||
|
rl_callback_handler_install(prompt, ReadlineInputCompleted);
|
||||||
|
|
||||||
|
int state;
|
||||||
|
do {
|
||||||
|
rl_callback_read_char();
|
||||||
|
state = getLoopState();
|
||||||
|
}
|
||||||
|
while (state == 0);
|
||||||
|
rl_callback_handler_remove();
|
||||||
|
|
||||||
|
if (state == 2) {
|
||||||
|
if (_lastInputWasEmpty) {
|
||||||
|
setLastInput(nullptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setLastInput(strdup(""));
|
||||||
|
_lastInputWasEmpty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_lastInputWasEmpty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief handle a signal
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ReadlineShell::signal () {
|
||||||
|
// set the global state, so the readline input loop can react on it
|
||||||
|
setLoopState(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,9 +31,8 @@
|
||||||
#define ARANGODB_UTILITIES_READLINE_SHELL_H 1
|
#define ARANGODB_UTILITIES_READLINE_SHELL_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
|
#include "Utilities/Completer.h"
|
||||||
#include "ShellImplementation.h"
|
#include "Utilities/ShellImplementation.h"
|
||||||
#include "Completer.h"
|
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
|
|
||||||
|
@ -44,22 +43,29 @@ namespace triagens {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// public constructor
|
/// @brief constructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ReadlineShell (std::string const& history, Completer *);
|
ReadlineShell (std::string const& history,
|
||||||
|
Completer*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destructor
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
~ReadlineShell ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor open
|
/// @brief line editor open
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool open (bool autoComplete);
|
bool open (bool autoComplete) override final;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor shutdown
|
/// @brief line editor shutdown
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool close ();
|
bool close () override final;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the history file path
|
/// @brief get the history file path
|
||||||
|
@ -68,26 +74,94 @@ namespace triagens {
|
||||||
/// the local file _historyFilename.
|
/// the local file _historyFilename.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual std::string historyPath ();
|
std::string historyPath () override final;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief add to history
|
/// @brief add to history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual void addHistory (char const*);
|
void addHistory (char const*) override final;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief save the history
|
/// @brief save the history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool writeHistory ();
|
bool writeHistory () override final;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief todo!!
|
/// @brief read a line from the input
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual char * getLine (char const *);
|
char* getLine (char const*) override final;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief handle a signal
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void signal () override final;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set the last input value
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setLastInput (char* input) {
|
||||||
|
_lastInput = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get the current input loop state
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int getLoopState () const {
|
||||||
|
return _loopState;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief set the current input loop state
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void setLoopState (int state) {
|
||||||
|
_loopState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief return the currently active shell instance
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static ReadlineShell* instance () {
|
||||||
|
return _instance.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief current state of input loop (may be affected by out-of-band signals)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::atomic<int> _loopState;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief last value entered by user. memory is allocated by readline
|
||||||
|
/// and must be freed using TRI_SystemFree()
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* _lastInput;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the input from the previous invocation was a CTRL-C
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool _lastInputWasEmpty;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief system-wide instance of the ReadlineShell
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static std::atomic<ReadlineShell*> _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace triagens;
|
using namespace triagens;
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
ShellImplementation* ShellImplFactory::buildShell (string const & history,
|
ShellImplementation* ShellImplFactory::buildShell (std::string const& history,
|
||||||
Completer* completer) {
|
Completer* completer) {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
//under windows the readline is not compilable
|
// under Windows the readline is not compilable
|
||||||
return new LinenoiseShell(history, completer);
|
return new LinenoiseShell(history, completer);
|
||||||
#elif defined TRI_HAVE_LINENOISE
|
#elif defined TRI_HAVE_LINENOISE
|
||||||
return new LinenoiseShell(history, completer);
|
return new LinenoiseShell(history, completer);
|
||||||
|
@ -57,7 +55,19 @@ ShellImplementation* ShellImplFactory::buildShell (string const & history,
|
||||||
// last resort!
|
// last resort!
|
||||||
return new DummyShell(history, completer);
|
return new DummyShell(history, completer);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShellImplFactory::hasCtrlCHandler () {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// under Windows the readline is not compilable
|
||||||
|
return false;
|
||||||
|
#elif defined TRI_HAVE_LINENOISE
|
||||||
|
return false;
|
||||||
|
#elif defined TRI_HAVE_READLINE
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -43,10 +43,16 @@ namespace triagens {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief check if line is complete
|
/// @brief creates a shell
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ShellImplementation * buildShell (std::string const & history, Completer *);
|
static ShellImplementation* buildShell (std::string const& history, Completer*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the shell will have a CTRL-C handler
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static bool hasCtrlCHandler ();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,14 @@ char* ShellImplementation::prompt (char const* the_prompt) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief handle a signal
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ShellImplementation::signal () {
|
||||||
|
// do nothing special
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -106,6 +106,12 @@ namespace triagens {
|
||||||
|
|
||||||
virtual char* getLine (const char*) = 0;
|
virtual char* getLine (const char*) = 0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief handle a signal
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
virtual void signal ();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- protected variables
|
// --SECTION-- protected variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -28,16 +28,34 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "V8LineEditor.h"
|
#include "V8LineEditor.h"
|
||||||
#include "Utilities/ShellImplFactory.h"
|
#include "Basics/logging.h"
|
||||||
|
|
||||||
#include "Basics/tri-strings.h"
|
|
||||||
#include "V8/v8-utils.h"
|
|
||||||
|
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
|
#include "Basics/tri-strings.h"
|
||||||
|
#include "Utilities/ShellImplFactory.h"
|
||||||
|
#include "V8/v8-utils.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace triagens;
|
using namespace triagens;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- helper functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief signal handler for CTRL-C
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
static void SignalHandler (int signal) {
|
||||||
|
// get the instance of the console
|
||||||
|
auto instance = triagens::V8LineEditor::instance();
|
||||||
|
|
||||||
|
if (instance != nullptr) {
|
||||||
|
instance->signal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- class V8Completer
|
// --SECTION-- class V8Completer
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -306,6 +324,8 @@ void V8Completer::getAlternatives (char const * text,
|
||||||
// --SECTION-- class V8LineEditor
|
// --SECTION-- class V8LineEditor
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
std::atomic<V8LineEditor*> V8LineEditor::_instance(nullptr);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors and destructors
|
// --SECTION-- constructors and destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -314,8 +334,18 @@ void V8Completer::getAlternatives (char const * text,
|
||||||
/// @brief constructs a new editor
|
/// @brief constructs a new editor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8LineEditor::V8LineEditor (v8::Handle<v8::Context> context, std::string const& history)
|
V8LineEditor::V8LineEditor (v8::Handle<v8::Context> context,
|
||||||
: LineEditor(history), _context(context), _completer(V8Completer()) {
|
std::string const& history)
|
||||||
|
: LineEditor(history),
|
||||||
|
_context(context),
|
||||||
|
_completer(V8Completer()) {
|
||||||
|
|
||||||
|
// register global instance
|
||||||
|
|
||||||
|
TRI_ASSERT(_instance.load() == nullptr);
|
||||||
|
_instance.store(this);
|
||||||
|
|
||||||
|
setupCtrlCHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -323,7 +353,30 @@ V8LineEditor::V8LineEditor (v8::Handle<v8::Context> context, std::string const&
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8LineEditor::~V8LineEditor () {
|
V8LineEditor::~V8LineEditor () {
|
||||||
// nothing
|
// unregister global instance
|
||||||
|
TRI_ASSERT(_instance.load() != nullptr);
|
||||||
|
_instance.store(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief setup a signal handler for CTRL-C
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void V8LineEditor::setupCtrlCHandler () {
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (ShellImplFactory::hasCtrlCHandler()) {
|
||||||
|
struct sigaction sa;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler = &SignalHandler;
|
||||||
|
|
||||||
|
int res = sigaction(SIGINT, &sa, 0);
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
LOG_ERROR("unable to install signal handler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -331,8 +384,7 @@ V8LineEditor::~V8LineEditor () {
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void V8LineEditor::initializeShell () {
|
void V8LineEditor::initializeShell () {
|
||||||
ShellImplFactory factory;
|
_shellImpl = ShellImplFactory::buildShell(_history, &_completer);
|
||||||
_shellImpl = factory.buildShell(_history, &_completer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -103,7 +103,8 @@ namespace triagens {
|
||||||
/// @brief constructor
|
/// @brief constructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8LineEditor (v8::Handle<v8::Context>, std::string const& history);
|
V8LineEditor (v8::Handle<v8::Context>,
|
||||||
|
std::string const& history);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destructor
|
/// @brief destructor
|
||||||
|
@ -111,18 +112,32 @@ namespace triagens {
|
||||||
|
|
||||||
~V8LineEditor ();
|
~V8LineEditor ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the global instance of the editor
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static V8LineEditor* instance () {
|
||||||
|
return _instance.load();
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- protected methods
|
// --SECTION-- protected methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief creates a concrete Shell with the correct parameter (Completer!!)
|
/// @brief creates a concrete Shell with the correct parameter (Completer!!)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void initializeShell () override;
|
void initializeShell () override;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief setup a signal handler for CTRL-C
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void setupCtrlCHandler ();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private variables
|
// --SECTION-- private variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -135,7 +150,17 @@ namespace triagens {
|
||||||
|
|
||||||
v8::Handle<v8::Context> _context;
|
v8::Handle<v8::Context> _context;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the completer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
V8Completer _completer;
|
V8Completer _completer;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the active instance of the editor
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static std::atomic<V8LineEditor*> _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,161 +37,26 @@ AC_ARG_WITH(readline-lib,
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl checks for the READLINE library
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
if test "x$READLINE_CPPFLAGS" != x; then
|
|
||||||
TR_INCLUDE([READLINE_CPPFLAGS])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl save flags
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
SAVE_CPPFLAGS="$CPPFLAGS"
|
|
||||||
CPPFLAGS="$CPPFLAGS $READLINE_CPPFLAGS"
|
|
||||||
|
|
||||||
SAVE_LDFLAGS="$LDFLAGS"
|
|
||||||
LDFLAGS="$LDFLAGS $READLINE_LDFLAGS"
|
|
||||||
|
|
||||||
SAVE_LIBS="$LIBS"
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl check for header and library
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes -o "x$tr_READLINE" = xmaybe; then
|
|
||||||
ch_READLINE="$tr_READLINE"
|
|
||||||
|
|
||||||
AC_CHECK_HEADERS(readline/readline.h, [tr_READLINE="yes"], [tr_READLINE="no"])
|
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes; then
|
|
||||||
AC_CHECK_LIB([readline], [readline], [READLINE_LIBS="-lreadline" tr_READLINE="yes"], [tr_READLINE="no"])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([READLINE support])
|
|
||||||
|
|
||||||
if test "x$tr_READLINE" != xyes; then
|
|
||||||
AC_MSG_RESULT([not found])
|
|
||||||
|
|
||||||
if test "x$ch_READLINE" = xyes; then
|
|
||||||
AC_MSG_ERROR([Please install readline support])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([readline])
|
|
||||||
fi
|
|
||||||
|
|
||||||
elif test "x$tr_READLINE" = xlinenoise; then
|
|
||||||
READLINE_CPPFLAGS="-I${srcdir}/3rdParty/linenoise -DUSE_UTF8"
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([READLINE support])
|
|
||||||
AC_MSG_RESULT([linenoise])
|
|
||||||
|
|
||||||
else
|
|
||||||
AC_MSG_CHECKING([READLINE support])
|
|
||||||
AC_MSG_RESULT([disabled])
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl grep readline version number
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes; then
|
|
||||||
|
|
||||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
||||||
/* end confdefs.h. */
|
|
||||||
#include <readline/readline.h>
|
|
||||||
|
|
||||||
main () {
|
|
||||||
#if defined(RL_VERSION_MAJOR) && defined(RL_VERSION_MINOR)
|
|
||||||
long sdnhg36ed = RL_VERSION_MAJOR RL_VERSION_MINOR ;
|
|
||||||
#else
|
|
||||||
long sdnhg36ed = RL_READLINE_VERSION hex ;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
_ACEOF
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([READLINE version])
|
|
||||||
eval "$ac_cpp conftest.$ac_ext" | fgrep "long sdnhg36ed" | awk '{print $4 "." $5}' > conftest.output
|
|
||||||
READLINE_VERSION=`cat conftest.output`
|
|
||||||
|
|
||||||
if test -z "$READLINE_VERSION"; then
|
|
||||||
AC_MSG_ERROR([Readline support is not working. Please re-install readline support])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$READLINE_VERSION])
|
|
||||||
rm -f conftest*
|
|
||||||
|
|
||||||
elif test "x$tr_READLINE" = xlinenoise; then
|
|
||||||
READLINE_VERSION="linenoise"
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([READLINE version])
|
|
||||||
AC_MSG_RESULT([$READLINE_VERSION])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl restore flags
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
LIBS="$SAVE_LIBS"
|
|
||||||
LDFLAGS="$SAVE_LDFLAGS"
|
|
||||||
CPPFLAGS="$SAVE_CPPFLAGS"
|
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes; then
|
|
||||||
CPPFLAGS="$CPPFLAGS -DHAVE_READLINE=1"
|
|
||||||
READLINE_CPPFLAGS="${READLINE_CPPFLAGS} -DTRI_READLINE_VERSION='\"${READLINE_VERSION}\"'"
|
|
||||||
|
|
||||||
elif test "x$tr_READLINE" = xlinenoise; then
|
|
||||||
READLINE_CPPFLAGS="${READLINE_CPPFLAGS} -DTRI_HAVE_LINENOISE -DTRI_READLINE_VERSION='\"${READLINE_VERSION}\"'"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl add substitutions
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
AM_CONDITIONAL(ENABLE_READLINE, test "x$tr_READLINE" = xyes)
|
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes; then
|
|
||||||
AC_DEFINE_UNQUOTED(TRI_HAVE_READLINE, 1, [true if readline is used])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL(ENABLE_LINENOISE, test "x$tr_READLINE" = xlinenoise)
|
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xlinenoise; then
|
|
||||||
AC_DEFINE_UNQUOTED(TRI_HAVE_LINENOISE, 1, [true if linenoise is used])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_SUBST(READLINE_VERSION)
|
|
||||||
AC_SUBST(READLINE_CPPFLAGS)
|
|
||||||
AC_SUBST(READLINE_LDFLAGS)
|
|
||||||
AC_SUBST(READLINE_LIBS)
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl informational output
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
||||||
if test "x$tr_READLINE" = xyes; then
|
|
||||||
LIB_INFO="$LIB_INFO|READLINE VERSION: ${READLINE_VERSION}"
|
|
||||||
|
|
||||||
LIB_INFO="$LIB_INFO|READLINE_CPPFLAGS: ${READLINE_CPPFLAGS}"
|
|
||||||
LIB_INFO="$LIB_INFO|READLINE_LDLIBS: ${READLINE_LDLIBS}"
|
|
||||||
LIB_INFO="$LIB_INFO|READLINE_LIBS: ${READLINE_LIBS}"
|
|
||||||
|
|
||||||
elif test "x$tr_READLINE" = xlinenoise; then
|
|
||||||
LIB_INFO="$LIB_INFO|LINENOISE VERSION: ${READLINE_VERSION}"
|
|
||||||
|
|
||||||
LIB_INFO="$LIB_INFO|LINENOISE_CPPFLAGS: ${READLINE_CPPFLAGS}"
|
|
||||||
LIB_INFO="$LIB_INFO|LINENOISE_LDLIBS: ${READLINE_LDLIBS}"
|
|
||||||
LIB_INFO="$LIB_INFO|LINENOISE_LIBS: ${READLINE_LIBS}"
|
|
||||||
|
|
||||||
else
|
|
||||||
LIB_INFO="$LIB_INFO|READLINE VERSION: disabled"
|
|
||||||
fi
|
|
||||||
|
|
||||||
LIB_INFO="$LIB_INFO|."
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
dnl --SECTION-- END-OF-FILE
|
dnl --SECTION-- END-OF-FILE
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue