mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
f078425b6d
|
@ -12,7 +12,7 @@ A basic example:
|
||||||
params: [ 1, 2, 3 ]
|
params: [ 1, 2, 3 ]
|
||||||
});
|
});
|
||||||
|
|
||||||
The above example will return *1*.
|
The above example will return *2*.
|
||||||
|
|
||||||
Some example that uses collections:
|
Some example that uses collections:
|
||||||
|
|
||||||
|
|
|
@ -1493,7 +1493,7 @@ AstNode* QueryAst::traverse (AstNode* node,
|
||||||
/// @brief determines the variables referenced in an expression
|
/// @brief determines the variables referenced in an expression
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::unordered_set<int64_t> QueryAst::getReferencedVariables (AstNode const* node) {
|
std::unordered_set<VariableId> QueryAst::getReferencedVariables (AstNode const* node) {
|
||||||
auto func = [&](AstNode* node, void* data) -> AstNode* {
|
auto func = [&](AstNode* node, void* data) -> AstNode* {
|
||||||
if (node == nullptr) {
|
if (node == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1507,14 +1507,14 @@ std::unordered_set<int64_t> QueryAst::getReferencedVariables (AstNode const* nod
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vars = static_cast<unordered_set<int64_t>*>(data);
|
auto vars = static_cast<unordered_set<VariableId>*>(data);
|
||||||
vars->insert(variable->id);
|
vars->insert(variable->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_set<int64_t> vars;
|
std::unordered_set<VariableId> vars;
|
||||||
traverse(_root, func, &vars);
|
traverse(_root, func, &vars);
|
||||||
|
|
||||||
return vars;
|
return vars;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "Aql/AstNode.h"
|
#include "Aql/AstNode.h"
|
||||||
#include "Aql/BindParameters.h"
|
#include "Aql/BindParameters.h"
|
||||||
#include "Aql/Scopes.h"
|
#include "Aql/Scopes.h"
|
||||||
|
#include "Aql/Variable.h"
|
||||||
#include "BasicsC/json.h"
|
#include "BasicsC/json.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -568,7 +569,7 @@ namespace triagens {
|
||||||
/// @brief determines the variables referenced in an expression
|
/// @brief determines the variables referenced in an expression
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::unordered_set<int64_t> getReferencedVariables (AstNode const*);
|
std::unordered_set<VariableId> getReferencedVariables (AstNode const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief normalize a function name
|
/// @brief normalize a function name
|
||||||
|
|
|
@ -217,7 +217,7 @@ Variable* Scopes::addVariable (char const* name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t id = ++_nextId;
|
VariableId id = ++_nextId;
|
||||||
|
|
||||||
// if this fails, the exception will propagate and be caught somewhere else
|
// if this fails, the exception will propagate and be caught somewhere else
|
||||||
auto variable = new Variable(name, id, isUserDefined);
|
auto variable = new Variable(name, id, isUserDefined);
|
||||||
|
@ -268,7 +268,7 @@ Variable* Scopes::getVariable (char const* name) const {
|
||||||
/// @brief return a variable by id - this does not respect the scopes!
|
/// @brief return a variable by id - this does not respect the scopes!
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Variable* Scopes::getVariable (int64_t id) const {
|
Variable* Scopes::getVariable (VariableId id) const {
|
||||||
auto it = _variables.find(id);
|
auto it = _variables.find(id);
|
||||||
|
|
||||||
if (it == _variables.end()) {
|
if (it == _variables.end()) {
|
||||||
|
|
|
@ -31,81 +31,11 @@
|
||||||
#define ARANGODB_AQL_SCOPES_H 1
|
#define ARANGODB_AQL_SCOPES_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
|
#include "Aql/Variable.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- struct Variable
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct Variable {
|
|
||||||
Variable (std::string const& name,
|
|
||||||
int64_t id,
|
|
||||||
bool isUserDefined)
|
|
||||||
: name(name),
|
|
||||||
value(nullptr),
|
|
||||||
id(id),
|
|
||||||
refCount(0),
|
|
||||||
isUserDefined(isUserDefined) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~Variable () {
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief registers a constant value for the variable
|
|
||||||
/// this constant value is used for constant propagation in optimizations
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void constValue (void* node) {
|
|
||||||
value = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns a constant value registered for this variable
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void* constValue () const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief whether or not the variable is reference counted
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool isReferenceCounted () const {
|
|
||||||
return (refCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief increase the variable's reference counter
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void increaseReferenceCount () {
|
|
||||||
++refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief decrease the variable's reference counter
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void decreaseReferenceCount () {
|
|
||||||
TRI_ASSERT(refCount > 0);
|
|
||||||
--refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- public variables
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
std::string const name;
|
|
||||||
void* value;
|
|
||||||
int64_t const id;
|
|
||||||
uint32_t refCount;
|
|
||||||
bool const isUserDefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public types
|
// --SECTION-- public types
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -274,7 +204,7 @@ namespace triagens {
|
||||||
/// @brief return a variable by id - this does not respect the scopes!
|
/// @brief return a variable by id - this does not respect the scopes!
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Variable* getVariable (int64_t) const;
|
Variable* getVariable (VariableId) const;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private variables
|
// --SECTION-- private variables
|
||||||
|
@ -286,7 +216,7 @@ namespace triagens {
|
||||||
/// @brief all variables used in the query
|
/// @brief all variables used in the query
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::unordered_map<int64_t, Variable*> _variables;
|
std::unordered_map<VariableId, Variable*> _variables;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief currently active scopes
|
/// @brief currently active scopes
|
||||||
|
@ -304,7 +234,7 @@ namespace triagens {
|
||||||
/// @brief next variable id
|
/// @brief next variable id
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int64_t _nextId;
|
VariableId _nextId;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Aql, AST variables
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||||
|
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Jan Steemann
|
||||||
|
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||||
|
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef ARANGODB_AQL_VARIABLE_H
|
||||||
|
#define ARANGODB_AQL_VARIABLE_H 1
|
||||||
|
|
||||||
|
#include "Basics/Common.h"
|
||||||
|
|
||||||
|
namespace triagens {
|
||||||
|
namespace aql {
|
||||||
|
|
||||||
|
typedef uint32_t VariableId;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- struct Variable
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct Variable {
|
||||||
|
Variable (std::string const& name,
|
||||||
|
VariableId id,
|
||||||
|
bool isUserDefined)
|
||||||
|
: name(name),
|
||||||
|
value(nullptr),
|
||||||
|
id(id),
|
||||||
|
refCount(0),
|
||||||
|
isUserDefined(isUserDefined) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~Variable () {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief registers a constant value for the variable
|
||||||
|
/// this constant value is used for constant propagation in optimizations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void constValue (void* node) {
|
||||||
|
value = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns a constant value registered for this variable
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void* constValue () const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief whether or not the variable is reference counted
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline bool isReferenceCounted () const {
|
||||||
|
return (refCount > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief increase the variable's reference counter
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void increaseReferenceCount () {
|
||||||
|
++refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief decrease the variable's reference counter
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void decreaseReferenceCount () {
|
||||||
|
TRI_ASSERT(refCount > 0);
|
||||||
|
--refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public variables
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
std::string const name;
|
||||||
|
void* value;
|
||||||
|
VariableId const id;
|
||||||
|
uint32_t refCount;
|
||||||
|
bool const isUserDefined;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- END-OF-FILE
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: outline-minor
|
||||||
|
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||||
|
// End:
|
|
@ -33,7 +33,7 @@
|
||||||
#include "BasicsC/files.h"
|
#include "BasicsC/files.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace triagentriagens;
|
using namespace triagens;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- class DummyShell
|
// --SECTION-- class DummyShell
|
||||||
|
@ -47,10 +47,9 @@ using namespace triagentriagens;
|
||||||
/// @brief constructs a new editor
|
/// @brief constructs a new editor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DummyShell::DummyShell (std::string const& history)
|
DummyShell::DummyShell (std::string const& history,
|
||||||
: _current(),
|
Completer* completer)
|
||||||
_historyFilename(history),
|
: ShellImplementation(history, completer) {
|
||||||
_state(STATE_NONE) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -83,29 +82,6 @@ bool DummyShell::close () {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get the history file path
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
string DummyShell::historyPath () {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief add to history
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void DummyShell::addHistory (char const* str) {
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief save history
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool DummyShell::writeHistory () {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor prompt
|
/// @brief line editor prompt
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -137,7 +113,7 @@ char* DummyShell::prompt (char const* prompt) {
|
||||||
p = dotdot.c_str();
|
p = dotdot.c_str();
|
||||||
|
|
||||||
if (cin.eof()) {
|
if (cin.eof()) {
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_current += sep;
|
_current += sep;
|
||||||
|
@ -164,7 +140,7 @@ char* DummyShell::prompt (char const* prompt) {
|
||||||
// extend line and check
|
// extend line and check
|
||||||
_current += result;
|
_current += result;
|
||||||
|
|
||||||
bool ok = isComplete(_current, lineno, strlen(result));
|
bool ok = _completer->isComplete(_current, lineno, strlen(result));
|
||||||
|
|
||||||
// stop if line is complete
|
// stop if line is complete
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
@ -173,11 +149,46 @@ char* DummyShell::prompt (char const* prompt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str());
|
char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str());
|
||||||
|
|
||||||
_current.clear();
|
_current.clear();
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get the history file path
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
string DummyShell::historyPath () {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief add to history
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DummyShell::addHistory (char const* str) {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief save history
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool DummyShell::writeHistory () {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the characters which the user has typed
|
||||||
|
/// @arg is the prompt of the shell
|
||||||
|
/// Note: this is the interface between our shell world and some implementation
|
||||||
|
/// of key events (linenoise, readline)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* DummyShell::getLine (char const* prompt) {
|
||||||
|
return this->prompt(prompt);
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -39,35 +39,37 @@
|
||||||
#include "V8/v8-utils.h"
|
#include "V8/v8-utils.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
class DummyShell : public ShellImplementation {
|
||||||
/// @addtogroup Shell
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class DummyShell: public ShellImplementation {
|
public:
|
||||||
|
|
||||||
public:
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// public constructor, destructor
|
/// public constructor, destructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DummyShell(string const& history, Completer *);
|
DummyShell (std::string const& history,
|
||||||
|
Completer*);
|
||||||
virtual ~DummyShell();
|
|
||||||
|
virtual ~DummyShell();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor open
|
/// @brief line editor open
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool open(bool autoComplete);
|
virtual bool open (bool autoComplete);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor shutdown
|
/// @brief line editor shutdown
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool close();
|
virtual bool close();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief line editor prompt
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
virtual char* prompt (char const* prompt);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the history file path
|
/// @brief get the history file path
|
||||||
|
@ -76,19 +78,19 @@ namespace triagens {
|
||||||
/// the local file _historyFilename.
|
/// the local file _historyFilename.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual std::string historyPath();
|
virtual std::string historyPath();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief add to history
|
/// @brief add to history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual void addHistory(const char*);
|
virtual void addHistory (const char*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief save the history
|
/// @brief save the history
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool writeHistory();
|
virtual bool writeHistory();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the characters which the user has typed
|
/// @brief returns the characters which the user has typed
|
||||||
|
@ -97,11 +99,7 @@ namespace triagens {
|
||||||
/// of key events (linenoise, readline)
|
/// of key events (linenoise, readline)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual char * getLine(char const *);
|
virtual char* getLine (char const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ bool LinenoiseShell::writeHistory() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * LinenoiseShell::getLine(char const * input) {
|
char* LinenoiseShell::getLine(char const* input) {
|
||||||
return linenoise(input);
|
return linenoise(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace triagens {
|
||||||
/// of key events (linenoise, readline)
|
/// of key events (linenoise, readline)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual char * getLine(char const *);
|
virtual char* getLine (char const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2011-2014, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "LinenoiseShell.h"
|
#include "LinenoiseShell.h"
|
||||||
#elif TRI_HAVE_LINENOISE
|
#elif TRI_HAVE_LINENOISE
|
||||||
#include "LinenoiseShell.h"
|
#include "LinenoiseShell.h"
|
||||||
#else
|
#elif TRI_HAVE_READLINE
|
||||||
#include "ReadlineShell.h"
|
#include "ReadlineShell.h"
|
||||||
|
#else
|
||||||
|
#include "DummyShell.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ShellImplFactory.h"
|
#include "ShellImplFactory.h"
|
||||||
|
@ -43,15 +43,19 @@
|
||||||
using namespace triagens;
|
using namespace triagens;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ShellImplementation * ShellImplFactory::buildShell (string const & history, Completer * completer) {
|
ShellImplementation* ShellImplFactory::buildShell (string const & history,
|
||||||
|
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);
|
||||||
#else
|
#elif defined TRI_HAVE_READLINE
|
||||||
return new ReadlineShell(history, completer);
|
return new ReadlineShell(history, completer);
|
||||||
|
#else
|
||||||
|
// last resort!
|
||||||
|
return new DummyShell(history, completer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,118 +32,123 @@
|
||||||
#include "BasicsC/tri-strings.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
namespace triagens {
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- class ShellImplementation
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
namespace triagens {
|
||||||
// --SECTION-- constructors and destructors
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- class ShellImplementation
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- constructors and destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief constructs a new editor
|
/// @brief constructs a new editor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ShellImplementation::ShellImplementation (string const& history, Completer * completer)
|
ShellImplementation::ShellImplementation (string const& history,
|
||||||
: _current(),
|
Completer* completer)
|
||||||
|
: _current(),
|
||||||
_historyFilename(history),
|
_historyFilename(history),
|
||||||
_state(STATE_NONE),
|
_state(STATE_NONE),
|
||||||
_completer(completer) {
|
_completer(completer) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destructor
|
/// @brief destructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ShellImplementation::~ShellImplementation () {
|
ShellImplementation::~ShellImplementation () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor prompt
|
/// @brief line editor prompt
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
char* ShellImplementation::prompt (char const* the_prompt) {
|
char* ShellImplementation::prompt (char const* the_prompt) {
|
||||||
string dotdot;
|
string dotdot;
|
||||||
char const* p = the_prompt;
|
char const* p = the_prompt;
|
||||||
size_t len1 = strlen(the_prompt);
|
size_t len1 = strlen(the_prompt);
|
||||||
size_t len2 = len1;
|
size_t len2 = len1;
|
||||||
size_t lineno = 0;
|
size_t lineno = 0;
|
||||||
|
|
||||||
if (len1 < 3) {
|
if (len1 < 3) {
|
||||||
dotdot = "> ";
|
dotdot = "> ";
|
||||||
len2 = 2;
|
len2 = 2;
|
||||||
}
|
|
||||||
else {
|
|
||||||
dotdot = string(len1 - 2, '.') + "> ";
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* sep = "";
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
// calling concrete implmentation of the shell
|
|
||||||
char* result = getLine(p);
|
|
||||||
|
|
||||||
p = dotdot.c_str();
|
|
||||||
|
|
||||||
if (result == 0) {
|
|
||||||
|
|
||||||
// give up, if the user pressed control-D on the top-most level
|
|
||||||
if (_current.empty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise clear current content
|
|
||||||
_current.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_current += sep;
|
|
||||||
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;
|
|
||||||
|
|
||||||
while (c1 || c2) {
|
|
||||||
if (c1) {
|
|
||||||
result += len1;
|
|
||||||
}
|
|
||||||
else if (c2) {
|
|
||||||
result += len2;
|
|
||||||
}
|
|
||||||
|
|
||||||
c1 = strncmp(result, the_prompt, len1) == 0;
|
|
||||||
c2 = strncmp(result, dotdot.c_str(), len2) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 readline
|
|
||||||
TRI_SystemFree(originalLine);
|
|
||||||
|
|
||||||
// stop if line is complete
|
|
||||||
if (ok) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str());
|
|
||||||
_current.clear();
|
|
||||||
|
|
||||||
return line;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
dotdot = string(len1 - 2, '.') + "> ";
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* sep = "";
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// calling concrete implmentation of the shell
|
||||||
|
char* result = getLine(p);
|
||||||
|
|
||||||
|
p = dotdot.c_str();
|
||||||
|
|
||||||
|
if (result == nullptr) {
|
||||||
|
|
||||||
|
// give up, if the user pressed control-D on the top-most level
|
||||||
|
if (_current.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise clear current content
|
||||||
|
_current.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_current += sep;
|
||||||
|
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;
|
||||||
|
|
||||||
|
while (c1 || c2) {
|
||||||
|
if (c1) {
|
||||||
|
result += len1;
|
||||||
|
}
|
||||||
|
else if (c2) {
|
||||||
|
result += len2;
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 = strncmp(result, the_prompt, len1) == 0;
|
||||||
|
c2 = strncmp(result, dotdot.c_str(), len2) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 readline
|
||||||
|
TRI_SystemFree(originalLine);
|
||||||
|
|
||||||
|
// stop if line is complete
|
||||||
|
if (ok) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* line = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, _current.c_str());
|
||||||
|
_current.clear();
|
||||||
|
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -37,10 +37,13 @@
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
|
|
||||||
class ShellImplementation {
|
class ShellImplementation {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief state of the console protected types
|
/// @brief state of the console protected types
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STATE_NONE = 0,
|
STATE_NONE = 0,
|
||||||
STATE_OPENED,
|
STATE_OPENED,
|
||||||
|
@ -49,11 +52,12 @@ namespace triagens {
|
||||||
console_state_e;
|
console_state_e;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// public constructor, destructor
|
/// public constructor, destructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ShellImplementation (std::string const& history, Completer *);
|
ShellImplementation (std::string const& history, Completer*);
|
||||||
|
|
||||||
virtual ~ShellImplementation ();
|
virtual ~ShellImplementation ();
|
||||||
|
|
||||||
|
@ -61,7 +65,7 @@ namespace triagens {
|
||||||
/// @brief line editor open
|
/// @brief line editor open
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual bool open (bool autoComplete) = 0;
|
virtual bool open (bool autoComplete) = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief line editor shutdown
|
/// @brief line editor shutdown
|
||||||
|
@ -100,15 +104,11 @@ namespace triagens {
|
||||||
/// @brief todo!!
|
/// @brief todo!!
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual char * getLine (const char*) = 0;
|
virtual char* getLine (const char*) = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
/// @}
|
// --SECTION-- protected variables
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- protected variables
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -134,11 +134,13 @@ namespace triagens {
|
||||||
/// @brief object which defines when the input is finished
|
/// @brief object which defines when the input is finished
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Completer * _completer;
|
Completer* _completer;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue