From 02fc3278c8527f78f007299f9efb9474c26d7397 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 20 Mar 2014 13:02:02 +0100 Subject: [PATCH] Implement missing operators for the Value class. Fixes #5804 --- doc/4.1-configuration-syntax.md | 3 + lib/base/CMakeLists.txt | 2 +- lib/base/array.cpp | 16 ++- lib/base/array.h | 1 + lib/base/dictionary.cpp | 19 +-- lib/base/dictionary.h | 1 + lib/base/value.cpp | 199 ++++++++-------------------- lib/base/value.h | 77 +++++++++++ lib/config/aexpression.cpp | 45 +++---- lib/config/config_parser.yy | 7 +- lib/icinga/service-notification.cpp | 3 +- lib/methods/CMakeLists.txt | 2 +- lib/methods/castfuncs.cpp | 42 ++++++ lib/methods/castfuncs.h | 45 +++++++ test/base-value.cpp | 2 +- tools/mkclass/classcompiler.cpp | 9 +- 16 files changed, 288 insertions(+), 185 deletions(-) create mode 100644 lib/methods/castfuncs.cpp create mode 100644 lib/methods/castfuncs.h diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md index 9f361e0a2..401461e17 100644 --- a/doc/4.1-configuration-syntax.md +++ b/doc/4.1-configuration-syntax.md @@ -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. ### Dictionary Operators diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 746355002..0fc7a9aa4 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -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) diff --git a/lib/base/array.cpp b/lib/base/array.cpp index 4adb5316d..54f3d6364 100644 --- a/lib/base/array.cpp +++ b/lib/base/array.cpp @@ -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(); - - std::copy(m_Data.begin(), m_Data.end(), std::back_inserter(clone->m_Data)); - + CopyTo(clone); return clone; } diff --git a/lib/base/array.h b/lib/base/array.h index 0cd528aaf..c1ff75fc3 100644 --- a/lib/base/array.h +++ b/lib/base/array.h @@ -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); diff --git a/lib/base/dictionary.cpp b/lib/base/dictionary.cpp index eada298fb..eed858856 100644 --- a/lib/base/dictionary.cpp +++ b/lib/base/dictionary.cpp @@ -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(); - - BOOST_FOREACH(const Dictionary::Pair& kv, m_Data) { - clone->Set(kv.first, kv.second); - } - + CopyTo(clone); return clone; } diff --git a/lib/base/dictionary.h b/lib/base/dictionary.h index 66c0e1ee3..790713c0d 100644 --- a/lib/base/dictionary.h +++ b/lib/base/dictionary.h @@ -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); diff --git a/lib/base/value.cpp b/lib/base/value.cpp index a9028c28c..ac11f7d31 100644 --- a/lib/base/value.cpp +++ b/lib/base/value.cpp @@ -80,6 +80,26 @@ bool Value::IsScalar(void) const return !IsEmpty() && !IsObject(); } +/** + * Checks whether the variant is a number. + * + * @returns true if the variant is a number. + */ +bool Value::IsNumber(void) const +{ + return (GetType() == ValueNumber); +} + +/** + * Checks whether the variant is a string. + * + * @returns true if the variant is a string. + */ +bool Value::IsString(void) const +{ + return (GetType() == ValueString); +} + /** * Checks whether the variant is a non-null object. * @@ -90,44 +110,35 @@ bool Value::IsObject(void) const return !IsEmpty() && (GetType() == ValueObject); } -Value::operator double(void) const +bool Value::ToBool(void) const { - const double *value = boost::get(&m_Value); - - if (value) - return *value; - - if (IsEmpty()) - return 0; - - return boost::lexical_cast(m_Value); -} - -Value::operator String(void) const -{ - Object *object; - double integral, fractional; - switch (GetType()) { - case ValueEmpty: - return String(); case ValueNumber: - fractional = modf(boost::get(m_Value), &integral); + return static_cast(boost::get(m_Value)); - if (fractional != 0) - return boost::lexical_cast(m_Value); - else - return boost::lexical_cast((long)integral); case ValueString: - return boost::get(m_Value); + return !boost::get(m_Value).IsEmpty(); + case ValueObject: - object = boost::get(m_Value).get(); - return "Object of type '" + Utility::GetTypeName(typeid(*object)) + "'"; + if (IsObjectType()) { + Dictionary::Ptr dictionary = *this; + return dictionary->GetLength() > 0; + } else if (IsObjectType()) { + 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(m_Value.which()); } -bool Value::operator==(bool rhs) const +String Value::GetTypeName(void) const { - if (!IsScalar()) - return false; + const Type *t; - return static_cast(*this) == rhs; -} - -bool Value::operator!=(bool rhs) const -{ - return !(*this == rhs); -} - -bool Value::operator==(int rhs) const -{ - if (!IsScalar()) - return false; - - return static_cast(*this) == rhs; -} - -bool Value::operator!=(int rhs) const -{ - return !(*this == rhs); -} - -bool Value::operator==(double rhs) const -{ - if (!IsScalar()) - return false; - - return static_cast(*this) == rhs; -} - -bool Value::operator!=(double rhs) const -{ - return !(*this == rhs); -} - -bool Value::operator==(const char *rhs) const -{ - return static_cast(*this) == rhs; -} - -bool Value::operator!=(const char *rhs) const -{ - return !(*this == rhs); -} - -bool Value::operator==(const String& rhs) const -{ - return static_cast(*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(*this) == static_cast(rhs); - - if (GetType() == ValueNumber || rhs.GetType() == ValueNumber) - return static_cast(*this) == static_cast(rhs); - else - return static_cast(*this) == static_cast(rhs); -} - -bool Value::operator!=(const Value& rhs) const -{ - return !(*this == rhs); -} - -Value icinga::operator+(const Value& lhs, const char *rhs) -{ - return static_cast(lhs) + rhs; -} - -Value icinga::operator+(const char *lhs, const Value& rhs) -{ - return lhs + static_cast(rhs); -} - -Value icinga::operator+(const Value& lhs, const String& rhs) -{ - return static_cast(lhs) + rhs; -} - -Value icinga::operator+(const String& lhs, const Value& rhs) -{ - return lhs + static_cast(rhs); -} - -std::ostream& icinga::operator<<(std::ostream& stream, const Value& value) -{ - stream << static_cast(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(*this)->GetReflectionType(); + if (!t) + return "Object"; + else + return t->GetName(); + default: + return "Invalid"; + } } diff --git a/lib/base/value.h b/lib/base/value.h index f8d8aa551..cec38ab10 100644 --- a/lib/base/value.h +++ b/lib/base/value.h @@ -70,6 +70,8 @@ public: m_Value = static_pointer_cast(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 @@ -126,6 +130,7 @@ public: cJSON *ToJson(void) const; ValueType GetType(void) const; + String GetTypeName(void) const; private: boost::variant 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); diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp index 5ef8d49d6..e96cd8c53 100644 --- a/lib/config/aexpression.cpp +++ b/lib/config/aexpression.cpp @@ -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()) 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(); - 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."); } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index ce426bd22..80ebe126b 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -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(); + arguments->Add(*$8); delete $8; + + AExpression::Ptr aexpr = make_shared(AEFunctionCall, AValue(ATSimple, "bool"), AValue(ATSimple, arguments), yylloc); + + ApplyRule::AddRule($3, $4, $6, aexpr, yylloc); } %% diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 908c2e5a0..5b5964b4e 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -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 @@ -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 { diff --git a/lib/methods/CMakeLists.txt b/lib/methods/CMakeLists.txt index 281c0a88d..49f11fe80 100644 --- a/lib/methods/CMakeLists.txt +++ b/lib/methods/CMakeLists.txt @@ -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 index 000000000..4b35b2f53 --- /dev/null +++ b/lib/methods/castfuncs.cpp @@ -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 index 000000000..7d314bba9 --- /dev/null +++ b/lib/methods/castfuncs.h @@ -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 */ diff --git a/test/base-value.cpp b/test/base-value.cpp index 2b9be0b00..83817abca 100644 --- a/test/base-value.cpp +++ b/test/base-value.cpp @@ -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() diff --git a/tools/mkclass/classcompiler.cpp b/tools/mkclass/classcompiler.cpp index 0c87e660b..725c185a5 100644 --- a/tools/mkclass/classcompiler.cpp +++ b/tools/mkclass/classcompiler.cpp @@ -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())