From 46d7cf3d6a7887314024ea6628568b3d9b19be1e Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 19 Mar 2014 13:25:06 +0100 Subject: [PATCH] Implement len() and the operators >, >=, < and <=. Refs #5789 --- doc/4.1-configuration-syntax.md | 2 +- lib/config/aexpression.cpp | 8 ++++++++ lib/config/aexpression.h | 6 +++++- lib/config/config_lexer.ll | 2 ++ lib/config/config_parser.yy | 26 ++++++++++++++++++++++++++ lib/methods/utilityfuncs.cpp | 17 +++++++++++++++++ lib/methods/utilityfuncs.h | 1 + 7 files changed, 60 insertions(+), 2 deletions(-) diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md index d3bdf2311..cd0b33136 100644 --- a/doc/4.1-configuration-syntax.md +++ b/doc/4.1-configuration-syntax.md @@ -320,7 +320,7 @@ Simple calculations can be performed using the constant expression syntax: check_interval = 30 + 60 } -Valid operators include ~, !, +, -, *, /, ==, !=, in and !in. The default precedence rules can be +Valid operators include ~, !, +, -, *, /, >, >=, <, <=, ==, !=, in and !in. The default precedence rules can be overridden by grouping expressions using parentheses: { diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp index 40dbadea8..5ef8d49d6 100644 --- a/lib/config/aexpression.cpp +++ b/lib/config/aexpression.cpp @@ -139,6 +139,14 @@ Value AExpression::Evaluate(const Dictionary::Ptr& locals) const } return arr2; + case AELessThan: + return (long)left < (long)right; + case AEGreaterThan: + return (long)left > (long)right; + case AELessThanOrEqual: + return (long)left <= (long)right; + case AEGreaterThanOrEqual: + return (long)left >= (long)right; default: ASSERT(!"Invalid operator."); } diff --git a/lib/config/aexpression.h b/lib/config/aexpression.h index a2dd99c12..56c16c33d 100644 --- a/lib/config/aexpression.h +++ b/lib/config/aexpression.h @@ -50,7 +50,11 @@ enum AOperator AELogicalAnd, AELogicalOr, AEFunctionCall, - AEArray + AEArray, + AELessThan, + AEGreaterThan, + AELessThanOrEqual, + AEGreaterThanOrEqual }; /** diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index f397a5ab7..54cb1f561 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -227,6 +227,8 @@ 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; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index f508747a6..ce426bd22 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -86,6 +86,8 @@ using namespace icinga; %token T_NOT_IN "!in (T_NOT_IN)" %token T_LOGICAL_AND "&& (T_LOGICAL_AND)" %token T_LOGICAL_OR "|| (T_LOGICAL_OR)" +%token T_LESS_THAN_OR_EQUAL "<= (T_LESS_THAN_OR_EQUAL)" +%token T_GREATER_THAN_OR_EQUAL ">= (T_GREATER_THAN_OR_EQUAL)" %token T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)" %token T_TYPE_ARRAY "array (T_TYPE_ARRAY)" %token T_TYPE_NUMBER "number (T_TYPE_NUMBER)" @@ -627,6 +629,30 @@ aexpression: T_STRING delete $1; delete $3; } + | aexpression T_LESS_THAN_OR_EQUAL aexpression + { + $$ = new Value(make_shared(AELessThanOrEqual, static_cast(*$1), static_cast(*$3), yylloc)); + delete $1; + delete $3; + } + | aexpression T_GREATER_THAN_OR_EQUAL aexpression + { + $$ = new Value(make_shared(AEGreaterThanOrEqual, static_cast(*$1), static_cast(*$3), yylloc)); + delete $1; + delete $3; + } + | aexpression '<' aexpression + { + $$ = new Value(make_shared(AELessThan, static_cast(*$1), static_cast(*$3), yylloc)); + delete $1; + delete $3; + } + | aexpression '>' aexpression + { + $$ = new Value(make_shared(AEGreaterThan, static_cast(*$1), static_cast(*$3), yylloc)); + delete $1; + delete $3; + } | aexpression T_EQUAL aexpression { $$ = new Value(make_shared(AEEqual, static_cast(*$1), static_cast(*$3), yylloc)); diff --git a/lib/methods/utilityfuncs.cpp b/lib/methods/utilityfuncs.cpp index 298b597e8..71a143691 100644 --- a/lib/methods/utilityfuncs.cpp +++ b/lib/methods/utilityfuncs.cpp @@ -20,12 +20,16 @@ #include "methods/utilityfuncs.h" #include "base/scriptfunction.h" #include "base/utility.h" +#include "base/convert.h" +#include "base/array.h" +#include "base/dictionary.h" #include using namespace icinga; REGISTER_SCRIPTFUNCTION(regex, &UtilityFuncs::Regex); REGISTER_SCRIPTFUNCTION(match, &Utility::Match); +REGISTER_SCRIPTFUNCTION(len, &UtilityFuncs::Len); bool UtilityFuncs::Regex(const String& pattern, const String& text) { @@ -33,3 +37,16 @@ bool UtilityFuncs::Regex(const String& pattern, const String& text) boost::smatch what; return boost::regex_search(text.GetData(), what, expr); } + +int UtilityFuncs::Len(const Value& value) +{ + if (value.IsObjectType()) { + Dictionary::Ptr dict = value; + return dict->GetLength(); + } else if (value.IsObjectType()) { + Array::Ptr array = value; + return array->GetLength(); + } else { + return Convert::ToString(value).GetLength(); + } +} \ No newline at end of file diff --git a/lib/methods/utilityfuncs.h b/lib/methods/utilityfuncs.h index 7612672be..cdaa51da4 100644 --- a/lib/methods/utilityfuncs.h +++ b/lib/methods/utilityfuncs.h @@ -33,6 +33,7 @@ class I2_METHODS_API UtilityFuncs { public: static bool Regex(const String& pattern, const String& text); + static int Len(const Value& value); private: UtilityFuncs(void); -- 2.40.0