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.
### <a id="operators"></a> Dictionary Operators
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
- workqueue.cpp zlibstream.cpp
+ value-operators.cpp workqueue.cpp zlibstream.cpp
)
target_link_libraries(base ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} cJSON mmatch)
m_Data.erase(it);
}
+void Array::CopyTo(const Array::Ptr& dest) const
+{
+ ASSERT(!OwnsLock());
+ ObjectLock olock(this);
+ ObjectLock xlock(dest);
+
+ std::copy(m_Data.begin(), m_Data.end(), std::back_inserter(dest->m_Data));
+}
+
/**
* Makes a shallow copy of an array.
*
*/
Array::Ptr Array::ShallowClone(void) const
{
- ASSERT(!OwnsLock());
- ObjectLock olock(this);
-
Array::Ptr clone = make_shared<Array>();
-
- std::copy(m_Data.begin(), m_Data.end(), std::back_inserter(clone->m_Data));
-
+ CopyTo(clone);
return clone;
}
void Remove(unsigned int index);
void Remove(Iterator it);
+ void CopyTo(const Array::Ptr& dest) const;
Array::Ptr ShallowClone(void) const;
static Array::Ptr FromJson(cJSON *json);
m_Data.erase(it);
}
+void Dictionary::CopyTo(const Dictionary::Ptr& dest) const
+{
+ ASSERT(!OwnsLock());
+ ObjectLock olock(this);
+
+ BOOST_FOREACH(const Dictionary::Pair& kv, m_Data) {
+ dest->Set(kv.first, kv.second);
+ }
+}
+
/**
* Makes a shallow copy of a dictionary.
*
*/
Dictionary::Ptr Dictionary::ShallowClone(void) const
{
- ASSERT(!OwnsLock());
- ObjectLock olock(this);
-
Dictionary::Ptr clone = make_shared<Dictionary>();
-
- BOOST_FOREACH(const Dictionary::Pair& kv, m_Data) {
- clone->Set(kv.first, kv.second);
- }
-
+ CopyTo(clone);
return clone;
}
void Remove(const String& key);
void Remove(Iterator it);
+ void CopyTo(const Dictionary::Ptr& dest) const;
Dictionary::Ptr ShallowClone(void) const;
static Dictionary::Ptr FromJson(cJSON *json);
}
/**
- * Checks whether the variant is a non-null object.
+ * Checks whether the variant is a number.
*
- * @returns true if the variant is a non-null object, false otherwise.
+ * @returns true if the variant is a number.
*/
-bool Value::IsObject(void) const
+bool Value::IsNumber(void) const
{
- return !IsEmpty() && (GetType() == ValueObject);
+ return (GetType() == ValueNumber);
}
-Value::operator double(void) const
+/**
+ * Checks whether the variant is a string.
+ *
+ * @returns true if the variant is a string.
+ */
+bool Value::IsString(void) const
{
- const double *value = boost::get<double>(&m_Value);
-
- if (value)
- return *value;
-
- if (IsEmpty())
- return 0;
-
- return boost::lexical_cast<double>(m_Value);
+ return (GetType() == ValueString);
}
-Value::operator String(void) const
+/**
+ * Checks whether the variant is a non-null object.
+ *
+ * @returns true if the variant is a non-null object, false otherwise.
+ */
+bool Value::IsObject(void) const
{
- Object *object;
- double integral, fractional;
+ return !IsEmpty() && (GetType() == ValueObject);
+}
+bool Value::ToBool(void) const
+{
switch (GetType()) {
- case ValueEmpty:
- return String();
case ValueNumber:
- fractional = modf(boost::get<double>(m_Value), &integral);
+ return static_cast<bool>(boost::get<double>(m_Value));
- if (fractional != 0)
- return boost::lexical_cast<String>(m_Value);
- else
- return boost::lexical_cast<String>((long)integral);
case ValueString:
- return boost::get<String>(m_Value);
+ return !boost::get<String>(m_Value).IsEmpty();
+
case ValueObject:
- object = boost::get<Object::Ptr>(m_Value).get();
- return "Object of type '" + Utility::GetTypeName(typeid(*object)) + "'";
+ if (IsObjectType<Dictionary>()) {
+ Dictionary::Ptr dictionary = *this;
+ return dictionary->GetLength() > 0;
+ } else if (IsObjectType<Array>()) {
+ Array::Ptr array = *this;
+ return array->GetLength() > 0;
+ } else {
+ return true;
+ }
+
+ case ValueEmpty:
+ return false;
+
default:
- BOOST_THROW_EXCEPTION(std::runtime_error("Unknown value type."));
+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid variant type."));
}
}
+
/**
* Converts a JSON object into a variant.
*
return static_cast<ValueType>(m_Value.which());
}
-bool Value::operator==(bool rhs) const
-{
- if (!IsScalar())
- return false;
-
- return static_cast<double>(*this) == rhs;
-}
-
-bool Value::operator!=(bool rhs) const
-{
- return !(*this == rhs);
-}
-
-bool Value::operator==(int rhs) const
-{
- if (!IsScalar())
- return false;
-
- return static_cast<double>(*this) == rhs;
-}
-
-bool Value::operator!=(int rhs) const
-{
- return !(*this == rhs);
-}
-
-bool Value::operator==(double rhs) const
-{
- if (!IsScalar())
- return false;
-
- return static_cast<double>(*this) == rhs;
-}
-
-bool Value::operator!=(double rhs) const
-{
- return !(*this == rhs);
-}
-
-bool Value::operator==(const char *rhs) const
-{
- return static_cast<String>(*this) == rhs;
-}
-
-bool Value::operator!=(const char *rhs) const
-{
- return !(*this == rhs);
-}
-
-bool Value::operator==(const String& rhs) const
-{
- return static_cast<String>(*this) == rhs;
-}
-
-bool Value::operator!=(const String& rhs) const
-{
- return !(*this == rhs);
-}
-
-bool Value::operator==(const Value& rhs) const
-{
- if (IsEmpty() != rhs.IsEmpty())
- return false;
-
- if (IsEmpty())
- return true;
-
- if (IsObject() != rhs.IsObject())
- return false;
-
- if (IsObject())
- return static_cast<Object::Ptr>(*this) == static_cast<Object::Ptr>(rhs);
-
- if (GetType() == ValueNumber || rhs.GetType() == ValueNumber)
- return static_cast<double>(*this) == static_cast<double>(rhs);
- else
- return static_cast<String>(*this) == static_cast<String>(rhs);
-}
-
-bool Value::operator!=(const Value& rhs) const
+String Value::GetTypeName(void) const
{
- return !(*this == rhs);
-}
-
-Value icinga::operator+(const Value& lhs, const char *rhs)
-{
- return static_cast<String>(lhs) + rhs;
-}
-
-Value icinga::operator+(const char *lhs, const Value& rhs)
-{
- return lhs + static_cast<String>(rhs);
-}
-
-Value icinga::operator+(const Value& lhs, const String& rhs)
-{
- return static_cast<String>(lhs) + rhs;
-}
-
-Value icinga::operator+(const String& lhs, const Value& rhs)
-{
- return lhs + static_cast<String>(rhs);
-}
+ const Type *t;
-std::ostream& icinga::operator<<(std::ostream& stream, const Value& value)
-{
- stream << static_cast<String>(value);
- return stream;
-}
-
-std::istream& icinga::operator>>(std::istream& stream, Value& value)
-{
- String tstr;
- stream >> tstr;
- value = tstr;
- return stream;
+ switch (GetType()) {
+ case ValueEmpty:
+ return "Empty";
+ case ValueNumber:
+ return "Number";
+ case ValueString:
+ return "String";
+ case ValueObject:
+ t = static_cast<Object::Ptr>(*this)->GetReflectionType();
+ if (!t)
+ return "Object";
+ else
+ return t->GetName();
+ default:
+ return "Invalid";
+ }
}
m_Value = static_pointer_cast<Object>(value);
}
+ bool ToBool(void) const;
+
operator double(void) const;
operator String(void) const;
bool IsEmpty(void) const;
bool IsScalar(void) const;
+ bool IsNumber(void) const;
+ bool IsString(void) const;
bool IsObject(void) const;
template<typename T>
cJSON *ToJson(void) const;
ValueType GetType(void) const;
+ String GetTypeName(void) const;
private:
boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
I2_BASE_API Value operator+(const Value& lhs, const String& rhs);
I2_BASE_API Value operator+(const String& lhs, const Value& rhs);
+I2_BASE_API Value operator+(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator+(const Value& lhs, double rhs);
+I2_BASE_API Value operator+(double lhs, const Value& rhs);
+I2_BASE_API Value operator+(const Value& lhs, int rhs);
+I2_BASE_API Value operator+(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator-(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator-(const Value& lhs, double rhs);
+I2_BASE_API Value operator-(double lhs, const Value& rhs);
+I2_BASE_API Value operator-(const Value& lhs, int rhs);
+I2_BASE_API Value operator-(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator*(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator*(const Value& lhs, double rhs);
+I2_BASE_API Value operator*(double lhs, const Value& rhs);
+I2_BASE_API Value operator*(const Value& lhs, int rhs);
+I2_BASE_API Value operator*(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator/(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator/(const Value& lhs, double rhs);
+I2_BASE_API Value operator/(double lhs, const Value& rhs);
+I2_BASE_API Value operator/(const Value& lhs, int rhs);
+I2_BASE_API Value operator/(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator&(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator&(const Value& lhs, double rhs);
+I2_BASE_API Value operator&(double lhs, const Value& rhs);
+I2_BASE_API Value operator&(const Value& lhs, int rhs);
+I2_BASE_API Value operator&(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator|(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator|(const Value& lhs, double rhs);
+I2_BASE_API Value operator|(double lhs, const Value& rhs);
+I2_BASE_API Value operator|(const Value& lhs, int rhs);
+I2_BASE_API Value operator|(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator<<(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator<<(const Value& lhs, double rhs);
+I2_BASE_API Value operator<<(double lhs, const Value& rhs);
+I2_BASE_API Value operator<<(const Value& lhs, int rhs);
+I2_BASE_API Value operator<<(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator>>(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator>>(const Value& lhs, double rhs);
+I2_BASE_API Value operator>>(double lhs, const Value& rhs);
+I2_BASE_API Value operator>>(const Value& lhs, int rhs);
+I2_BASE_API Value operator>>(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator<(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator<(const Value& lhs, double rhs);
+I2_BASE_API Value operator<(double lhs, const Value& rhs);
+I2_BASE_API Value operator<(const Value& lhs, int rhs);
+I2_BASE_API Value operator<(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator>(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator>(const Value& lhs, double rhs);
+I2_BASE_API Value operator>(double lhs, const Value& rhs);
+I2_BASE_API Value operator>(const Value& lhs, int rhs);
+I2_BASE_API Value operator>(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator<=(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator<=(const Value& lhs, double rhs);
+I2_BASE_API Value operator<=(double lhs, const Value& rhs);
+I2_BASE_API Value operator<=(const Value& lhs, int rhs);
+I2_BASE_API Value operator<=(int lhs, const Value& rhs);
+
+I2_BASE_API Value operator>=(const Value& lhs, const Value& rhs);
+I2_BASE_API Value operator>=(const Value& lhs, double rhs);
+I2_BASE_API Value operator>=(double lhs, const Value& rhs);
+I2_BASE_API Value operator>=(const Value& lhs, int rhs);
+I2_BASE_API Value operator>=(int lhs, const Value& rhs);
+
I2_BASE_API std::ostream& operator<<(std::ostream& stream, const Value& value);
I2_BASE_API std::istream& operator>>(std::istream& stream, Value& value);
case AENegate:
return ~(long)left;
case AEAdd:
- if (left.GetType() == ValueString || right.GetType() == ValueString)
- return (String)left + (String)right;
- else
- return (double)left + (double)right;
+ return left + right;
case AESubtract:
- return (double)left + (double)right;
+ return left - right;
case AEMultiply:
- return (double)left * (double)right;
+ return left * right;
case AEDivide:
- return (double)left / (double)right;
+ return left / right;
case AEBinaryAnd:
- return (long)left & (long)right;
+ return left & right;
case AEBinaryOr:
- return (long)left | (long)right;
+ return left | right;
case AEShiftLeft:
- return (long)left << (long)right;
+ return left << right;
case AEShiftRight:
- return (long)left >> (long)right;
+ return left >> right;
case AEEqual:
return left == right;
case AENotEqual:
return left != right;
+ case AELessThan:
+ return left < right;
+ case AEGreaterThan:
+ return left > right;
+ case AELessThanOrEqual:
+ return left <= right;
+ case AEGreaterThanOrEqual:
+ return left >= right;
case AEIn:
if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid right side argument for 'in' operator: " + JsonSerialize(right)));
return !found;
case AELogicalAnd:
- return (long)left && (long)right;
+ return left.ToBool() && right.ToBool();
case AELogicalOr:
- return (long)left || (long)right;
+ return left.ToBool() || right.ToBool();
case AEFunctionCall:
funcName = left;
func = ScriptFunctionRegistry::GetInstance()->GetItem(funcName);
arr = left;
arr2 = make_shared<Array>();
- BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
- arr2->Add(aexpr->Evaluate(locals));
+ if (arr) {
+ BOOST_FOREACH(const AExpression::Ptr& aexpr, arr) {
+ arr2->Add(aexpr->Evaluate(locals));
+ }
}
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.");
}
BOOST_THROW_EXCEPTION(std::invalid_argument("'apply' cannot be used with types '" + String($3) + "' and '" + String($6) + "'."));
}
- ApplyRule::AddRule($3, $4, $6, *$8, yylloc);
+ Array::Ptr arguments = make_shared<Array>();
+ arguments->Add(*$8);
delete $8;
+
+ AExpression::Ptr aexpr = make_shared<AExpression>(AEFunctionCall, AValue(ATSimple, "bool"), AValue(ATSimple, arguments), yylloc);
+
+ ApplyRule::AddRule($3, $4, $6, aexpr, yylloc);
}
%%
#include "base/utility.h"
#include "base/exception.h"
#include "base/context.h"
+#include "base/convert.h"
#include "config/configitembuilder.h"
#include <boost/foreach.hpp>
if (notifications.empty())
Log(LogInformation, "icinga", "Service '" + GetName() + "' does not have any notifications.");
- Log(LogDebug, "icinga", "Service '" + GetName() + "' has " + notifications.size() + " notification(s).");
+ Log(LogDebug, "icinga", "Service '" + GetName() + "' has " + Convert::ToString(notifications.size()) + " notification(s).");
BOOST_FOREACH(const Notification::Ptr& notification, notifications) {
try {
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
add_library(methods SHARED
- icingachecktask.cpp nullchecktask.cpp nulleventtask.cpp
+ castfuncs.cpp icingachecktask.cpp nullchecktask.cpp nulleventtask.cpp
pluginchecktask.cpp plugineventtask.cpp pluginnotificationtask.cpp
randomchecktask.cpp timeperiodtask.cpp utilityfuncs.cpp
)
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-present 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 "methods/castfuncs.h"
+#include "base/scriptfunction.h"
+
+using namespace icinga;
+
+REGISTER_SCRIPTFUNCTION(string, &CastFuncs::CastString);
+REGISTER_SCRIPTFUNCTION(number, &CastFuncs::CastNumber);
+REGISTER_SCRIPTFUNCTION(bool, &CastFuncs::CastBool);
+
+String CastFuncs::CastString(const Value& value)
+{
+ return value;
+}
+
+double CastFuncs::CastNumber(const Value& value)
+{
+ return value;
+}
+
+bool CastFuncs::CastBool(const Value& value)
+{
+ return value.ToBool();
+}
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-present 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 CASTFUNCS_H
+#define CASTFUNCS_H
+
+#include "methods/i2-methods.h"
+#include "base/qstring.h"
+
+namespace icinga
+{
+
+/**
+ * @ingroup methods
+ */
+class I2_METHODS_API CastFuncs
+{
+public:
+ static String CastString(const Value& value);
+ static double CastNumber(const Value& value);
+ static bool CastBool(const Value& value);
+
+private:
+ CastFuncs(void);
+};
+
+}
+
+#endif /* CASTFUNCS_H */
std::istringstream ibuf("3");
ibuf >> v;
- BOOST_CHECK(v == 3);
+ BOOST_CHECK(v != 3);
}
BOOST_AUTO_TEST_SUITE_END()
prot = "public";
std::cout << prot << ":" << std::endl
- << "\t" << "void Set" << it->GetFriendlyName() << "(const " << it->Type << "& value)" << std::endl
+ << "\t" << "void Set" << it->GetFriendlyName() << "(";
+
+ if (it->Type == "bool" || it->Type == "double" || it->Type == "int")
+ std::cout << it->Type;
+ else
+ std::cout << "const " << it->Type << "&";
+
+ std::cout << " value)" << std::endl
<< "\t" << "{" << std::endl;
if (it->SetAccessor.empty())