mirror of https://github.com/Icinga/icinga2.git
parent
67d8bc219e
commit
aacc699dd4
|
@ -30,7 +30,7 @@ add_library(base SHARED
|
|||
netstring.cpp networkstream.cpp object.cpp objectlock.cpp process.cpp
|
||||
process-unix.cpp process-windows.cpp qstring.cpp ringbuffer.cpp script.cpp
|
||||
script.th scriptfunction.cpp scriptfunctionwrapper.cpp scriptinterpreter.cpp
|
||||
scriptlanguage.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
|
||||
scriptlanguage.cpp scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
|
||||
statsfunction.cpp stdiostream.cpp stream_bio.cpp stream.cpp streamlogger.cpp streamlogger.th
|
||||
sysloglogger.cpp sysloglogger.th tcpsocket.cpp threadpool.cpp timer.cpp
|
||||
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "methods/utilityfuncs.h"
|
||||
#include "base/scriptutils.h"
|
||||
#include "base/scriptfunction.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/convert.h"
|
||||
#include "base/array.h"
|
||||
#include "base/dictionary.h"
|
||||
#include "base/serializer.h"
|
||||
#include "base/logger_fwd.h"
|
||||
#include <boost/regex.hpp>
|
||||
#include <algorithm>
|
||||
|
@ -30,21 +31,21 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_SCRIPTFUNCTION(regex, &UtilityFuncs::Regex);
|
||||
REGISTER_SCRIPTFUNCTION(regex, &ScriptUtils::Regex);
|
||||
REGISTER_SCRIPTFUNCTION(match, &Utility::Match);
|
||||
REGISTER_SCRIPTFUNCTION(len, &UtilityFuncs::Len);
|
||||
REGISTER_SCRIPTFUNCTION(union, &UtilityFuncs::Union);
|
||||
REGISTER_SCRIPTFUNCTION(intersection, &UtilityFuncs::Intersection);
|
||||
REGISTER_SCRIPTFUNCTION(log, &UtilityFuncs::Log);
|
||||
REGISTER_SCRIPTFUNCTION(len, &ScriptUtils::Len);
|
||||
REGISTER_SCRIPTFUNCTION(union, &ScriptUtils::Union);
|
||||
REGISTER_SCRIPTFUNCTION(intersection, &ScriptUtils::Intersection);
|
||||
REGISTER_SCRIPTFUNCTION(log, &ScriptUtils::Log);
|
||||
|
||||
bool UtilityFuncs::Regex(const String& pattern, const String& text)
|
||||
bool ScriptUtils::Regex(const String& pattern, const String& text)
|
||||
{
|
||||
boost::regex expr(pattern.GetData());
|
||||
boost::smatch what;
|
||||
return boost::regex_search(text.GetData(), what, expr);
|
||||
}
|
||||
|
||||
int UtilityFuncs::Len(const Value& value)
|
||||
int ScriptUtils::Len(const Value& value)
|
||||
{
|
||||
if (value.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr dict = value;
|
||||
|
@ -57,7 +58,7 @@ int UtilityFuncs::Len(const Value& value)
|
|||
}
|
||||
}
|
||||
|
||||
Array::Ptr UtilityFuncs::Union(const std::vector<Value>& arguments)
|
||||
Array::Ptr ScriptUtils::Union(const std::vector<Value>& arguments)
|
||||
{
|
||||
std::set<Value> values;
|
||||
|
||||
|
@ -77,7 +78,7 @@ Array::Ptr UtilityFuncs::Union(const std::vector<Value>& arguments)
|
|||
return result;
|
||||
}
|
||||
|
||||
Array::Ptr UtilityFuncs::Intersection(const std::vector<Value>& arguments)
|
||||
Array::Ptr ScriptUtils::Intersection(const std::vector<Value>& arguments)
|
||||
{
|
||||
if (arguments.size() == 0)
|
||||
return make_shared<Array>();
|
||||
|
@ -101,7 +102,10 @@ Array::Ptr UtilityFuncs::Intersection(const std::vector<Value>& arguments)
|
|||
return result;
|
||||
}
|
||||
|
||||
void UtilityFuncs::Log(const String& message)
|
||||
void ScriptUtils::Log(const Value& message)
|
||||
{
|
||||
::Log(LogInformation, "config", message);
|
||||
if (message.IsString())
|
||||
::Log(LogInformation, "config", message);
|
||||
else
|
||||
::Log(LogInformation, "config", JsonSerialize(message));
|
||||
}
|
|
@ -17,10 +17,10 @@
|
|||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef UTILITYFUNCS_H
|
||||
#define UTILITYFUNCS_H
|
||||
#ifndef SCRIPTUTILS_H
|
||||
#define SCRIPTUTILS_H
|
||||
|
||||
#include "methods/i2-methods.h"
|
||||
#include "base/i2-base.h"
|
||||
#include "base/qstring.h"
|
||||
#include "base/array.h"
|
||||
|
||||
|
@ -28,21 +28,21 @@ namespace icinga
|
|||
{
|
||||
|
||||
/**
|
||||
* @ingroup methods
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_METHODS_API UtilityFuncs
|
||||
class I2_BASE_API ScriptUtils
|
||||
{
|
||||
public:
|
||||
static bool Regex(const String& pattern, const String& text);
|
||||
static int Len(const Value& value);
|
||||
static Array::Ptr Union(const std::vector<Value>& arguments);
|
||||
static Array::Ptr Intersection(const std::vector<Value>& arguments);
|
||||
static void Log(const String& message);
|
||||
static void Log(const Value& message);
|
||||
|
||||
private:
|
||||
UtilityFuncs(void);
|
||||
ScriptUtils(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* UTILITYFUNCS_H */
|
||||
#endif /* SCRIPTUTILS_H */
|
|
@ -201,10 +201,19 @@ Value icinga::operator+(const Value& lhs, const Value& rhs)
|
|||
return static_cast<String>(lhs) + static_cast<String>(rhs);
|
||||
else if ((lhs.IsNumber() || lhs.IsEmpty()) && (rhs.IsNumber() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty()))
|
||||
return static_cast<double>(lhs) + static_cast<double>(rhs);
|
||||
else if (lhs.IsObjectType<Array>() && rhs.IsObjectType<Array>()) {
|
||||
else if ((lhs.IsObjectType<Array>() || lhs.IsEmpty()) && (rhs.IsObjectType<Array>() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty())) {
|
||||
Array::Ptr result = make_shared<Array>();
|
||||
static_cast<Array::Ptr>(lhs)->CopyTo(result);
|
||||
static_cast<Array::Ptr>(rhs)->CopyTo(result);
|
||||
if (!lhs.IsEmpty())
|
||||
static_cast<Array::Ptr>(lhs)->CopyTo(result);
|
||||
if (!rhs.IsEmpty())
|
||||
static_cast<Array::Ptr>(rhs)->CopyTo(result);
|
||||
return result;
|
||||
} else if ((lhs.IsObjectType<Dictionary>() || lhs.IsEmpty()) && (rhs.IsObjectType<Dictionary>() || rhs.IsEmpty()) && !(lhs.IsEmpty() && rhs.IsEmpty())) {
|
||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||
if (!lhs.IsEmpty())
|
||||
static_cast<Dictionary::Ptr>(lhs)->CopyTo(result);
|
||||
if (!rhs.IsEmpty())
|
||||
static_cast<Dictionary::Ptr>(rhs)->CopyTo(result);
|
||||
return result;
|
||||
} else {
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Operator + cannot be applied to values of type '" + lhs.GetTypeName() + "' and '" + rhs.GetTypeName() + "'"));
|
||||
|
|
|
@ -30,7 +30,7 @@ add_library(config SHARED
|
|||
aexpression.cpp applyrule.cpp base-type.conf base-type.cpp
|
||||
configcompilercontext.cpp configcompiler.cpp configerror.cpp configitembuilder.cpp
|
||||
configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
|
||||
configtype.cpp debuginfo.cpp expression.cpp expressionlist.cpp typerule.cpp typerulelist.cpp
|
||||
configtype.cpp debuginfo.cpp typerule.cpp typerulelist.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(config ${Boost_LIBRARIES} base)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
using namespace icinga;
|
||||
|
||||
AExpression::AExpression(OpCallback op, const Value& operand1, const DebugInfo& di)
|
||||
: m_Operator(op), m_Operand1(operand1), m_DebugInfo(di)
|
||||
: m_Operator(op), m_Operand1(operand1), m_Operand2(), m_DebugInfo(di)
|
||||
{ }
|
||||
|
||||
AExpression::AExpression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di)
|
||||
|
@ -46,10 +46,66 @@ Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
|
|||
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
|
||||
throw;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression.") << 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(m_DebugInfo));
|
||||
}
|
||||
}
|
||||
|
||||
void AExpression::ExtractPath(const std::vector<String>& path, const Array::Ptr& result) const
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (m_Operator == &AExpression::OpDict) {
|
||||
Array::Ptr exprl = m_Operand1;
|
||||
BOOST_FOREACH(const AExpression::Ptr& expr, exprl) {
|
||||
expr->ExtractPath(path, result);
|
||||
}
|
||||
} else if (m_Operator == &AExpression::OpSet && path[0] == m_Operand1) {
|
||||
AExpression::Ptr exprl = m_Operand2;
|
||||
|
||||
if (path.size() == 1) {
|
||||
result->Add(m_Operand1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->ExtractPath(sub_path, result);
|
||||
} else if (m_Operator == &AExpression::OpDict && static_cast<bool>(m_Operand2)) {
|
||||
AExpression::Ptr exprl = m_Operand1;
|
||||
exprl->ExtractPath(path, result);
|
||||
}
|
||||
}
|
||||
|
||||
void AExpression::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (m_Operator == &AExpression::OpDict) {
|
||||
Array::Ptr exprl = m_Operand1;
|
||||
BOOST_FOREACH(const AExpression::Ptr& expr, exprl) {
|
||||
expr->FindDebugInfoPath(path, result);
|
||||
}
|
||||
} else if (m_Operator == &AExpression::OpSet && path[0] == m_Operand1) {
|
||||
AExpression::Ptr exprl = m_Operand2;
|
||||
|
||||
if (path.size() == 1) {
|
||||
result = m_DebugInfo;
|
||||
} else {
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->FindDebugInfoPath(sub_path, result);
|
||||
}
|
||||
} else if (m_Operator == &AExpression::OpDict && static_cast<bool>(m_Operand2)) {
|
||||
AExpression::Ptr exprl = m_Operand1;
|
||||
exprl->FindDebugInfoPath(path, result);
|
||||
}
|
||||
}
|
||||
|
||||
void AExpression::MakeInline(void)
|
||||
{
|
||||
ASSERT(m_Operator == &AExpression::OpDict);
|
||||
m_Operand2 = true;
|
||||
}
|
||||
|
||||
Value AExpression::EvaluateOperand1(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
return static_cast<AExpression::Ptr>(m_Operand1)->Evaluate(locals);
|
||||
|
@ -150,12 +206,12 @@ Value AExpression::OpGreaterThanOrEqual(const Dictionary::Ptr& locals) const
|
|||
|
||||
Value AExpression::OpIn(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value right = EvaluateOperand1(locals);
|
||||
Value right = EvaluateOperand2(locals);
|
||||
|
||||
if (!right.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonSerialize(right)));
|
||||
|
||||
Value left = EvaluateOperand2(locals);
|
||||
Value left = EvaluateOperand1(locals);
|
||||
|
||||
Array::Ptr arr = right;
|
||||
bool found = false;
|
||||
|
@ -214,3 +270,53 @@ Value AExpression::OpArray(const Dictionary::Ptr& locals) const
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
Value AExpression::OpDict(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Array::Ptr arr = m_Operand1;
|
||||
bool in_place = m_Operand2;
|
||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||
|
||||
if (arr) {
|
||||
BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
|
||||
aexpr->Evaluate(in_place ? locals : result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Value AExpression::OpSet(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value right = EvaluateOperand2(locals);
|
||||
locals->Set(m_Operand1, right);
|
||||
return right;
|
||||
}
|
||||
|
||||
Value AExpression::OpSetPlus(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value result = locals->Get(m_Operand1) + EvaluateOperand2(locals);
|
||||
locals->Set(m_Operand1, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Value AExpression::OpSetMinus(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value result = locals->Get(m_Operand1) - EvaluateOperand2(locals);
|
||||
locals->Set(m_Operand1, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Value AExpression::OpSetMultiply(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value result = locals->Get(m_Operand1) * EvaluateOperand2(locals);
|
||||
locals->Set(m_Operand1, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Value AExpression::OpSetDivide(const Dictionary::Ptr& locals) const
|
||||
{
|
||||
Value result = locals->Get(m_Operand1) / EvaluateOperand2(locals);
|
||||
locals->Set(m_Operand1, result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "config/i2-config.h"
|
||||
#include "config/debuginfo.h"
|
||||
#include "base/array.h"
|
||||
#include "base/dictionary.h"
|
||||
|
||||
namespace icinga
|
||||
|
@ -41,6 +42,10 @@ public:
|
|||
AExpression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di);
|
||||
|
||||
Value Evaluate(const Dictionary::Ptr& locals) const;
|
||||
void ExtractPath(const std::vector<String>& path, const Array::Ptr& result) const;
|
||||
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
|
||||
|
||||
void MakeInline(void);
|
||||
|
||||
Value OpLiteral(const Dictionary::Ptr& locals) const;
|
||||
Value OpVariable(const Dictionary::Ptr& locals) const;
|
||||
|
@ -65,6 +70,12 @@ public:
|
|||
Value OpLogicalOr(const Dictionary::Ptr& locals) const;
|
||||
Value OpFunctionCall(const Dictionary::Ptr& locals) const;
|
||||
Value OpArray(const Dictionary::Ptr& locals) const;
|
||||
Value OpDict(const Dictionary::Ptr& locals) const;
|
||||
Value OpSet(const Dictionary::Ptr& locals) const;
|
||||
Value OpSetPlus(const Dictionary::Ptr& locals) const;
|
||||
Value OpSetMinus(const Dictionary::Ptr& locals) const;
|
||||
Value OpSetMultiply(const Dictionary::Ptr& locals) const;
|
||||
Value OpSetDivide(const Dictionary::Ptr& locals) const;
|
||||
|
||||
private:
|
||||
OpCallback m_Operator;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "config/configcompiler.h"
|
||||
#include "config/expression.h"
|
||||
#include "config/typerule.h"
|
||||
#include "config/configcompilercontext.h"
|
||||
|
||||
|
@ -225,16 +224,16 @@ const return T_CONST;
|
|||
apply return T_APPLY;
|
||||
to return T_TO;
|
||||
where return T_WHERE;
|
||||
\<\< return T_SHIFT_LEFT;
|
||||
\>\> return T_SHIFT_RIGHT;
|
||||
\<= return T_LESS_THAN_OR_EQUAL;
|
||||
\>= return T_GREATER_THAN_OR_EQUAL;
|
||||
== return T_EQUAL;
|
||||
!= return T_NOT_EQUAL;
|
||||
!in return T_NOT_IN;
|
||||
in return T_IN;
|
||||
&& return T_LOGICAL_AND;
|
||||
\|\| return T_LOGICAL_OR;
|
||||
\<\< { yylval->op = &AExpression::OpShiftLeft; return T_SHIFT_LEFT; }
|
||||
\>\> { yylval->op = &AExpression::OpShiftRight; return T_SHIFT_RIGHT; }
|
||||
\<= { yylval->op = &AExpression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; }
|
||||
\>= { yylval->op = &AExpression::OpGreaterThanOrEqual; return T_GREATER_THAN_OR_EQUAL; }
|
||||
== { yylval->op = &AExpression::OpEqual; return T_EQUAL; }
|
||||
!= { yylval->op = &AExpression::OpNotEqual; return T_NOT_EQUAL; }
|
||||
!in { yylval->op = &AExpression::OpNotIn; return T_NOT_IN; }
|
||||
in { yylval->op = &AExpression::OpIn; return T_IN; }
|
||||
&& { yylval->op = &AExpression::OpLogicalAnd; return T_LOGICAL_AND; }
|
||||
\|\| { yylval->op = &AExpression::OpLogicalOr; return T_LOGICAL_OR; }
|
||||
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
|
||||
\<[^\>]*\> { yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING_ANGLE; }
|
||||
-?[0-9]+(\.[0-9]+)?ms { yylval->num = strtod(yytext, NULL) / 1000; return T_NUMBER; }
|
||||
|
@ -243,11 +242,19 @@ in return T_IN;
|
|||
-?[0-9]+(\.[0-9]+)?m { yylval->num = strtod(yytext, NULL) * 60; return T_NUMBER; }
|
||||
-?[0-9]+(\.[0-9]+)?s { yylval->num = strtod(yytext, NULL); return T_NUMBER; }
|
||||
-?[0-9]+(\.[0-9]+)? { yylval->num = strtod(yytext, NULL); return T_NUMBER; }
|
||||
= { yylval->op = OperatorSet; return T_SET; }
|
||||
\+= { yylval->op = OperatorPlus; return T_PLUS_EQUAL; }
|
||||
-= { yylval->op = OperatorMinus; return T_MINUS_EQUAL; }
|
||||
\*= { yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; }
|
||||
\/= { yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; }
|
||||
= { yylval->op = &AExpression::OpSet; return T_SET; }
|
||||
\+= { yylval->op = &AExpression::OpSetPlus; return T_SET_PLUS; }
|
||||
-= { yylval->op = &AExpression::OpSetMinus; return T_SET_MINUS; }
|
||||
\*= { yylval->op = &AExpression::OpSetMultiply; return T_SET_MULTIPLY; }
|
||||
\/= { yylval->op = &AExpression::OpSetDivide; return T_SET_DIVIDE; }
|
||||
\+ { yylval->op = &AExpression::OpAdd; return T_PLUS; }
|
||||
\- { yylval->op = &AExpression::OpSubtract; return T_MINUS; }
|
||||
\* { yylval->op = &AExpression::OpMultiply; return T_MULTIPLY; }
|
||||
\/ { yylval->op = &AExpression::OpMultiply; return T_DIVIDE; }
|
||||
\& { yylval->op = &AExpression::OpBinaryAnd; return T_BINARY_AND; }
|
||||
\| { yylval->op = &AExpression::OpBinaryOr; return T_BINARY_OR; }
|
||||
\< { yylval->op = &AExpression::OpLessThan; return T_LESS_THAN; }
|
||||
\> { yylval->op = &AExpression::OpLessThan; return T_GREATER_THAN; }
|
||||
}
|
||||
|
||||
. return yytext[0];
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "i2-config.h"
|
||||
#include "config/expression.h"
|
||||
#include "config/expressionlist.h"
|
||||
#include "config/configitembuilder.h"
|
||||
#include "config/configcompiler.h"
|
||||
#include "config/configcompilercontext.h"
|
||||
|
@ -86,13 +84,10 @@ using namespace icinga;
|
|||
char *text;
|
||||
double num;
|
||||
icinga::Value *variant;
|
||||
icinga::ExpressionOperator op;
|
||||
icinga::AExpression::OpCallback op;
|
||||
icinga::TypeSpecifier type;
|
||||
std::vector<String> *slist;
|
||||
Expression *expr;
|
||||
ExpressionList *exprl;
|
||||
Array *array;
|
||||
Value *aexpr;
|
||||
}
|
||||
|
||||
%token <text> T_STRING
|
||||
|
@ -100,23 +95,34 @@ using namespace icinga;
|
|||
%token <num> T_NUMBER
|
||||
%token T_NULL
|
||||
%token <text> T_IDENTIFIER
|
||||
|
||||
%token <op> T_SET "= (T_SET)"
|
||||
%token <op> T_PLUS_EQUAL "+= (T_PLUS_EQUAL)"
|
||||
%token <op> T_MINUS_EQUAL "-= (T_MINUS_EQUAL)"
|
||||
%token <op> T_MULTIPLY_EQUAL "*= (T_MULTIPLY_EQUAL)"
|
||||
%token <op> T_DIVIDE_EQUAL "/= (T_DIVIDE_EQUAL)"
|
||||
%token <op> T_SET_PLUS "+= (T_SET_PLUS)"
|
||||
%token <op> T_SET_MINUS "-= (T_SET_MINUS)"
|
||||
%token <op> T_SET_MULTIPLY "*= (T_SET_MULTIPLY)"
|
||||
%token <op> T_SET_DIVIDE "/= (T_SET_DIVIDE)"
|
||||
|
||||
%token <op> T_SHIFT_LEFT "<< (T_SHIFT_LEFT)"
|
||||
%token <op> T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)"
|
||||
%token <op> T_EQUAL "== (T_EQUAL)"
|
||||
%token <op> T_NOT_EQUAL "!= (T_NOT_EQUAL)"
|
||||
%token <op> T_IN "in (T_IN)"
|
||||
%token <op> T_NOT_IN "!in (T_NOT_IN)"
|
||||
%token <op> T_LOGICAL_AND "&& (T_LOGICAL_AND)"
|
||||
%token <op> T_LOGICAL_OR "|| (T_LOGICAL_OR)"
|
||||
%token <op> T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)"
|
||||
%token <op> T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)"
|
||||
%token <op> T_PLUS "+ (T_PLUS)"
|
||||
%token <op> T_MINUS "- (T_MINUS)"
|
||||
%token <op> T_MULTIPLY "* (T_MULTIPLY)"
|
||||
%token <op> T_DIVIDE "/ (T_DIVIDE)"
|
||||
%token <op> T_BINARY_AND "& (T_BINARY_AND)"
|
||||
%token <op> T_BINARY_OR "| (T_BINARY_OR)"
|
||||
%token <op> T_LESS_THAN "< (T_LESS_THAN)"
|
||||
%token <op> T_GREATER_THAN "> (T_GREATER_THAN)"
|
||||
|
||||
%token T_VAR "var (T_VAR)"
|
||||
%token T_CONST "const (T_CONST)"
|
||||
%token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)"
|
||||
%token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)"
|
||||
%token T_EQUAL "== (T_EQUAL)"
|
||||
%token T_NOT_EQUAL "!= (T_NOT_EQUAL)"
|
||||
%token T_IN "in (T_IN)"
|
||||
%token T_NOT_IN "!in (T_NOT_IN)"
|
||||
%token T_LOGICAL_AND "&& (T_LOGICAL_AND)"
|
||||
%token T_LOGICAL_OR "|| (T_LOGICAL_OR)"
|
||||
%token T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)"
|
||||
%token T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)"
|
||||
%token <type> T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)"
|
||||
%token <type> T_TYPE_ARRAY "array (T_TYPE_ARRAY)"
|
||||
%token <type> T_TYPE_NUMBER "number (T_TYPE_NUMBER)"
|
||||
|
@ -139,20 +145,19 @@ using namespace icinga;
|
|||
%token T_TO "to (T_TO)"
|
||||
%token T_WHERE "where (T_WHERE)"
|
||||
%type <text> identifier
|
||||
%type <array> array_items
|
||||
%type <array> array_items_inner
|
||||
%type <variant> value
|
||||
%type <expr> expression
|
||||
%type <exprl> expressions
|
||||
%type <exprl> expressions_inner
|
||||
%type <exprl> expressionlist
|
||||
%type <array> rterm_items
|
||||
%type <array> rterm_items_inner
|
||||
%type <array> lterm_items
|
||||
%type <array> lterm_items_inner
|
||||
%type <variant> typerulelist
|
||||
%type <op> operator
|
||||
%type <op> lbinary_op
|
||||
%type <op> rbinary_op
|
||||
%type <type> type
|
||||
%type <num> partial_specifier
|
||||
%type <slist> object_inherits_list
|
||||
%type <slist> object_inherits_specifier
|
||||
%type <aexpr> aexpression
|
||||
%type <variant> rterm
|
||||
%type <variant> lterm
|
||||
%type <num> variable_decl
|
||||
%left T_LOGICAL_OR
|
||||
%left T_LOGICAL_AND
|
||||
|
@ -179,14 +184,17 @@ void yyerror(YYLTYPE *locp, ConfigCompiler *, const char *err)
|
|||
|
||||
int yyparse(ConfigCompiler *context);
|
||||
|
||||
static std::stack<Array::Ptr> m_Arrays;
|
||||
static bool m_Abstract;
|
||||
|
||||
static std::stack<TypeRuleList::Ptr> m_RuleLists;
|
||||
static ConfigType::Ptr m_Type;
|
||||
|
||||
static Dictionary::Ptr m_ModuleScope;
|
||||
|
||||
void ConfigCompiler::Compile(void)
|
||||
{
|
||||
m_ModuleScope = make_shared<Dictionary>();
|
||||
|
||||
try {
|
||||
yyparse(this);
|
||||
} catch (const ConfigError& ex) {
|
||||
|
@ -208,16 +216,20 @@ statements: /* empty */
|
|||
|
||||
statement: object | type | include | include_recursive | library | variable | apply
|
||||
{ }
|
||||
| value
|
||||
| lterm
|
||||
{
|
||||
AExpression::Ptr aexpr = *$1;
|
||||
aexpr->Evaluate(m_ModuleScope);
|
||||
delete $1;
|
||||
}
|
||||
;
|
||||
|
||||
include: T_INCLUDE value
|
||||
include: T_INCLUDE rterm
|
||||
{
|
||||
context->HandleInclude(*$2, false, DebugInfoRange(@1, @2));
|
||||
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$2);
|
||||
delete $2;
|
||||
|
||||
context->HandleInclude(aexpr->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2));
|
||||
}
|
||||
| T_INCLUDE T_STRING_ANGLE
|
||||
{
|
||||
|
@ -226,16 +238,22 @@ include: T_INCLUDE value
|
|||
}
|
||||
;
|
||||
|
||||
include_recursive: T_INCLUDE_RECURSIVE value
|
||||
include_recursive: T_INCLUDE_RECURSIVE rterm
|
||||
{
|
||||
context->HandleIncludeRecursive(*$2, "*.conf", DebugInfoRange(@1, @2));
|
||||
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$2);
|
||||
delete $2;
|
||||
|
||||
context->HandleIncludeRecursive(aexpr->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2));
|
||||
}
|
||||
| T_INCLUDE_RECURSIVE value value
|
||||
| T_INCLUDE_RECURSIVE rterm rterm
|
||||
{
|
||||
context->HandleIncludeRecursive(*$2, *$3, DebugInfoRange(@1, @3));
|
||||
AExpression::Ptr aexpr1 = static_cast<AExpression::Ptr>(*$2);
|
||||
delete $2;
|
||||
|
||||
AExpression::Ptr aexpr2 = static_cast<AExpression::Ptr>(*$3);
|
||||
delete $3;
|
||||
|
||||
context->HandleIncludeRecursive(aexpr1->Evaluate(m_ModuleScope), aexpr2->Evaluate(m_ModuleScope), DebugInfoRange(@1, @3));
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -246,22 +264,15 @@ library: T_LIBRARY T_STRING
|
|||
}
|
||||
;
|
||||
|
||||
variable: variable_decl identifier T_SET value
|
||||
variable: variable_decl identifier T_SET rterm
|
||||
{
|
||||
Value *value = $4;
|
||||
if (value->IsObjectType<ExpressionList>()) {
|
||||
Dictionary::Ptr dict = make_shared<Dictionary>();
|
||||
ExpressionList::Ptr exprl = *value;
|
||||
exprl->Execute(dict);
|
||||
delete value;
|
||||
value = new Value(dict);
|
||||
}
|
||||
AExpression::Ptr aexpr = static_cast<AExpression::Ptr>(*$4);
|
||||
delete $4;
|
||||
|
||||
ScriptVariable::Ptr sv = ScriptVariable::Set($2, *value);
|
||||
ScriptVariable::Ptr sv = ScriptVariable::Set($2, aexpr->Evaluate(m_ModuleScope));
|
||||
sv->SetConstant(true);
|
||||
|
||||
free($2);
|
||||
delete value;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -399,7 +410,7 @@ object:
|
|||
{
|
||||
m_Abstract = false;
|
||||
}
|
||||
object_declaration identifier T_STRING object_inherits_specifier expressionlist
|
||||
object_declaration identifier T_STRING object_inherits_specifier rterm
|
||||
{
|
||||
DebugInfo di = DebugInfoRange(@2, @6);
|
||||
ConfigItemBuilder::Ptr item = make_shared<ConfigItemBuilder>(di);
|
||||
|
@ -437,10 +448,11 @@ object:
|
|||
delete $5;
|
||||
}
|
||||
|
||||
if ($6) {
|
||||
ExpressionList::Ptr exprl = ExpressionList::Ptr($6);
|
||||
item->AddExpressionList(exprl);
|
||||
}
|
||||
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$6);
|
||||
delete $6;
|
||||
|
||||
exprl->MakeInline();
|
||||
item->AddExpression(exprl);
|
||||
|
||||
item->SetAbstract(m_Abstract);
|
||||
|
||||
|
@ -487,96 +499,36 @@ object_inherits_specifier:
|
|||
}
|
||||
;
|
||||
|
||||
expressionlist: '{' expressions '}'
|
||||
lbinary_op: T_SET
|
||||
| T_SET_PLUS
|
||||
| T_SET_MINUS
|
||||
| T_SET_MULTIPLY
|
||||
| T_SET_DIVIDE
|
||||
{
|
||||
if ($2)
|
||||
$$ = $2;
|
||||
else
|
||||
$$ = new ExpressionList();
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
expressions: expressions_inner
|
||||
lterm_items: lterm_items_inner
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| expressions_inner ','
|
||||
| lterm_items_inner ','
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
expressions_inner: /* empty */
|
||||
lterm_items_inner: /* empty */
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| expression
|
||||
{
|
||||
$$ = new ExpressionList();
|
||||
$$->AddExpression(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| expressions_inner ',' expression
|
||||
{
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new ExpressionList();
|
||||
|
||||
$$->AddExpression(*$3);
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
expression: identifier operator value
|
||||
{
|
||||
$$ = new Expression($1, $2, *$3, DebugInfoRange(@1, @3));
|
||||
free($1);
|
||||
delete $3;
|
||||
}
|
||||
| identifier '[' T_STRING ']' operator value
|
||||
{
|
||||
Expression subexpr($3, $5, *$6, DebugInfoRange(@1, @6));
|
||||
free($3);
|
||||
delete $6;
|
||||
|
||||
ExpressionList::Ptr subexprl = make_shared<ExpressionList>();
|
||||
subexprl->AddExpression(subexpr);
|
||||
|
||||
$$ = new Expression($1, OperatorPlus, subexprl, DebugInfoRange(@1, @6));
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
operator: T_SET
|
||||
| T_PLUS_EQUAL
|
||||
| T_MINUS_EQUAL
|
||||
| T_MULTIPLY_EQUAL
|
||||
| T_DIVIDE_EQUAL
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
array_items: array_items_inner
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| array_items_inner ','
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
array_items_inner: /* empty */
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| aexpression
|
||||
| lterm
|
||||
{
|
||||
$$ = new Array();
|
||||
$$->Add(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| array_items_inner ',' aexpression
|
||||
| lterm_items_inner ',' lterm
|
||||
{
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
|
@ -588,7 +540,93 @@ array_items_inner: /* empty */
|
|||
}
|
||||
;
|
||||
|
||||
aexpression: T_STRING
|
||||
lterm: T_IDENTIFIER lbinary_op rterm
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>($2, $1, static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $3;
|
||||
}
|
||||
| identifier '[' T_STRING ']' lbinary_op rterm
|
||||
{
|
||||
AExpression::Ptr subexpr = make_shared<AExpression>($5, $3, static_cast<AExpression::Ptr>(*$6), DebugInfoRange(@1, @6));
|
||||
free($3);
|
||||
delete $6;
|
||||
|
||||
Array::Ptr subexprl = make_shared<Array>();
|
||||
subexprl->Add(subexpr);
|
||||
|
||||
AExpression::Ptr expr = make_shared<AExpression>(&AExpression::OpDict, subexprl, DebugInfoRange(@1, @6));
|
||||
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpSetPlus, $1, expr, DebugInfoRange(@1, @6)));
|
||||
free($1);
|
||||
}
|
||||
| rterm
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
rbinary_op: T_PLUS
|
||||
| T_MINUS
|
||||
| T_MULTIPLY
|
||||
| T_DIVIDE
|
||||
| T_BINARY_AND
|
||||
| T_BINARY_OR
|
||||
| T_LESS_THAN
|
||||
| T_GREATER_THAN
|
||||
| T_LESS_THAN_OR_EQUAL
|
||||
| T_GREATER_THAN_OR_EQUAL
|
||||
| T_EQUAL
|
||||
| T_NOT_EQUAL
|
||||
| T_IN
|
||||
| T_NOT_IN
|
||||
| T_LOGICAL_AND
|
||||
| T_LOGICAL_OR
|
||||
| T_SHIFT_LEFT
|
||||
| T_SHIFT_RIGHT
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
rterm_items: rterm_items_inner
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| rterm_items_inner ','
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
rterm_items_inner: /* empty */
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| rterm
|
||||
{
|
||||
$$ = new Array();
|
||||
$$->Add(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| rterm_items_inner ',' rterm
|
||||
{
|
||||
if ($1)
|
||||
$$ = $1;
|
||||
else
|
||||
$$ = new Array();
|
||||
|
||||
$$->Add(*$3);
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
rbinary_op: '+'
|
||||
{
|
||||
$$ = &AExpression::OpAdd;
|
||||
}
|
||||
;
|
||||
|
||||
rterm: T_STRING
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLiteral, $1, @1));
|
||||
free($1);
|
||||
|
@ -601,7 +639,7 @@ aexpression: T_STRING
|
|||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLiteral, Empty, @1));
|
||||
}
|
||||
| T_IDENTIFIER '(' array_items ')'
|
||||
| T_IDENTIFIER '(' rterm_items ')'
|
||||
{
|
||||
Array::Ptr arguments = Array::Ptr($3);
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpFunctionCall, $1, make_shared<AExpression>(&AExpression::OpLiteral, arguments, @3), DebugInfoRange(@1, @4)));
|
||||
|
@ -612,152 +650,41 @@ aexpression: T_STRING
|
|||
$$ = new Value(make_shared<AExpression>(&AExpression::OpVariable, $1, @1));
|
||||
free($1);
|
||||
}
|
||||
| '!' aexpression
|
||||
| '!' rterm
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpNegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
|
||||
delete $2;
|
||||
}
|
||||
| '~' aexpression
|
||||
| '~' rterm
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpNegate, static_cast<AExpression::Ptr>(*$2), DebugInfoRange(@1, @2)));
|
||||
delete $2;
|
||||
}
|
||||
| '[' array_items ']'
|
||||
| '[' rterm_items ']'
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpArray, Array::Ptr($2), DebugInfoRange(@1, @3)));
|
||||
}
|
||||
| '(' aexpression ')'
|
||||
| '{' lterm_items '}'
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpDict, Array::Ptr($2), DebugInfoRange(@1, @3)));
|
||||
}
|
||||
| '(' rterm ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| aexpression '+' aexpression
|
||||
| rterm rbinary_op rterm
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpAdd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
$$ = new Value(make_shared<AExpression>($2, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '-' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpSubtract, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '*' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpMultiply, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '/' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpDivide, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '&' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpBinaryAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '|' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpBinaryOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @2)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_IN aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_NOT_IN aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpNotIn, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_LESS_THAN_OR_EQUAL aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLessThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_GREATER_THAN_OR_EQUAL aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpGreaterThanOrEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '<' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLessThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression '>' aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpGreaterThan, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_EQUAL aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_NOT_EQUAL aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpNotEqual, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_SHIFT_LEFT aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpShiftLeft, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_SHIFT_RIGHT aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpShiftRight, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_LOGICAL_AND aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLogicalAnd, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| aexpression T_LOGICAL_OR aexpression
|
||||
{
|
||||
$$ = new Value(make_shared<AExpression>(&AExpression::OpLogicalOr, static_cast<AExpression::Ptr>(*$1), static_cast<AExpression::Ptr>(*$3), DebugInfoRange(@1, @3)));
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
value: expressionlist
|
||||
{
|
||||
ExpressionList::Ptr exprl = ExpressionList::Ptr($1);
|
||||
$$ = new Value(exprl);
|
||||
}
|
||||
| aexpression
|
||||
{
|
||||
AExpression::Ptr aexpr = *$1;
|
||||
$$ = new Value(aexpr->Evaluate(Dictionary::Ptr()));
|
||||
delete $1;
|
||||
}
|
||||
;
|
||||
|
||||
optional_template: /* empty */
|
||||
| T_TEMPLATE
|
||||
;
|
||||
|
||||
apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE aexpression
|
||||
apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE rterm
|
||||
{
|
||||
if (!ApplyRule::IsValidCombination($3, $6)) {
|
||||
BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with types '" + String($3) + "' and '" + String($6) + "'.") << errinfo_debuginfo(@1));
|
||||
|
|
|
@ -48,7 +48,7 @@ ConfigItem::ItemMap ConfigItem::m_Items;
|
|||
* @param debuginfo Debug information.
|
||||
*/
|
||||
ConfigItem::ConfigItem(const String& type, const String& name,
|
||||
bool abstract, const ExpressionList::Ptr& exprl,
|
||||
bool abstract, const AExpression::Ptr& exprl,
|
||||
const std::vector<String>& parents, const DebugInfo& debuginfo)
|
||||
: m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
|
||||
m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo)
|
||||
|
@ -100,19 +100,19 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
|
|||
*
|
||||
* @returns The expression list.
|
||||
*/
|
||||
ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
|
||||
AExpression::Ptr ConfigItem::GetExpressionList(void) const
|
||||
{
|
||||
return m_ExpressionList;
|
||||
}
|
||||
|
||||
ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
|
||||
AExpression::Ptr ConfigItem::GetLinkedExpressionList(void)
|
||||
{
|
||||
ASSERT(OwnsLock());
|
||||
|
||||
if (m_LinkedExpressionList)
|
||||
return m_LinkedExpressionList;
|
||||
|
||||
m_LinkedExpressionList = make_shared<ExpressionList>();
|
||||
Array::Ptr subexprs = make_shared<Array>();
|
||||
|
||||
BOOST_FOREACH(const String& name, m_ParentNames) {
|
||||
ConfigItem::Ptr parent = ConfigItem::GetObject(m_Type, name);
|
||||
|
@ -123,18 +123,20 @@ ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
|
|||
" exist (" << m_DebugInfo << ")";
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str(), m_DebugInfo);
|
||||
} else {
|
||||
ExpressionList::Ptr pexprl;
|
||||
AExpression::Ptr pexprl;
|
||||
|
||||
{
|
||||
ObjectLock olock(parent);
|
||||
pexprl = parent->GetLinkedExpressionList();
|
||||
}
|
||||
|
||||
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
|
||||
subexprs->Add(pexprl);
|
||||
}
|
||||
}
|
||||
|
||||
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, m_ExpressionList, m_DebugInfo));
|
||||
subexprs->Add(m_ExpressionList);
|
||||
|
||||
m_LinkedExpressionList = make_shared<AExpression>(&AExpression::OpDict, subexprs, true, m_DebugInfo);
|
||||
|
||||
return m_LinkedExpressionList;
|
||||
}
|
||||
|
@ -144,7 +146,7 @@ Dictionary::Ptr ConfigItem::GetProperties(void)
|
|||
ASSERT(OwnsLock());
|
||||
|
||||
Dictionary::Ptr properties = make_shared<Dictionary>();
|
||||
GetLinkedExpressionList()->Execute(properties);
|
||||
GetLinkedExpressionList()->Evaluate(properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define CONFIGITEM_H
|
||||
|
||||
#include "config/i2-config.h"
|
||||
#include "config/expressionlist.h"
|
||||
#include "config/aexpression.h"
|
||||
#include "base/dynamicobject.h"
|
||||
|
||||
namespace icinga
|
||||
|
@ -45,7 +45,7 @@ public:
|
|||
DECLARE_PTR_TYPEDEFS(ConfigItem);
|
||||
|
||||
ConfigItem(const String& type, const String& name, bool abstract,
|
||||
const ExpressionList::Ptr& exprl, const std::vector<String>& parents,
|
||||
const AExpression::Ptr& exprl, const std::vector<String>& parents,
|
||||
const DebugInfo& debuginfo);
|
||||
|
||||
String GetType(void) const;
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
std::vector<ConfigItem::Ptr> GetParents(void) const;
|
||||
|
||||
ExpressionList::Ptr GetLinkedExpressionList(void);
|
||||
AExpression::Ptr GetLinkedExpressionList(void);
|
||||
Dictionary::Ptr GetProperties(void);
|
||||
|
||||
DynamicObject::Ptr Commit(void);
|
||||
|
@ -72,21 +72,21 @@ public:
|
|||
static void DiscardItems(void);
|
||||
|
||||
private:
|
||||
ExpressionList::Ptr GetExpressionList(void) const;
|
||||
AExpression::Ptr GetExpressionList(void) const;
|
||||
|
||||
String m_Type; /**< The object type. */
|
||||
String m_Name; /**< The name. */
|
||||
bool m_Abstract; /**< Whether this is a template. */
|
||||
bool m_Validated; /** Whether this object has been validated. */
|
||||
|
||||
ExpressionList::Ptr m_ExpressionList;
|
||||
AExpression::Ptr m_ExpressionList;
|
||||
std::vector<String> m_ParentNames; /**< The names of parent configuration
|
||||
items. */
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
|
||||
ExpressionList::Ptr m_LinkedExpressionList;
|
||||
AExpression::Ptr m_LinkedExpressionList;
|
||||
|
||||
DynamicObject::Ptr m_Object;
|
||||
DynamicObject::Ptr m_Object;
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
using namespace icinga;
|
||||
|
||||
ConfigItemBuilder::ConfigItemBuilder(void)
|
||||
: m_Abstract(false), m_ExpressionList(make_shared<ExpressionList>())
|
||||
: m_Abstract(false), m_Expressions(make_shared<Array>())
|
||||
{
|
||||
m_DebugInfo.FirstLine = 0;
|
||||
m_DebugInfo.FirstColumn = 0;
|
||||
|
@ -35,7 +35,7 @@ ConfigItemBuilder::ConfigItemBuilder(void)
|
|||
}
|
||||
|
||||
ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
|
||||
: m_Abstract(false), m_ExpressionList(make_shared<ExpressionList>())
|
||||
: m_Abstract(false), m_Expressions(make_shared<Array>())
|
||||
{
|
||||
m_DebugInfo = debugInfo;
|
||||
}
|
||||
|
@ -60,21 +60,9 @@ void ConfigItemBuilder::AddParent(const String& parent)
|
|||
m_Parents.push_back(parent);
|
||||
}
|
||||
|
||||
void ConfigItemBuilder::AddExpression(const Expression& expr)
|
||||
void ConfigItemBuilder::AddExpression(const AExpression::Ptr& expr)
|
||||
{
|
||||
m_ExpressionList->AddExpression(expr);
|
||||
}
|
||||
|
||||
void ConfigItemBuilder::AddExpression(const String& key, ExpressionOperator op,
|
||||
const Value& value)
|
||||
{
|
||||
Expression expr(key, op, value, m_DebugInfo);
|
||||
AddExpression(expr);
|
||||
}
|
||||
|
||||
void ConfigItemBuilder::AddExpressionList(const ExpressionList::Ptr& exprl)
|
||||
{
|
||||
AddExpression("", OperatorExecute, exprl);
|
||||
m_Expressions->Add(expr);
|
||||
}
|
||||
|
||||
ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
||||
|
@ -102,16 +90,12 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
|||
BOOST_THROW_EXCEPTION(std::invalid_argument("Configuration item '" + m_Name + "' of type '" + m_Type + "' must not inherit from itself."));
|
||||
}
|
||||
|
||||
ExpressionList::Ptr exprl = make_shared<ExpressionList>();
|
||||
Array::Ptr exprs = make_shared<Array>();
|
||||
exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
|
||||
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__type", make_shared<AExpression>(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo));
|
||||
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo));
|
||||
|
||||
Expression execExpr("", OperatorExecute, m_ExpressionList, m_DebugInfo);
|
||||
exprl->AddExpression(execExpr);
|
||||
|
||||
Expression typeExpr("__type", OperatorSet, m_Type, m_DebugInfo);
|
||||
exprl->AddExpression(typeExpr);
|
||||
|
||||
Expression nameExpr("__name", OperatorSet, m_Name, m_DebugInfo);
|
||||
exprl->AddExpression(nameExpr);
|
||||
AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
|
||||
|
||||
return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
|
||||
m_Parents, m_DebugInfo);
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
#define CONFIGITEMBUILDER_H
|
||||
|
||||
#include "config/debuginfo.h"
|
||||
#include "config/expression.h"
|
||||
#include "config/expressionlist.h"
|
||||
#include "config/aexpression.h"
|
||||
#include "config/configitem.h"
|
||||
#include "base/object.h"
|
||||
|
||||
|
@ -49,10 +48,7 @@ public:
|
|||
|
||||
void AddParent(const String& parent);
|
||||
|
||||
void AddExpression(const Expression& expr);
|
||||
void AddExpression(const String& key, ExpressionOperator op,
|
||||
const Value& value);
|
||||
void AddExpressionList(const ExpressionList::Ptr& exprl);
|
||||
void AddExpression(const AExpression::Ptr& expr);
|
||||
|
||||
ConfigItem::Ptr Compile(void);
|
||||
|
||||
|
@ -62,7 +58,7 @@ private:
|
|||
bool m_Abstract; /**< Whether the item is abstract. */
|
||||
std::vector<String> m_Parents; /**< The names of parent configuration
|
||||
items. */
|
||||
ExpressionList::Ptr m_ExpressionList; /**< Expressions for this item. */
|
||||
Array::Ptr m_Expressions; /**< Expressions for this item. */
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
};
|
||||
|
||||
|
|
|
@ -1,204 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/expression.h"
|
||||
#include "config/expressionlist.h"
|
||||
#include "base/objectlock.h"
|
||||
#include "base/debug.h"
|
||||
#include "base/array.h"
|
||||
#include <sstream>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
Expression::Expression(const String& key, ExpressionOperator op,
|
||||
const Value& value, const DebugInfo& debuginfo)
|
||||
: m_Key(key), m_Operator(op), m_Value(value), m_DebugInfo(debuginfo)
|
||||
{
|
||||
ASSERT(op != OperatorExecute || value.IsObjectType<ExpressionList>());
|
||||
}
|
||||
|
||||
Value Expression::DeepClone(const Value& value)
|
||||
{
|
||||
if (value.IsObjectType<Array>()) {
|
||||
Array::Ptr array = value;
|
||||
Array::Ptr result = make_shared<Array>();
|
||||
|
||||
ObjectLock olock(array);
|
||||
|
||||
BOOST_FOREACH(const Value& item, array) {
|
||||
result->Add(DeepClone(item));
|
||||
}
|
||||
|
||||
return result;
|
||||
} else if (value.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr dict = value;
|
||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||
|
||||
ObjectLock olock(dict);
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
result->Set(kv.first, DeepClone(kv.second));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
||||
{
|
||||
Value oldValue, newValue;
|
||||
|
||||
ExpressionList::Ptr valueExprl;
|
||||
Dictionary::Ptr valueDict;
|
||||
Array::Ptr valueArray;
|
||||
if (m_Value.IsObjectType<ExpressionList>())
|
||||
valueExprl = m_Value;
|
||||
|
||||
if (m_Value.IsObjectType<Dictionary>())
|
||||
valueDict = m_Value;
|
||||
|
||||
if (m_Value.IsObjectType<Array>())
|
||||
valueArray = m_Value;
|
||||
|
||||
newValue = m_Value;
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
Array::Ptr array;
|
||||
|
||||
switch (m_Operator) {
|
||||
case OperatorExecute:
|
||||
if (!valueExprl)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Operand for OperatorExecute must be an ExpressionList."));
|
||||
|
||||
valueExprl->Execute(dictionary);
|
||||
|
||||
return;
|
||||
|
||||
case OperatorSet:
|
||||
if (valueExprl) {
|
||||
dict = make_shared<Dictionary>();
|
||||
valueExprl->Execute(dict);
|
||||
newValue = dict;
|
||||
} else {
|
||||
newValue = DeepClone(newValue);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OperatorPlus:
|
||||
oldValue = dictionary->Get(m_Key);
|
||||
|
||||
if (oldValue.IsObjectType<Dictionary>())
|
||||
dict = oldValue;
|
||||
|
||||
if (oldValue.IsObjectType<Array>())
|
||||
array = oldValue;
|
||||
|
||||
if (valueExprl) {
|
||||
if (!dict)
|
||||
dict = make_shared<Dictionary>();
|
||||
|
||||
valueExprl->Execute(dict);
|
||||
|
||||
newValue = dict;
|
||||
} else if (valueDict) {
|
||||
if (!dict)
|
||||
dict = make_shared<Dictionary>();
|
||||
|
||||
ObjectLock olock(valueDict);
|
||||
|
||||
String key;
|
||||
Value value;
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, valueDict) {
|
||||
dict->Set(kv.first, DeepClone(kv.second));
|
||||
}
|
||||
|
||||
newValue = dict;
|
||||
} else if (valueArray) {
|
||||
if (!array)
|
||||
array = make_shared<Array>();
|
||||
|
||||
ObjectLock olock(valueArray);
|
||||
|
||||
BOOST_FOREACH(const Value& value, valueArray) {
|
||||
array->Add(DeepClone(value));
|
||||
}
|
||||
|
||||
newValue = array;
|
||||
} else {
|
||||
std::ostringstream message;
|
||||
message << "+= only works for dictionaries and arrays ("
|
||||
<< m_DebugInfo << ")";
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument(message.str()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Not yet implemented."));
|
||||
}
|
||||
|
||||
dictionary->Set(m_Key, newValue);
|
||||
}
|
||||
|
||||
void Expression::ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (path[0] == m_Key) {
|
||||
if (!m_Value.IsObjectType<ExpressionList>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Specified path does not exist."));
|
||||
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
|
||||
if (path.size() == 1) {
|
||||
result->AddExpression(Expression("", OperatorExecute, exprl, m_DebugInfo));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->ExtractPath(sub_path, result);
|
||||
} else if (m_Operator == OperatorExecute) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
exprl->ExtractPath(path, result);
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (path[0] == m_Key) {
|
||||
if (path.size() == 1) {
|
||||
result = m_DebugInfo;
|
||||
} else if (m_Value.IsObjectType<ExpressionList>()) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->FindDebugInfoPath(sub_path, result);
|
||||
}
|
||||
} else if (m_Operator == OperatorExecute) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
exprl->FindDebugInfoPath(path, result);
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef EXPRESSION_H
|
||||
#define EXPRESSION_H
|
||||
|
||||
#include "config/i2-config.h"
|
||||
#include "config/debuginfo.h"
|
||||
#include "base/dictionary.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* The operator in a configuration expression.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
enum ExpressionOperator
|
||||
{
|
||||
OperatorExecute,
|
||||
OperatorSet,
|
||||
OperatorPlus,
|
||||
OperatorMinus,
|
||||
OperatorMultiply,
|
||||
OperatorDivide
|
||||
};
|
||||
|
||||
class ExpressionList;
|
||||
|
||||
/**
|
||||
* A configuration expression.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct I2_CONFIG_API Expression
|
||||
{
|
||||
public:
|
||||
Expression(const String& key, ExpressionOperator op, const Value& value,
|
||||
const DebugInfo& debuginfo);
|
||||
|
||||
void Execute(const Dictionary::Ptr& dictionary) const;
|
||||
|
||||
void ExtractPath(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
|
||||
|
||||
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
|
||||
|
||||
private:
|
||||
String m_Key;
|
||||
ExpressionOperator m_Operator;
|
||||
Value m_Value;
|
||||
DebugInfo m_DebugInfo;
|
||||
|
||||
static Value DeepClone(const Value& value);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* EXPRESSION_H */
|
|
@ -1,60 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/expressionlist.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Adds an expression to an expression list.
|
||||
*
|
||||
* @param expression The expression that should be added.
|
||||
*/
|
||||
void ExpressionList::AddExpression(const Expression& expression)
|
||||
{
|
||||
m_Expressions.push_back(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the expression list.
|
||||
*
|
||||
* @param dictionary The dictionary that should be manipulated by the
|
||||
* expressions.
|
||||
*/
|
||||
void ExpressionList::Execute(const Dictionary::Ptr& dictionary) const
|
||||
{
|
||||
BOOST_FOREACH(const Expression& expression, m_Expressions) {
|
||||
expression.Execute(dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionList::ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const
|
||||
{
|
||||
BOOST_FOREACH(const Expression& expression, m_Expressions) {
|
||||
expression.ExtractPath(path, result);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionList::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
|
||||
{
|
||||
BOOST_FOREACH(const Expression& expression, m_Expressions) {
|
||||
expression.FindDebugInfoPath(path, result);
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef EXPRESSIONLIST_H
|
||||
#define EXPRESSIONLIST_H
|
||||
|
||||
#include "config/i2-config.h"
|
||||
#include "config/expression.h"
|
||||
#include "base/dictionary.h"
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of configuration expressions.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class I2_CONFIG_API ExpressionList : public Object
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(ExpressionList);
|
||||
|
||||
void AddExpression(const Expression& expression);
|
||||
|
||||
void Execute(const Dictionary::Ptr& dictionary) const;
|
||||
|
||||
void ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
|
||||
|
||||
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
|
||||
|
||||
private:
|
||||
std::vector<Expression> m_Expressions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* EXPRESSIONLIST_H */
|
|
@ -77,7 +77,7 @@ void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
|||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo());
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, host->GetName());
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo()));
|
||||
|
||||
builder->AddParent(rule.GetTemplate());
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ void Host::UpdateSlaveServices(void)
|
|||
path.push_back("services");
|
||||
path.push_back(kv.first);
|
||||
|
||||
ExpressionList::Ptr exprl;
|
||||
AExpression::Ptr exprl;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
|
@ -130,9 +130,9 @@ void Host::UpdateSlaveServices(void)
|
|||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, GetName());
|
||||
builder->AddExpression("display_name", OperatorSet, kv.first);
|
||||
builder->AddExpression("short_name", OperatorSet, kv.first);
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetName(), di), di));
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "display_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "short_name", make_shared<AExpression>(&AExpression::OpLiteral, kv.first, di), di));
|
||||
|
||||
if (!kv.second.IsObjectType<Dictionary>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be either a string or a dictionary."));
|
||||
|
@ -150,10 +150,10 @@ void Host::UpdateSlaveServices(void)
|
|||
}
|
||||
|
||||
/* Clone attributes from the service expression list. */
|
||||
ExpressionList::Ptr svc_exprl = make_shared<ExpressionList>();
|
||||
Array::Ptr svc_exprl = make_shared<Array>();
|
||||
exprl->ExtractPath(path, svc_exprl);
|
||||
|
||||
builder->AddExpressionList(svc_exprl);
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, svc_exprl, true, di));
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Register();
|
||||
|
|
|
@ -193,7 +193,7 @@ void Service::UpdateSlaveDependencies(void)
|
|||
path.push_back("dependencies");
|
||||
path.push_back(kv.first);
|
||||
|
||||
ExpressionList::Ptr exprl;
|
||||
AExpression::Ptr exprl;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
|
@ -210,8 +210,8 @@ void Service::UpdateSlaveDependencies(void)
|
|||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Dependency");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("child_host", OperatorSet, GetHost()->GetName());
|
||||
builder->AddExpression("child_service", OperatorSet, GetShortName());
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "child_service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
|
||||
|
||||
Dictionary::Ptr dependency = kv.second;
|
||||
|
||||
|
@ -226,10 +226,10 @@ void Service::UpdateSlaveDependencies(void)
|
|||
}
|
||||
|
||||
/* Clone attributes from the scheduled downtime expression list. */
|
||||
ExpressionList::Ptr sd_exprl = make_shared<ExpressionList>();
|
||||
Array::Ptr sd_exprl = make_shared<Array>();
|
||||
exprl->ExtractPath(path, sd_exprl);
|
||||
|
||||
builder->AddExpressionList(sd_exprl);
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
|
||||
|
||||
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||
dependencyItem->Register();
|
||||
|
|
|
@ -342,7 +342,7 @@ void Service::UpdateSlaveScheduledDowntimes(void)
|
|||
path.push_back("scheduled_downtimes");
|
||||
path.push_back(kv.first);
|
||||
|
||||
ExpressionList::Ptr exprl;
|
||||
AExpression::Ptr exprl;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
|
@ -359,8 +359,8 @@ void Service::UpdateSlaveScheduledDowntimes(void)
|
|||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("ScheduledDowntime");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, GetHost()->GetName());
|
||||
builder->AddExpression("service", OperatorSet, GetShortName());
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
|
||||
|
||||
Dictionary::Ptr scheduledDowntime = kv.second;
|
||||
|
||||
|
@ -375,10 +375,10 @@ void Service::UpdateSlaveScheduledDowntimes(void)
|
|||
}
|
||||
|
||||
/* Clone attributes from the scheduled downtime expression list. */
|
||||
ExpressionList::Ptr sd_exprl = make_shared<ExpressionList>();
|
||||
Array::Ptr sd_exprl = make_shared<Array>();
|
||||
exprl->ExtractPath(path, sd_exprl);
|
||||
|
||||
builder->AddExpressionList(sd_exprl);
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
|
||||
|
||||
ConfigItem::Ptr scheduledDowntimeItem = builder->Compile();
|
||||
scheduledDowntimeItem->Register();
|
||||
|
|
|
@ -121,7 +121,7 @@ void Service::UpdateSlaveNotifications(void)
|
|||
path.push_back("notifications");
|
||||
path.push_back(kv.first);
|
||||
|
||||
ExpressionList::Ptr exprl;
|
||||
AExpression::Ptr exprl;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
|
@ -138,8 +138,8 @@ void Service::UpdateSlaveNotifications(void)
|
|||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, GetHost()->GetName());
|
||||
builder->AddExpression("service", OperatorSet, GetShortName());
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, GetHost()->GetName(), di), di));
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "service", make_shared<AExpression>(&AExpression::OpLiteral, GetShortName(), di), di));
|
||||
|
||||
Dictionary::Ptr notification = kv.second;
|
||||
|
||||
|
@ -154,10 +154,10 @@ void Service::UpdateSlaveNotifications(void)
|
|||
}
|
||||
|
||||
/* Clone attributes from the notification expression list. */
|
||||
ExpressionList::Ptr nfc_exprl = make_shared<ExpressionList>();
|
||||
Array::Ptr nfc_exprl = make_shared<Array>();
|
||||
exprl->ExtractPath(path, nfc_exprl);
|
||||
|
||||
builder->AddExpressionList(nfc_exprl);
|
||||
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, nfc_exprl, true, di));
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
notificationItem->Register();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
add_library(methods SHARED
|
||||
castfuncs.cpp icingachecktask.cpp nullchecktask.cpp nulleventtask.cpp
|
||||
pluginchecktask.cpp plugineventtask.cpp pluginnotificationtask.cpp
|
||||
randomchecktask.cpp timeperiodtask.cpp utilityfuncs.cpp
|
||||
randomchecktask.cpp timeperiodtask.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(methods ${Boost_LIBRARIES} base config icinga)
|
||||
|
|
Loading…
Reference in New Issue