]> granicus.if.org Git - icinga2/commitdiff
Implement missing operators for the Value class.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 20 Mar 2014 12:02:02 +0000 (13:02 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 20 Mar 2014 12:02:31 +0000 (13:02 +0100)
Fixes #5804

16 files changed:
doc/4.1-configuration-syntax.md
lib/base/CMakeLists.txt
lib/base/array.cpp
lib/base/array.h
lib/base/dictionary.cpp
lib/base/dictionary.h
lib/base/value.cpp
lib/base/value.h
lib/config/aexpression.cpp
lib/config/config_parser.yy
lib/icinga/service-notification.cpp
lib/methods/CMakeLists.txt
lib/methods/castfuncs.cpp [new file with mode: 0644]
lib/methods/castfuncs.h [new file with mode: 0644]
test/base-value.cpp
tools/mkclass/classcompiler.cpp

index 9f361e0a23e9f770f17f5cd2870dfae5699f5732..401461e17c53be671176e86d70ce3d8e4953ed4f 100644 (file)
@@ -195,6 +195,9 @@ 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.
 
 ### <a id="operators"></a> Dictionary Operators
 
index 746355002fe1efee91bfbfbfd143035c18b48ba6..0fc7a9aa475a151c0ab50aa2fbdd53dab8d262d3 100644 (file)
@@ -34,7 +34,7 @@ add_library(base SHARED
   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)
index 4adb5316d88bc688f1580640b16c1fa7a96b95c4..54f3d6364bd1f578dbd6ce9e0d60bf346ed16da8 100644 (file)
@@ -149,6 +149,15 @@ void Array::Remove(Array::Iterator it)
        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.
  *
@@ -156,13 +165,8 @@ void Array::Remove(Array::Iterator it)
  */
 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;
 }
 
index 0cd528aaf4c690eea4eecc22b24952d7a51fbfad..c1ff75fc3b830dc48fb0bb01541b3761ae07706e 100644 (file)
@@ -55,6 +55,7 @@ public:
        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);
index eada298fbdb8f55dc05962cda3e13bb140139f29..eed8588568851876feee0ac1bb6e47719738785d 100644 (file)
@@ -198,6 +198,16 @@ void Dictionary::Remove(Dictionary::Iterator it)
        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.
  *
@@ -205,15 +215,8 @@ void Dictionary::Remove(Dictionary::Iterator it)
  */
 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;
 }
 
index 66c0e1ee3659b8bab67e48150ac06444d3144089..790713c0daba4a6abe2346ccc5ea8481e12b691f 100644 (file)
@@ -58,6 +58,7 @@ public:
        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);
index a9028c28ce6ffe9634b3573157c3c2e6979290da..ac11f7d3173c95443bb935070b3f2be55cabcfe8 100644 (file)
@@ -81,53 +81,64 @@ bool Value::IsScalar(void) const
 }
 
 /**
- * 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.
  *
@@ -196,120 +207,24 @@ ValueType Value::GetType(void) const
        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";
+       }
 }
index f8d8aa551d4cb762da1c1182fa38e85cf964772f..cec38ab10ec12864cc2b20d958f90c121d49c9c1 100644 (file)
@@ -70,6 +70,8 @@ public:
                m_Value = static_pointer_cast<Object>(value);
        }
 
+       bool ToBool(void) const;
+
        operator double(void) const;
        operator String(void) const;
 
@@ -111,6 +113,8 @@ public:
 
        bool IsEmpty(void) const;
        bool IsScalar(void) const;
+       bool IsNumber(void) const;
+       bool IsString(void) const;
        bool IsObject(void) const;
 
        template<typename T>
@@ -126,6 +130,7 @@ public:
        cJSON *ToJson(void) const;
 
        ValueType GetType(void) const;
+       String GetTypeName(void) const;
 
 private:
        boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
@@ -139,6 +144,78 @@ I2_BASE_API Value operator+(const char *lhs, const Value& rhs);
 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);
 
index 5ef8d49d68c48bf9a95ea5f3bdc03c16b4363525..e96cd8c537ee66862eb4bc582ddb1836b7396fd8 100644 (file)
@@ -63,28 +63,33 @@ Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
                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)));
@@ -114,9 +119,9 @@ Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
 
                        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);
@@ -134,19 +139,13 @@ Value AExpression::Evaluate(const Dictionary::Ptr& locals) const
                        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.");
        }
index ce426bd228e52020bf2a487da68097413373eca8..80ebe126b28cceb049d2925e3ffd5219459d7ce1 100644 (file)
@@ -714,7 +714,12 @@ apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE a
                        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);
        }
 %%
index 908c2e5a0c56f70b81c831501c2b6670ea65afbc..5b5964b4e4c6fa748d5d4f0c0036d071b9e91f97 100644 (file)
@@ -26,6 +26,7 @@
 #include "base/utility.h"
 #include "base/exception.h"
 #include "base/context.h"
+#include "base/convert.h"
 #include "config/configitembuilder.h"
 #include <boost/foreach.hpp>
 
@@ -68,7 +69,7 @@ void Service::SendNotifications(NotificationType type, const CheckResult::Ptr& c
        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 {
index 281c0a88dc0f280dd49c15ea99542bcd28df712c..49f11fe809343a57712ede3913d004978b96fbb6 100644 (file)
@@ -16,7 +16,7 @@
 # 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
 )
diff --git a/lib/methods/castfuncs.cpp b/lib/methods/castfuncs.cpp
new file mode 100644 (file)
index 0000000..4b35b2f
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * 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();
+}
diff --git a/lib/methods/castfuncs.h b/lib/methods/castfuncs.h
new file mode 100644 (file)
index 0000000..7d314bb
--- /dev/null
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * 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 */
index 2b9be0b00eac3f69e9a5f823088f20199309a84b..83817abcaa84136f48aedc1ded83abd796a7b651 100644 (file)
@@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(format)
        std::istringstream ibuf("3");
        ibuf >> v;
 
-       BOOST_CHECK(v == 3);
+       BOOST_CHECK(v != 3);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
index 0c87e660b1e47a3137f6a5e9a0fa77a4c27ed221..725c185a5c8ca94e5d1494dda79e14a0ea235bf4 100644 (file)
@@ -409,7 +409,14 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo& locp)
                                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())