Refactor the AST

refs #7622
This commit is contained in:
Gunnar Beutner 2014-11-09 19:48:28 +01:00 committed by Gunnar Beutner
parent e3c5063aff
commit ec109b04dd
16 changed files with 961 additions and 628 deletions

View File

@ -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>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& 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<Expression> ApplyRule::GetExpression(void) const
{
return m_Expression;
}
Expression::Ptr ApplyRule::GetFilter(void) const
boost::shared_ptr<Expression> 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<Expression> 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>& expression, const boost::shared_ptr<Expression>& filter, const String& fkvar,
const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Object::Ptr& scope)
{
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
}

View File

@ -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<Expression> GetExpression(void) const;
boost::shared_ptr<Expression> GetFilter(void) const;
String GetFKVar(void) const;
String GetFVVar(void) const;
Expression::Ptr GetFTerm(void) const;
boost::shared_ptr<Expression> 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>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Object::Ptr& scope);
static void EvaluateRules(bool clear);
static void RegisterType(const String& sourceType, const std::vector<String>& 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<Expression> m_Expression;
boost::shared_ptr<Expression> m_Filter;
String m_FKVar;
String m_FVVar;
Expression::Ptr m_FTerm;
boost::shared_ptr<Expression> 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>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
const DebugInfo& di, const Object::Ptr& scope);
};

View File

@ -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; }

View File

