From ec109b04ddcb3cd725e10b14dc3eee35b19bf7e8 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 9 Nov 2014 19:48:28 +0100 Subject: [PATCH] Refactor the AST refs #7622 --- lib/config/applyrule.cpp | 14 +- lib/config/applyrule.hpp | 20 +- lib/config/config_lexer.ll | 36 +- lib/config/config_parser.yy | 356 ++++++--------- lib/config/configitem.cpp | 12 +- lib/config/configitem.hpp | 6 +- lib/config/configitembuilder.cpp | 32 +- lib/config/configitembuilder.hpp | 4 +- lib/config/expression.cpp | 398 +++++++--------- lib/config/expression.hpp | 604 ++++++++++++++++++++++--- lib/config/objectrule.cpp | 6 +- lib/config/objectrule.hpp | 9 +- lib/icinga/dependency-apply.cpp | 29 +- lib/icinga/notification-apply.cpp | 23 +- lib/icinga/scheduleddowntime-apply.cpp | 20 +- lib/icinga/service-apply.cpp | 20 +- 16 files changed, 961 insertions(+), 628 deletions(-) diff --git a/lib/config/applyrule.cpp b/lib/config/applyrule.cpp index 8509fd00d..d013c6b0a 100644 --- a/lib/config/applyrule.cpp +++ b/lib/config/applyrule.cpp @@ -27,8 +27,8 @@ using namespace icinga; ApplyRule::RuleMap ApplyRule::m_Rules; ApplyRule::CallbackMap ApplyRule::m_Callbacks; -ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, - const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, +ApplyRule::ApplyRule(const String& targetType, const String& name, const boost::shared_ptr& expression, + const boost::shared_ptr& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr& fterm, const DebugInfo& di, const Object::Ptr& scope) : m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar), m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope) @@ -44,12 +44,12 @@ String ApplyRule::GetName(void) const return m_Name; } -Expression::Ptr ApplyRule::GetExpression(void) const +boost::shared_ptr ApplyRule::GetExpression(void) const { return m_Expression; } -Expression::Ptr ApplyRule::GetFilter(void) const +boost::shared_ptr ApplyRule::GetFilter(void) const { return m_Filter; } @@ -64,7 +64,7 @@ String ApplyRule::GetFVVar(void) const return m_FVVar; } -Expression::Ptr ApplyRule::GetFTerm(void) const +boost::shared_ptr ApplyRule::GetFTerm(void) const { return m_FTerm; } @@ -80,8 +80,8 @@ Object::Ptr ApplyRule::GetScope(void) const } void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name, - const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar, - const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope) + const boost::shared_ptr& expression, const boost::shared_ptr& filter, const String& fkvar, + const String& fvvar, const boost::shared_ptr& fterm, const DebugInfo& di, const Object::Ptr& scope) { m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope)); } diff --git a/lib/config/applyrule.hpp b/lib/config/applyrule.hpp index 4682bfe0f..015556672 100644 --- a/lib/config/applyrule.hpp +++ b/lib/config/applyrule.hpp @@ -40,18 +40,18 @@ public: String GetTargetType(void) const; String GetName(void) const; - Expression::Ptr GetExpression(void) const; - Expression::Ptr GetFilter(void) const; + boost::shared_ptr GetExpression(void) const; + boost::shared_ptr GetFilter(void) const; String GetFKVar(void) const; String GetFVVar(void) const; - Expression::Ptr GetFTerm(void) const; + boost::shared_ptr GetFTerm(void) const; DebugInfo GetDebugInfo(void) const; Object::Ptr GetScope(void) const; bool EvaluateFilter(const Object::Ptr& scope) const; - static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression, - const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope); + static void AddRule(const String& sourceType, const String& targetType, const String& name, const boost::shared_ptr& expression, + const boost::shared_ptr& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr& fterm, const DebugInfo& di, const Object::Ptr& scope); static void EvaluateRules(bool clear); static void RegisterType(const String& sourceType, const std::vector& targetTypes, const ApplyRule::Callback& callback); @@ -62,19 +62,19 @@ public: private: String m_TargetType; String m_Name; - Expression::Ptr m_Expression; - Expression::Ptr m_Filter; + boost::shared_ptr m_Expression; + boost::shared_ptr m_Filter; String m_FKVar; String m_FVVar; - Expression::Ptr m_FTerm; + boost::shared_ptr m_FTerm; DebugInfo m_DebugInfo; Object::Ptr m_Scope; static CallbackMap m_Callbacks; static RuleMap m_Rules; - ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, - const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, + ApplyRule(const String& targetType, const String& name, const boost::shared_ptr& expression, + const boost::shared_ptr& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr& fterm, const DebugInfo& di, const Object::Ptr& scope); }; diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index a578707fb..90f03577b 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -234,16 +234,16 @@ __function return T_FUNCTION; __return return T_RETURN; __for return T_FOR; =\> return T_FOLLOWS; -\<\< { yylval->op = &Expression::OpShiftLeft; return T_SHIFT_LEFT; } -\>\> { yylval->op = &Expression::OpShiftRight; return T_SHIFT_RIGHT; } -\<= { yylval->op = &Expression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; } -\>= { yylval->op = &Expression::OpGreaterThanOrEqual; return T_GREATER_THAN_OR_EQUAL; } -== { yylval->op = &Expression::OpEqual; return T_EQUAL; } -!= { yylval->op = &Expression::OpNotEqual; return T_NOT_EQUAL; } -!in { yylval->op = &Expression::OpNotIn; return T_NOT_IN; } -in { yylval->op = &Expression::OpIn; return T_IN; } -&& { yylval->op = &Expression::OpLogicalAnd; return T_LOGICAL_AND; } -\|\| { yylval->op = &Expression::OpLogicalOr; return T_LOGICAL_OR; } +\<\< return T_SHIFT_LEFT; +\>\> return T_SHIFT_RIGHT; +\<= return T_LESS_THAN_OR_EQUAL; +\>= return T_GREATER_THAN_OR_EQUAL; +== return T_EQUAL; +!= return T_NOT_EQUAL; +!in return T_NOT_IN; +in return T_IN; +&& return T_LOGICAL_AND; +\|\| return T_LOGICAL_OR; [a-zA-Z_][a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; } @[a-zA-Z_][a-zA-Z0-9\-_]* { yylval->text = strdup(yytext + 1); return T_IDENTIFIER; } \<[^\>]*\> { yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING_ANGLE; } @@ -258,14 +258,14 @@ in { yylval->op = &Expression::OpIn; return T_IN; } -= { yylval->csop = OpSetSubtract; return T_SET_SUBTRACT; } \*= { yylval->csop = OpSetMultiply; return T_SET_MULTIPLY; } \/= { yylval->csop = OpSetDivide; return T_SET_DIVIDE; } -\+ { yylval->op = &Expression::OpAdd; return T_PLUS; } -\- { yylval->op = &Expression::OpSubtract; return T_MINUS; } -\* { yylval->op = &Expression::OpMultiply; return T_MULTIPLY; } -\/ { yylval->op = &Expression::OpMultiply; return T_DIVIDE_OP; } -\& { yylval->op = &Expression::OpBinaryAnd; return T_BINARY_AND; } -\| { yylval->op = &Expression::OpBinaryOr; return T_BINARY_OR; } -\< { yylval->op = &Expression::OpLessThan; return T_LESS_THAN; } -\> { yylval->op = &Expression::OpLessThan; return T_GREATER_THAN; } +\+ return T_PLUS; +\- return T_MINUS; +\* return T_MULTIPLY; +\/ return T_DIVIDE_OP; +\& return T_BINARY_AND; +\| return T_BINARY_OR; +\< return T_LESS_THAN; +\> return T_GREATER_THAN; } [\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!ignore_newlines) return T_NEWLINE; } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 22fcc22a9..0e362aa6c 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -32,7 +32,6 @@ #include "config/objectrule.hpp" #include "base/value.hpp" #include "base/utility.hpp" -#include "base/array.hpp" #include "base/scriptvariable.hpp" #include "base/exception.hpp" #include "base/dynamictype.hpp" @@ -73,11 +72,10 @@ using namespace icinga; int ignore_newlines = 0; -static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *left, Value *right, DebugInfo& diLeft, DebugInfo& diRight) +template +static void MakeRBinaryOp(Expression** result, Expression *left, Expression *right, DebugInfo& diLeft, DebugInfo& diRight) { - *result = new Value(new Expression(op, *left, *right, DebugInfoRange(diLeft, diRight))); - delete left; - delete right; + *result = new T(left, right, DebugInfoRange(diLeft, diRight)); } %} @@ -94,12 +92,12 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef %union { char *text; double num; + icinga::Expression *expr; icinga::Value *variant; - icinga::Expression::OpCallback op; CombinedSetOp csop; icinga::TypeSpecifier type; std::vector *slist; - Array *array; + std::vector *elist; } %token T_NEWLINE "new-line" @@ -115,24 +113,24 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef %token T_SET_MULTIPLY "*= (T_SET_MULTIPLY)" %token T_SET_DIVIDE "/= (T_SET_DIVIDE)" -%token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)" -%token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)" -%token T_EQUAL "== (T_EQUAL)" -%token T_NOT_EQUAL "!= (T_NOT_EQUAL)" -%token T_IN "in (T_IN)" -%token T_NOT_IN "!in (T_NOT_IN)" -%token T_LOGICAL_AND "&& (T_LOGICAL_AND)" -%token T_LOGICAL_OR "|| (T_LOGICAL_OR)" -%token T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)" -%token T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)" -%token T_PLUS "+ (T_PLUS)" -%token T_MINUS "- (T_MINUS)" -%token T_MULTIPLY "* (T_MULTIPLY)" -%token T_DIVIDE_OP "/ (T_DIVIDE_OP)" -%token T_BINARY_AND "& (T_BINARY_AND)" -%token T_BINARY_OR "| (T_BINARY_OR)" -%token T_LESS_THAN "< (T_LESS_THAN)" -%token T_GREATER_THAN "> (T_GREATER_THAN)" +%token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)" +%token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)" +%token T_EQUAL "== (T_EQUAL)" +%token T_NOT_EQUAL "!= (T_NOT_EQUAL)" +%token T_IN "in (T_IN)" +%token T_NOT_IN "!in (T_NOT_IN)" +%token T_LOGICAL_AND "&& (T_LOGICAL_AND)" +%token T_LOGICAL_OR "|| (T_LOGICAL_OR)" +%token T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)" +%token T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)" +%token T_PLUS "+ (T_PLUS)" +%token T_MINUS "- (T_MINUS)" +%token T_MULTIPLY "* (T_MULTIPLY)" +%token T_DIVIDE_OP "/ (T_DIVIDE_OP)" +%token T_BINARY_AND "& (T_BINARY_AND)" +%token T_BINARY_OR "| (T_BINARY_OR)" +%token T_LESS_THAN "< (T_LESS_THAN)" +%token T_GREATER_THAN "> (T_GREATER_THAN)" %token T_CONST "const (T_CONST)" %token T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)" @@ -165,25 +163,25 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef %token T_FOLLOWS "=> (T_FOLLOWS)" %type identifier -%type rterm_items -%type rterm_items_inner -%type identifier_items -%type identifier_items_inner -%type indexer -%type indexer_items -%type indexer_item -%type lterm_items -%type lterm_items_inner +%type rterm_items +%type rterm_items_inner +%type identifier_items +%type identifier_items_inner +%type indexer +%type indexer_items +%type indexer_item +%type lterm_items +%type lterm_items_inner %type typerulelist %type combined_set_op %type type -%type rterm -%type rterm_array -%type rterm_scope -%type lterm -%type object -%type apply -%type optional_rterm +%type rterm +%type rterm_array +%type rterm_scope +%type lterm +%type object +%type apply +%type optional_rterm %type target_type_specifier %left T_LOGICAL_OR @@ -223,11 +221,11 @@ static Dictionary::Ptr m_ModuleScope; static std::stack m_Apply; static std::stack m_ObjectAssign; static std::stack m_SeenAssign; -static std::stack m_Assign; -static std::stack m_Ignore; +static std::stack m_Assign; +static std::stack m_Ignore; static std::stack m_FKVar; static std::stack m_FVVar; -static std::stack m_FTerm; +static std::stack m_FTerm; void ConfigCompiler::Compile(void) { @@ -239,11 +237,11 @@ void ConfigCompiler::Compile(void) m_Apply = std::stack(); m_ObjectAssign = std::stack(); m_SeenAssign = std::stack(); - m_Assign = std::stack(); - m_Ignore = std::stack(); + m_Assign = std::stack(); + m_Ignore = std::stack(); m_FKVar = std::stack(); m_FVVar = std::stack(); - m_FTerm = std::stack(); + m_FTerm = std::stack(); try { yyparse(this); @@ -270,18 +268,15 @@ statement: type | include | include_recursive | library | constant { } | lterm { - Expression::Ptr aexpr = *$1; - aexpr->Evaluate(m_ModuleScope); + $1->Evaluate(m_ModuleScope); delete $1; } ; include: T_INCLUDE rterm sep { - Expression::Ptr aexpr = *$2; + context->HandleInclude($2->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2)); delete $2; - - context->HandleInclude(aexpr->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2)); } | T_INCLUDE T_STRING_ANGLE { @@ -292,20 +287,14 @@ include: T_INCLUDE rterm sep include_recursive: T_INCLUDE_RECURSIVE rterm { - Expression::Ptr aexpr = *$2; + context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2)); delete $2; - - context->HandleIncludeRecursive(aexpr->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2)); } | T_INCLUDE_RECURSIVE rterm ',' rterm { - Expression::Ptr aexpr1 = *$2; + context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), $4->Evaluate(m_ModuleScope), DebugInfoRange(@1, @4)); delete $2; - - Expression::Ptr aexpr2 = *$4; delete $4; - - context->HandleIncludeRecursive(aexpr1->Evaluate(m_ModuleScope), aexpr2->Evaluate(m_ModuleScope), DebugInfoRange(@1, @4)); } ; @@ -318,13 +307,11 @@ library: T_LIBRARY T_STRING sep constant: T_CONST identifier T_SET rterm sep { - Expression::Ptr aexpr = *$4; + ScriptVariable::Ptr sv = ScriptVariable::Set($2, $4->Evaluate(m_ModuleScope)); + free($2); delete $4; - ScriptVariable::Ptr sv = ScriptVariable::Set($2, aexpr->Evaluate(m_ModuleScope)); sv->SetConstant(true); - - free($2); } ; @@ -447,20 +434,13 @@ object: { m_ObjectAssign.pop(); - Array::Ptr args = new Array(); - - args->Add(m_Abstract.top()); + bool abstract = m_Abstract.top(); m_Abstract.pop(); String type = $3; - args->Add(type); free($3); - args->Add(*$4); - delete $4; - - Expression::Ptr exprl = *$5; - delete $5; + DictExpression *exprl = dynamic_cast($5); exprl->MakeInline(); if (m_SeenAssign.top() && !ObjectRule::IsValidSourceType(type)) @@ -468,17 +448,13 @@ object: m_SeenAssign.pop(); - Expression::Ptr rex = new Expression(&Expression::OpLogicalNegate, m_Ignore.top(), DebugInfoRange(@2, @5)); + Expression *rex = new LogicalNegateExpression(m_Ignore.top(), DebugInfoRange(@2, @5)); m_Ignore.pop(); - Expression::Ptr filter = new Expression(&Expression::OpLogicalAnd, m_Assign.top(), rex, DebugInfoRange(@2, @5)); + Expression *filter = new LogicalAndExpression(m_Assign.top(), rex, DebugInfoRange(@2, @5)); m_Assign.pop(); - args->Add(filter); - - args->Add(context->GetZone()); - - $$ = new Value(new Expression(&Expression::OpObject, args, exprl, DebugInfoRange(@2, @5))); + $$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), exprl, DebugInfoRange(@2, @5)); } ; @@ -500,12 +476,12 @@ identifier_items: identifier_items_inner identifier_items_inner: /* empty */ { - $$ = new Array(); + $$ = new std::vector(); } | identifier { - $$ = new Array(); - $$->Add($1); + $$ = new std::vector(); + $$->push_back($1); free($1); } | identifier_items_inner ',' identifier @@ -513,44 +489,42 @@ identifier_items_inner: /* empty */ if ($1) $$ = $1; else - $$ = new Array(); + $$ = new std::vector(); - $$->Add($3); + $$->push_back($3); free($3); } ; indexer: identifier { - $$ = new Array(); - $$->Add(MakeLiteral($1)); + $$ = new std::vector(); + $$->push_back(MakeLiteral($1)); free($1); } | identifier indexer_items { $$ = $2; - $$->Insert(0, MakeLiteral($1)); + $$->insert($$->begin(), MakeLiteral($1)); free($1); } ; indexer_items: indexer_item { - $$ = new Array(); - $$->Add(*$1); - delete $1; + $$ = new std::vector(); + $$->push_back($1); } | indexer_items indexer_item { $$ = $1; - $$->Add(*$2); - delete $2; + $$->push_back($2); } ; indexer_item: '.' identifier { - $$ = new Value(MakeLiteral($2)); + $$ = MakeLiteral($2); free($2); } | '[' rterm ']' @@ -571,7 +545,7 @@ combined_set_op: T_SET lterm_items: /* empty */ { - $$ = new Array(); + $$ = new std::vector(); } | lterm_items_inner { @@ -584,32 +558,29 @@ lterm_items: /* empty */ lterm_items_inner: lterm { - $$ = new Array(); - $$->Add(*$1); - delete $1; + $$ = new std::vector(); + $$->push_back($1); } | lterm_items_inner sep lterm { if ($1) $$ = $1; else - $$ = new Array(); + $$ = new std::vector(); - $$->Add(*$3); - delete $3; + $$->push_back($3); } ; lterm: indexer combined_set_op rterm { - $$ = new Value(new Expression(&Expression::OpSet, MakeArray(Array::Ptr($1), $2), *$3, DebugInfoRange(@1, @3))); - delete $3; + $$ = new SetExpression(*$1, $2, $3, DebugInfoRange(@1, @3)); + delete $1; } | T_IMPORT rterm { - Expression::Ptr avar = new Expression(&Expression::OpVariable, "type", DebugInfoRange(@1, @2)); - $$ = new Value(new Expression(&Expression::OpImport, avar, *$2, DebugInfoRange(@1, @2))); - delete $2; + Expression *avar = new VariableExpression("type", DebugInfoRange(@1, @2)); + $$ = new ImportExpression(avar, $2, DebugInfoRange(@1, @2)); } | T_ASSIGN T_WHERE rterm { @@ -618,27 +589,24 @@ lterm: indexer combined_set_op rterm m_SeenAssign.top() = true; - m_Assign.top() = new Expression(&Expression::OpLogicalOr, m_Assign.top(), *$3, DebugInfoRange(@1, @3)); - delete $3; + m_Assign.top() = new LogicalOrExpression(m_Assign.top(), $3, DebugInfoRange(@1, @3)); - $$ = new Value(MakeLiteral()); + $$ = MakeLiteral(); } | T_IGNORE T_WHERE rterm { if ((m_Apply.empty() || !m_Apply.top()) && (m_ObjectAssign.empty() || !m_ObjectAssign.top())) BOOST_THROW_EXCEPTION(ConfigError("'ignore' keyword not valid in this context.")); - m_Ignore.top() = new Expression(&Expression::OpLogicalOr, m_Ignore.top(), *$3, DebugInfoRange(@1, @3)); - delete $3; + m_Ignore.top() = new LogicalOrExpression(m_Ignore.top(), $3, DebugInfoRange(@1, @3)); - $$ = new Value(MakeLiteral()); + $$ = MakeLiteral(); } | T_RETURN rterm { - Expression::Ptr aname = MakeLiteral("__result"); - $$ = new Value(new Expression(&Expression::OpSet, MakeArray(MakeArray(MakeLiteral(aname)), OpSetLiteral), *$2, DebugInfoRange(@1, @2))); - delete $2; - + std::vector vname; + vname.push_back(MakeLiteral("__result")); + $$ = new SetExpression(vname, OpSetLiteral, $2, DebugInfoRange(@1, @2)); } | apply { @@ -656,7 +624,7 @@ lterm: indexer combined_set_op rterm rterm_items: /* empty */ { - $$ = new Array(); + $$ = new std::vector(); } | rterm_items_inner { @@ -670,98 +638,99 @@ rterm_items: /* empty */ rterm_items_inner: rterm { - $$ = new Array(); - $$->Add(*$1); - delete $1; + $$ = new std::vector(); + $$->push_back($1); } | rterm_items_inner arraysep rterm { $$ = $1; - $$->Add(*$3); - delete $3; + $$->push_back($3); } ; rterm_array: '[' newlines rterm_items newlines ']' { - $$ = new Value(new Expression(&Expression::OpArray, Array::Ptr($3), DebugInfoRange(@1, @5))); + $$ = new ArrayExpression(*$3, DebugInfoRange(@1, @5)); + delete $3; } | '[' newlines rterm_items ']' { - $$ = new Value(new Expression(&Expression::OpArray, Array::Ptr($3), DebugInfoRange(@1, @4))); + $$ = new ArrayExpression(*$3, DebugInfoRange(@1, @4)); + delete $3; } | '[' rterm_items newlines ']' { - $$ = new Value(new Expression(&Expression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @4))); + $$ = new ArrayExpression(*$2, DebugInfoRange(@1, @4)); + delete $2; } | '[' rterm_items ']' { - $$ = new Value(new Expression(&Expression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3))); + $$ = new ArrayExpression(*$2, DebugInfoRange(@1, @3)); + delete $2; } ; rterm_scope: '{' newlines lterm_items newlines '}' { - $$ = new Value(new Expression(&Expression::OpDict, Array::Ptr($3), DebugInfoRange(@1, @5))); + $$ = new DictExpression(*$3, DebugInfoRange(@1, @5)); + delete $3; } | '{' newlines lterm_items '}' { - $$ = new Value(new Expression(&Expression::OpDict, Array::Ptr($3), DebugInfoRange(@1, @4))); + $$ = new DictExpression(*$3, DebugInfoRange(@1, @4)); + delete $3; } | '{' lterm_items newlines '}' { - $$ = new Value(new Expression(&Expression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @4))); + $$ = new DictExpression(*$2, DebugInfoRange(@1, @4)); + delete $2; } | '{' lterm_items '}' { - $$ = new Value(new Expression(&Expression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @3))); + $$ = new DictExpression(*$2, DebugInfoRange(@1, @3)); + delete $2; } ; rterm: T_STRING { - $$ = new Value(MakeLiteral($1)); + $$ = MakeLiteral($1); free($1); } | T_NUMBER { - $$ = new Value(MakeLiteral($1)); + $$ = MakeLiteral($1); } | T_NULL { - $$ = new Value(MakeLiteral()); + $$ = MakeLiteral(); } | rterm '.' T_IDENTIFIER { - $$ = new Value(new Expression(&Expression::OpIndexer, *$1, MakeLiteral($3), DebugInfoRange(@1, @3))); - delete $1; + $$ = new IndexerExpression($1, MakeLiteral($3), DebugInfoRange(@1, @3)); free($3); } | rterm '(' rterm_items ')' { - $$ = new Value(new Expression(&Expression::OpFunctionCall, *$1, MakeLiteral(Array::Ptr($3)), DebugInfoRange(@1, @4))); - delete $1; + $$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4)); + delete $3; } | T_IDENTIFIER { - $$ = new Value(new Expression(&Expression::OpVariable, $1, @1)); + $$ = new VariableExpression($1, @1); free($1); } | '!' rterm { - $$ = new Value(new Expression(&Expression::OpLogicalNegate, *$2, DebugInfoRange(@1, @2))); - delete $2; + $$ = new LogicalNegateExpression($2, DebugInfoRange(@1, @2)); } | '~' rterm { - $$ = new Value(new Expression(&Expression::OpNegate, *$2, DebugInfoRange(@1, @2))); - delete $2; + $$ = new NegateExpression($2, DebugInfoRange(@1, @2)); } | rterm '[' rterm ']' { - $$ = new Value(new Expression(&Expression::OpIndexer, *$1, *$3, DebugInfoRange(@1, @4))); - delete $1; - delete $3; + $$ = new IndexerExpression($1, $3, DebugInfoRange(@1, @4)); } | rterm_array { @@ -780,62 +749,50 @@ rterm: T_STRING ignore_newlines--; $$ = $3; } - | rterm T_LOGICAL_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_LOGICAL_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_BINARY_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_BINARY_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_IN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_NOT_IN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_NOT_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_LESS_THAN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_LESS_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_GREATER_THAN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_GREATER_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_SHIFT_LEFT rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_SHIFT_RIGHT rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_PLUS rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_MINUS rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_MULTIPLY rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } - | rterm T_DIVIDE_OP rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } + | rterm T_LOGICAL_OR rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_LOGICAL_AND rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_BINARY_OR rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_BINARY_AND rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_IN rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_NOT_IN rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_EQUAL rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_NOT_EQUAL rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_LESS_THAN rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_LESS_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_GREATER_THAN rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_GREATER_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_SHIFT_LEFT rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_SHIFT_RIGHT rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_PLUS rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_MINUS rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_MULTIPLY rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } + | rterm T_DIVIDE_OP rterm { MakeRBinaryOp(&$$, $1, $3, @1, @3); } | T_FUNCTION identifier '(' identifier_items ')' rterm_scope { - Expression::Ptr aexpr = *$6; - delete $6; + DictExpression *aexpr = dynamic_cast($6); aexpr->MakeInline(); - $$ = new Value(new Expression(&Expression::OpFunction, MakeArray($2, aexpr), Array::Ptr($4), DebugInfoRange(@1, @6))); + $$ = new FunctionExpression($2, *$4, aexpr, DebugInfoRange(@1, @6)); free($2); + delete $4; } | T_FUNCTION '(' identifier_items ')' rterm_scope { - Expression::Ptr aexpr = *$5; - delete $5; + DictExpression *aexpr = dynamic_cast($5); aexpr->MakeInline(); - $$ = new Value(new Expression(&Expression::OpFunction, MakeArray(Empty, aexpr), Array::Ptr($3), DebugInfoRange(@1, @5))); + $$ = new FunctionExpression("", *$3, aexpr, DebugInfoRange(@1, @5)); + delete $3; } | T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope { - Expression::Ptr aexpr = *$7; - delete $7; - - Expression::Ptr ascope = *$9; - delete $9; - - $$ = new Value(new Expression(&Expression::OpFor, MakeArray($3, $5, aexpr), ascope, DebugInfoRange(@1, @9))); + $$ = new ForExpression($3, $5, $7, $9, DebugInfoRange(@1, @9)); free($3); free($5); } | T_FOR '(' identifier T_IN rterm ')' rterm_scope { - Expression::Ptr aexpr = *$5; - delete $5; - - Expression::Ptr ascope = *$7; - delete $7; - - $$ = new Value(new Expression(&Expression::OpFor, MakeArray($3, Empty, aexpr), ascope, DebugInfoRange(@1, @7))); + $$ = new ForExpression($3, "", $5, $7, DebugInfoRange(@1, @7)); free($3); } ; @@ -859,8 +816,7 @@ apply_for_specifier: /* empty */ m_FVVar.top() = $5; free($5); - m_FTerm.top() = *$7; - delete $7; + m_FTerm.top() = $7; } | T_APPLY_FOR '(' identifier T_IN rterm ')' { @@ -869,14 +825,13 @@ apply_for_specifier: /* empty */ m_FVVar.top() = ""; - m_FTerm.top() = *$5; - delete $5; + m_FTerm.top() = $5; } ; optional_rterm: /* empty */ { - $$ = new Value(MakeLiteral(Empty)); + $$ = MakeLiteral(); } | rterm { @@ -892,7 +847,7 @@ apply: m_Ignore.push(MakeLiteral(false)); m_FKVar.push(""); m_FVVar.push(""); - m_FTerm.push(Expression::Ptr()); + m_FTerm.push(NULL); } T_APPLY identifier optional_rterm apply_for_specifier target_type_specifier rterm { @@ -900,8 +855,6 @@ apply: String type = $3; free($3); - Expression::Ptr aname = *$4; - delete $4; String target = $6; free($6); @@ -929,9 +882,7 @@ apply: BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5))); } - Expression::Ptr exprl = *$7; - delete $7; - + DictExpression *exprl = dynamic_cast($7); exprl->MakeInline(); // assign && !ignore @@ -940,10 +891,10 @@ apply: m_SeenAssign.pop(); - Expression::Ptr rex = new Expression(&Expression::OpLogicalNegate, m_Ignore.top(), DebugInfoRange(@2, @5)); + Expression *rex = new LogicalNegateExpression(m_Ignore.top(), DebugInfoRange(@2, @5)); m_Ignore.pop(); - Expression::Ptr filter = new Expression(&Expression::OpLogicalAnd, m_Assign.top(), rex, DebugInfoRange(@2, @5)); + Expression *filter = new LogicalAndExpression(m_Assign.top(), rex, DebugInfoRange(@2, @5)); m_Assign.pop(); String fkvar = m_FKVar.top(); @@ -952,19 +903,10 @@ apply: String fvvar = m_FVVar.top(); m_FVVar.pop(); - Expression::Ptr fterm = m_FTerm.top(); + Expression *fterm = m_FTerm.top(); m_FTerm.pop(); - Array::Ptr args = new Array(); - args->Add(type); - args->Add(target); - args->Add(aname); - args->Add(filter); - args->Add(fkvar); - args->Add(fvvar); - args->Add(fterm); - - $$ = new Value(new Expression(&Expression::OpApply, args, exprl, DebugInfoRange(@2, @5))); + $$ = new ApplyExpression(type, target, $4, filter, fkvar, fvvar, fterm, exprl, DebugInfoRange(@2, @5)); } ; diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 65c1da063..53ac6e317 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -56,11 +56,11 @@ ConfigItem::ItemList ConfigItem::m_UnnamedItems; * @param debuginfo Debug information. */ ConfigItem::ConfigItem(const String& type, const String& name, - bool abstract, const Expression::Ptr& exprl, + bool abstract, const boost::shared_ptr& exprl, const DebugInfo& debuginfo, const Object::Ptr& scope, const String& zone) : m_Type(type), m_Name(name), m_Abstract(abstract), - m_ExpressionList(exprl), m_DebugInfo(debuginfo), + m_Expression(exprl), m_DebugInfo(debuginfo), m_Scope(scope), m_Zone(zone) { } @@ -115,9 +115,9 @@ Object::Ptr ConfigItem::GetScope(void) const * * @returns The expression list. */ -Expression::Ptr ConfigItem::GetExpressionList(void) const +boost::shared_ptr ConfigItem::GetExpression(void) const { - return m_ExpressionList; + return m_Expression; } /** @@ -160,7 +160,7 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard) DebugHint debugHints; try { - m_ExpressionList->Evaluate(dobj, &debugHints); + m_Expression->Evaluate(dobj, &debugHints); } catch (const ConfigError& ex) { const DebugInfo *di = boost::get_error_info(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo()); @@ -169,7 +169,7 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard) } if (discard) - m_ExpressionList.reset(); + m_Expression.reset(); dobj->SetParentScope(Dictionary::Ptr()); diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index ea6bd6d06..51a74fccc 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -38,7 +38,7 @@ public: DECLARE_PTR_TYPEDEFS(ConfigItem); ConfigItem(const String& type, const String& name, bool abstract, - const Expression::Ptr& exprl, const DebugInfo& debuginfo, + const boost::shared_ptr& exprl, const DebugInfo& debuginfo, const Object::Ptr& scope, const String& zone); String GetType(void) const; @@ -47,7 +47,7 @@ public: std::vector GetParents(void) const; - Expression::Ptr GetExpressionList(void) const; + boost::shared_ptr GetExpression(void) const; DynamicObject::Ptr Commit(bool discard = true); void Register(void); @@ -70,7 +70,7 @@ private: String m_Name; /**< The name. */ bool m_Abstract; /**< Whether this is a template. */ - Expression::Ptr m_ExpressionList; + boost::shared_ptr m_Expression; std::vector m_ParentNames; /**< The names of parent configuration items. */ DebugInfo m_DebugInfo; /**< Debug information. */ diff --git a/lib/config/configitembuilder.cpp b/lib/config/configitembuilder.cpp index 7820aedf2..994a9dac2 100644 --- a/lib/config/configitembuilder.cpp +++ b/lib/config/configitembuilder.cpp @@ -25,7 +25,7 @@ using namespace icinga; ConfigItemBuilder::ConfigItemBuilder(void) - : m_Abstract(false), m_Expressions(new Array()) + : m_Abstract(false) { m_DebugInfo.FirstLine = 0; m_DebugInfo.FirstColumn = 0; @@ -34,7 +34,7 @@ ConfigItemBuilder::ConfigItemBuilder(void) } ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo) - : m_Abstract(false), m_Expressions(new Array()) + : m_Abstract(false) { m_DebugInfo = debugInfo; } @@ -64,9 +64,9 @@ void ConfigItemBuilder::SetZone(const String& zone) m_Zone = zone; } -void ConfigItemBuilder::AddExpression(const Expression::Ptr& expr) +void ConfigItemBuilder::AddExpression(Expression *expr) { - m_Expressions->Add(expr); + m_Expressions.push_back(expr); } ConfigItem::Ptr ConfigItemBuilder::Compile(void) @@ -89,19 +89,25 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void) BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str())); } - Array::Ptr exprs = new Array(); + std::vector exprs; + Array::Ptr templateArray = new Array(); templateArray->Add(m_Name); - exprs->Add(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("templates")), OpSetAdd), - new Expression(&Expression::OpLiteral, templateArray, m_DebugInfo), - m_DebugInfo)); + std::vector indexer; + indexer.push_back(new LiteralExpression("templates")); - exprs->Add(new Expression(&Expression::OpDict, m_Expressions, true, m_DebugInfo)); - - Expression::Ptr exprl = new Expression(&Expression::OpDict, exprs, true, m_DebugInfo); + exprs.push_back(new SetExpression(indexer, OpSetAdd, + new LiteralExpression(templateArray), m_DebugInfo)); - return new ConfigItem(m_Type, m_Name, m_Abstract, exprl, + DictExpression *dexpr = new DictExpression(m_Expressions, m_DebugInfo); + dexpr->MakeInline(); + exprs.push_back(dexpr); + + DictExpression *exprl = new DictExpression(exprs, m_DebugInfo); + exprl->MakeInline(); + + return new ConfigItem(m_Type, m_Name, m_Abstract, boost::shared_ptr(exprl), m_DebugInfo, m_Scope, m_Zone); } + diff --git a/lib/config/configitembuilder.hpp b/lib/config/configitembuilder.hpp index 923ce138f..b9795c6cc 100644 --- a/lib/config/configitembuilder.hpp +++ b/lib/config/configitembuilder.hpp @@ -48,7 +48,7 @@ public: void SetScope(const Object::Ptr& scope); void SetZone(const String& zone); - void AddExpression(const Expression::Ptr& expr); + void AddExpression(Expression *expr); ConfigItem::Ptr Compile(void); @@ -56,7 +56,7 @@ private: String m_Type; /**< The object type. */ String m_Name; /**< The name. */ bool m_Abstract; /**< Whether the item is abstract. */ - Array::Ptr m_Expressions; /**< Expressions for this item. */ + std::vector m_Expressions; /**< Expressions for this item. */ DebugInfo m_DebugInfo; /**< Debug information. */ Object::Ptr m_Scope; /**< variable scope. */ String m_Zone; /**< The zone. */ diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index b1514d70b..0e6cd204a 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -38,219 +38,212 @@ using namespace icinga; -Expression::Expression(OpCallback op, const Value& operand1, const DebugInfo& di) - : m_Operator(op), m_Operand1(operand1), m_Operand2(), m_DebugInfo(di) -{ } - -Expression::Expression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di) - : m_Operator(op), m_Operand1(operand1), m_Operand2(operand2), m_DebugInfo(di) +Expression::~Expression(void) { } Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const { try { #ifdef _DEBUG - if (m_Operator != &Expression::OpLiteral) { - std::ostringstream msgbuf; - ShowCodeFragment(msgbuf, m_DebugInfo, false); - Log(LogDebug, "Expression") - << "Executing:\n" << msgbuf.str(); - } + std::ostringstream msgbuf; + ShowCodeFragment(msgbuf, GetDebugInfo(), false); + Log(LogDebug, "Expression") + << "Executing:\n" << msgbuf.str(); #endif /* _DEBUG */ - return m_Operator(this, context, dhint); + return DoEvaluate(context, dhint); } catch (const std::exception& ex) { if (boost::get_error_info(ex)) throw; else - BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression: " + String(ex.what())) << boost::errinfo_nested_exception(boost::current_exception()) << errinfo_debuginfo(m_DebugInfo)); + BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression: " + String(ex.what())) + << boost::errinfo_nested_exception(boost::current_exception()) + << errinfo_debuginfo(GetDebugInfo())); } } -void Expression::MakeInline(void) +const DebugInfo& Expression::GetDebugInfo(void) const { - if (m_Operator == &Expression::OpDict) - m_Operand2 = true; + static DebugInfo debugInfo; + return debugInfo; } -void Expression::DumpOperand(std::ostream& stream, const Value& operand, int indent) { - if (operand.IsObjectType()) { - Array::Ptr arr = operand; - stream << String(indent, ' ') << "Array:\n"; - ObjectLock olock(arr); - BOOST_FOREACH(const Value& elem, arr) { - DumpOperand(stream, elem, indent + 1); - } - } else if (operand.IsObjectType()) { - Expression::Ptr left = operand; - left->Dump(stream, indent); - } else { - stream << String(indent, ' ') << JsonEncode(operand) << "\n"; - } -} - -void Expression::Dump(std::ostream& stream, int indent) const +std::vector icinga::MakeIndexer(const String& index1) { - String sym = Utility::GetSymbolName(reinterpret_cast(m_Operator)); - stream << String(indent, ' ') << "op: " << Utility::DemangleSymbolName(sym) << "\n"; - stream << String(indent, ' ') << "left:\n"; - DumpOperand(stream, m_Operand1, indent + 1); - - stream << String(indent, ' ') << "right:\n"; - DumpOperand(stream, m_Operand2, indent + 1); + std::vector result; + result.push_back(MakeLiteral(index1)); + return result; } -Value Expression::EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint) const +void DictExpression::MakeInline(void) { - return static_cast(m_Operand1)->Evaluate(context, dhint); + m_Inline = true; } -Value Expression::EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint) const +LiteralExpression::LiteralExpression(const Value& value) + : m_Value(value) +{ } + +Value LiteralExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return static_cast(m_Operand2)->Evaluate(context, dhint); + return m_Value; } -Value Expression::OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +const DebugInfo& DebuggableExpression::GetDebugInfo(void) const { - return expr->m_Operand1; + return m_DebugInfo; } -Value Expression::OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value VariableExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { Object::Ptr scope = context; while (scope) { - if (HasField(scope, expr->m_Operand1)) - return GetField(scope, expr->m_Operand1); + if (HasField(scope, m_Variable)) + return GetField(scope, m_Variable); scope = GetField(scope, "__parent"); } - return ScriptVariable::Get(expr->m_Operand1); + return ScriptVariable::Get(m_Variable); } -Value Expression::OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value NegateExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return ~(long)expr->EvaluateOperand1(context); + return ~(long)m_Operand->Evaluate(context); } -Value Expression::OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value LogicalNegateExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return !expr->EvaluateOperand1(context).ToBool(); + return !m_Operand->Evaluate(context).ToBool(); } -Value Expression::OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value AddExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) + expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) + m_Operand2->Evaluate(context); } -Value Expression::OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value SubtractExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) - expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) - m_Operand2->Evaluate(context); } -Value Expression::OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value MultiplyExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) * expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) * m_Operand2->Evaluate(context); } -Value Expression::OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value DivideExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) / expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) / m_Operand2->Evaluate(context); } -Value Expression::OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value BinaryAndExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) & expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) & m_Operand2->Evaluate(context); } -Value Expression::OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value BinaryOrExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) | expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) | m_Operand2->Evaluate(context); } -Value Expression::OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value ShiftLeftExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) << expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) << m_Operand2->Evaluate(context); } -Value Expression::OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value ShiftRightExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) >> expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) >> m_Operand2->Evaluate(context); } -Value Expression::OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value EqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) == expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) == m_Operand2->Evaluate(context); } -Value Expression::OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value NotEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) != expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) != m_Operand2->Evaluate(context); } -Value Expression::OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value LessThanExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) < expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) < m_Operand2->Evaluate(context); } -Value Expression::OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value GreaterThanExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) > expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) > m_Operand2->Evaluate(context); } -Value Expression::OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value LessThanOrEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) <= expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) <= m_Operand2->Evaluate(context); } -Value Expression::OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value GreaterThanOrEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context) >= expr->EvaluateOperand2(context); + return m_Operand1->Evaluate(context) >= m_Operand2->Evaluate(context); } -Value Expression::OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value InExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Value right = expr->EvaluateOperand2(context); + Value right = m_Operand2->Evaluate(context); if (right.IsEmpty()) return false; else if (!right.IsObjectType()) BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right))); - Value left = expr->EvaluateOperand1(context); + Value left = m_Operand1->Evaluate(context); Array::Ptr arr = right; - bool found = false; ObjectLock olock(arr); BOOST_FOREACH(const Value& value, arr) { if (value == left) { - found = true; - break; + return true; } } - return found; + return false; } -Value Expression::OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value NotInExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return !OpIn(expr, context, dhint); + Value right = m_Operand2->Evaluate(context); + + if (right.IsEmpty()) + return false; + else if (!right.IsObjectType()) + BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right))); + + Value left = m_Operand1->Evaluate(context); + + Array::Ptr arr = right; + ObjectLock olock(arr); + BOOST_FOREACH(const Value& value, arr) { + if (value == left) + return false; + } + + return true; } -Value Expression::OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value LogicalAndExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context).ToBool() && expr->EvaluateOperand2(context).ToBool(); + return m_Operand1->Evaluate(context).ToBool() && m_Operand2->Evaluate(context).ToBool(); } -Value Expression::OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value LogicalOrExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - return expr->EvaluateOperand1(context).ToBool() || expr->EvaluateOperand2(context).ToBool(); + return m_Operand1->Evaluate(context).ToBool() || m_Operand2->Evaluate(context).ToBool(); } -Value Expression::OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value FunctionCallExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Value funcName = expr->EvaluateOperand1(context); + Value funcName = m_FName->Evaluate(context); ScriptFunction::Ptr func; @@ -262,48 +255,37 @@ Value Expression::OpFunctionCall(const Expression *expr, const Object::Ptr& cont if (!func) BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist.")); - Array::Ptr arr = expr->EvaluateOperand2(context); std::vector arguments; - for (Array::SizeType index = 0; index < arr->GetLength(); index++) { - const Expression::Ptr& aexpr = arr->Get(index); - arguments.push_back(aexpr->Evaluate(context)); + BOOST_FOREACH(Expression *arg, m_Args) { + arguments.push_back(arg->Evaluate(context)); } return func->Invoke(arguments); } -Value Expression::OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value ArrayExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr arr = expr->m_Operand1; Array::Ptr result = new Array(); - if (arr) { - for (Array::SizeType index = 0; index < arr->GetLength(); index++) { - const Expression::Ptr& aexpr = arr->Get(index); - result->Add(aexpr->Evaluate(context)); - } + BOOST_FOREACH(Expression *aexpr, m_Expressions) { + result->Add(aexpr->Evaluate(context)); } return result; } -Value Expression::OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value DictExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr arr = expr->m_Operand1; - bool in_place = expr->m_Operand2; Dictionary::Ptr result = new Dictionary(); result->Set("__parent", context); - if (arr) { - for (Array::SizeType index = 0; index < arr->GetLength(); index++) { - const Expression::Ptr& aexpr = arr->Get(index); - Object::Ptr acontext = in_place ? context : result; - aexpr->Evaluate(acontext, dhint); + BOOST_FOREACH(Expression *aexpr, m_Expressions) { + Object::Ptr acontext = m_Inline ? context : result; + aexpr->Evaluate(acontext, dhint); - if (HasField(acontext, "__result")) - break; - } + if (HasField(acontext, "__result")) + break; } Dictionary::Ptr xresult = result->ShallowClone(); @@ -311,22 +293,18 @@ Value Expression::OpDict(const Expression *expr, const Object::Ptr& context, Deb return xresult; } -Value Expression::OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr left = expr->m_Operand1; - Array::Ptr indexer = left->Get(0); - int csop = left->Get(1); - DebugHint *sdhint = dhint; Value parent, object; String index; - for (Array::SizeType i = 0; i < indexer->GetLength(); i++) { - Expression::Ptr indexExpr = indexer->Get(i); + for (Array::SizeType i = 0; i < m_Indexer.size(); i++) { + Expression *indexExpr = m_Indexer[i]; String tempindex = indexExpr->Evaluate(context, dhint); - if (i == indexer->GetLength() - 1) + if (i == m_Indexer.size() - 1) index = tempindex; if (i == 0) { @@ -335,65 +313,59 @@ Value Expression::OpSet(const Expression *expr, const Object::Ptr& context, Debu } else { parent = object; - Expression::Ptr eparent = new Expression(&Expression::OpLiteral, parent, expr->m_DebugInfo); - Expression::Ptr eindex = new Expression(&Expression::OpLiteral, tempindex, expr->m_DebugInfo); + LiteralExpression *eparent = MakeLiteral(parent); + LiteralExpression *eindex = MakeLiteral(tempindex); - Expression::Ptr eip = new Expression(&Expression::OpIndexer, eparent, eindex, expr->m_DebugInfo); - object = eip->Evaluate(context, dhint); + IndexerExpression eip(eparent, eindex, m_DebugInfo); + object = eip.Evaluate(context, dhint); } if (sdhint) sdhint = sdhint->GetChild(index); - if (i != indexer->GetLength() - 1 && object.IsEmpty()) { + if (i != m_Indexer.size() - 1 && object.IsEmpty()) { object = new Dictionary(); SetField(parent, tempindex, object); } } - Value right = expr->EvaluateOperand2(context, dhint); + Value right = m_Operand2->Evaluate(context, dhint); - if (csop != OpSetLiteral) { - Expression::OpCallback op; + if (m_Op != OpSetLiteral) { + Expression *lhs = MakeLiteral(object); + Expression *rhs = MakeLiteral(right); - switch (csop) { + switch (m_Op) { case OpSetAdd: - op = &Expression::OpAdd; + right = AddExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint); break; case OpSetSubtract: - op = &Expression::OpSubtract; + right = SubtractExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint); break; case OpSetMultiply: - op = &Expression::OpMultiply; + right = MultiplyExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint); break; case OpSetDivide: - op = &Expression::OpDivide; + right = DivideExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint); break; default: VERIFY(!"Invalid opcode."); } - - Expression::Ptr ecp = new Expression(op, - new Expression(&Expression::OpLiteral, object, expr->m_DebugInfo), - new Expression(&Expression::OpLiteral, right, expr->m_DebugInfo), - expr->m_DebugInfo); - - right = ecp->Evaluate(context, dhint); } SetField(parent, index, right); if (sdhint) - sdhint->AddMessage("=", expr->m_DebugInfo); + sdhint->AddMessage("=", m_DebugInfo); return right; } -Value Expression::OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value IndexerExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Value value = expr->EvaluateOperand1(context); - Value index = expr->EvaluateOperand2(context); + Value value = m_Operand1->Evaluate(context); + Value index = m_Operand2->Evaluate(context); if (value.IsObjectType()) { Dictionary::Ptr dict = value; @@ -421,88 +393,69 @@ Value Expression::OpIndexer(const Expression *expr, const Object::Ptr& context, } } -Value Expression::OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint) +Value ImportExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Value type = expr->EvaluateOperand1(context); - Value name = expr->EvaluateOperand2(context); + Value type = m_Type->Evaluate(context); + Value name = m_Name->Evaluate(context); ConfigItem::Ptr item = ConfigItem::GetObject(type, name); if (!item) BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'")); - item->GetExpressionList()->Evaluate(context, dhint); + item->GetExpression()->Evaluate(context, dhint); return Empty; } -Value Expression::FunctionWrapper(const std::vector& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Object::Ptr& scope) +Value Expression::FunctionWrapper(const std::vector& arguments, + const std::vector& funcargs, const boost::shared_ptr& expr, const Object::Ptr& scope) { - if (arguments.size() < funcargs->GetLength()) + if (arguments.size() < funcargs.size()) BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function")); Dictionary::Ptr context = new Dictionary(); context->Set("__parent", scope); - for (std::vector::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++) - context->Set(funcargs->Get(i), arguments[i]); + for (std::vector::size_type i = 0; i < std::min(arguments.size(), funcargs.size()); i++) + context->Set(funcargs[i], arguments[i]); expr->Evaluate(context); return context->Get("__result"); } -Value Expression::OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint) +Value FunctionExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr left = expr->m_Operand1; - Expression::Ptr aexpr = left->Get(1); - String name = left->Get(0); + ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&Expression::FunctionWrapper, _1, m_Args, m_Expression, context)); - Array::Ptr funcargs = expr->m_Operand2; - ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, context)); - - if (!name.IsEmpty()) - ScriptFunction::Register(name, func); + if (!m_Name.IsEmpty()) + ScriptFunction::Register(m_Name, func); return func; } -Value Expression::OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint) +Value ApplyExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr left = expr->m_Operand1; - Expression::Ptr exprl = expr->m_Operand2; - String type = left->Get(0); - String target = left->Get(1); - Expression::Ptr aname = left->Get(2); - Expression::Ptr filter = left->Get(3); - String fkvar = left->Get(4); - String fvvar = left->Get(5); - Expression::Ptr fterm = left->Get(6); + String name = m_Name->Evaluate(context, dhint); - String name = aname->Evaluate(context, dhint); - - ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, context); + ApplyRule::AddRule(m_Type, m_Target, name, m_Expression, m_Filter, m_FKVar, m_FVVar, m_FTerm, m_DebugInfo, context); return Empty; } -Value Expression::OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint) +Value ObjectExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr left = expr->m_Operand1; - Expression::Ptr exprl = expr->m_Operand2; - bool abstract = left->Get(0); - String type = left->Get(1); - Expression::Ptr aname = left->Get(2); - Expression::Ptr filter = left->Get(3); - String zone = left->Get(4); + String name; - String name = aname->Evaluate(context, dhint); + if (m_Name) + name = m_Name->Evaluate(context, dhint); - ConfigItemBuilder::Ptr item = new ConfigItemBuilder(expr->m_DebugInfo); + ConfigItemBuilder::Ptr item = new ConfigItemBuilder(m_DebugInfo); String checkName = name; - if (!abstract) { - Type::Ptr ptype = Type::GetByName(type); + if (!m_Abstract) { + Type::Ptr ptype = Type::GetByName(m_Type); NameComposer *nc = dynamic_cast(ptype.get()); @@ -511,50 +464,44 @@ Value Expression::OpObject(const Expression* expr, const Object::Ptr& context, D } if (!checkName.IsEmpty()) { - ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName); + ConfigItem::Ptr oldItem = ConfigItem::GetObject(m_Type, checkName); if (oldItem) { std::ostringstream msgbuf; - msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << expr->m_DebugInfo << "; previous definition: " << oldItem->GetDebugInfo(); - BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(expr->m_DebugInfo)); + msgbuf << "Object '" << name << "' of type '" << m_Type << "' re-defined: " << m_DebugInfo << "; previous definition: " << oldItem->GetDebugInfo(); + BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(m_DebugInfo)); } } - item->SetType(type); + item->SetType(m_Type); if (name.FindFirstOf("!") != String::NPos) { std::ostringstream msgbuf; - msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'"; - BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(expr->m_DebugInfo)); + msgbuf << "Name for object '" << name << "' of type '" << m_Type << "' is invalid: Object names may not contain '!'"; + BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(m_DebugInfo)); } item->SetName(name); - item->AddExpression(exprl); - item->SetAbstract(abstract); + item->AddExpression(new OwnedExpression(m_Expression)); + item->SetAbstract(m_Abstract); item->SetScope(context); - item->SetZone(zone); + item->SetZone(m_Zone); item->Compile()->Register(); - if (ObjectRule::IsValidSourceType(type)) - ObjectRule::AddRule(type, name, filter, expr->m_DebugInfo, context); + if (ObjectRule::IsValidSourceType(m_Type)) + ObjectRule::AddRule(m_Type, name, m_Filter, m_DebugInfo, context); return Empty; } -Value Expression::OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint) +Value ForExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const { - Array::Ptr left = expr->m_Operand1; - String kvar = left->Get(0); - String vvar = left->Get(1); - Expression::Ptr aexpr = left->Get(2); - Expression::Ptr ascope = expr->m_Operand2; - - Value value = aexpr->Evaluate(context, dhint); + Value value = m_Value->Evaluate(context, dhint); if (value.IsObjectType()) { - if (!vvar.IsEmpty()) - BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(expr->m_DebugInfo)); + if (!m_FVVar.IsEmpty()) + BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(m_DebugInfo)); Array::Ptr arr = value; @@ -562,13 +509,13 @@ Value Expression::OpFor(const Expression* expr, const Object::Ptr& context, Debu BOOST_FOREACH(const Value& value, arr) { Dictionary::Ptr xcontext = new Dictionary(); xcontext->Set("__parent", context); - xcontext->Set(kvar, value); + xcontext->Set(m_FKVar, value); - ascope->Evaluate(xcontext, dhint); + m_Expression->Evaluate(xcontext, dhint); } } else if (value.IsObjectType()) { - if (vvar.IsEmpty()) - BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(expr->m_DebugInfo)); + if (m_FVVar.IsEmpty()) + BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(m_DebugInfo)); Dictionary::Ptr dict = value; @@ -576,13 +523,13 @@ Value Expression::OpFor(const Expression* expr, const Object::Ptr& context, Debu BOOST_FOREACH(const Dictionary::Pair& kv, dict) { Dictionary::Ptr xcontext = new Dictionary(); xcontext->Set("__parent", context); - xcontext->Set(kvar, kv.first); - xcontext->Set(vvar, kv.second); + xcontext->Set(m_FKVar, kv.first); + xcontext->Set(m_FVVar, kv.second); - ascope->Evaluate(xcontext, dhint); + m_Expression->Evaluate(xcontext, dhint); } } else - BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(expr->m_DebugInfo)); + BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(m_DebugInfo)); return Empty; } @@ -618,11 +565,6 @@ Dictionary::Ptr DebugHint::ToDictionary(void) const return result; } -Expression::Ptr icinga::MakeLiteral(const Value& lit) -{ - return new Expression(&Expression::OpLiteral, lit, DebugInfo()); -} - bool Expression::HasField(const Object::Ptr& context, const String& field) { Dictionary::Ptr dict = dynamic_pointer_cast(context); diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index 0a6a7348c..0d5837250 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -24,6 +24,7 @@ #include "base/debuginfo.hpp" #include "base/array.hpp" #include "base/dictionary.hpp" +#include namespace icinga { @@ -58,75 +59,564 @@ enum CombinedSetOp /** * @ingroup config */ -class I2_CONFIG_API Expression : public Object +class I2_CONFIG_API Expression { public: - DECLARE_PTR_TYPEDEFS(Expression); - - typedef Value (*OpCallback)(const Expression *, const Object::Ptr&, DebugHint *dhint); - - Expression(OpCallback op, const Value& operand1, const DebugInfo& di); - Expression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di); + virtual ~Expression(void); Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const; - void MakeInline(void); - - void Dump(std::ostream& stream, int indent = 0) const; + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const = 0; + virtual const DebugInfo& GetDebugInfo(void) const; - static Value OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint); - static Value OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint); - -private: - OpCallback m_Operator; - Value m_Operand1; - Value m_Operand2; - DebugInfo m_DebugInfo; - - Value EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint = NULL) const; - Value EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint = NULL) const; - - static void DumpOperand(std::ostream& stream, const Value& operand, int indent); - - static Value FunctionWrapper(const std::vector& arguments, const Array::Ptr& funcargs, - const Expression::Ptr& expr, const Object::Ptr& scope); +public: + static Value FunctionWrapper(const std::vector& arguments, + const std::vector& funcargs, + const boost::shared_ptr& expr, const Object::Ptr& scope); static bool HasField(const Object::Ptr& context, const String& field); static Value GetField(const Object::Ptr& context, const String& field); static void SetField(const Object::Ptr& context, const String& field, const Value& value); }; -I2_CONFIG_API Expression::Ptr MakeLiteral(const Value& lit = Value()); +I2_CONFIG_API std::vector MakeIndexer(const String& index1); + +class I2_CONFIG_API OwnedExpression : public Expression +{ +public: + OwnedExpression(const boost::shared_ptr& expression) + : m_Expression(expression) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const + { + return m_Expression->DoEvaluate(context, dhint); + } + + virtual const DebugInfo& GetDebugInfo(void) const + { + return m_Expression->GetDebugInfo(); + } + +private: + boost::shared_ptr m_Expression; +}; + +class I2_CONFIG_API LiteralExpression : public Expression +{ +public: + LiteralExpression(const Value& value = Value()); + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + Value m_Value; +}; + +inline LiteralExpression *MakeLiteral(const Value& literal = Value()) +{ + return new LiteralExpression(literal); +} + +class I2_CONFIG_API DebuggableExpression : public Expression +{ +public: + DebuggableExpression(const DebugInfo& debugInfo) + : m_DebugInfo(debugInfo) + { } + +protected: + virtual const DebugInfo& GetDebugInfo(void) const; + + DebugInfo m_DebugInfo; +}; + +class I2_CONFIG_API UnaryExpression : public DebuggableExpression +{ +public: + UnaryExpression(Expression *operand, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Operand(operand) + { } + + ~UnaryExpression(void) + { + delete m_Operand; + } + +protected: + Expression *m_Operand; +}; + +class I2_CONFIG_API BinaryExpression : public DebuggableExpression +{ +public: + BinaryExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Operand1(operand1), m_Operand2(operand2) + { } + + ~BinaryExpression(void) + { + delete m_Operand1; + delete m_Operand2; + } + +protected: + Expression *m_Operand1; + Expression *m_Operand2; +}; + + +class I2_CONFIG_API VariableExpression : public DebuggableExpression +{ +public: + VariableExpression(const String& variable, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Variable(variable) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + String m_Variable; +}; + +class I2_CONFIG_API NegateExpression : public UnaryExpression +{ +public: + NegateExpression(Expression *operand, const DebugInfo& debugInfo) + : UnaryExpression(operand, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API LogicalNegateExpression : public UnaryExpression +{ +public: + LogicalNegateExpression(Expression *operand, const DebugInfo& debugInfo) + : UnaryExpression(operand, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API AddExpression : public BinaryExpression +{ +public: + AddExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API SubtractExpression : public BinaryExpression +{ +public: + SubtractExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API MultiplyExpression : public BinaryExpression +{ +public: + MultiplyExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API DivideExpression : public BinaryExpression +{ +public: + DivideExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API BinaryAndExpression : public BinaryExpression +{ +public: + BinaryAndExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API BinaryOrExpression : public BinaryExpression +{ +public: + BinaryOrExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API ShiftLeftExpression : public BinaryExpression +{ +public: + ShiftLeftExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API ShiftRightExpression : public BinaryExpression +{ +public: + ShiftRightExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API EqualExpression : public BinaryExpression +{ +public: + EqualExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API NotEqualExpression : public BinaryExpression +{ +public: + NotEqualExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API LessThanExpression : public BinaryExpression +{ +public: + LessThanExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API GreaterThanExpression : public BinaryExpression +{ +public: + GreaterThanExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API LessThanOrEqualExpression : public BinaryExpression +{ +public: + LessThanOrEqualExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API GreaterThanOrEqualExpression : public BinaryExpression +{ +public: + GreaterThanOrEqualExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API InExpression : public BinaryExpression +{ +public: + InExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API NotInExpression : public BinaryExpression +{ +public: + NotInExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API LogicalAndExpression : public BinaryExpression +{ +public: + LogicalAndExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API LogicalOrExpression : public BinaryExpression +{ +public: + LogicalOrExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API FunctionCallExpression : public DebuggableExpression +{ +public: + FunctionCallExpression(Expression *fname, const std::vector& args, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_FName(fname), m_Args(args) + { } + + ~FunctionCallExpression(void) + { + delete m_FName; + + BOOST_FOREACH(Expression *expr, m_Args) + delete expr; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +public: + Expression *m_FName; + std::vector m_Args; +}; + +class I2_CONFIG_API ArrayExpression : public DebuggableExpression +{ +public: + ArrayExpression(const std::vector& expressions, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Expressions(expressions) + { } + + ~ArrayExpression(void) + { + BOOST_FOREACH(Expression *expr, m_Expressions) + delete expr; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + std::vector m_Expressions; +}; + +class I2_CONFIG_API DictExpression : public DebuggableExpression +{ +public: + DictExpression(const std::vector& expressions, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Expressions(expressions), m_Inline(false) + { } + + ~DictExpression(void) + { + BOOST_FOREACH(Expression *expr, m_Expressions) + delete expr; + } + + void MakeInline(void); + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + std::vector m_Expressions; + bool m_Inline; +}; + +class I2_CONFIG_API SetExpression : public DebuggableExpression +{ +public: + SetExpression(const std::vector& indexer, CombinedSetOp op, Expression *operand2, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Op(op), m_Indexer(indexer), m_Operand2(operand2) + { } + + ~SetExpression(void) + { + BOOST_FOREACH(Expression *expr, m_Indexer) + delete expr; + + delete m_Operand2; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + CombinedSetOp m_Op; + std::vector m_Indexer; + Expression *m_Operand2; + +}; + +class I2_CONFIG_API IndexerExpression : public BinaryExpression +{ +public: + IndexerExpression(Expression *operand1, Expression *operand2, const DebugInfo& debugInfo) + : BinaryExpression(operand1, operand2, debugInfo) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; +}; + +class I2_CONFIG_API ImportExpression : public DebuggableExpression +{ +public: + ImportExpression(Expression *type, Expression *name, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Type(type), m_Name(name) + { } + + ~ImportExpression(void) + { + delete m_Type; + delete m_Name; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + Expression *m_Type; + Expression *m_Name; +}; + +class I2_CONFIG_API FunctionExpression : public DebuggableExpression +{ +public: + FunctionExpression(const String& name, const std::vector& args, Expression *expression, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Name(name), m_Args(args), m_Expression(expression) + { } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + String m_Name; + std::vector m_Args; + boost::shared_ptr m_Expression; +}; + +class I2_CONFIG_API ApplyExpression : public DebuggableExpression +{ +public: + ApplyExpression(const String& type, const String& target, Expression *name, + Expression *filter, const String& fkvar, const String& fvvar, + Expression *fterm, Expression *expression, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Type(type), m_Target(target), + m_Name(name), m_Filter(filter), m_FKVar(fkvar), m_FVVar(fvvar), + m_FTerm(fterm), m_Expression(expression) + { } + + ~ApplyExpression(void) + { + delete m_Name; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + String m_Type; + String m_Target; + Expression *m_Name; + boost::shared_ptr m_Filter; + String m_FKVar; + String m_FVVar; + boost::shared_ptr m_FTerm; + boost::shared_ptr m_Expression; +}; + +class I2_CONFIG_API ObjectExpression : public DebuggableExpression +{ +public: + ObjectExpression(bool abstract, const String& type, Expression *name, Expression *filter, const String& zone, Expression *expression, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type), m_Name(name), m_Filter(filter), m_Zone(zone), m_Expression(expression) + { } + + ~ObjectExpression(void) + { + delete m_Name; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + bool m_Abstract; + String m_Type; + Expression *m_Name; + boost::shared_ptr m_Filter; + String m_Zone; + boost::shared_ptr m_Expression; +}; + +class I2_CONFIG_API ForExpression : public DebuggableExpression +{ +public: + ForExpression(const String& fkvar, const String& fvvar, Expression *value, Expression *expression, const DebugInfo& debugInfo) + : DebuggableExpression(debugInfo), m_FKVar(fkvar), m_FVVar(fvvar), m_Value(value), m_Expression(expression) + { } + + ~ForExpression(void) + { + delete m_Value; + delete m_Expression; + } + +protected: + virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const; + +private: + String m_FKVar; + String m_FVVar; + Expression *m_Value; + Expression *m_Expression; +}; } diff --git a/lib/config/objectrule.cpp b/lib/config/objectrule.cpp index 1b2c1952b..fb38b81fe 100644 --- a/lib/config/objectrule.cpp +++ b/lib/config/objectrule.cpp @@ -26,7 +26,7 @@ using namespace icinga; ObjectRule::RuleMap ObjectRule::m_Rules; ObjectRule::CallbackMap ObjectRule::m_Callbacks; -ObjectRule::ObjectRule(const String& name, const Expression::Ptr& filter, +ObjectRule::ObjectRule(const String& name, const boost::shared_ptr& filter, const DebugInfo& di, const Object::Ptr& scope) : m_Name(name), m_Filter(filter), m_DebugInfo(di), m_Scope(scope) { } @@ -36,7 +36,7 @@ String ObjectRule::GetName(void) const return m_Name; } -Expression::Ptr ObjectRule::GetFilter(void) const +boost::shared_ptr ObjectRule::GetFilter(void) const { return m_Filter; } @@ -52,7 +52,7 @@ Object::Ptr ObjectRule::GetScope(void) const } void ObjectRule::AddRule(const String& sourceType, const String& name, - const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope) + const boost::shared_ptr& filter, const DebugInfo& di, const Object::Ptr& scope) { m_Rules[sourceType].push_back(ObjectRule(name, filter, di, scope)); } diff --git a/lib/config/objectrule.hpp b/lib/config/objectrule.hpp index cdb94af40..42bf19cb3 100644 --- a/lib/config/objectrule.hpp +++ b/lib/config/objectrule.hpp @@ -39,14 +39,14 @@ public: typedef std::map > RuleMap; String GetName(void) const; - Expression::Ptr GetFilter(void) const; + boost::shared_ptr GetFilter(void) const; DebugInfo GetDebugInfo(void) const; Object::Ptr GetScope(void) const; bool EvaluateFilter(const Object::Ptr& scope) const; static void AddRule(const String& sourceType, const String& name, - const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope); + const boost::shared_ptr& filter, const DebugInfo& di, const Object::Ptr& scope); static void EvaluateRules(bool clear); static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback); @@ -54,15 +54,14 @@ public: private: String m_Name; - Expression::Ptr m_Filter; + boost::shared_ptr m_Filter; DebugInfo m_DebugInfo; Object::Ptr m_Scope; static CallbackMap m_Callbacks; static RuleMap m_Rules; - ObjectRule(const String& name, const Expression::Ptr& filter, - const DebugInfo& di, const Object::Ptr& scope); + ObjectRule(const String& name, const boost::shared_ptr& filter, const DebugInfo& di, const Object::Ptr& scope); }; } diff --git a/lib/icinga/dependency-apply.cpp b/lib/icinga/dependency-apply.cpp index ed5756afc..386861523 100644 --- a/lib/icinga/dependency-apply.cpp +++ b/lib/icinga/dependency-apply.cpp @@ -58,33 +58,18 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c Service::Ptr service; tie(host, service) = GetHostService(checkable); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("parent_host_name")), OpSetLiteral), - MakeLiteral(host->GetName()), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); + builder->AddExpression(new SetExpression(MakeIndexer("child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("child_host_name")), OpSetLiteral), - MakeLiteral(host->GetName()), - di)); - - if (service) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("child_service_name")), OpSetLiteral), - MakeLiteral(service->GetShortName()), - di)); - } + if (service) + builder->AddExpression(new SetExpression(MakeIndexer("child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZone(); - if (!zone.IsEmpty()) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral), - MakeLiteral(zone), - di)); - } + if (!zone.IsEmpty()) + builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di)); - builder->AddExpression(rule.GetExpression()); + builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr dependencyItem = builder->Compile(); DynamicObject::Ptr dobj = dependencyItem->Commit(); diff --git a/lib/icinga/notification-apply.cpp b/lib/icinga/notification-apply.cpp index f9f299486..160933cc4 100644 --- a/lib/icinga/notification-apply.cpp +++ b/lib/icinga/notification-apply.cpp @@ -58,28 +58,17 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, Service::Ptr service; tie(host, service) = GetHostService(checkable); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral), - MakeLiteral(host->GetName()), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); - if (service) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("service_name")), OpSetLiteral), - MakeLiteral(service->GetShortName()), - di)); - } + if (service) + builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZone(); - if (!zone.IsEmpty()) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral), - MakeLiteral(zone), - di)); - } + if (!zone.IsEmpty()) + builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di)); - builder->AddExpression(rule.GetExpression()); + builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr notificationItem = builder->Compile(); DynamicObject::Ptr dobj = notificationItem->Commit(); diff --git a/lib/icinga/scheduleddowntime-apply.cpp b/lib/icinga/scheduleddowntime-apply.cpp index 8b830f401..27b3ba5ae 100644 --- a/lib/icinga/scheduleddowntime-apply.cpp +++ b/lib/icinga/scheduleddowntime-apply.cpp @@ -57,28 +57,18 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check Service::Ptr service; tie(host, service) = GetHostService(checkable); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral), - MakeLiteral(host->GetName()), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); - if (service) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("service_name")), OpSetLiteral), - MakeLiteral(service->GetShortName()), - di)); - } + if (service) + builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZone(); if (!zone.IsEmpty()) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral), - MakeLiteral(zone), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di)); } - builder->AddExpression(rule.GetExpression()); + builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr downtimeItem = builder->Compile(); DynamicObject::Ptr dobj = downtimeItem->Commit(); diff --git a/lib/icinga/service-apply.cpp b/lib/icinga/service-apply.cpp index 83543261f..7b24b58a8 100644 --- a/lib/icinga/service-apply.cpp +++ b/lib/icinga/service-apply.cpp @@ -52,26 +52,16 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String& builder->SetName(name); builder->SetScope(locals); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral), - MakeLiteral(host->GetName()), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("name")), OpSetLiteral), - MakeLiteral(name), - di)); + builder->AddExpression(new SetExpression(MakeIndexer("name"), OpSetLiteral, MakeLiteral(name), di)); String zone = host->GetZone(); - if (!zone.IsEmpty()) { - builder->AddExpression(new Expression(&Expression::OpSet, - MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral), - MakeLiteral(zone), - di)); - } + if (!zone.IsEmpty()) + builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di)); - builder->AddExpression(rule.GetExpression()); + builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr serviceItem = builder->Compile(); DynamicObject::Ptr dobj = serviceItem->Commit();