]> granicus.if.org Git - icinga2/commitdiff
Implement a boolean sub-type for the Value class
authorGunnar Beutner <gunnar@beutner.name>
Wed, 10 Dec 2014 08:04:49 +0000 (09:04 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 10 Dec 2014 08:05:16 +0000 (09:05 +0100)
fixes #8043

lib/base/json.cpp
lib/base/primitivetype.cpp
lib/base/scriptutils.cpp
lib/base/value-operators.cpp
lib/base/value.cpp
lib/base/value.hpp
lib/config/config_lexer.ll
lib/config/config_parser.yy
lib/livestatus/attributefilter.cpp
tools/mkclass/classcompiler.cpp

index 3eab02799b50319a45120e3b2fe5daf57e0df979..8faedbdefcb8bff6227aee2a0ba4e229bed75992 100644 (file)
@@ -74,6 +74,10 @@ static void Encode(yajl_gen handle, const Value& value)
                        if (yajl_gen_double(handle, static_cast<double>(value)) == yajl_gen_invalid_number)
                                yajl_gen_double(handle, 0);
 
+                       break;
+               case ValueBoolean:
+                       yajl_gen_bool(handle, value.ToBool());
+
                        break;
                case ValueString:
                        str = value;
@@ -220,7 +224,7 @@ static int DecodeBoolean(void *ctx, int value)
        JsonContext *context = static_cast<JsonContext *>(ctx);
 
        try {
-               context->AddValue(value);
+               context->AddValue(static_cast<bool>(value));
        } catch (...) {
                context->SaveException();
                return 0;
index 026cda6d5a21553b3f981e050225b8fe16fd3828..4debd405fc64491026dcd8f1898ef9b576cd32f5 100644 (file)
@@ -22,6 +22,7 @@
 using namespace icinga;
 
 REGISTER_BUILTIN_TYPE(Number);
+REGISTER_BUILTIN_TYPE(Boolean);
 
 PrimitiveType::PrimitiveType(const String& name)
        : m_Name(name)
index f5fceb72a75c53fe1db2e220143bed8a28540e49..0e11870fd4a3dc6fa451b9e184710fe2a6e168ea 100644 (file)
@@ -218,6 +218,8 @@ Type::Ptr ScriptUtils::TypeOf(const Value& value)
                        return Type::GetByName("Object");
                case ValueNumber:
                        return Type::GetByName("Number");
+               case ValueBoolean:
+                       return Type::GetByName("Boolean");
                case ValueString:
                        return Type::GetByName("String");
                case ValueObject:
index 8b5b7f771a68f19374b3e7a3256f2306b86cb3ad..ca3d8790291e5c8999bd359e87369f7d6e44843b 100644 (file)
@@ -55,6 +55,11 @@ Value::operator String(void) const
                                return boost::lexical_cast<std::string>(m_Value);
                        else
                                return boost::lexical_cast<std::string>((long)integral);
+               case ValueBoolean:
+                       if (boost::get<bool>(m_Value))
+                               return "true";
+                       else
+                               return "false";
                case ValueString:
                        return boost::get<String>(m_Value);
                case ValueObject:
@@ -133,7 +138,7 @@ bool Value::operator==(const Value& rhs) const
 {
        if (IsNumber() && rhs.IsNumber())
                return Get<double>() == rhs.Get<double>();
-       else if ((IsNumber() || IsEmpty()) && (rhs.IsNumber() || rhs.IsEmpty()) && !(IsEmpty() && rhs.IsEmpty()))
+       else if ((IsBoolean() || IsNumber() || IsEmpty()) && (rhs.IsBoolean() || rhs.IsNumber() || rhs.IsEmpty()) && !(IsEmpty() && rhs.IsEmpty()))
                return static_cast<double>(*this) == static_cast<double>(rhs);
 
        if (IsString() && rhs.IsString())
index 15cf95462de1f20726aaefc1ce8130b638709341..3ec73880a230a63cfc334b559b709f04d2952cf4 100644 (file)
@@ -32,6 +32,9 @@ bool Value::ToBool(void) const
                case ValueNumber:
                        return static_cast<bool>(boost::get<double>(m_Value));
 
+               case ValueBoolean:
+                       return boost::get<bool>(m_Value);
+
                case ValueString:
                        return !boost::get<String>(m_Value).IsEmpty();
 
@@ -63,6 +66,8 @@ String Value::GetTypeName(void) const
                        return "Empty";
                case ValueNumber:
                        return "Number";
+               case ValueBoolean:
+                       return "Boolean";
                case ValueString:
                        return "String";
                case ValueObject:
index d13a70a164c6f019cc4325844015abff29506c86..52cdd14e0f0fd892640fc3e1bcccc532bb8f522e 100644 (file)
@@ -37,8 +37,9 @@ enum ValueType
 {
        ValueEmpty = 0,
        ValueNumber = 1,
-       ValueString = 2,
-       ValueObject = 3
+       ValueBoolean = 2,
+       ValueString = 3,
+       ValueObject = 4
 };
 
 /**
@@ -73,6 +74,10 @@ public:
                : m_Value(value)
        { }
 
+       inline Value(bool value)
+               : m_Value(value)
+       { }
+
        inline Value(const String& value)
                : m_Value(value)
        { }
@@ -178,6 +183,16 @@ public:
                return (GetType() == ValueNumber);
        }
 
+       /**
+        * Checks whether the variant is a boolean.
+        *
+        * @returns true if the variant is a boolean.
+        */
+       inline bool IsBoolean(void) const
+       {
+               return (GetType() == ValueBoolean);
+       }
+
        /**
        * Checks whether the variant is a string.
        *
@@ -220,7 +235,7 @@ public:
        String GetTypeName(void) const;
 
 private:
-       boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
+       boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
 
        template<typename T>
        const T& Get(void) const
index 5252f8d91a50dd8dd786e49bc0f96a97a8cc8545..bbb7a6cbd1a2715a6d9c77f1466b884da859542b 100644 (file)
@@ -175,8 +175,8 @@ include                             return T_INCLUDE;
 include_recursive              return T_INCLUDE_RECURSIVE;
 library                                return T_LIBRARY;
 null                           return T_NULL;
-true                           { yylval->num = 1; return T_NUMBER; }
-false                          { yylval->num = 0; return T_NUMBER; }
+true                           { yylval->boolean = 1; return T_BOOLEAN; }
+false                          { yylval->boolean = 0; return T_BOOLEAN; }
 const                          return T_CONST;
 local                          return T_LOCAL;
 use                            return T_USE;
index d6364e2c5eba237d953bbedaeaa89fa6233eb7bf..bdfad171b02ae0480e8a64c34ef7b8f7462aa808 100644 (file)
@@ -90,6 +90,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
 %union {
        char *text;
        double num;
+       bool boolean;
        icinga::Expression *expr;
        icinga::Value *variant;
        CombinedSetOp csop;
@@ -104,6 +105,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
 %token <text> T_STRING
 %token <text> T_STRING_ANGLE
 %token <num> T_NUMBER
+%token <boolean> T_BOOLEAN
 %token T_NULL
 %token <text> T_IDENTIFIER
 
@@ -739,6 +741,10 @@ rterm_without_indexer: T_STRING
        {
                $$ = MakeLiteral($1);
        }
+       | T_BOOLEAN
+       {
+               $$ = MakeLiteral($1);
+       }
        | T_NULL
        {
                $$ = MakeLiteral();
index 6260afef1d2af98c177f11c5c1d3c792a49883f3..3f6f153e0244daae5cb68f9b3c7f5c6c2d9f906c 100644 (file)
@@ -57,7 +57,7 @@ bool AttributeFilter::Apply(const Table::Ptr& table, const Value& row)
                }
        } else {
                if (m_Operator == "=") {
-                       if (value.GetType() == ValueNumber)
+                       if (value.GetType() == ValueNumber || value.GetType() == ValueBoolean)
                                return (static_cast<double>(value) == Convert::ToDouble(m_Operand));
                        else
                                return (static_cast<String>(value) == m_Operand);
index bb3e6c924d3b7ac7eaf03eb2828519522fd9731c..5a3d4fc14e6addf7c663931acc02fc02c2ca36bf 100644 (file)
@@ -299,8 +299,10 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
                for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
                        std::string ftype = it->Type;
 
-                       if (ftype == "bool" || ftype == "int" || ftype == "double")
+                       if (ftype == "int" || ftype == "double")
                                ftype = "Number";
+                       else if (ftype == "bool")
+                               ftype = "Boolean";
 
                        if (ftype.find("::Ptr") != std::string::npos)
                                ftype = ftype.substr(0, ftype.size() - strlen("::Ptr"));