From 3b58eccf3096a7b0d221bc5b55578a60314d15f4 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 4 Mar 2023 14:10:08 +0100 Subject: [PATCH] fixed #14384 - added `Platform::windows` to specify if a platform is a Windows one --- lib/platform.cpp | 31 +++++++++++++++++++++++++++---- lib/platform.h | 6 +++--- lib/symboldatabase.cpp | 1 + lib/tokenize.cpp | 2 +- test/testplatform.cpp | 17 ++++++++++++----- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/platform.cpp b/lib/platform.cpp index 833c012ab8e..017731f85e4 100644 --- a/lib/platform.cpp +++ b/lib/platform.cpp @@ -40,6 +40,7 @@ bool Platform::set(Type t) case Type::Unspecified: // unknown type sizes (sizes etc are set but are not known) case Type::Native: // same as system this code was compile on type = t; + windows = false; sizeof_bool = sizeof(bool); sizeof_short = sizeof(short); sizeof_int = sizeof(int); @@ -62,6 +63,7 @@ bool Platform::set(Type t) case Type::Win32W: case Type::Win32A: type = t; + windows = true; sizeof_bool = 1; // 4 in Visual C++ 4.2 sizeof_short = 2; sizeof_int = 4; @@ -79,6 +81,7 @@ bool Platform::set(Type t) return true; case Type::Win64: type = t; + windows = true; sizeof_bool = 1; sizeof_short = 2; sizeof_int = 4; @@ -96,6 +99,7 @@ bool Platform::set(Type t) return true; case Type::Unix32: type = t; + windows = false; sizeof_bool = 1; sizeof_short = 2; sizeof_int = 4; @@ -113,6 +117,7 @@ bool Platform::set(Type t) return true; case Type::Unix64: type = t; + windows = false; sizeof_bool = 1; sizeof_short = 2; sizeof_int = 4; @@ -138,6 +143,7 @@ bool Platform::set(Type t) bool Platform::set(const std::string& platformstr, std::string& errstr, const std::vector& paths, bool debug) { + // TODO: needs to be invalidated in case it was already set if (platformstr == "win32A") set(Type::Win32A); else if (platformstr == "win32W") @@ -231,6 +237,14 @@ bool Platform::loadFromFile(const std::vector& paths, const std::st return loadFromXmlDocument(&doc); } +static const char* xmlText(const tinyxml2::XMLElement* node, bool& error) +{ + const char* const str = node->GetText(); + if (!str) + error = true; + return str; +} + static unsigned int xmlTextAsUInt(const tinyxml2::XMLElement* node, bool& error) { unsigned int retval = 0; @@ -239,6 +253,14 @@ static unsigned int xmlTextAsUInt(const tinyxml2::XMLElement* node, bool& error) return retval; } +static unsigned int xmlTextAsBool(const tinyxml2::XMLElement* node, bool& error) +{ + bool retval = false; + if (node->QueryBoolText(&retval) != tinyxml2::XML_SUCCESS) + error = true; + return retval; +} + bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc) { const tinyxml2::XMLElement * const rootnode = doc->FirstChildElement(); @@ -250,11 +272,9 @@ bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc) for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) { const char* name = node->Name(); if (std::strcmp(name, "default-sign") == 0) { - const char* str = node->GetText(); - if (str) + const char * const str = xmlText(node, error); + if (!error) defaultSign = *str; - else - error = true; } else if (std::strcmp(name, "char_bit") == 0) char_bit = xmlTextAsUInt(node, error); else if (std::strcmp(name, "sizeof") == 0) { @@ -284,6 +304,9 @@ bool Platform::loadFromXmlDocument(const tinyxml2::XMLDocument *doc) sizeof_wchar_t = xmlTextAsUInt(sz, error); } } + else if (std::strcmp(node->Name(), "windows") == 0) { + windows = xmlTextAsBool(node, error); + } } calculateBitMembers(); type = Type::File; diff --git a/lib/platform.h b/lib/platform.h index 4673c4859e6..c117edf5856 100644 --- a/lib/platform.h +++ b/lib/platform.h @@ -132,6 +132,8 @@ class CPPCHECKLIB Platform { char defaultSign; // unsigned:'u', signed:'s', unknown:'\0' + bool windows{false}; // indicates if the platform is Windows + enum Type : std::uint8_t { Unspecified, // No platform specified Native, // whatever system this code was compiled on @@ -167,9 +169,7 @@ class CPPCHECKLIB Platform { * @return true if Windows platform type. */ bool isWindows() const { - return type == Type::Win32A || - type == Type::Win32W || - type == Type::Win64; + return windows; } const char *toString() const { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index b6528d9a9e6..6aabd1606b5 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7851,6 +7851,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to else if (Token::simpleMatch(tok->previous(), "sizeof (")) { ValueType valuetype(ValueType::Sign::UNSIGNED, ValueType::Type::LONG, 0U); + // TODO: handle via sizeof_size_t instead if (mSettings.platform.type == Platform::Type::Win64) valuetype.type = ValueType::Type::LONGLONG; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 80abb4cb2bb..86146cc5e02 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -10385,7 +10385,7 @@ void Tokenizer::simplifyMicrosoftStringFunctions() if (!mSettings.platform.isWindows()) return; - const bool ansi = mSettings.platform.type == Platform::Type::Win32A; + const bool ansi = (mSettings.platform.type == Platform::Type::Win32A); // TODO: check for UNICODE define instead for (Token *tok = list.front(); tok; tok = tok->next()) { if (tok->strAt(1) != "(") continue; diff --git a/test/testplatform.cpp b/test/testplatform.cpp index c0f7bb2c017..0b49ef965ef 100644 --- a/test/testplatform.cpp +++ b/test/testplatform.cpp @@ -37,11 +37,12 @@ class TestPlatform : public TestFixture { TEST_CASE(valid_config_win32w); TEST_CASE(valid_config_unix32); TEST_CASE(valid_config_win64); + // TODO: test native and unspecified TEST_CASE(valid_config_file_1); TEST_CASE(valid_config_file_2); - TEST_CASE(valid_config_file_3); TEST_CASE(valid_config_file_4); TEST_CASE(invalid_config_file_1); + TEST_CASE(invalid_config_file_2); TEST_CASE(empty_elements); TEST_CASE(default_platform); TEST_CASE(limitsDefines); @@ -210,6 +211,7 @@ class TestPlatform : public TestFixture { // Similar to the avr8 platform file. constexpr char xmldata[] = "\n" "\n" + " false\n" " 8\n" " unsigned\n" " \n" @@ -254,6 +256,7 @@ class TestPlatform : public TestFixture { // char_bit > 8. constexpr char xmldata[] = "\n" "\n" + " true\n" " 20\n" " signed\n" " \n" @@ -273,7 +276,7 @@ class TestPlatform : public TestFixture { PlatformTest platform; ASSERT(readPlatform(platform, xmldata)); ASSERT_EQUALS(Platform::Type::File, platform.type); - ASSERT(!platform.isWindows()); + ASSERT(platform.isWindows()); ASSERT_EQUALS(20, platform.char_bit); ASSERT_EQUALS('s', platform.defaultSign); ASSERT_EQUALS(1, platform.sizeof_bool); @@ -293,11 +296,12 @@ class TestPlatform : public TestFixture { ASSERT_EQUALS(100, platform.long_long_bit); } - void valid_config_file_3() const { - // Valid platform configuration without any usable information. + void invalid_config_file_2() const { + // Invalid platform configuration without any usable information. // Similar like an empty file. constexpr char xmldata[] = "\n" "\n" + " true\n" " 8\n" " unsigned\n" " \n" @@ -324,6 +328,7 @@ class TestPlatform : public TestFixture { // set to 0. constexpr char xmldata[] = "\n" "\n" + " true\n" " 0\n" " z\n" " \n" @@ -343,7 +348,7 @@ class TestPlatform : public TestFixture { PlatformTest platform; ASSERT(readPlatform(platform, xmldata)); ASSERT_EQUALS(Platform::Type::File, platform.type); - ASSERT(!platform.isWindows()); + ASSERT(platform.isWindows()); ASSERT_EQUALS(0, platform.char_bit); ASSERT_EQUALS('z', platform.defaultSign); ASSERT_EQUALS(0, platform.sizeof_bool); @@ -367,6 +372,7 @@ class TestPlatform : public TestFixture { // Invalid XML file: mismatching elements "boolt" vs "bool". constexpr char xmldata[] = "\n" "\n" + " false\n" " 8\n" " unsigned\n" " \n" @@ -392,6 +398,7 @@ class TestPlatform : public TestFixture { // Similar like an empty file. constexpr char xmldata[] = "\n" "\n" + " \n" " \n" " \n" " \n"