mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 13:45:04 +02:00
parent
14c94fabde
commit
d366dd8e30
@ -181,6 +181,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
|||||||
%type <csop> combined_set_op
|
%type <csop> combined_set_op
|
||||||
%type <type> type
|
%type <type> type
|
||||||
%type <expr> rterm
|
%type <expr> rterm
|
||||||
|
%type <expr> rterm_without_indexer
|
||||||
%type <expr> rterm_array
|
%type <expr> rterm_array
|
||||||
%type <expr> rterm_scope
|
%type <expr> rterm_scope
|
||||||
%type <expr> lterm
|
%type <expr> lterm
|
||||||
@ -505,17 +506,10 @@ identifier_items_inner: /* empty */
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
indexer: identifier
|
indexer: rterm_without_indexer indexer_items
|
||||||
{
|
|
||||||
$$ = new std::vector<Expression *>();
|
|
||||||
$$->push_back(MakeLiteral($1));
|
|
||||||
free($1);
|
|
||||||
}
|
|
||||||
| identifier indexer_items
|
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$->insert($$->begin(), MakeLiteral($1));
|
$$->insert($$->begin(), $1);
|
||||||
free($1);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -591,6 +585,16 @@ lterm: T_LOCAL indexer combined_set_op rterm
|
|||||||
$$ = new SetExpression(*$1, $2, $3, false, DebugInfoRange(@1, @3));
|
$$ = new SetExpression(*$1, $2, $3, false, DebugInfoRange(@1, @3));
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
|
| T_LOCAL identifier combined_set_op rterm
|
||||||
|
{
|
||||||
|
$$ = new SetExpression(MakeIndexer($2), $3, $4, true, DebugInfoRange(@1, @4));
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
| identifier combined_set_op rterm
|
||||||
|
{
|
||||||
|
$$ = new SetExpression(MakeIndexer($1), $2, $3, false, DebugInfoRange(@1, @3));
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
| T_INCLUDE rterm
|
| T_INCLUDE rterm
|
||||||
{
|
{
|
||||||
VMFrame frame;
|
VMFrame frame;
|
||||||
@ -735,7 +739,18 @@ rterm_scope: '{' newlines lterm_items newlines '}'
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rterm: T_STRING
|
rterm: rterm_without_indexer
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
| indexer
|
||||||
|
{
|
||||||
|
$$ = new IndexerExpression(*$1, @1);
|
||||||
|
delete $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
rterm_without_indexer: T_STRING
|
||||||
{
|
{
|
||||||
$$ = MakeLiteral($1);
|
$$ = MakeLiteral($1);
|
||||||
free($1);
|
free($1);
|
||||||
@ -748,11 +763,6 @@ rterm: T_STRING
|
|||||||
{
|
{
|
||||||
$$ = MakeLiteral();
|
$$ = MakeLiteral();
|
||||||
}
|
}
|
||||||
| rterm '.' T_IDENTIFIER
|
|
||||||
{
|
|
||||||
$$ = new IndexerExpression($1, MakeLiteral($3), DebugInfoRange(@1, @3));
|
|
||||||
free($3);
|
|
||||||
}
|
|
||||||
| rterm '(' rterm_items ')'
|
| rterm '(' rterm_items ')'
|
||||||
{
|
{
|
||||||
$$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4));
|
$$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4));
|
||||||
@ -771,10 +781,6 @@ rterm: T_STRING
|
|||||||
{
|
{
|
||||||
$$ = new NegateExpression($2, DebugInfoRange(@1, @2));
|
$$ = new NegateExpression($2, DebugInfoRange(@1, @2));
|
||||||
}
|
}
|
||||||
| rterm '[' rterm ']'
|
|
||||||
{
|
|
||||||
$$ = new IndexerExpression($1, $3, DebugInfoRange(@1, @4));
|
|
||||||
}
|
|
||||||
| rterm_array
|
| rterm_array
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
@ -100,10 +100,7 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
|||||||
Array::Ptr templateArray = new Array();
|
Array::Ptr templateArray = new Array();
|
||||||
templateArray->Add(m_Name);
|
templateArray->Add(m_Name);
|
||||||
|
|
||||||
std::vector<Expression *> indexer;
|
exprs.push_back(new SetExpression(MakeIndexer("templates"), OpSetAdd,
|
||||||
indexer.push_back(new LiteralExpression("templates"));
|
|
||||||
|
|
||||||
exprs.push_back(new SetExpression(indexer, OpSetAdd,
|
|
||||||
new LiteralExpression(templateArray), false, m_DebugInfo));
|
new LiteralExpression(templateArray), false, m_DebugInfo));
|
||||||
|
|
||||||
DictExpression *dexpr = new DictExpression(m_Expressions, m_DebugInfo);
|
DictExpression *dexpr = new DictExpression(m_Expressions, m_DebugInfo);
|
||||||
|
@ -64,7 +64,7 @@ const DebugInfo& Expression::GetDebugInfo(void) const
|
|||||||
std::vector<Expression *> icinga::MakeIndexer(const String& index1)
|
std::vector<Expression *> icinga::MakeIndexer(const String& index1)
|
||||||
{
|
{
|
||||||
std::vector<Expression *> result;
|
std::vector<Expression *> result;
|
||||||
result.push_back(MakeLiteral(index1));
|
result.push_back(new VariableExpression(index1));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,20 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||||||
|
|
||||||
for (Array::SizeType i = 0; i < m_Indexer.size(); i++) {
|
for (Array::SizeType i = 0; i < m_Indexer.size(); i++) {
|
||||||
Expression *indexExpr = m_Indexer[i];
|
Expression *indexExpr = m_Indexer[i];
|
||||||
String tempindex = indexExpr->Evaluate(frame, dhint);
|
|
||||||
|
String tempindex;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
VariableExpression *vexpr = dynamic_cast<VariableExpression *>(indexExpr);
|
||||||
|
|
||||||
|
if (!vexpr) {
|
||||||
|
object = indexExpr->Evaluate(frame, dhint);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tempindex = vexpr->GetVariable();
|
||||||
|
} else
|
||||||
|
tempindex = indexExpr->Evaluate(frame, dhint);
|
||||||
|
|
||||||
if (psdhint) {
|
if (psdhint) {
|
||||||
sdhint = psdhint->GetChild(tempindex);
|
sdhint = psdhint->GetChild(tempindex);
|
||||||
@ -290,7 +303,7 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
object = VMOps::Indexer(frame, parent, tempindex);
|
object = VMOps::GetField(parent, tempindex);
|
||||||
|
|
||||||
if (i != m_Indexer.size() - 1 && object.IsEmpty()) {
|
if (i != m_Indexer.size() - 1 && object.IsEmpty()) {
|
||||||
object = new Dictionary();
|
object = new Dictionary();
|
||||||
@ -333,7 +346,7 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||||||
|
|
||||||
Value IndexerExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
Value IndexerExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||||
{
|
{
|
||||||
return VMOps::Indexer(frame, m_Operand1->Evaluate(frame), m_Operand2->Evaluate(frame));
|
return VMOps::Indexer(frame, m_Indexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value ImportExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
Value ImportExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||||
|
@ -213,6 +213,11 @@ public:
|
|||||||
: DebuggableExpression(debugInfo), m_Variable(variable)
|
: DebuggableExpression(debugInfo), m_Variable(variable)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
String GetVariable(void) const
|
||||||
|
{
|
||||||
|
return m_Variable;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
|
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
|
||||||
|
|
||||||
@ -532,15 +537,18 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class I2_CONFIG_API IndexerExpression : public BinaryExpression
|
class I2_CONFIG_API IndexerExpression : public DebuggableExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IndexerExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo = DebugInfo())
|
IndexerExpression(const std::vector<Expression *>& indexer, const DebugInfo& debugInfo = DebugInfo())
|
||||||
: BinaryExpression(operand1, operand2, debugInfo)
|
: DebuggableExpression(debugInfo), m_Indexer(indexer)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
|
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Expression *> m_Indexer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class I2_CONFIG_API ImportExpression : public DebuggableExpression
|
class I2_CONFIG_API ImportExpression : public DebuggableExpression
|
||||||
|
@ -72,32 +72,19 @@ public:
|
|||||||
return func->Invoke(arguments);
|
return func->Invoke(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Value Indexer(VMFrame& frame, const Value& value, const String& index)
|
static inline Value Indexer(VMFrame& frame, const std::vector<Expression *>& indexer)
|
||||||
{
|
{
|
||||||
if (value.IsObjectType<Dictionary>()) {
|
Value result = indexer[0]->Evaluate(frame);
|
||||||
Dictionary::Ptr dict = value;
|
|
||||||
return dict->Get(index);
|
|
||||||
} else if (value.IsObjectType<Array>()) {
|
|
||||||
Array::Ptr arr = value;
|
|
||||||
return arr->Get(Convert::ToLong(index));
|
|
||||||
} else if (value.IsObject()) {
|
|
||||||
Object::Ptr object = value;
|
|
||||||
Type::Ptr type = object->GetReflectionType();
|
|
||||||
|
|
||||||
if (!type)
|
for (int i = 1; i < indexer.size(); i++) {
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Dot operator applied to object which does not support reflection"));
|
if (result.IsEmpty())
|
||||||
|
|
||||||
int field = type->GetFieldId(index);
|
|
||||||
|
|
||||||
if (field == -1)
|
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Tried to access invalid property '" + index + "'"));
|
|
||||||
|
|
||||||
return object->GetField(field);
|
|
||||||
} else if (value.IsEmpty()) {
|
|
||||||
return Empty;
|
return Empty;
|
||||||
} else {
|
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Dot operator cannot be applied to type '" + value.GetTypeName() + "'"));
|
Value index = indexer[i]->Evaluate(frame);
|
||||||
|
result = GetField(result, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Value NewFunction(VMFrame& frame, const String& name, const std::vector<String>& args,
|
static inline Value NewFunction(VMFrame& frame, const String& name, const std::vector<String>& args,
|
||||||
@ -234,7 +221,14 @@ public:
|
|||||||
|
|
||||||
if (dict)
|
if (dict)
|
||||||
return dict->Get(field);
|
return dict->Get(field);
|
||||||
else {
|
|
||||||
|
Array::Ptr arr = dynamic_pointer_cast<Array>(context);
|
||||||
|
|
||||||
|
if (arr) {
|
||||||
|
int index = Convert::ToLong(field);
|
||||||
|
return arr->Get(index);
|
||||||
|
}
|
||||||
|
|
||||||
Type::Ptr type = context->GetReflectionType();
|
Type::Ptr type = context->GetReflectionType();
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
@ -247,15 +241,26 @@ public:
|
|||||||
|
|
||||||
return context->GetField(fid);
|
return context->GetField(fid);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value)
|
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value)
|
||||||
{
|
{
|
||||||
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
|
||||||
|
|
||||||
if (dict)
|
if (dict) {
|
||||||
dict->Set(field, value);
|
dict->Set(field, value);
|
||||||
else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Ptr arr = dynamic_pointer_cast<Array>(context);
|
||||||
|
|
||||||
|
if (arr) {
|
||||||
|
int index = Convert::ToLong(field);
|
||||||
|
if (index >= arr->GetLength())
|
||||||
|
arr->Resize(index + 1);
|
||||||
|
arr->Set(index, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Type::Ptr type = context->GetReflectionType();
|
Type::Ptr type = context->GetReflectionType();
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
@ -274,7 +279,6 @@ public:
|
|||||||
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
|
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline Value FunctionWrapper(const std::vector<Value>& arguments,
|
static inline Value FunctionWrapper(const std::vector<Value>& arguments,
|
||||||
|
@ -208,10 +208,9 @@ BOOST_AUTO_TEST_CASE(advanced)
|
|||||||
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
||||||
delete expr;
|
delete expr;
|
||||||
|
|
||||||
/* Uncomment this once #7800 is fixed
|
|
||||||
expr = ConfigCompiler::CompileText("<test>", "local v = { a = 3}; v.a");
|
expr = ConfigCompiler::CompileText("<test>", "local v = { a = 3}; v.a");
|
||||||
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
||||||
delete expr;*/
|
delete expr;
|
||||||
|
|
||||||
expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
|
expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
|
||||||
BOOST_CHECK(expr == NULL);
|
BOOST_CHECK(expr == NULL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user