From fc1603eb9b90d4e830733981e1c63b4938f3e28d Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 26 Jul 2016 13:19:28 +0200 Subject: [PATCH] MathLib, ValueType: Support integer suffix "i64" --- lib/mathlib.cpp | 76 ++++++++++++++++++++++++------------- lib/symboldatabase.cpp | 8 +++- test/testmathlib.cpp | 5 +++ test/testsymboldatabase.cpp | 2 + 4 files changed, 63 insertions(+), 28 deletions(-) diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 7c0071bf5..b681c61ef 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -49,7 +49,7 @@ MathLib::value::value(const std::string &s) : } if (!MathLib::isInt(s)) - throw InternalError(0, "Invalid value"); + throw InternalError(0, "Invalid value: " + s); type = MathLib::value::INT; intValue = MathLib::toLongNumber(s); @@ -68,7 +68,8 @@ MathLib::value::value(const std::string &s) : type = MathLib::value::LONG; else if (type == MathLib::value::LONG) type = MathLib::value::LONGLONG; - } + } else if (i > 2U && c == '4' && s[i-1] == '6' && s[i-2] == 'i') + type = MathLib::value::LONGLONG; } } } @@ -829,7 +830,7 @@ bool MathLib::isFloatHex(const std::string& s) bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end) { - enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64} state = START; + enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64} state = START; for (; it != end; ++it) { switch (state) { case START: @@ -845,6 +846,8 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string:: case SUFFIX_U: if (*it == 'l' || *it == 'L') state = SUFFIX_UL; // UL + else if (*it == 'i') + state = SUFFIX_UI; else return false; break; @@ -882,6 +885,18 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string:: else return false; break; + case SUFFIX_UI: + if (*it == '6') + state = SUFFIX_UI6; + else + return false; + break; + case SUFFIX_UI6: + if (*it == '4') + state = SUFFIX_UI64; + else + return false; + break; default: return false; } @@ -893,7 +908,8 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string:: (state == SUFFIX_LL) || (state == SUFFIX_ULL) || (state == SUFFIX_LLU) || - (state == SUFFIX_I64)); + (state == SUFFIX_I64) || + (state == SUFFIX_UI64)); } /*! \brief Does the string represent a binary number? @@ -986,33 +1002,41 @@ bool MathLib::isInt(const std::string & s) return isDec(s) || isIntHex(s) || isOct(s) || isBin(s); } +static std::string getsuffix(const std::string& value) +{ + if (value.size() > 3 && value[value.size() - 3] == 'i' && value[value.size() - 2] == '6' && value[value.size() - 1] == '4') { + if (value[value.size() - 4] == 'u') + return "ULL"; + return "LL"; + } + bool isUnsigned = false; + unsigned int longState = 0; + for (std::size_t i = 1U; i < value.size(); ++i) { + char c = value[value.size() - i]; + if (c == 'u' || c == 'U') + isUnsigned = true; + else if (c == 'L' || c == 'l') + longState++; + else break; + } + if (longState == 0) + return isUnsigned ? "U" : ""; + if (longState == 1) + return isUnsigned ? "UL" : "L"; + if (longState == 2) + return isUnsigned ? "ULL" : "LL"; + else return ""; +} + static std::string intsuffix(const std::string & first, const std::string & second) { - std::string suffix1, suffix2; - for (std::size_t i = 1U; i < first.size(); ++i) { - char c = first[first.size() - i]; - if (c == 'l' || c == 'u') - c = c - 'a' + 'A'; - if (c != 'L' && c != 'U') - break; - suffix1 = c + suffix1; - } - for (std::size_t i = 1U; i < second.size(); ++i) { - char c = second[second.size() - i]; - if (c == 'l' || c == 'u') - c = c - 'a' + 'A'; - if (c != 'L' && c != 'U') - break; - suffix2 = c + suffix2; - } - - if (suffix1 == "ULL" || suffix2 == "ULL" - || suffix1 == "LLU" || suffix2 == "LLU") + std::string suffix1 = getsuffix(first); + std::string suffix2 = getsuffix(second); + if (suffix1 == "ULL" || suffix2 == "ULL") return "ULL"; if (suffix1 == "LL" || suffix2 == "LL") return "LL"; - if (suffix1 == "UL" || suffix2 == "UL" - || suffix1 == "LU" || suffix2 == "LU") + if (suffix1 == "UL" || suffix2 == "UL") return "UL"; if (suffix1 == "L" || suffix2 == "L") return "L"; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index a5a249095..22bc731b8 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4412,12 +4412,16 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens, bool cpp, char defau ValueType::Type type = ValueType::Type::INT; if (MathLib::isIntHex(tok->str())) sign = ValueType::Sign::UNSIGNED; - for (std::size_t pos = tok->str().size() - 1U; pos > 0U && std::isalpha(tok->str()[pos]); --pos) { + for (std::size_t pos = tok->str().size() - 1U; pos > 0U; --pos) { const char suffix = tok->str()[pos]; if (suffix == 'u' || suffix == 'U') sign = ValueType::Sign::UNSIGNED; - if (suffix == 'l' || suffix == 'L') + else if (suffix == 'l' || suffix == 'L') type = (type == ValueType::Type::INT) ? ValueType::Type::LONG : ValueType::Type::LONGLONG; + else if (pos > 2U && suffix == '4' && tok->str()[pos - 1] == '6' && tok->str()[pos - 2] == 'i') { + type = ValueType::Type::LONGLONG; + pos -= 2; + } else break; } ::setValueType(tok, ValueType(sign, type, 0U), cpp, defsign, lib); } diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index cf6b7f7a6..773ab2b4d 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -177,7 +177,9 @@ private: ASSERT_EQUALS("2L", MathLib::add("1L", "1")); ASSERT_EQUALS("2UL", MathLib::add("1UL", "1")); ASSERT_EQUALS("2LL", MathLib::add("1LL", "1")); + ASSERT_EQUALS("2LL", MathLib::add("1i64", "1")); ASSERT_EQUALS("2ULL", MathLib::add("1ULL", "1")); + ASSERT_EQUALS("2ULL", MathLib::add("1ui64","1")); ASSERT_EQUALS("2U", MathLib::add("1", "1U")); ASSERT_EQUALS("2U", MathLib::add("1U", "1U")); @@ -738,6 +740,9 @@ private: value = "i64"; ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); + + value = "ui64"; + ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); } void ispositive() const { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 0d99542ee..936ec0cd5 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3534,6 +3534,8 @@ private: ASSERT_EQUALS("unsigned long", typeOf("1UL", "1UL")); ASSERT_EQUALS("signed long long", typeOf("1LL", "1LL")); ASSERT_EQUALS("unsigned long long", typeOf("1ULL", "1ULL")); + ASSERT_EQUALS("signed long long", typeOf("1i64", "1i64")); + ASSERT_EQUALS("unsigned long long", typeOf("1ui64", "1ui64")); ASSERT_EQUALS("unsigned int", typeOf("1u", "1u")); ASSERT_EQUALS("signed long", typeOf("1l", "1l")); ASSERT_EQUALS("unsigned long", typeOf("1ul", "1ul"));