diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md
index 4a848d88f..f602b5cd8 100644
--- a/doc/4.1-configuration-syntax.md
+++ b/doc/4.1-configuration-syntax.md
@@ -190,14 +190,16 @@ Functions can be called using the `()` operator:
check_interval = len(MyGroups) * 1m
}
-Function | Description
----------------------|-----------------------
-regex(pattern, text) | Returns true if the regex pattern matches the text, false otherwise.
-match(pattern, text) | Returns true if the wildcard pattern matches the text, false otherwise.
-len(value) | Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes.
-string(value) | Converts the value to a string.
-number(value) | Converts the value to a number.
-bool(value) | Converts to value to a bool.
+Function | Description
+--------------------------------|-----------------------
+regex(pattern, text) | Returns true if the regex pattern matches the text, false otherwise.
+match(pattern, text) | Returns true if the wildcard pattern matches the text, false otherwise.
+len(value) | Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes.
+union(array, array, ...) | Returns an array containing all unique elements from the specified arrays.
+intersection(array, array, ...) | Returns an array containing all unique elements which are common to all specified arrays.
+string(value) | Converts the value to a string.
+number(value) | Converts the value to a number.
+bool(value) | Converts to value to a bool.
### Dictionary Operators
diff --git a/lib/base/array.cpp b/lib/base/array.cpp
index 54f3d6364..102d679e4 100644
--- a/lib/base/array.cpp
+++ b/lib/base/array.cpp
@@ -149,6 +149,14 @@ void Array::Remove(Array::Iterator it)
m_Data.erase(it);
}
+void Array::Resize(size_t new_size)
+{
+ ASSERT(!OwnsLock());
+ ObjectLock olock(this);
+
+ m_Data.resize(new_size);
+}
+
void Array::CopyTo(const Array::Ptr& dest) const
{
ASSERT(!OwnsLock());
diff --git a/lib/base/array.h b/lib/base/array.h
index c1ff75fc3..744c790ca 100644
--- a/lib/base/array.h
+++ b/lib/base/array.h
@@ -55,6 +55,8 @@ public:
void Remove(unsigned int index);
void Remove(Iterator it);
+ void Resize(size_t new_size);
+
void CopyTo(const Array::Ptr& dest) const;
Array::Ptr ShallowClone(void) const;
diff --git a/lib/base/scriptfunctionwrapper.cpp b/lib/base/scriptfunctionwrapper.cpp
index 2e0b96045..d5d1efb5d 100644
--- a/lib/base/scriptfunctionwrapper.cpp
+++ b/lib/base/scriptfunctionwrapper.cpp
@@ -32,8 +32,3 @@ boost::function& arguments)> icinga::WrapScriptF
{
return boost::bind(&ScriptFunctionWrapperVV, function, _1);
}
-
-boost::function& arguments)> icinga::WrapScriptFunction(Value (*function)(const std::vector&))
-{
- return boost::bind(function, _1);
-}
diff --git a/lib/base/scriptfunctionwrapper.h b/lib/base/scriptfunctionwrapper.h
index 7edd2013b..c629a2e53 100644
--- a/lib/base/scriptfunctionwrapper.h
+++ b/lib/base/scriptfunctionwrapper.h
@@ -267,7 +267,11 @@ boost::function& arguments)> WrapScriptFunction(
return boost::bind(&ScriptFunctionWrapperR, function, _1);
}
-boost::function& arguments)> I2_BASE_API WrapScriptFunction(Value (*function)(const std::vector&));
+template
+boost::function& arguments)> WrapScriptFunction(TR (*function)(const std::vector&))
+{
+ return boost::bind(function, _1);
+}
}
diff --git a/lib/methods/utilityfuncs.cpp b/lib/methods/utilityfuncs.cpp
index 71a143691..290ab1576 100644
--- a/lib/methods/utilityfuncs.cpp
+++ b/lib/methods/utilityfuncs.cpp
@@ -24,12 +24,15 @@
#include "base/array.h"
#include "base/dictionary.h"
#include
+#include
using namespace icinga;
REGISTER_SCRIPTFUNCTION(regex, &UtilityFuncs::Regex);
REGISTER_SCRIPTFUNCTION(match, &Utility::Match);
REGISTER_SCRIPTFUNCTION(len, &UtilityFuncs::Len);
+REGISTER_SCRIPTFUNCTION(union, &UtilityFuncs::Union);
+REGISTER_SCRIPTFUNCTION(intersection, &UtilityFuncs::Intersection);
bool UtilityFuncs::Regex(const String& pattern, const String& text)
{
@@ -49,4 +52,48 @@ int UtilityFuncs::Len(const Value& value)
} else {
return Convert::ToString(value).GetLength();
}
-}
\ No newline at end of file
+}
+
+Array::Ptr UtilityFuncs::Union(const std::vector& arguments)
+{
+ std::set values;
+
+ BOOST_FOREACH(const Value& varr, arguments) {
+ Array::Ptr arr = varr;
+
+ BOOST_FOREACH(const Value& value, arr) {
+ values.insert(value);
+ }
+ }
+
+ Array::Ptr result = make_shared();
+ BOOST_FOREACH(const Value& value, values) {
+ result->Add(value);
+ }
+
+ return result;
+}
+
+Array::Ptr UtilityFuncs::Intersection(const std::vector& arguments)
+{
+ if (arguments.size() == 0)
+ return make_shared();
+
+ Array::Ptr result = make_shared();
+
+ Array::Ptr arr1 = static_cast(arguments[0])->ShallowClone();
+
+ for (int i = 1; i < arguments.size(); i++) {
+ std::sort(arr1->Begin(), arr1->End());
+
+ Array::Ptr arr2 = static_cast(arguments[i])->ShallowClone();
+ std::sort(arr2->Begin(), arr2->End());
+
+ result->Resize(std::max(arr1->GetLength(), arr2->GetLength()));
+ Array::Iterator it = std::set_intersection(arr1->Begin(), arr1->End(), arr2->Begin(), arr2->End(), result->Begin());
+ result->Resize(it - result->Begin());
+ arr1 = result;
+ }
+
+ return result;
+}
diff --git a/lib/methods/utilityfuncs.h b/lib/methods/utilityfuncs.h
index cdaa51da4..4dbbb57f4 100644
--- a/lib/methods/utilityfuncs.h
+++ b/lib/methods/utilityfuncs.h
@@ -22,6 +22,7 @@
#include "methods/i2-methods.h"
#include "base/qstring.h"
+#include "base/array.h"
namespace icinga
{
@@ -34,6 +35,8 @@ class I2_METHODS_API UtilityFuncs
public:
static bool Regex(const String& pattern, const String& text);
static int Len(const Value& value);
+ static Array::Ptr Union(const std::vector& arguments);
+ static Array::Ptr Intersection(const std::vector& arguments);
private:
UtilityFuncs(void);