@ -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<typename T>
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<String> *slist;
Array *array;
std::vector<Expression *> *elist;
}
%token T_NEWLINE "new-line"
@ -115,24 +113,24 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef
%token <csop> T_SET_MULTIPLY "*= (T_SET_MULTIPLY)"
%token <csop> T_SET_DIVIDE "/= (T_SET_DIVIDE)"
%token <op> T_SHIFT_LEFT "<< (T_SHIFT_LEFT)"
%token <op> T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)"
%token <op> T_EQUAL "== (T_EQUAL)"
%token <op> T_NOT_EQUAL "!= (T_NOT_EQUAL)"
%token <op> T_IN "in (T_IN)"
%token <op> T_NOT_IN "!in (T_NOT_IN)"
%token <op> T_LOGICAL_AND "&& (T_LOGICAL_AND)"
%token <op> T_LOGICAL_OR "|| (T_LOGICAL_OR)"
%token <op> T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)"
%token <op> T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)"
%token <op> T_PLUS "+ (T_PLUS)"
%token <op> T_MINUS "- (T_MINUS)"
%token <op> T_MULTIPLY "* (T_MULTIPLY)"
%token <op> T_DIVIDE_OP "/ (T_DIVIDE_OP)"
%token <op> T_BINARY_AND "& (T_BINARY_AND)"
%token <op> T_BINARY_OR "| (T_BINARY_OR)"
%token <op> T_LESS_THAN "< (T_LESS_THAN)"
%token <op> 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 <type> 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 <text> identifier
%type <array> rterm_items
%type <array> rterm_items_inner
%type <array> identifier_items
%type <array> identifier_items_inner
%type <array> indexer
%type <array> indexer_items
%type <variant> indexer_item
%type <array> lterm_items
%type <array> lterm_items_inner
%type <elist> rterm_items
%type <elist> rterm_items_inner
%type <slist> identifier_items
%type <slist> identifier_items_inner
%type <elist> indexer
%type <elist> indexer_items
%type <expr> indexer_item
%type <elist> lterm_items
%type <elist> lterm_items_inner
%type <variant> typerulelist
%type <csop> combined_set_op
%type <type> type
%type <variant> rterm
%type <variant> rterm_array
%type <variant> rterm_scope
%type <variant> lterm
%type <variant> object
%type <variant> apply
%type <variant> optional_rterm
%type <expr> rterm
%type <expr> rterm_array
%type <expr> rterm_scope
%type <expr> lterm
%type <expr> object
%type <expr> apply
%type <expr> optional_rterm
%type <text> target_type_specifier
%left T_LOGICAL_OR
@ -223,11 +221,11 @@ static Dictionary::Ptr m_ModuleScope;
static std::stack<bool> m_Apply;
static std::stack<bool> m_ObjectAssign;
static std::stack<bool> m_SeenAssign;
static std::stack<Expression::Ptr> m_Assign;
static std::stack<Expression::Ptr> m_Ignore;
static std::stack<Expression *> m_Assign;
static std::stack<Expression *> m_Ignore;
static std::stack<String> m_FKVar;
static std::stack<String> m_FVVar;
static std::stack<Expression::Ptr> m_FTerm;
static std::stack<Expression *> m_FTerm;
void ConfigCompiler::Compile(void)
{
@ -239,11 +237,11 @@ void ConfigCompiler::Compile(void)
m_Apply = std::stack<bool>();
m_ObjectAssign = std::stack<bool>();
m_SeenAssign = std::stack<bool>();
m_Assign = std::stack<Expression::Ptr>();
m_Ignore = std::stack<Expression::Ptr>();
m_Assign = std::stack<Expression *>();
m_Ignore = std::stack<Expression *>();
m_FKVar = std::stack<String>();
m_FVVar = std::stack<String>();
m_FTerm = std::stack<Expression::Ptr>();
m_FTerm = std::stack<Expression *>();
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<DictExpression *>($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<String>();
}
| identifier
{
$$ = new Array();
$$->Add($1);
$$ = new std::vector<String>();
$$->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<String>();
$$->Add($3);
$$->push_back($3);
free($3);
}
;
indexer: identifier
{
$$ = new Array();
$$->Add(MakeLiteral($1));
$$ = new std::vector<Expression *>();
$$->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<Expression *>();
$$->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<Expression *>();
}
| lterm_items_inner
{
@ -584,32 +558,29 @@ lterm_items: /* empty */
lterm_items_inner: lterm
{
$$ = new Array();
$$->Add(*$1);
delete $1;
$$ = new std::vector<Expression *>();
$$->push_back($1);
}
| lterm_items_inner sep lterm
{
if ($1)
$$ = $1;
else
$$ = new Array();
$$ = new std::vector<Expression *>();
$$->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<Expression *> 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<Expression *>();
}
| rterm_items_inner
{
@ -670,98 +638,99 @@ rterm_items: /* empty */
rterm_items_inner: rterm
{
$$ = new Array();
$$->Add(*$1);
delete $1;
$$ = new std::vector<Expression *>();
$$->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<LogicalOrExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LOGICAL_AND rterm { MakeRBinaryOp<LogicalAndExpression>(&$$, $1, $3, @1, @3); }
| rterm T_BINARY_OR rterm { MakeRBinaryOp<BinaryOrExpression>(&$$, $1, $3, @1, @3); }
| rterm T_BINARY_AND rterm { MakeRBinaryOp<BinaryAndExpression>(&$$, $1, $3, @1, @3); }
| rterm T_IN rterm { MakeRBinaryOp<InExpression>(&$$, $1, $3, @1, @3); }
| rterm T_NOT_IN rterm { MakeRBinaryOp<NotInExpression>(&$$, $1, $3, @1, @3); }
| rterm T_EQUAL rterm { MakeRBinaryOp<EqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_NOT_EQUAL rterm { MakeRBinaryOp<NotEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LESS_THAN rterm { MakeRBinaryOp<LessThanExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LESS_THAN_OR_EQUAL rterm { MakeRBinaryOp<LessThanOrEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_GREATER_THAN rterm { MakeRBinaryOp<GreaterThanExpression>(&$$, $1, $3, @1, @3); }
| rterm T_GREATER_THAN_OR_EQUAL rterm { MakeRBinaryOp<GreaterThanOrEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_SHIFT_LEFT rterm { MakeRBinaryOp<ShiftLeftExpression>(&$$, $1, $3, @1, @3); }
| rterm T_SHIFT_RIGHT rterm { MakeRBinaryOp<ShiftRightExpression>(&$$, $1, $3, @1, @3); }
| rterm T_PLUS rterm { MakeRBinaryOp<AddExpression>(&$$, $1, $3, @1, @3); }
| rterm T_MINUS rterm { MakeRBinaryOp<SubtractExpression>(&$$, $1, $3, @1, @3); }
| rterm T_MULTIPLY rterm { MakeRBinaryOp<MultiplyExpression>(&$$, $1, $3, @1, @3); }
| rterm T_DIVIDE_OP rterm { MakeRBinaryOp<DivideExpression>(&$$, $1, $3, @1, @3); }
| T_FUNCTION identifier '(' identifier_items ')' rterm_scope
{
Expression::Ptr aexpr = *$6;
delete $6;
DictExpression *aexpr = dynamic_cast<DictExpression *>($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<DictExpression *>($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<DictExpression *>($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));
}
;

View File

@ -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<Expression>& 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<Expression> 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<errinfo_debuginfo>(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());

View File

@ -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<Expression>& exprl, const DebugInfo& debuginfo,
const Object::Ptr& scope, const String& zone);
String GetType(void) const;
@ -47,7 +47,7 @@ public:
std::vector<ConfigItem::Ptr> GetParents(void) const;
Expression::Ptr GetExpressionList(void) const;
boost::shared_ptr<Expression> 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<Expression> m_Expression;
std::vector<String> m_ParentNames; /**< The names of parent configuration
items. */
DebugInfo m_DebugInfo; /**< Debug information. */

View File

@ -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<Expression *> 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<Expression *> 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<Expression>(exprl),
m_DebugInfo, m_Scope, m_Zone);
}

View File

@ -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<Expression *> m_Expressions; /**< Expressions for this item. */
DebugInfo m_DebugInfo; /**< Debug information. */
Object::Ptr m_Scope; /**< variable scope. */
String m_Zone; /**< The zone. */

View File

@ -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<boost::errinfo_nested_exception>(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>()) {
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>()) {
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<Expression *> icinga::MakeIndexer(const String& index1)
{
String sym = Utility::GetSymbolName(reinterpret_cast<const void *>(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<Expression *> 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<Expression::Ptr>(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<Expression::Ptr>(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<Array>())
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<Array>())
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<Value> 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>()) {
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<Value>& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Object::Ptr& scope)
Value Expression::FunctionWrapper(const std::vector<Value>& arguments,
const std::vector<String>& funcargs, const boost::shared_ptr<Expression>& 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<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++)
context->Set(funcargs->Get(i), arguments[i]);
for (std::vector<Value>::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<NameComposer *>(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<Array>()) {
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<Dictionary>()) {
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<Dictionary>(context);

View File

@ -24,6 +24,7 @@
#include "base/debuginfo.hpp"
#include "base/array.hpp"
#include "base/dictionary.hpp"
#include <boost/foreach.hpp>
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<Value>& arguments, const Array::Ptr& funcargs,
const Expression::Ptr& expr, const Object::Ptr& scope);
public:
static Value FunctionWrapper(const std::vector<Value>& arguments,
const std::vector<String>& funcargs,
const boost::shared_ptr<Expression>& 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<Expression *> MakeIndexer(const String& index1);
class I2_CONFIG_API OwnedExpression : public Expression
{
public:
OwnedExpression(const boost::shared_ptr<Expression>& 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<Expression> 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<Expression *>& 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<Expression *> m_Args;
};
class I2_CONFIG_API ArrayExpression : public DebuggableExpression
{
public:
ArrayExpression(const std::vector<Expression *>& 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<Expression *> m_Expressions;
};
class I2_CONFIG_API DictExpression : public DebuggableExpression
{
public:
DictExpression(const std::vector<Expression *>& 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<Expression *> m_Expressions;
bool m_Inline;
};
class I2_CONFIG_API SetExpression : public DebuggableExpression
{
public:
SetExpression(const std::vector<Expression *>& 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<Expression *> 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<String>& 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<String> m_Args;
boost::shared_ptr<Expression> 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<Expression> m_Filter;
String m_FKVar;
String m_FVVar;
boost::shared_ptr<Expression> m_FTerm;
boost::shared_ptr<Expression> 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<Expression> m_Filter;
String m_Zone;
boost::shared_ptr<Expression> 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;
};
}

View File

@ -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<Expression>& 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<Expression> 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<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope)
{
m_Rules[sourceType].push_back(ObjectRule(name, filter, di, scope));
}

View File

@ -39,14 +39,14 @@ public:
typedef std::map<String, std::vector<ObjectRule> > RuleMap;
String GetName(void) const;
Expression::Ptr GetFilter(void) const;
boost::shared_ptr<Expression> 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<Expression>& 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<Expression> 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<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope);
};
}

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();