mirror of https://gitee.com/bigwinds/arangodb
moved to strings, fixed #1432: arangosh doesn't ignore prefixed ....> on paste
This commit is contained in:
parent
f5d301a814
commit
9de6bd39db
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0.2. */
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -110,18 +110,20 @@ extern int Aqldebug;
|
|||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 17 "arangod/Aql/grammar.y" /* yacc.c:1909 */
|
||||
#line 17 "arangod/Aql/grammar.y" /* yacc.c:1915 */
|
||||
|
||||
triagens::aql::AstNode* node;
|
||||
char* strval;
|
||||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 124 "arangod/Aql/grammar.hpp" /* yacc.c:1909 */
|
||||
#line 124 "arangod/Aql/grammar.hpp" /* yacc.c:1915 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
|
|
@ -45,8 +45,10 @@
|
|||
using namespace triagens::basics;
|
||||
using namespace triagens::rest;
|
||||
using namespace triagens::arango;
|
||||
using namespace arangodb;
|
||||
using namespace std;
|
||||
|
||||
std::atomic<triagens::V8LineEditor*> triagens::arango::serverConsole(nullptr);
|
||||
std::atomic<V8LineEditor*> triagens::arango::serverConsole(nullptr);
|
||||
triagens::basics::Mutex triagens::arango::serverConsoleMutex;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -180,26 +182,22 @@ start_pretty_print();
|
|||
nrCommands = 0;
|
||||
}
|
||||
|
||||
char* input;
|
||||
string input;
|
||||
bool eof;
|
||||
{
|
||||
MUTEX_LOCKER(serverConsoleMutex);
|
||||
input = console.prompt("arangod> ");
|
||||
input = console.prompt("arangod> ", "arangod", eof);
|
||||
}
|
||||
|
||||
if (eof) {
|
||||
_userAborted = true;
|
||||
}
|
||||
|
||||
if (_userAborted) {
|
||||
if (input != nullptr) {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (input == nullptr) {
|
||||
_userAborted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*input == '\0') {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
if (input.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -210,8 +208,7 @@ start_pretty_print();
|
|||
v8::TryCatch tryCatch;
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
TRI_ExecuteJavaScriptString(isolate, localContext, TRI_V8_STRING(input), name, true);
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
TRI_ExecuteJavaScriptString(isolate, localContext, TRI_V8_STRING(input.c_str()), name, true);
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
std::cout << TRI_StringifyV8Exception(isolate, &tryCatch);
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace triagens {
|
|||
/// @brief the line editor object for use in debugging
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern std::atomic<V8LineEditor*> serverConsole;
|
||||
extern std::atomic<arangodb::V8LineEditor*> serverConsole;
|
||||
extern triagens::basics::Mutex serverConsoleMutex;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -74,6 +74,7 @@ using namespace std;
|
|||
using namespace triagens::basics;
|
||||
using namespace triagens::arango;
|
||||
using namespace triagens::rest;
|
||||
using namespace arangodb;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- forward declarations
|
||||
|
@ -620,7 +621,7 @@ static void JS_EnableNativeBacktraces (const v8::FunctionCallbackInfo<v8::Value>
|
|||
TRI_V8_TRY_CATCH_END
|
||||
}
|
||||
|
||||
extern triagens::V8LineEditor* theConsole;
|
||||
extern V8LineEditor* theConsole;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief starts a debugging console
|
||||
|
@ -638,20 +639,20 @@ static void JS_Debug (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
debug, args[0]);
|
||||
}
|
||||
|
||||
triagens::V8LineEditor* console = triagens::arango::serverConsole.load();
|
||||
V8LineEditor* console = triagens::arango::serverConsole.load();
|
||||
|
||||
if (console != nullptr) {
|
||||
MUTEX_LOCKER(triagens::arango::serverConsoleMutex);
|
||||
if (serverConsole.load() != nullptr) {
|
||||
while (true) {
|
||||
char* input = console->prompt("debug> ");
|
||||
bool eof;
|
||||
string input = console->prompt("debug> ", "debug", eof);
|
||||
|
||||
if (input == nullptr) {
|
||||
if (eof) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*input == '\0') {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
if (input.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -661,8 +662,8 @@ static void JS_Debug (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
v8::TryCatch tryCatch;
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
TRI_ExecuteJavaScriptString(isolate, isolate->GetCurrentContext(), TRI_V8_STRING(input), name, true);
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
TRI_ExecuteJavaScriptString(isolate, isolate->GetCurrentContext(),
|
||||
TRI_V8_STRING(input.c_str()), name, true);
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
std::cout << TRI_StringifyV8Exception(isolate, &tryCatch);
|
||||
|
|
|
@ -814,15 +814,15 @@ void ArangoClient::log (const char* format,
|
|||
/// @brief logs output, with prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ArangoClient::log (const char* format,
|
||||
const char* prompt,
|
||||
const char* str) {
|
||||
void ArangoClient::log (const string& format,
|
||||
const string& prompt,
|
||||
const string& str) {
|
||||
if (_log) {
|
||||
string sanitised = StripBinary(str);
|
||||
string sanitised = StripBinary(str.c_str());
|
||||
|
||||
if (! sanitised.empty()) {
|
||||
// do not print terminal escape sequences into log
|
||||
fprintf(_log, format, prompt, sanitised.c_str());
|
||||
fprintf(_log, format.c_str(), prompt.c_str(), sanitised.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,7 +270,9 @@ namespace triagens {
|
|||
/// @brief log output, with prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void log (const char*, const char*, const char*);
|
||||
void log (const std::string& format,
|
||||
const std::string& prompt,
|
||||
const std::string& str);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flush log
|
||||
|
|
|
@ -69,6 +69,7 @@ using namespace triagens::rest;
|
|||
using namespace triagens::httpclient;
|
||||
using namespace triagens::v8client;
|
||||
using namespace triagens::arango;
|
||||
using namespace arangodb;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
@ -1505,7 +1506,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
|||
v8::Context::Scope contextScope(context);
|
||||
v8::Local<v8::String> name(TRI_V8_ASCII_STRING(TRI_V8_SHELL_COMMAND_NAME));
|
||||
|
||||
triagens::V8LineEditor console(context, ".arangosh.history");
|
||||
V8LineEditor console(context, ".arangosh.history");
|
||||
console.open(BaseClient.autoComplete());
|
||||
|
||||
uint64_t nrCommands = 0;
|
||||
|
@ -1545,6 +1546,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
|||
if (BaseClient.colors()) {
|
||||
|
||||
#ifdef TRI_HAVE_LINENOISE
|
||||
|
||||
// linenoise doesn't need escape sequences for escape sequences
|
||||
goodPrompt = TRI_SHELL_COLOR_BOLD_GREEN + dynamicPrompt + TRI_SHELL_COLOR_RESET;
|
||||
badPrompt = TRI_SHELL_COLOR_BOLD_RED + dynamicPrompt + TRI_SHELL_COLOR_RESET;
|
||||
|
@ -1584,33 +1586,30 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
|||
}
|
||||
#endif
|
||||
|
||||
char* input = console.prompt(promptError ? badPrompt.c_str() : goodPrompt.c_str());
|
||||
bool eof;
|
||||
string input
|
||||
= console.prompt(promptError ? badPrompt.c_str() : goodPrompt.c_str(),
|
||||
"arangosh", eof);
|
||||
|
||||
if (input == nullptr) {
|
||||
if (eof) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*input == '\0') {
|
||||
if (input.empty()) {
|
||||
// input string is empty, but we must still free it
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
continue;
|
||||
}
|
||||
|
||||
BaseClient.log("%s%s\n", dynamicPrompt.c_str(), input);
|
||||
BaseClient.log("%s%s\n", dynamicPrompt, input);
|
||||
|
||||
string i = triagens::basics::StringUtils::trim(input);
|
||||
|
||||
if (i == "exit" || i == "quit" || i == "exit;" || i == "quit;") {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == "help" || i == "help;") {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
input = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, "help()");
|
||||
if (input == nullptr) {
|
||||
LOG_FATAL_AND_EXIT("out of memory");
|
||||
}
|
||||
input = "help()";
|
||||
}
|
||||
|
||||
console.addHistory(input);
|
||||
|
@ -1623,7 +1622,7 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
|||
promptError = false;
|
||||
|
||||
// execute command and register its result in __LAST__
|
||||
v8::Handle<v8::Value> v = TRI_ExecuteJavaScriptString(isolate, context, TRI_V8_STRING(input), name, true);
|
||||
v8::Handle<v8::Value> v = TRI_ExecuteJavaScriptString(isolate, context, TRI_V8_STRING(input.c_str()), name, true);
|
||||
|
||||
if (v.IsEmpty()) {
|
||||
context->Global()->Set(TRI_V8_ASCII_STRING("_last"), v8::Undefined(isolate));
|
||||
|
@ -1632,8 +1631,6 @@ static void RunShell (v8::Isolate* isolate, v8::Handle<v8::Context> context, boo
|
|||
context->Global()->Set(TRI_V8_ASCII_STRING("_last"), v);
|
||||
}
|
||||
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
|
||||
|
||||
if (tryCatch.HasCaught()) {
|
||||
// command failed
|
||||
string exception(TRI_StringifyV8Exception(isolate, &tryCatch));
|
||||
|
|
|
@ -70,7 +70,7 @@ function DatabaseSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testVersion : function () {
|
||||
assertMatch(/(^2\.5)|(-devel$)/, internal.db._version());
|
||||
assertMatch(/(^2\.7)|(-devel$)/, internal.db._version());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace arangodb {
|
||||
|
||||
class Completer {
|
||||
|
||||
|
@ -60,8 +60,7 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual bool isComplete (std::string const&,
|
||||
size_t lineno,
|
||||
size_t column) = 0;
|
||||
size_t lineno) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief computes all strings which begins with the given text
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,16 +23,18 @@
|
|||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "LineEditor.h"
|
||||
|
||||
#include "Utilities/ShellImplementation.h"
|
||||
#include "Utilities/Completer.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace triagens;
|
||||
using namespace arangodb;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class LineEditor
|
||||
|
@ -62,6 +64,23 @@ LineEditor::~LineEditor () {
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- static public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sort the alternatives results vector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LineEditor::sortAlternatives (vector<string>& completions) {
|
||||
std::sort(completions.begin(), completions.end(),
|
||||
[](std::string const& l, std::string const& r) -> bool {
|
||||
int res = strcasecmp(l.c_str(), r.c_str());
|
||||
return (res < 0);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -88,8 +107,10 @@ bool LineEditor::close () {
|
|||
/// @brief line editor prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* LineEditor::prompt (char const* prompt) {
|
||||
return _shellImpl->prompt(prompt);
|
||||
string LineEditor::prompt (const string& prompt,
|
||||
const string& begin,
|
||||
bool& eof) {
|
||||
return _shellImpl->prompt(prompt, begin, eof);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -105,9 +126,9 @@ string LineEditor::historyPath () {
|
|||
/// @brief add to history
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LineEditor::addHistory (char const* str) {
|
||||
void LineEditor::addHistory (const string& line) {
|
||||
prepareShell();
|
||||
return _shellImpl->addHistory(str);
|
||||
return _shellImpl->addHistory(line);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -127,19 +148,6 @@ void LineEditor::signal () {
|
|||
_shellImpl->signal();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sort the alternatives results vector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LineEditor::sortAlternatives (vector<string>& completions) {
|
||||
std::sort(completions.begin(), completions.end(),
|
||||
[](std::string const& l, std::string const& r) -> bool {
|
||||
int res = strcasecmp(l.c_str(), r.c_str());
|
||||
return (res < 0);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- protected methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -153,8 +161,3 @@ void LineEditor::prepareShell () {
|
|||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief abstract line editor
|
||||
/// @brief base class for a line editor
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,7 +23,7 @@
|
|||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -31,8 +31,9 @@
|
|||
#define ARANGODB_UTILITIES_LINE_EDITOR_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "LineEditor.h"
|
||||
#include "Completer.h"
|
||||
|
||||
namespace arangodb {
|
||||
class ShellImplementation;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class LineEditor
|
||||
|
@ -42,12 +43,9 @@
|
|||
/// @brief line editor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace triagens {
|
||||
class ShellImplementation;
|
||||
|
||||
class LineEditor {
|
||||
LineEditor(LineEditor const&);
|
||||
LineEditor& operator= (LineEditor const&);
|
||||
LineEditor(LineEditor const&) = delete;
|
||||
LineEditor& operator= (LineEditor const&) = delete;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public constants
|
||||
|
@ -79,6 +77,16 @@ namespace triagens {
|
|||
|
||||
virtual ~LineEditor ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- static public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sort the alternatives results vector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void sortAlternatives (std::vector<std::string>&);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -101,7 +109,9 @@ namespace triagens {
|
|||
/// @brief line editor prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* prompt (char const*);
|
||||
std::string prompt (const std::string& prompt,
|
||||
const std::string& begin,
|
||||
bool& eof);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the history file path
|
||||
|
@ -116,7 +126,7 @@ namespace triagens {
|
|||
/// @brief add to history
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addHistory (const char*);
|
||||
void addHistory (const std::string&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief save the history
|
||||
|
@ -130,12 +140,6 @@ namespace triagens {
|
|||
|
||||
void signal ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sort the alternatives results vector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void sortAlternatives (std::vector<std::string>&);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- protected methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -148,8 +152,14 @@ namespace triagens {
|
|||
|
||||
void prepareShell ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- virtual protected methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a concrete Shell with the correct parameter (Completer!!)
|
||||
/// @brief creates a concrete Shell with the correct parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void initializeShell () = 0;
|
||||
|
@ -160,19 +170,23 @@ namespace triagens {
|
|||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the shell implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ShellImplementation* _shellImpl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief path to the history file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _history;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,11 +23,12 @@
|
|||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ReadlineShell.h"
|
||||
|
||||
#include "Basics/tri-strings.h"
|
||||
#include "Utilities/Completer.h"
|
||||
#include "Utilities/LineEditor.h"
|
||||
|
@ -38,58 +39,60 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace triagens;
|
||||
using namespace arangodb;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
Completer* COMPLETER;
|
||||
|
||||
static char WordBreakCharacters[] = {
|
||||
' ', '\t', '\n', '"', '\\', '\'', '`', '@',
|
||||
'<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
|
||||
'\0'
|
||||
};
|
||||
|
||||
static char* CompletionGenerator (char const* text, int state) {
|
||||
static size_t currentIndex;
|
||||
static vector<string> result;
|
||||
// compute the possible completion
|
||||
if (state == 0) {
|
||||
COMPLETER->getAlternatives(text, result);
|
||||
LineEditor::sortAlternatives(result);
|
||||
}
|
||||
|
||||
if (currentIndex < result.size()) {
|
||||
return TRI_SystemDuplicateString(result[currentIndex++].c_str());
|
||||
}
|
||||
|
||||
currentIndex = 0;
|
||||
result.clear();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static char** AttemptedCompletion (char const* text, int start, int end) {
|
||||
char** result = rl_completion_matches(text, CompletionGenerator);
|
||||
rl_attempted_completion_over = true;
|
||||
|
||||
if (result != nullptr && result[0] != nullptr && result[1] == nullptr) {
|
||||
size_t n = strlen(result[0]);
|
||||
|
||||
if (result[0][n - 1] == ')') {
|
||||
result[0][n - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#if RL_READLINE_VERSION >= 0x0500
|
||||
// issue #289
|
||||
rl_completion_suppress_append = 1;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ReadlineShell
|
||||
// -----------------------------------------------------------------------------
|
||||
static char WordBreakCharacters[] = {
|
||||
' ', '\t', '\n', '"', '\\', '\'', '`', '@',
|
||||
'<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
|
||||
'\0'
|
||||
};
|
||||
|
||||
static char* CompletionGenerator (char const* text, int state) {
|
||||
static size_t currentIndex;
|
||||
static vector<string> result;
|
||||
|
||||
// compute the possible completion
|
||||
if (state == 0) {
|
||||
COMPLETER->getAlternatives(text, result);
|
||||
LineEditor::sortAlternatives(result);
|
||||
}
|
||||
|
||||
if (currentIndex < result.size()) {
|
||||
return TRI_SystemDuplicateString(result[currentIndex++].c_str());
|
||||
}
|
||||
|
||||
currentIndex = 0;
|
||||
result.clear();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static char** AttemptedCompletion (char const* text, int start, int end) {
|
||||
char** result = rl_completion_matches(text, CompletionGenerator);
|
||||
rl_attempted_completion_over = true;
|
||||
|
||||
if (result != nullptr && result[0] != nullptr && result[1] == nullptr) {
|
||||
size_t n = strlen(result[0]);
|
||||
|
||||
if (result[0][n - 1] == ')') {
|
||||
result[0][n - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#if RL_READLINE_VERSION >= 0x0500
|
||||
// issue #289
|
||||
rl_completion_suppress_append = 1;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief callback function that readline calls periodically while waiting
|
||||
|
@ -99,8 +102,7 @@ namespace {
|
|||
static int ReadlineIdle () {
|
||||
auto instance = ReadlineShell::instance();
|
||||
|
||||
if (instance != nullptr &&
|
||||
instance->getLoopState() == 2) {
|
||||
if (instance != nullptr && instance->getLoopState() == 2) {
|
||||
rl_done = 1;
|
||||
}
|
||||
|
||||
|
@ -124,8 +126,10 @@ static void ReadlineInputCompleted (char* value) {
|
|||
}
|
||||
|
||||
if (instance->getLoopState() == 2) {
|
||||
|
||||
// CTRL-C received
|
||||
rl_done = 1;
|
||||
|
||||
// replace current input with nothing
|
||||
rl_replace_line("", 0);
|
||||
|
||||
|
@ -133,16 +137,27 @@ static void ReadlineInputCompleted (char* value) {
|
|||
// avoid memleak
|
||||
TRI_SystemFree(value);
|
||||
}
|
||||
instance->setLastInput(nullptr);
|
||||
|
||||
instance->setLastInput("");
|
||||
}
|
||||
else if (value == nullptr) {
|
||||
rl_done = 1;
|
||||
rl_replace_line("", 0);
|
||||
instance->setLoopState(3);
|
||||
instance->setLastInput("");
|
||||
}
|
||||
else {
|
||||
instance->setLoopState(1);
|
||||
instance->setLastInput(value);
|
||||
instance->setLastInput(value == 0 ? "" : value);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// --SECTION-- class ReadlineShell
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -151,15 +166,18 @@ static void ReadlineInputCompleted (char* value) {
|
|||
|
||||
std::atomic<ReadlineShell*> ReadlineShell::_instance(nullptr);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructs a new editor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ReadlineShell::ReadlineShell (std::string const& history,
|
||||
Completer* completer)
|
||||
ReadlineShell::ReadlineShell (std::string const& history, Completer* completer)
|
||||
: ShellImplementation(history, completer),
|
||||
_loopState(0),
|
||||
_lastInput(nullptr),
|
||||
_lastInput(),
|
||||
_lastInputWasEmpty(false) {
|
||||
|
||||
COMPLETER = completer;
|
||||
|
@ -184,7 +202,7 @@ ReadlineShell::~ReadlineShell () {
|
|||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// --SECTION-- ShellImplementation methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -193,6 +211,7 @@ ReadlineShell::~ReadlineShell () {
|
|||
|
||||
bool ReadlineShell::open (bool autoComplete) {
|
||||
if (autoComplete) {
|
||||
|
||||
// issue #289: do not append a space after completion
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
|
@ -273,31 +292,29 @@ string ReadlineShell::historyPath () {
|
|||
/// @brief add to history
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ReadlineShell::addHistory (char const* str) {
|
||||
if (*str == '\0') {
|
||||
void ReadlineShell::addHistory (const string& str) {
|
||||
if (str.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
history_set_pos(history_length-1);
|
||||
history_set_pos(history_length - 1);
|
||||
|
||||
if (current_history()) {
|
||||
do {
|
||||
if (strcmp(current_history()->line, str) == 0) {
|
||||
#ifndef __APPLE__
|
||||
if (strcmp(current_history()->line, str.c_str()) == 0) {
|
||||
HIST_ENTRY* e = remove_history(where_history());
|
||||
|
||||
if (e != nullptr) {
|
||||
free_history_entry(e);
|
||||
}
|
||||
#else
|
||||
remove_history(where_history());
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (previous_history());
|
||||
}
|
||||
|
||||
add_history(str);
|
||||
add_history(str.c_str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -312,28 +329,39 @@ bool ReadlineShell::writeHistory () {
|
|||
/// @brief read a line from the input
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* ReadlineShell::getLine (char const* prompt) {
|
||||
string ReadlineShell::getLine (const string& prompt, bool& eof) {
|
||||
setLoopState(0);
|
||||
|
||||
rl_event_hook = ReadlineIdle;
|
||||
rl_callback_handler_install(prompt, ReadlineInputCompleted);
|
||||
rl_callback_handler_install(prompt.c_str(), ReadlineInputCompleted);
|
||||
|
||||
int state;
|
||||
|
||||
eof = false;
|
||||
|
||||
do {
|
||||
rl_callback_read_char();
|
||||
state = getLoopState();
|
||||
}
|
||||
while (state == 0);
|
||||
|
||||
rl_callback_handler_remove();
|
||||
|
||||
if (state == 2) {
|
||||
setLastInput("");
|
||||
|
||||
if (_lastInputWasEmpty) {
|
||||
setLastInput(nullptr);
|
||||
eof = true;
|
||||
}
|
||||
else {
|
||||
setLastInput(strdup(""));
|
||||
_lastInputWasEmpty = true;
|
||||
}
|
||||
}
|
||||
else if (state == 3) {
|
||||
setLastInput("");
|
||||
eof = true;
|
||||
_lastInputWasEmpty = false;
|
||||
}
|
||||
else {
|
||||
_lastInputWasEmpty = false;
|
||||
}
|
||||
|
@ -353,8 +381,3 @@ void ReadlineShell::signal () {
|
|||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -30,24 +30,29 @@
|
|||
#ifndef ARANGODB_UTILITIES_READLINE_SHELL_H
|
||||
#define ARANGODB_UTILITIES_READLINE_SHELL_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Utilities/Completer.h"
|
||||
#include "Utilities/ShellImplementation.h"
|
||||
|
||||
namespace triagens {
|
||||
#include "Utilities/Completer.h"
|
||||
|
||||
class Completer;
|
||||
namespace arangodb {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ReadlineShell
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class ReadlineShell : public ShellImplementation {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ReadlineShell (std::string const& history,
|
||||
Completer*);
|
||||
ReadlineShell (std::string const& history, Completer*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
|
@ -55,6 +60,12 @@ namespace triagens {
|
|||
|
||||
~ReadlineShell ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- ShellImplementation methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief line editor open
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -80,7 +91,7 @@ namespace triagens {
|
|||
/// @brief add to history
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addHistory (char const*) override final;
|
||||
void addHistory (const std::string&) override final;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief save the history
|
||||
|
@ -92,7 +103,7 @@ namespace triagens {
|
|||
/// @brief read a line from the input
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* getLine (char const*) override final;
|
||||
std::string getLine (const std::string& prompt, bool& eof) override final;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief handle a signal
|
||||
|
@ -100,11 +111,31 @@ namespace triagens {
|
|||
|
||||
void signal () override final;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- static public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the currently active shell instance
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ReadlineShell* instance () {
|
||||
return _instance.load();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the last input value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setLastInput (char* input) {
|
||||
void setLastInput (const std::string& input) {
|
||||
_lastInput = input;
|
||||
}
|
||||
|
||||
|
@ -124,14 +155,6 @@ namespace triagens {
|
|||
_loopState = state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the currently active shell instance
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ReadlineShell* instance () {
|
||||
return _instance.load();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -145,11 +168,10 @@ namespace triagens {
|
|||
std::atomic<int> _loopState;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief last value entered by user. memory is allocated by readline
|
||||
/// and must be freed using TRI_SystemFree()
|
||||
/// @brief last value entered by user.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* _lastInput;
|
||||
std::string _lastInput;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the input from the previous invocation was a CTRL-C
|
||||
|
@ -171,8 +193,3 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
using namespace triagens;
|
||||
using namespace arangodb;
|
||||
|
||||
ShellImplementation* ShellImplFactory::buildShell (std::string const& history,
|
||||
Completer* completer) {
|
||||
|
|
|
@ -33,11 +33,12 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
namespace triagens {
|
||||
|
||||
namespace arangodb {
|
||||
class ShellImplementation;
|
||||
class Completer;
|
||||
}
|
||||
|
||||
namespace triagens {
|
||||
class ShellImplFactory {
|
||||
|
||||
public:
|
||||
|
@ -46,7 +47,7 @@ namespace triagens {
|
|||
/// @brief creates a shell
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ShellImplementation* buildShell (std::string const& history, Completer*);
|
||||
static arangodb::ShellImplementation* buildShell (std::string const& history, arangodb::Completer*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the shell will have a CTRL-C handler
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief implementation of basis class ShellImplementation
|
||||
/// @brief implementation of the base class ShellImplementation
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,17 +23,20 @@
|
|||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ShellImplementation.h"
|
||||
|
||||
#include "Basics/tri-strings.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Utilities/Completer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace triagens {
|
||||
using namespace arangodb;
|
||||
using namespace triagens::basics;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ShellImplementation
|
||||
|
@ -44,7 +47,7 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructs a new editor
|
||||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ShellImplementation::ShellImplementation (string const& history,
|
||||
|
@ -71,38 +74,33 @@ ShellImplementation::~ShellImplementation () {
|
|||
/// @brief line editor prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* ShellImplementation::prompt (char const* the_prompt) {
|
||||
string dotdot;
|
||||
char const* p = the_prompt;
|
||||
size_t len1 = strlen(the_prompt);
|
||||
size_t len2 = len1;
|
||||
string ShellImplementation::prompt (const string& prompt,
|
||||
const string& plain,
|
||||
bool& eof) {
|
||||
size_t lineno = 0;
|
||||
string dotdot = "...> ";
|
||||
string p = prompt;
|
||||
string sep = "";
|
||||
string line;
|
||||
|
||||
if (len1 < 3) {
|
||||
dotdot = "> ";
|
||||
len2 = 2;
|
||||
}
|
||||
else {
|
||||
dotdot = string(len1 - 2, '.') + "> ";
|
||||
}
|
||||
|
||||
char const* sep = "";
|
||||
eof = false;
|
||||
|
||||
while (true) {
|
||||
|
||||
// calling concrete implmentation of the shell
|
||||
char* result = getLine(p);
|
||||
line = getLine(p, eof);
|
||||
p = dotdot;
|
||||
|
||||
p = dotdot.c_str();
|
||||
|
||||
if (result == nullptr) {
|
||||
if (eof) {
|
||||
|
||||
// give up, if the user pressed control-D on the top-most level
|
||||
if (_current.empty()) {
|
||||
return nullptr;
|
||||
return "";
|
||||
}
|
||||
|
||||
// otherwise clear current content
|
||||
_current.clear();
|
||||
eof = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -110,38 +108,40 @@ char* ShellImplementation::prompt (char const* the_prompt) {
|
|||
sep = "\n";
|
||||
++lineno;
|
||||
|
||||
// remove any the_prompt at the beginning of the line
|
||||
char* originalLine = result;
|
||||
bool c1 = strncmp(result, the_prompt, len1) == 0;
|
||||
bool c2 = strncmp(result, dotdot.c_str(), len2) == 0;
|
||||
// remove any prompt at the beginning of the line
|
||||
size_t pos = string::npos;
|
||||
|
||||
while (c1 || c2) {
|
||||
if (c1) {
|
||||
result += len1;
|
||||
}
|
||||
else if (c2) {
|
||||
result += len2;
|
||||
}
|
||||
if (StringUtils::isPrefix(line, plain)) {
|
||||
pos = line.find('>');
|
||||
}
|
||||
else if (StringUtils::isPrefix(line, "...")) {
|
||||
pos = line.find('>');
|
||||
}
|
||||
|
||||
c1 = strncmp(result, the_prompt, len1) == 0;
|
||||
c2 = strncmp(result, dotdot.c_str(), len2) == 0;
|
||||
if (pos != string::npos) {
|
||||
pos = line.find_first_not_of(" \t", pos + 1);
|
||||
|
||||
if (pos != string::npos) {
|
||||
line = line.substr(pos);
|
||||
}
|
||||
else {
|
||||
line.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// extend line and check
|
||||
_current += result;
|
||||
|
||||
bool ok = _completer->isComplete(_current, lineno, strlen(result));
|
||||
|
||||
// cannot use TRI_Free, because it was allocated by the system call inside readline
|
||||
TRI_SystemFree(originalLine);
|
||||
_current += line;
|
||||
|
||||
// stop if line is complete
|
||||
bool ok = _completer->isComplete(_current, lineno);
|
||||
|
||||
if (ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str());
|
||||
// clear current line
|
||||
line = _current;
|
||||
_current.clear();
|
||||
|
||||
return line;
|
||||
|
@ -155,13 +155,6 @@ void ShellImplementation::signal () {
|
|||
// do nothing special
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a basis class for concrete implementations for a shell
|
||||
/// @brief a base class for implementations for a shell
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -22,8 +22,9 @@
|
|||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Esteban Lombeyda
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -32,35 +33,69 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "Completer.h"
|
||||
namespace arangodb {
|
||||
class Completer;
|
||||
|
||||
namespace triagens {
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ShellImplementation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class ShellImplementation {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief state of the console protected types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- protected types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
|
||||
typedef enum {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief state of the console
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum console_state_e {
|
||||
STATE_NONE = 0,
|
||||
STATE_OPENED,
|
||||
STATE_CLOSED
|
||||
}
|
||||
console_state_e;
|
||||
STATE_OPENED = 1,
|
||||
STATE_CLOSED = 2
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// public constructor, destructor
|
||||
/// @brief constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ShellImplementation (std::string const& history, Completer*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~ShellImplementation ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief line editor prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string prompt (const std::string& prompt,
|
||||
const std::string& begin,
|
||||
bool& eof);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- virtual public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief line editor open
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -73,12 +108,6 @@ namespace triagens {
|
|||
|
||||
virtual bool close () = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief line editor prompt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual char* prompt (char const* prompt);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the history file path
|
||||
///
|
||||
|
@ -92,7 +121,7 @@ namespace triagens {
|
|||
/// @brief add to history
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void addHistory (const char*) = 0;
|
||||
virtual void addHistory (const std::string&) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief save the history
|
||||
|
@ -101,10 +130,10 @@ namespace triagens {
|
|||
virtual bool writeHistory () = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief todo!!
|
||||
/// @brief get next line
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual char* getLine (const char*) = 0;
|
||||
virtual std::string getLine (const std::string& prompt, bool& eof) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief handle a signal
|
||||
|
@ -150,8 +179,3 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,7 +23,7 @@
|
|||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. Frank Celler
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace triagens;
|
||||
using namespace arangodb;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- helper functions
|
||||
|
@ -48,7 +49,7 @@ using namespace triagens;
|
|||
#ifndef _WIN32
|
||||
static void SignalHandler (int signal) {
|
||||
// get the instance of the console
|
||||
auto instance = triagens::V8LineEditor::instance();
|
||||
auto instance = V8LineEditor::instance();
|
||||
|
||||
if (instance != nullptr) {
|
||||
instance->signal();
|
||||
|
@ -60,7 +61,7 @@ static void SignalHandler (int signal) {
|
|||
// --SECTION-- class V8Completer
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool V8Completer::isComplete (std::string const& source, size_t lineno, size_t column) {
|
||||
bool V8Completer::isComplete (std::string const& source, size_t lineno) {
|
||||
int openParen = 0;
|
||||
int openBrackets = 0;
|
||||
int openBraces = 0;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
// --SECTION-- class V8Completer
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace triagens {
|
||||
namespace arangodb {
|
||||
|
||||
class V8Completer : public Completer {
|
||||
|
||||
|
@ -56,8 +56,7 @@ namespace triagens {
|
|||
public:
|
||||
|
||||
bool isComplete (std::string const&,
|
||||
size_t lineno,
|
||||
size_t column) override final;
|
||||
size_t lineno) override final;
|
||||
|
||||
void getAlternatives (char const*,
|
||||
std::vector<std::string>&) override final;
|
||||
|
|
Loading…
Reference in New Issue