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::RuleMap ApplyRule::m_Rules;
ApplyRule::CallbackMap ApplyRule::m_Callbacks; ApplyRule::CallbackMap ApplyRule::m_Callbacks;
ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, ApplyRule::ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, 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) const DebugInfo& di, const Object::Ptr& scope)
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar), : 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) m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
@ -44,12 +44,12 @@ String ApplyRule::GetName(void) const
return m_Name; return m_Name;
} }
Expression::Ptr ApplyRule::GetExpression(void) const boost::shared_ptr<Expression> ApplyRule::GetExpression(void) const
{ {
return m_Expression; return m_Expression;
} }
Expression::Ptr ApplyRule::GetFilter(void) const boost::shared_ptr<Expression> ApplyRule::GetFilter(void) const
{ {
return m_Filter; return m_Filter;
} }
@ -64,7 +64,7 @@ String ApplyRule::GetFVVar(void) const
return m_FVVar; return m_FVVar;
} }
Expression::Ptr ApplyRule::GetFTerm(void) const boost::shared_ptr<Expression> ApplyRule::GetFTerm(void) const
{ {
return m_FTerm; 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, void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar, const boost::shared_ptr<Expression>& expression, const boost::shared_ptr<Expression>& filter, const String& fkvar,
const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope) 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)); 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 GetTargetType(void) const;
String GetName(void) const; String GetName(void) const;
Expression::Ptr GetExpression(void) const; boost::shared_ptr<Expression> GetExpression(void) const;
Expression::Ptr GetFilter(void) const; boost::shared_ptr<Expression> GetFilter(void) const;
String GetFKVar(void) const; String GetFKVar(void) const;
String GetFVVar(void) const; String GetFVVar(void) const;
Expression::Ptr GetFTerm(void) const; boost::shared_ptr<Expression> GetFTerm(void) const;
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
Object::Ptr GetScope(void) const; Object::Ptr GetScope(void) const;
bool EvaluateFilter(const Object::Ptr& scope) const; bool EvaluateFilter(const Object::Ptr& scope) const;
static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression, static void AddRule(const String& sourceType, const String& targetType, const String& name, const boost::shared_ptr<Expression>& 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>& 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 EvaluateRules(bool clear);
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback); static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
@ -62,19 +62,19 @@ public:
private: private:
String m_TargetType; String m_TargetType;
String m_Name; String m_Name;
Expression::Ptr m_Expression; boost::shared_ptr<Expression> m_Expression;
Expression::Ptr m_Filter; boost::shared_ptr<Expression> m_Filter;
String m_FKVar; String m_FKVar;
String m_FVVar; String m_FVVar;
Expression::Ptr m_FTerm; boost::shared_ptr<Expression> m_FTerm;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
Object::Ptr m_Scope; Object::Ptr m_Scope;
static CallbackMap m_Callbacks; static CallbackMap m_Callbacks;
static RuleMap m_Rules; static RuleMap m_Rules;
ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression, ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, 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); const DebugInfo& di, const Object::Ptr& scope);
}; };

View File

@ -234,16 +234,16 @@ __function return T_FUNCTION;
__return return T_RETURN; __return return T_RETURN;
__for return T_FOR; __for return T_FOR;
=\> return T_FOLLOWS; =\> return T_FOLLOWS;
\<\< { yylval->op = &Expression::OpShiftLeft; return T_SHIFT_LEFT; } \<\< return T_SHIFT_LEFT;
\>\> { yylval->op = &Expression::OpShiftRight; return T_SHIFT_RIGHT; } \>\> return T_SHIFT_RIGHT;
\<= { yylval->op = &Expression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; } \<= return T_LESS_THAN_OR_EQUAL;
\>= { yylval->op = &Expression::OpGreaterThanOrEqual; return T_GREATER_THAN_OR_EQUAL; } \>= return T_GREATER_THAN_OR_EQUAL;
== { yylval->op = &Expression::OpEqual; return T_EQUAL; } == return T_EQUAL;
!= { yylval->op = &Expression::OpNotEqual; return T_NOT_EQUAL; } != return T_NOT_EQUAL;
!in { yylval->op = &Expression::OpNotIn; return T_NOT_IN; } !in return T_NOT_IN;
in { yylval->op = &Expression::OpIn; return T_IN; } in return T_IN;
&& { yylval->op = &Expression::OpLogicalAnd; return T_LOGICAL_AND; } && return T_LOGICAL_AND;
\|\| { yylval->op = &Expression::OpLogicalOr; return T_LOGICAL_OR; } \|\| 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); return T_IDENTIFIER; }
@[a-zA-Z_][a-zA-Z0-9\-_]* { yylval->text = strdup(yytext + 1); 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; } \<[^\>]*\> { 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 = OpSetSubtract; return T_SET_SUBTRACT; }
\*= { yylval->csop = OpSetMultiply; return T_SET_MULTIPLY; } \*= { yylval->csop = OpSetMultiply; return T_SET_MULTIPLY; }
\/= { yylval->csop = OpSetDivide; return T_SET_DIVIDE; } \/= { yylval->csop = OpSetDivide; return T_SET_DIVIDE; }
\+ { yylval->op = &Expression::OpAdd; return T_PLUS; } \+ return T_PLUS;
\- { yylval->op = &Expression::OpSubtract; return T_MINUS; } \- return T_MINUS;
\* { yylval->op = &Expression::OpMultiply; return T_MULTIPLY; } \* return T_MULTIPLY;
\/ { yylval->op = &Expression::OpMultiply; return T_DIVIDE_OP; } \/ return T_DIVIDE_OP;
\& { yylval->op = &Expression::OpBinaryAnd; return T_BINARY_AND; } \& return T_BINARY_AND;
\| { yylval->op = &Expression::OpBinaryOr; return T_BINARY_OR; } \| return T_BINARY_OR;
\< { yylval->op = &Expression::OpLessThan; return T_LESS_THAN; } \< return T_LESS_THAN;
\> { yylval->op = &Expression::OpLessThan; return T_GREATER_THAN; } \> return T_GREATER_THAN;
} }
[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!ignore_newlines) return T_NEWLINE; } [\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!ignore_newlines) return T_NEWLINE; }

View File

@ -32,7 +32,6 @@
#include "config/objectrule.hpp" #include "config/objectrule.hpp"
#include "base/value.hpp" #include "base/value.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/array.hpp"
#include "base/scriptvariable.hpp" #include "base/scriptvariable.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
@ -73,11 +72,10 @@ using namespace icinga;
int ignore_newlines = 0; 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))); *result = new T(left, right, DebugInfoRange(diLeft, diRight));
delete left;
delete right;
} }
%} %}
@ -94,12 +92,12 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef
%union { %union {
char *text; char *text;
double num; double num;
icinga::Expression *expr;
icinga::Value *variant; icinga::Value *variant;
icinga::Expression::OpCallback op;
CombinedSetOp csop; CombinedSetOp csop;
icinga::TypeSpecifier type; icinga::TypeSpecifier type;
std::vector<String> *slist; std::vector<String> *slist;
Array *array; std::vector<Expression *> *elist;
} }
%token T_NEWLINE "new-line" %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_MULTIPLY "*= (T_SET_MULTIPLY)"
%token <csop> T_SET_DIVIDE "/= (T_SET_DIVIDE)" %token <csop> T_SET_DIVIDE "/= (T_SET_DIVIDE)"
%token <op> T_SHIFT_LEFT "<< (T_SHIFT_LEFT)" %token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)"
%token <op> T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)" %token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)"
%token <op> T_EQUAL "== (T_EQUAL)" %token T_EQUAL "== (T_EQUAL)"
%token <op> T_NOT_EQUAL "!= (T_NOT_EQUAL)" %token T_NOT_EQUAL "!= (T_NOT_EQUAL)"
%token <op> T_IN "in (T_IN)" %token T_IN "in (T_IN)"
%token <op> T_NOT_IN "!in (T_NOT_IN)" %token T_NOT_IN "!in (T_NOT_IN)"
%token <op> T_LOGICAL_AND "&& (T_LOGICAL_AND)" %token T_LOGICAL_AND "&& (T_LOGICAL_AND)"
%token <op> T_LOGICAL_OR "|| (T_LOGICAL_OR)" %token T_LOGICAL_OR "|| (T_LOGICAL_OR)"
%token <op> T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)" %token T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)"
%token <op> T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)" %token T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)"
%token <op> T_PLUS "+ (T_PLUS)" %token T_PLUS "+ (T_PLUS)"
%token <op> T_MINUS "- (T_MINUS)" %token T_MINUS "- (T_MINUS)"
%token <op> T_MULTIPLY "* (T_MULTIPLY)" %token T_MULTIPLY "* (T_MULTIPLY)"
%token <op> T_DIVIDE_OP "/ (T_DIVIDE_OP)" %token T_DIVIDE_OP "/ (T_DIVIDE_OP)"
%token <op> T_BINARY_AND "& (T_BINARY_AND)" %token T_BINARY_AND "& (T_BINARY_AND)"
%token <op> T_BINARY_OR "| (T_BINARY_OR)" %token T_BINARY_OR "| (T_BINARY_OR)"
%token <op> T_LESS_THAN "< (T_LESS_THAN)" %token T_LESS_THAN "< (T_LESS_THAN)"
%token <op> T_GREATER_THAN "> (T_GREATER_THAN)" %token T_GREATER_THAN "> (T_GREATER_THAN)"
%token T_CONST "const (T_CONST)" %token T_CONST "const (T_CONST)"
%token <type> T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)" %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)" %token T_FOLLOWS "=> (T_FOLLOWS)"
%type <text> identifier %type <text> identifier
%type <array> rterm_items %type <elist> rterm_items
%type <array> rterm_items_inner %type <elist> rterm_items_inner
%type <array> identifier_items %type <slist> identifier_items
%type <array> identifier_items_inner %type <slist> identifier_items_inner
%type <array> indexer %type <elist> indexer
%type <array> indexer_items %type <elist> indexer_items
%type <variant> indexer_item %type <expr> indexer_item
%type <array> lterm_items %type <elist> lterm_items
%type <array> lterm_items_inner %type <elist> lterm_items_inner
%type <variant> typerulelist %type <variant> typerulelist
%type <csop> combined_set_op %type <csop> combined_set_op
%type <type> type %type <type> type
%type <variant> rterm %type <expr> rterm
%type <variant> rterm_array %type <expr> rterm_array
%type <variant> rterm_scope %type <expr> rterm_scope
%type <variant> lterm %type <expr> lterm
%type <variant> object %type <expr> object
%type <variant> apply %type <expr> apply
%type <variant> optional_rterm %type <expr> optional_rterm
%type <text> target_type_specifier %type <text> target_type_specifier
%left T_LOGICAL_OR %left T_LOGICAL_OR
@ -223,11 +221,11 @@ static Dictionary::Ptr m_ModuleScope;
static std::stack<bool> m_Apply; static std::stack<bool> m_Apply;
static std::stack<bool> m_ObjectAssign; static std::stack<bool> m_ObjectAssign;
static std::stack<bool> m_SeenAssign; static std::stack<bool> m_SeenAssign;
static std::stack<Expression::Ptr> m_Assign; static std::stack<Expression *> m_Assign;
static std::stack<Expression::Ptr> m_Ignore; static std::stack<Expression *> m_Ignore;
static std::stack<String> m_FKVar; static std::stack<String> m_FKVar;
static std::stack<String> m_FVVar; static std::stack<String> m_FVVar;
static std::stack<Expression::Ptr> m_FTerm; static std::stack<Expression *> m_FTerm;
void ConfigCompiler::Compile(void) void ConfigCompiler::Compile(void)
{ {
@ -239,11 +237,11 @@ void ConfigCompiler::Compile(void)
m_Apply = std::stack<bool>(); m_Apply = std::stack<bool>();
m_ObjectAssign = std::stack<bool>(); m_ObjectAssign = std::stack<bool>();
m_SeenAssign = std::stack<bool>(); m_SeenAssign = std::stack<bool>();
m_Assign = std::stack<Expression::Ptr>(); m_Assign = std::stack<Expression *>();
m_Ignore = std::stack<Expression::Ptr>(); m_Ignore = std::stack<Expression *>();
m_FKVar = std::stack<String>(); m_FKVar = std::stack<String>();
m_FVVar = std::stack<String>(); m_FVVar = std::stack<String>();
m_FTerm = std::stack<Expression::Ptr>(); m_FTerm = std::stack<Expression *>();
try { try {
yyparse(this); yyparse(this);
@ -270,18 +268,15 @@ statement: type | include | include_recursive | library | constant
{ } { }
| lterm | lterm
{ {
Expression::Ptr aexpr = *$1; $1->Evaluate(m_ModuleScope);
aexpr->Evaluate(m_ModuleScope);
delete $1; delete $1;
} }
; ;
include: T_INCLUDE rterm sep include: T_INCLUDE rterm sep
{ {
Expression::Ptr aexpr = *$2; context->HandleInclude($2->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2));
delete $2; delete $2;
context->HandleInclude(aexpr->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2));
} }
| T_INCLUDE T_STRING_ANGLE | T_INCLUDE T_STRING_ANGLE
{ {
@ -292,20 +287,14 @@ include: T_INCLUDE rterm sep
include_recursive: T_INCLUDE_RECURSIVE rterm include_recursive: T_INCLUDE_RECURSIVE rterm
{ {
Expression::Ptr aexpr = *$2; context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2));
delete $2; delete $2;
context->HandleIncludeRecursive(aexpr->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2));
} }
| T_INCLUDE_RECURSIVE rterm ',' rterm | T_INCLUDE_RECURSIVE rterm ',' rterm
{ {
Expression::Ptr aexpr1 = *$2; context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), $4->Evaluate(m_ModuleScope), DebugInfoRange(@1, @4));
delete $2; delete $2;
Expression::Ptr aexpr2 = *$4;
delete $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 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; delete $4;
ScriptVariable::Ptr sv = ScriptVariable::Set($2, aexpr->Evaluate(m_ModuleScope));
sv->SetConstant(true); sv->SetConstant(true);
free($2);
} }
; ;
@ -447,20 +434,13 @@ object:
{ {
m_ObjectAssign.pop(); m_ObjectAssign.pop();
Array::Ptr args = new Array(); bool abstract = m_Abstract.top();
args->Add(m_Abstract.top());
m_Abstract.pop(); m_Abstract.pop();
String type = $3; String type = $3;
args->Add(type);
free($3); free($3);
args->Add(*$4); DictExpression *exprl = dynamic_cast<DictExpression *>($5);
delete $4;
Expression::Ptr exprl = *$5;
delete $5;
exprl->MakeInline(); exprl->MakeInline();
if (m_SeenAssign.top() && !ObjectRule::IsValidSourceType(type)) if (m_SeenAssign.top() && !ObjectRule::IsValidSourceType(type))
@ -468,17 +448,13 @@ object:
m_SeenAssign.pop(); 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(); 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(); m_Assign.pop();
args->Add(filter); $$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), exprl, DebugInfoRange(@2, @5));
args->Add(context->GetZone());
$$ = new Value(new Expression(&Expression::OpObject, args, exprl, DebugInfoRange(@2, @5)));
} }
; ;
@ -500,12 +476,12 @@ identifier_items: identifier_items_inner
identifier_items_inner: /* empty */ identifier_items_inner: /* empty */
{ {
$$ = new Array(); $$ = new std::vector<String>();
} }
| identifier | identifier
{ {
$$ = new Array(); $$ = new std::vector<String>();
$$->Add($1); $$->push_back($1);
free($1); free($1);
} }
| identifier_items_inner ',' identifier | identifier_items_inner ',' identifier
@ -513,44 +489,42 @@ identifier_items_inner: /* empty */
if ($1) if ($1)
$$ = $1; $$ = $1;
else else
$$ = new Array(); $$ = new std::vector<String>();
$$->Add($3); $$->push_back($3);
free($3); free($3);
} }
; ;
indexer: identifier indexer: identifier
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
$$->Add(MakeLiteral($1)); $$->push_back(MakeLiteral($1));
free($1); free($1);
} }
| identifier indexer_items | identifier indexer_items
{ {
$$ = $2; $$ = $2;
$$->Insert(0, MakeLiteral($1)); $$->insert($$->begin(), MakeLiteral($1));
free($1); free($1);
} }
; ;
indexer_items: indexer_item indexer_items: indexer_item
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
$$->Add(*$1); $$->push_back($1);
delete $1;
} }
| indexer_items indexer_item | indexer_items indexer_item
{ {
$$ = $1; $$ = $1;
$$->Add(*$2); $$->push_back($2);
delete $2;
} }
; ;
indexer_item: '.' identifier indexer_item: '.' identifier
{ {
$$ = new Value(MakeLiteral($2)); $$ = MakeLiteral($2);
free($2); free($2);
} }
| '[' rterm ']' | '[' rterm ']'
@ -571,7 +545,7 @@ combined_set_op: T_SET
lterm_items: /* empty */ lterm_items: /* empty */
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
} }
| lterm_items_inner | lterm_items_inner
{ {
@ -584,32 +558,29 @@ lterm_items: /* empty */
lterm_items_inner: lterm lterm_items_inner: lterm
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
$$->Add(*$1); $$->push_back($1);
delete $1;
} }
| lterm_items_inner sep lterm | lterm_items_inner sep lterm
{ {
if ($1) if ($1)
$$ = $1; $$ = $1;
else else
$$ = new Array(); $$ = new std::vector<Expression *>();
$$->Add(*$3); $$->push_back($3);
delete $3;
} }
; ;
lterm: indexer combined_set_op rterm lterm: indexer combined_set_op rterm
{ {
$$ = new Value(new Expression(&Expression::OpSet, MakeArray(Array::Ptr($1), $2), *$3, DebugInfoRange(@1, @3))); $$ = new SetExpression(*$1, $2, $3, DebugInfoRange(@1, @3));
delete $3; delete $1;
} }
| T_IMPORT rterm | T_IMPORT rterm
{ {
Expression::Ptr avar = new Expression(&Expression::OpVariable, "type", DebugInfoRange(@1, @2)); Expression *avar = new VariableExpression("type", DebugInfoRange(@1, @2));
$$ = new Value(new Expression(&Expression::OpImport, avar, *$2, DebugInfoRange(@1, @2))); $$ = new ImportExpression(avar, $2, DebugInfoRange(@1, @2));
delete $2;
} }
| T_ASSIGN T_WHERE rterm | T_ASSIGN T_WHERE rterm
{ {
@ -618,27 +589,24 @@ lterm: indexer combined_set_op rterm
m_SeenAssign.top() = true; m_SeenAssign.top() = true;
m_Assign.top() = new Expression(&Expression::OpLogicalOr, m_Assign.top(), *$3, DebugInfoRange(@1, @3)); m_Assign.top() = new LogicalOrExpression(m_Assign.top(), $3, DebugInfoRange(@1, @3));
delete $3;
$$ = new Value(MakeLiteral()); $$ = MakeLiteral();
} }
| T_IGNORE T_WHERE rterm | T_IGNORE T_WHERE rterm
{ {
if ((m_Apply.empty() || !m_Apply.top()) && (m_ObjectAssign.empty() || !m_ObjectAssign.top())) if ((m_Apply.empty() || !m_Apply.top()) && (m_ObjectAssign.empty() || !m_ObjectAssign.top()))
BOOST_THROW_EXCEPTION(ConfigError("'ignore' keyword not valid in this context.")); 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)); m_Ignore.top() = new LogicalOrExpression(m_Ignore.top(), $3, DebugInfoRange(@1, @3));
delete $3;
$$ = new Value(MakeLiteral()); $$ = MakeLiteral();
} }
| T_RETURN rterm | T_RETURN rterm
{ {
Expression::Ptr aname = MakeLiteral("__result"); std::vector<Expression *> vname;
$$ = new Value(new Expression(&Expression::OpSet, MakeArray(MakeArray(MakeLiteral(aname)), OpSetLiteral), *$2, DebugInfoRange(@1, @2))); vname.push_back(MakeLiteral("__result"));
delete $2; $$ = new SetExpression(vname, OpSetLiteral, $2, DebugInfoRange(@1, @2));
} }
| apply | apply
{ {
@ -656,7 +624,7 @@ lterm: indexer combined_set_op rterm
rterm_items: /* empty */ rterm_items: /* empty */
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
} }
| rterm_items_inner | rterm_items_inner
{ {
@ -670,98 +638,99 @@ rterm_items: /* empty */
rterm_items_inner: rterm rterm_items_inner: rterm
{ {
$$ = new Array(); $$ = new std::vector<Expression *>();
$$->Add(*$1); $$->push_back($1);
delete $1;
} }
| rterm_items_inner arraysep rterm | rterm_items_inner arraysep rterm
{ {
$$ = $1; $$ = $1;
$$->Add(*$3); $$->push_back($3);
delete $3;
} }
; ;
rterm_array: '[' newlines rterm_items newlines ']' 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 ']' | '[' 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 ']' | '[' 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 ']' | '[' 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 '}' 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 '}' | '{' 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 '}' | '{' 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 '}' | '{' 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 rterm: T_STRING
{ {
$$ = new Value(MakeLiteral($1)); $$ = MakeLiteral($1);
free($1); free($1);
} }
| T_NUMBER | T_NUMBER
{ {
$$ = new Value(MakeLiteral($1)); $$ = MakeLiteral($1);
} }
| T_NULL | T_NULL
{ {
$$ = new Value(MakeLiteral()); $$ = MakeLiteral();
} }
| rterm '.' T_IDENTIFIER | rterm '.' T_IDENTIFIER
{ {
$$ = new Value(new Expression(&Expression::OpIndexer, *$1, MakeLiteral($3), DebugInfoRange(@1, @3))); $$ = new IndexerExpression($1, MakeLiteral($3), DebugInfoRange(@1, @3));
delete $1;
free($3); free($3);
} }
| rterm '(' rterm_items ')' | rterm '(' rterm_items ')'
{ {
$$ = new Value(new Expression(&Expression::OpFunctionCall, *$1, MakeLiteral(Array::Ptr($3)), DebugInfoRange(@1, @4))); $$ = new FunctionCallExpression($1, *$3, DebugInfoRange(@1, @4));
delete $1; delete $3;
} }
| T_IDENTIFIER | T_IDENTIFIER
{ {
$$ = new Value(new Expression(&Expression::OpVariable, $1, @1)); $$ = new VariableExpression($1, @1);
free($1); free($1);
} }
| '!' rterm | '!' rterm
{ {
$$ = new Value(new Expression(&Expression::OpLogicalNegate, *$2, DebugInfoRange(@1, @2))); $$ = new LogicalNegateExpression($2, DebugInfoRange(@1, @2));
delete $2;
} }
| '~' rterm | '~' rterm
{ {
$$ = new Value(new Expression(&Expression::OpNegate, *$2, DebugInfoRange(@1, @2))); $$ = new NegateExpression($2, DebugInfoRange(@1, @2));
delete $2;
} }
| rterm '[' rterm ']' | rterm '[' rterm ']'
{ {
$$ = new Value(new Expression(&Expression::OpIndexer, *$1, *$3, DebugInfoRange(@1, @4))); $$ = new IndexerExpression($1, $3, DebugInfoRange(@1, @4));
delete $1;
delete $3;
} }
| rterm_array | rterm_array
{ {
@ -780,62 +749,50 @@ rterm: T_STRING
ignore_newlines--; ignore_newlines--;
$$ = $3; $$ = $3;
} }
| rterm T_LOGICAL_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LOGICAL_OR rterm { MakeRBinaryOp<LogicalOrExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LOGICAL_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LOGICAL_AND rterm { MakeRBinaryOp<LogicalAndExpression>(&$$, $1, $3, @1, @3); }
| rterm T_BINARY_OR rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_BINARY_OR rterm { MakeRBinaryOp<BinaryOrExpression>(&$$, $1, $3, @1, @3); }
| rterm T_BINARY_AND rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_BINARY_AND rterm { MakeRBinaryOp<BinaryAndExpression>(&$$, $1, $3, @1, @3); }
| rterm T_IN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_IN rterm { MakeRBinaryOp<InExpression>(&$$, $1, $3, @1, @3); }
| rterm T_NOT_IN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_NOT_IN rterm { MakeRBinaryOp<NotInExpression>(&$$, $1, $3, @1, @3); }
| rterm T_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_EQUAL rterm { MakeRBinaryOp<EqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_NOT_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_NOT_EQUAL rterm { MakeRBinaryOp<NotEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LESS_THAN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LESS_THAN rterm { MakeRBinaryOp<LessThanExpression>(&$$, $1, $3, @1, @3); }
| rterm T_LESS_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_LESS_THAN_OR_EQUAL rterm { MakeRBinaryOp<LessThanOrEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_GREATER_THAN rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_GREATER_THAN rterm { MakeRBinaryOp<GreaterThanExpression>(&$$, $1, $3, @1, @3); }
| rterm T_GREATER_THAN_OR_EQUAL rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_GREATER_THAN_OR_EQUAL rterm { MakeRBinaryOp<GreaterThanOrEqualExpression>(&$$, $1, $3, @1, @3); }
| rterm T_SHIFT_LEFT rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_SHIFT_LEFT rterm { MakeRBinaryOp<ShiftLeftExpression>(&$$, $1, $3, @1, @3); }
| rterm T_SHIFT_RIGHT rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_SHIFT_RIGHT rterm { MakeRBinaryOp<ShiftRightExpression>(&$$, $1, $3, @1, @3); }
| rterm T_PLUS rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_PLUS rterm { MakeRBinaryOp<AddExpression>(&$$, $1, $3, @1, @3); }
| rterm T_MINUS rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_MINUS rterm { MakeRBinaryOp<SubtractExpression>(&$$, $1, $3, @1, @3); }
| rterm T_MULTIPLY rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_MULTIPLY rterm { MakeRBinaryOp<MultiplyExpression>(&$$, $1, $3, @1, @3); }
| rterm T_DIVIDE_OP rterm { MakeRBinaryOp(&$$, $2, $1, $3, @1, @3); } | rterm T_DIVIDE_OP rterm { MakeRBinaryOp<DivideExpression>(&$$, $1, $3, @1, @3); }
| T_FUNCTION identifier '(' identifier_items ')' rterm_scope | T_FUNCTION identifier '(' identifier_items ')' rterm_scope
{ {
Expression::Ptr aexpr = *$6; DictExpression *aexpr = dynamic_cast<DictExpression *>($6);
delete $6;
aexpr->MakeInline(); 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); free($2);
delete $4;
} }
| T_FUNCTION '(' identifier_items ')' rterm_scope | T_FUNCTION '(' identifier_items ')' rterm_scope
{ {
Expression::Ptr aexpr = *$5; DictExpression *aexpr = dynamic_cast<DictExpression *>($5);
delete $5;
aexpr->MakeInline(); 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 | T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope
{ {
Expression::Ptr aexpr = *$7; $$ = new ForExpression($3, $5, $7, $9, DebugInfoRange(@1, @9));
delete $7;
Expression::Ptr ascope = *$9;
delete $9;
$$ = new Value(new Expression(&Expression::OpFor, MakeArray($3, $5, aexpr), ascope, DebugInfoRange(@1, @9)));
free($3); free($3);
free($5); free($5);
} }
| T_FOR '(' identifier T_IN rterm ')' rterm_scope | T_FOR '(' identifier T_IN rterm ')' rterm_scope
{ {
Expression::Ptr aexpr = *$5; $$ = new ForExpression($3, "", $5, $7, DebugInfoRange(@1, @7));
delete $5;
Expression::Ptr ascope = *$7;
delete $7;
$$ = new Value(new Expression(&Expression::OpFor, MakeArray($3, Empty, aexpr), ascope, DebugInfoRange(@1, @7)));
free($3); free($3);
} }
; ;
@ -859,8 +816,7 @@ apply_for_specifier: /* empty */
m_FVVar.top() = $5; m_FVVar.top() = $5;
free($5); free($5);
m_FTerm.top() = *$7; m_FTerm.top() = $7;
delete $7;
} }
| T_APPLY_FOR '(' identifier T_IN rterm ')' | T_APPLY_FOR '(' identifier T_IN rterm ')'
{ {
@ -869,14 +825,13 @@ apply_for_specifier: /* empty */
m_FVVar.top() = ""; m_FVVar.top() = "";
m_FTerm.top() = *$5; m_FTerm.top() = $5;
delete $5;
} }
; ;
optional_rterm: /* empty */ optional_rterm: /* empty */
{ {
$$ = new Value(MakeLiteral(Empty)); $$ = MakeLiteral();
} }
| rterm | rterm
{ {
@ -892,7 +847,7 @@ apply:
m_Ignore.push(MakeLiteral(false)); m_Ignore.push(MakeLiteral(false));
m_FKVar.push(""); m_FKVar.push("");
m_FVVar.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 T_APPLY identifier optional_rterm apply_for_specifier target_type_specifier rterm
{ {
@ -900,8 +855,6 @@ apply:
String type = $3; String type = $3;
free($3); free($3);
Expression::Ptr aname = *$4;
delete $4;
String target = $6; String target = $6;
free($6); free($6);
@ -929,9 +882,7 @@ apply:
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5))); BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5)));
} }
Expression::Ptr exprl = *$7; DictExpression *exprl = dynamic_cast<DictExpression *>($7);
delete $7;
exprl->MakeInline(); exprl->MakeInline();
// assign && !ignore // assign && !ignore
@ -940,10 +891,10 @@ apply:
m_SeenAssign.pop(); 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(); 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(); m_Assign.pop();
String fkvar = m_FKVar.top(); String fkvar = m_FKVar.top();
@ -952,19 +903,10 @@ apply:
String fvvar = m_FVVar.top(); String fvvar = m_FVVar.top();
m_FVVar.pop(); m_FVVar.pop();
Expression::Ptr fterm = m_FTerm.top(); Expression *fterm = m_FTerm.top();
m_FTerm.pop(); m_FTerm.pop();
Array::Ptr args = new Array(); $$ = new ApplyExpression(type, target, $4, filter, fkvar, fvvar, fterm, exprl, DebugInfoRange(@2, @5));
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)));
} }
; ;

View File

@ -56,11 +56,11 @@ ConfigItem::ItemList ConfigItem::m_UnnamedItems;
* @param debuginfo Debug information. * @param debuginfo Debug information.
*/ */
ConfigItem::ConfigItem(const String& type, const String& name, 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 DebugInfo& debuginfo, const Object::Ptr& scope,
const String& zone) const String& zone)
: m_Type(type), m_Name(name), m_Abstract(abstract), : 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) m_Scope(scope), m_Zone(zone)
{ {
} }
@ -115,9 +115,9 @@ Object::Ptr ConfigItem::GetScope(void) const
* *
* @returns The expression list. * @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; DebugHint debugHints;
try { try {
m_ExpressionList->Evaluate(dobj, &debugHints); m_Expression->Evaluate(dobj, &debugHints);
} catch (const ConfigError& ex) { } catch (const ConfigError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo()); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
@ -169,7 +169,7 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
} }
if (discard) if (discard)
m_ExpressionList.reset(); m_Expression.reset();
dobj->SetParentScope(Dictionary::Ptr()); dobj->SetParentScope(Dictionary::Ptr());

View File

@ -38,7 +38,7 @@ public:
DECLARE_PTR_TYPEDEFS(ConfigItem); DECLARE_PTR_TYPEDEFS(ConfigItem);
ConfigItem(const String& type, const String& name, bool abstract, 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); const Object::Ptr& scope, const String& zone);
String GetType(void) const; String GetType(void) const;
@ -47,7 +47,7 @@ public:
std::vector<ConfigItem::Ptr> GetParents(void) const; 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); DynamicObject::Ptr Commit(bool discard = true);
void Register(void); void Register(void);
@ -70,7 +70,7 @@ private:
String m_Name; /**< The name. */ String m_Name; /**< The name. */
bool m_Abstract; /**< Whether this is a template. */ 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 std::vector<String> m_ParentNames; /**< The names of parent configuration
items. */ items. */
DebugInfo m_DebugInfo; /**< Debug information. */ DebugInfo m_DebugInfo; /**< Debug information. */

View File

@ -25,7 +25,7 @@
using namespace icinga; using namespace icinga;
ConfigItemBuilder::ConfigItemBuilder(void) ConfigItemBuilder::ConfigItemBuilder(void)
: m_Abstract(false), m_Expressions(new Array()) : m_Abstract(false)
{ {
m_DebugInfo.FirstLine = 0; m_DebugInfo.FirstLine = 0;
m_DebugInfo.FirstColumn = 0; m_DebugInfo.FirstColumn = 0;
@ -34,7 +34,7 @@ ConfigItemBuilder::ConfigItemBuilder(void)
} }
ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo) ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
: m_Abstract(false), m_Expressions(new Array()) : m_Abstract(false)
{ {
m_DebugInfo = debugInfo; m_DebugInfo = debugInfo;
} }
@ -64,9 +64,9 @@ void ConfigItemBuilder::SetZone(const String& zone)
m_Zone = 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) ConfigItem::Ptr ConfigItemBuilder::Compile(void)
@ -89,19 +89,25 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str())); BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
} }
Array::Ptr exprs = new Array(); std::vector<Expression *> exprs;
Array::Ptr templateArray = new Array(); Array::Ptr templateArray = new Array();
templateArray->Add(m_Name); templateArray->Add(m_Name);
exprs->Add(new Expression(&Expression::OpSet, std::vector<Expression *> indexer;
MakeArray(MakeArray(MakeLiteral("templates")), OpSetAdd), indexer.push_back(new LiteralExpression("templates"));
new Expression(&Expression::OpLiteral, templateArray, m_DebugInfo),
m_DebugInfo));
exprs->Add(new Expression(&Expression::OpDict, m_Expressions, true, m_DebugInfo)); exprs.push_back(new SetExpression(indexer, OpSetAdd,
new LiteralExpression(templateArray), m_DebugInfo));
Expression::Ptr exprl = new Expression(&Expression::OpDict, exprs, true, m_DebugInfo); DictExpression *dexpr = new DictExpression(m_Expressions, m_DebugInfo);
dexpr->MakeInline();
exprs.push_back(dexpr);
return new ConfigItem(m_Type, m_Name, m_Abstract, exprl, 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); m_DebugInfo, m_Scope, m_Zone);
} }

View File

@ -48,7 +48,7 @@ public:
void SetScope(const Object::Ptr& scope); void SetScope(const Object::Ptr& scope);
void SetZone(const String& zone); void SetZone(const String& zone);
void AddExpression(const Expression::Ptr& expr); void AddExpression(Expression *expr);
ConfigItem::Ptr Compile(void); ConfigItem::Ptr Compile(void);
@ -56,7 +56,7 @@ private:
String m_Type; /**< The object type. */ String m_Type; /**< The object type. */
String m_Name; /**< The name. */ String m_Name; /**< The name. */
bool m_Abstract; /**< Whether the item is abstract. */ 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. */ DebugInfo m_DebugInfo; /**< Debug information. */
Object::Ptr m_Scope; /**< variable scope. */ Object::Ptr m_Scope; /**< variable scope. */
String m_Zone; /**< The zone. */ String m_Zone; /**< The zone. */

View File

@ -38,219 +38,212 @@
using namespace icinga; using namespace icinga;
Expression::Expression(OpCallback op, const Value& operand1, const DebugInfo& di) Expression::~Expression(void)
: 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)
{ } { }
Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const
{ {
try { try {
#ifdef _DEBUG #ifdef _DEBUG
if (m_Operator != &Expression::OpLiteral) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
ShowCodeFragment(msgbuf, m_DebugInfo, false); ShowCodeFragment(msgbuf, GetDebugInfo(), false);
Log(LogDebug, "Expression") Log(LogDebug, "Expression")
<< "Executing:\n" << msgbuf.str(); << "Executing:\n" << msgbuf.str();
}
#endif /* _DEBUG */ #endif /* _DEBUG */
return m_Operator(this, context, dhint); return DoEvaluate(context, dhint);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
if (boost::get_error_info<boost::errinfo_nested_exception>(ex)) if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
throw; throw;
else 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) static DebugInfo debugInfo;
m_Operand2 = true; return debugInfo;
} }
void Expression::DumpOperand(std::ostream& stream, const Value& operand, int indent) { std::vector<Expression *> icinga::MakeIndexer(const String& index1)
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
{ {
String sym = Utility::GetSymbolName(reinterpret_cast<const void *>(m_Operator)); std::vector<Expression *> result;
stream << String(indent, ' ') << "op: " << Utility::DemangleSymbolName(sym) << "\n"; result.push_back(MakeLiteral(index1));
stream << String(indent, ' ') << "left:\n"; return result;
DumpOperand(stream, m_Operand1, indent + 1);
stream << String(indent, ' ') << "right:\n";
DumpOperand(stream, m_Operand2, indent + 1);
} }
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; Object::Ptr scope = context;
while (scope) { while (scope) {
if (HasField(scope, expr->m_Operand1)) if (HasField(scope, m_Variable))
return GetField(scope, expr->m_Operand1); return GetField(scope, m_Variable);
scope = GetField(scope, "__parent"); 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()) if (right.IsEmpty())
return false; return false;
else if (!right.IsObjectType<Array>()) else if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right))); 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; Array::Ptr arr = right;
bool found = false;
ObjectLock olock(arr); ObjectLock olock(arr);
BOOST_FOREACH(const Value& value, arr) { BOOST_FOREACH(const Value& value, arr) {
if (value == left) { if (value == left) {
found = true; return true;
break;
} }
} }
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; ScriptFunction::Ptr func;
@ -262,71 +255,56 @@ Value Expression::OpFunctionCall(const Expression *expr, const Object::Ptr& cont
if (!func) if (!func)
BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist.")); BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
Array::Ptr arr = expr->EvaluateOperand2(context);
std::vector<Value> arguments; std::vector<Value> arguments;
for (Array::SizeType index = 0; index < arr->GetLength(); index++) { BOOST_FOREACH(Expression *arg, m_Args) {
const Expression::Ptr& aexpr = arr->Get(index); arguments.push_back(arg->Evaluate(context));
arguments.push_back(aexpr->Evaluate(context));
} }
return func->Invoke(arguments); 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(); Array::Ptr result = new Array();
if (arr) { BOOST_FOREACH(Expression *aexpr, m_Expressions) {
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
const Expression::Ptr& aexpr = arr->Get(index);
result->Add(aexpr->Evaluate(context)); result->Add(aexpr->Evaluate(context));
} }
}
return result; 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(); Dictionary::Ptr result = new Dictionary();
result->Set("__parent", context); result->Set("__parent", context);
if (arr) { BOOST_FOREACH(Expression *aexpr, m_Expressions) {
for (Array::SizeType index = 0; index < arr->GetLength(); index++) { Object::Ptr acontext = m_Inline ? context : result;
const Expression::Ptr& aexpr = arr->Get(index);
Object::Ptr acontext = in_place ? context : result;
aexpr->Evaluate(acontext, dhint); aexpr->Evaluate(acontext, dhint);
if (HasField(acontext, "__result")) if (HasField(acontext, "__result"))
break; break;
} }
}
Dictionary::Ptr xresult = result->ShallowClone(); Dictionary::Ptr xresult = result->ShallowClone();
xresult->Remove("__parent"); xresult->Remove("__parent");
return xresult; 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; DebugHint *sdhint = dhint;
Value parent, object; Value parent, object;
String index; String index;
for (Array::SizeType i = 0; i < indexer->GetLength(); i++) { for (Array::SizeType i = 0; i < m_Indexer.size(); i++) {
Expression::Ptr indexExpr = indexer->Get(i); Expression *indexExpr = m_Indexer[i];
String tempindex = indexExpr->Evaluate(context, dhint); String tempindex = indexExpr->Evaluate(context, dhint);
if (i == indexer->GetLength() - 1) if (i == m_Indexer.size() - 1)
index = tempindex; index = tempindex;
if (i == 0) { if (i == 0) {
@ -335,65 +313,59 @@ Value Expression::OpSet(const Expression *expr, const Object::Ptr& context, Debu
} else { } else {
parent = object; parent = object;
Expression::Ptr eparent = new Expression(&Expression::OpLiteral, parent, expr->m_DebugInfo); LiteralExpression *eparent = MakeLiteral(parent);
Expression::Ptr eindex = new Expression(&Expression::OpLiteral, tempindex, expr->m_DebugInfo); LiteralExpression *eindex = MakeLiteral(tempindex);
Expression::Ptr eip = new Expression(&Expression::OpIndexer, eparent, eindex, expr->m_DebugInfo); IndexerExpression eip(eparent, eindex, m_DebugInfo);
object = eip->Evaluate(context, dhint); object = eip.Evaluate(context, dhint);
} }
if (sdhint) if (sdhint)
sdhint = sdhint->GetChild(index); sdhint = sdhint->GetChild(index);
if (i != indexer->GetLength() - 1 && object.IsEmpty()) { if (i != m_Indexer.size() - 1 && object.IsEmpty()) {
object = new Dictionary(); object = new Dictionary();
SetField(parent, tempindex, object); SetField(parent, tempindex, object);
} }
} }
Value right = expr->EvaluateOperand2(context, dhint); Value right = m_Operand2->Evaluate(context, dhint);
if (csop != OpSetLiteral) { if (m_Op != OpSetLiteral) {
Expression::OpCallback op; Expression *lhs = MakeLiteral(object);
Expression *rhs = MakeLiteral(right);
switch (csop) { switch (m_Op) {
case OpSetAdd: case OpSetAdd:
op = &Expression::OpAdd; right = AddExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
break; break;
case OpSetSubtract: case OpSetSubtract:
op = &Expression::OpSubtract; right = SubtractExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
break; break;
case OpSetMultiply: case OpSetMultiply:
op = &Expression::OpMultiply; right = MultiplyExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
break; break;
case OpSetDivide: case OpSetDivide:
op = &Expression::OpDivide; right = DivideExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
break; break;
default: default:
VERIFY(!"Invalid opcode."); 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); SetField(parent, index, right);
if (sdhint) if (sdhint)
sdhint->AddMessage("=", expr->m_DebugInfo); sdhint->AddMessage("=", m_DebugInfo);
return right; 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 value = m_Operand1->Evaluate(context);
Value index = expr->EvaluateOperand2(context); Value index = m_Operand2->Evaluate(context);
if (value.IsObjectType<Dictionary>()) { if (value.IsObjectType<Dictionary>()) {
Dictionary::Ptr dict = value; 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 type = m_Type->Evaluate(context);
Value name = expr->EvaluateOperand2(context); Value name = m_Name->Evaluate(context);
ConfigItem::Ptr item = ConfigItem::GetObject(type, name); ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
if (!item) if (!item)
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'")); BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
item->GetExpressionList()->Evaluate(context, dhint); item->GetExpression()->Evaluate(context, dhint);
return Empty; 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")); BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
Dictionary::Ptr context = new Dictionary(); Dictionary::Ptr context = new Dictionary();
context->Set("__parent", scope); context->Set("__parent", scope);
for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++) for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs.size()); i++)
context->Set(funcargs->Get(i), arguments[i]); context->Set(funcargs[i], arguments[i]);
expr->Evaluate(context); expr->Evaluate(context);
return context->Get("__result"); 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; ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&Expression::FunctionWrapper, _1, m_Args, m_Expression, context));
Expression::Ptr aexpr = left->Get(1);
String name = left->Get(0);
Array::Ptr funcargs = expr->m_Operand2; if (!m_Name.IsEmpty())
ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, context)); ScriptFunction::Register(m_Name, func);
if (!name.IsEmpty())
ScriptFunction::Register(name, func);
return 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; String name = m_Name->Evaluate(context, dhint);
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 = aname->Evaluate(context, dhint); ApplyRule::AddRule(m_Type, m_Target, name, m_Expression, m_Filter, m_FKVar, m_FVVar, m_FTerm, m_DebugInfo, context);
ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, context);
return Empty; 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; String name;
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 = 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; String checkName = name;
if (!abstract) { if (!m_Abstract) {
Type::Ptr ptype = Type::GetByName(type); Type::Ptr ptype = Type::GetByName(m_Type);
NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get()); 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()) { if (!checkName.IsEmpty()) {
ConfigItem::Ptr oldItem = ConfigItem::GetObject(type, checkName); ConfigItem::Ptr oldItem = ConfigItem::GetObject(m_Type, checkName);
if (oldItem) { if (oldItem) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << expr->m_DebugInfo << "; previous definition: " << oldItem->GetDebugInfo(); msgbuf << "Object '" << name << "' of type '" << m_Type << "' re-defined: " << m_DebugInfo << "; previous definition: " << oldItem->GetDebugInfo();
BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(expr->m_DebugInfo)); BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(m_DebugInfo));
} }
} }
item->SetType(type); item->SetType(m_Type);
if (name.FindFirstOf("!") != String::NPos) { if (name.FindFirstOf("!") != String::NPos) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'"; msgbuf << "Name for object '" << name << "' of type '" << m_Type << "' is invalid: Object names may not contain '!'";
BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(expr->m_DebugInfo)); BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(m_DebugInfo));
} }
item->SetName(name); item->SetName(name);
item->AddExpression(exprl); item->AddExpression(new OwnedExpression(m_Expression));
item->SetAbstract(abstract); item->SetAbstract(m_Abstract);
item->SetScope(context); item->SetScope(context);
item->SetZone(zone); item->SetZone(m_Zone);
item->Compile()->Register(); item->Compile()->Register();
if (ObjectRule::IsValidSourceType(type)) if (ObjectRule::IsValidSourceType(m_Type))
ObjectRule::AddRule(type, name, filter, expr->m_DebugInfo, context); ObjectRule::AddRule(m_Type, name, m_Filter, m_DebugInfo, context);
return Empty; 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; Value value = m_Value->Evaluate(context, dhint);
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);
if (value.IsObjectType<Array>()) { if (value.IsObjectType<Array>()) {
if (!vvar.IsEmpty()) if (!m_FVVar.IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(expr->m_DebugInfo)); BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(m_DebugInfo));
Array::Ptr arr = value; 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) { BOOST_FOREACH(const Value& value, arr) {
Dictionary::Ptr xcontext = new Dictionary(); Dictionary::Ptr xcontext = new Dictionary();
xcontext->Set("__parent", context); 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>()) { } else if (value.IsObjectType<Dictionary>()) {
if (vvar.IsEmpty()) if (m_FVVar.IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(expr->m_DebugInfo)); BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(m_DebugInfo));
Dictionary::Ptr dict = value; 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) { BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
Dictionary::Ptr xcontext = new Dictionary(); Dictionary::Ptr xcontext = new Dictionary();
xcontext->Set("__parent", context); xcontext->Set("__parent", context);
xcontext->Set(kvar, kv.first); xcontext->Set(m_FKVar, kv.first);
xcontext->Set(vvar, kv.second); xcontext->Set(m_FVVar, kv.second);
ascope->Evaluate(xcontext, dhint); m_Expression->Evaluate(xcontext, dhint);
} }
} else } 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; return Empty;
} }
@ -618,11 +565,6 @@ Dictionary::Ptr DebugHint::ToDictionary(void) const
return result; 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) bool Expression::HasField(const Object::Ptr& context, const String& field)
{ {
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context); Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);

View File

@ -24,6 +24,7 @@
#include "base/debuginfo.hpp" #include "base/debuginfo.hpp"
#include "base/array.hpp" #include "base/array.hpp"
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include <boost/foreach.hpp>
namespace icinga namespace icinga
{ {
@ -58,75 +59,564 @@ enum CombinedSetOp
/** /**
* @ingroup config * @ingroup config
*/ */
class I2_CONFIG_API Expression : public Object class I2_CONFIG_API Expression
{ {
public: public:
DECLARE_PTR_TYPEDEFS(Expression); virtual ~Expression(void);
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);
Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const; Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const;
void MakeInline(void); virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const = 0;
virtual const DebugInfo& GetDebugInfo(void) const;
void Dump(std::ostream& stream, int indent = 0) const; public:
static Value FunctionWrapper(const std::vector<Value>& arguments,
static Value OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); const std::vector<String>& funcargs,
static Value OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint); const boost::shared_ptr<Expression>& expr, const Object::Ptr& scope);
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);
static bool HasField(const Object::Ptr& context, const String& field); static bool HasField(const Object::Ptr& context, const String& field);
static Value GetField(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); 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::RuleMap ObjectRule::m_Rules;
ObjectRule::CallbackMap ObjectRule::m_Callbacks; 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) const DebugInfo& di, const Object::Ptr& scope)
: m_Name(name), m_Filter(filter), m_DebugInfo(di), m_Scope(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; return m_Name;
} }
Expression::Ptr ObjectRule::GetFilter(void) const boost::shared_ptr<Expression> ObjectRule::GetFilter(void) const
{ {
return m_Filter; return m_Filter;
} }
@ -52,7 +52,7 @@ Object::Ptr ObjectRule::GetScope(void) const
} }
void ObjectRule::AddRule(const String& sourceType, const String& name, 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)); 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; typedef std::map<String, std::vector<ObjectRule> > RuleMap;
String GetName(void) const; String GetName(void) const;
Expression::Ptr GetFilter(void) const; boost::shared_ptr<Expression> GetFilter(void) const;
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
Object::Ptr GetScope(void) const; Object::Ptr GetScope(void) const;
bool EvaluateFilter(const Object::Ptr& scope) const; bool EvaluateFilter(const Object::Ptr& scope) const;
static void AddRule(const String& sourceType, const String& name, 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 EvaluateRules(bool clear);
static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback); static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
@ -54,15 +54,14 @@ public:
private: private:
String m_Name; String m_Name;
Expression::Ptr m_Filter; boost::shared_ptr<Expression> m_Filter;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
Object::Ptr m_Scope; Object::Ptr m_Scope;
static CallbackMap m_Callbacks; static CallbackMap m_Callbacks;
static RuleMap m_Rules; static RuleMap m_Rules;
ObjectRule(const String& name, const Expression::Ptr& filter, ObjectRule(const String& name, const boost::shared_ptr<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope);
const DebugInfo& di, const Object::Ptr& scope);
}; };
} }

View File

@ -58,33 +58,18 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c
Service::Ptr service; Service::Ptr service;
tie(host, service) = GetHostService(checkable); tie(host, service) = GetHostService(checkable);
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
MakeArray(MakeArray(MakeLiteral("parent_host_name")), OpSetLiteral), builder->AddExpression(new SetExpression(MakeIndexer("child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
MakeLiteral(host->GetName()),
di));
builder->AddExpression(new Expression(&Expression::OpSet, if (service)
MakeArray(MakeArray(MakeLiteral("child_host_name")), OpSetLiteral), builder->AddExpression(new SetExpression(MakeIndexer("child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
MakeLiteral(host->GetName()),
di));
if (service) {
builder->AddExpression(new Expression(&Expression::OpSet,
MakeArray(MakeArray(MakeLiteral("child_service_name")), OpSetLiteral),
MakeLiteral(service->GetShortName()),
di));
}
String zone = checkable->GetZone(); String zone = checkable->GetZone();
if (!zone.IsEmpty()) { if (!zone.IsEmpty())
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral),
MakeLiteral(zone),
di));
}
builder->AddExpression(rule.GetExpression()); builder->AddExpression(new OwnedExpression(rule.GetExpression()));
ConfigItem::Ptr dependencyItem = builder->Compile(); ConfigItem::Ptr dependencyItem = builder->Compile();
DynamicObject::Ptr dobj = dependencyItem->Commit(); DynamicObject::Ptr dobj = dependencyItem->Commit();

View File

@ -58,28 +58,17 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable,
Service::Ptr service; Service::Ptr service;
tie(host, service) = GetHostService(checkable); tie(host, service) = GetHostService(checkable);
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral),
MakeLiteral(host->GetName()),
di));
if (service) { if (service)
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
MakeArray(MakeArray(MakeLiteral("service_name")), OpSetLiteral),
MakeLiteral(service->GetShortName()),
di));
}
String zone = checkable->GetZone(); String zone = checkable->GetZone();
if (!zone.IsEmpty()) { if (!zone.IsEmpty())
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral),
MakeLiteral(zone),
di));
}
builder->AddExpression(rule.GetExpression()); builder->AddExpression(new OwnedExpression(rule.GetExpression()));
ConfigItem::Ptr notificationItem = builder->Compile(); ConfigItem::Ptr notificationItem = builder->Compile();
DynamicObject::Ptr dobj = notificationItem->Commit(); DynamicObject::Ptr dobj = notificationItem->Commit();

View File

@ -57,28 +57,18 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check
Service::Ptr service; Service::Ptr service;
tie(host, service) = GetHostService(checkable); tie(host, service) = GetHostService(checkable);
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral),
MakeLiteral(host->GetName()),
di));
if (service) { if (service)
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
MakeArray(MakeArray(MakeLiteral("service_name")), OpSetLiteral),
MakeLiteral(service->GetShortName()),
di));
}
String zone = checkable->GetZone(); String zone = checkable->GetZone();
if (!zone.IsEmpty()) { if (!zone.IsEmpty()) {
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral),
MakeLiteral(zone),
di));
} }
builder->AddExpression(rule.GetExpression()); builder->AddExpression(new OwnedExpression(rule.GetExpression()));
ConfigItem::Ptr downtimeItem = builder->Compile(); ConfigItem::Ptr downtimeItem = builder->Compile();
DynamicObject::Ptr dobj = downtimeItem->Commit(); DynamicObject::Ptr dobj = downtimeItem->Commit();

View File

@ -52,26 +52,16 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String&
builder->SetName(name); builder->SetName(name);
builder->SetScope(locals); builder->SetScope(locals);
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
MakeArray(MakeArray(MakeLiteral("host_name")), OpSetLiteral),
MakeLiteral(host->GetName()),
di));
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("name"), OpSetLiteral, MakeLiteral(name), di));
MakeArray(MakeArray(MakeLiteral("name")), OpSetLiteral),
MakeLiteral(name),
di));
String zone = host->GetZone(); String zone = host->GetZone();
if (!zone.IsEmpty()) { if (!zone.IsEmpty())
builder->AddExpression(new Expression(&Expression::OpSet, builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
MakeArray(MakeArray(MakeLiteral("zone")), OpSetLiteral),
MakeLiteral(zone),
di));
}
builder->AddExpression(rule.GetExpression()); builder->AddExpression(new OwnedExpression(rule.GetExpression()));
ConfigItem::Ptr serviceItem = builder->Compile(); ConfigItem::Ptr serviceItem = builder->Compile();
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = serviceItem->Commit();