From f17d5b719a3128791570e6109bdb8ec317c0afbe Mon Sep 17 00:00:00 2001 From: Mathias Schmid <50880400+matzeschmid@users.noreply.github.com> Date: Fri, 29 Jan 2021 14:54:19 +0100 Subject: [PATCH] Fix library data platform type (#3084) --- gui/cppchecklibrarydata.cpp | 48 +++++ gui/cppchecklibrarydata.h | 10 + .../memory_resource_unhandled_element.cfg | 12 ++ .../files/memory_resource_valid.cfg | 15 ++ .../files/platform_type_unhandled_element.cfg | 8 + .../files/platform_type_valid.cfg | 19 ++ gui/test/cppchecklibrarydata/resources.qrc | 4 + .../testcppchecklibrarydata.cpp | 175 +++++++++++++++++- .../testcppchecklibrarydata.h | 2 + 9 files changed, 286 insertions(+), 7 deletions(-) create mode 100644 gui/test/cppchecklibrarydata/files/memory_resource_unhandled_element.cfg create mode 100644 gui/test/cppchecklibrarydata/files/memory_resource_valid.cfg create mode 100644 gui/test/cppchecklibrarydata/files/platform_type_unhandled_element.cfg create mode 100644 gui/test/cppchecklibrarydata/files/platform_type_valid.cfg diff --git a/gui/cppchecklibrarydata.cpp b/gui/cppchecklibrarydata.cpp index 793573347..0683a4c7c 100644 --- a/gui/cppchecklibrarydata.cpp +++ b/gui/cppchecklibrarydata.cpp @@ -271,6 +271,29 @@ static CppcheckLibraryData::PodType loadPodType(const QXmlStreamReader &xmlReade return podtype; } +static CppcheckLibraryData::PlatformType loadPlatformType(QXmlStreamReader &xmlReader) +{ + CppcheckLibraryData::PlatformType platformType; + platformType.name = xmlReader.attributes().value("name").toString(); + platformType.value = xmlReader.attributes().value("value").toString(); + + QXmlStreamReader::TokenType type; + while ((type = xmlReader.readNext()) != QXmlStreamReader::EndElement || + xmlReader.name().toString() != "platformtype") { + if (type != QXmlStreamReader::StartElement) + continue; + const QString elementName = xmlReader.name().toString(); + if (QStringList({"unsigned", "long", "pointer", "const_ptr", "ptr_ptr"}).contains(elementName)) { + platformType.types.append(elementName); + } else if (elementName == "platform") { + platformType.platforms.append(xmlReader.attributes().value("type").toString()); + } else { + unhandledElement(xmlReader); + } + } + return platformType; +} + QString CppcheckLibraryData::open(QIODevice &file) { clear(); @@ -305,6 +328,8 @@ QString CppcheckLibraryData::open(QIODevice &file) smartPointers.append(loadSmartPointer(xmlReader)); else if (elementName == "type-checks") typeChecks.append(loadTypeChecks(xmlReader)); + else if (elementName == "platformtype") + platformTypes.append(loadPlatformType(xmlReader)); else unhandledElement(xmlReader); } catch (std::runtime_error &e) { @@ -545,6 +570,25 @@ static void writeTypeChecks(QXmlStreamWriter &xmlWriter, const CppcheckLibraryDa xmlWriter.writeEndElement(); } +static void writePlatformType (QXmlStreamWriter &xmlWriter, const CppcheckLibraryData::PlatformType &pt) +{ + xmlWriter.writeStartElement("platformtype"); + xmlWriter.writeAttribute("name", pt.name); + xmlWriter.writeAttribute("value", pt.value); + foreach (const QString type, pt.types) { + xmlWriter.writeStartElement(type); + xmlWriter.writeEndElement(); + } + foreach (const QString platform, pt.platforms) { + xmlWriter.writeStartElement("platform"); + if (!platform.isEmpty()) { + xmlWriter.writeAttribute("type", platform); + } + xmlWriter.writeEndElement(); + } + xmlWriter.writeEndElement(); +} + QString CppcheckLibraryData::toString() const { QString outputString; @@ -602,6 +646,10 @@ QString CppcheckLibraryData::toString() const xmlWriter.writeEndElement(); } + foreach (const PlatformType &pt, platformTypes) { + writePlatformType(xmlWriter, pt); + } + xmlWriter.writeEndElement(); return outputString; diff --git a/gui/cppchecklibrarydata.h b/gui/cppchecklibrarydata.h index 52a18964a..af1f25efa 100644 --- a/gui/cppchecklibrarydata.h +++ b/gui/cppchecklibrarydata.h @@ -171,6 +171,13 @@ public: QString sign; }; + struct PlatformType { + QString name; + QString value; + QStringList types; // Keeps element names w/o attribute (e.g. unsigned) + QStringList platforms; // Keeps "type" attribute of each "platform" element + }; + using TypeChecks = QList>; void clear() { @@ -182,6 +189,7 @@ public: podtypes.clear(); smartPointers.clear(); typeChecks.clear(); + platformTypes.clear(); } void swap(CppcheckLibraryData &other) { @@ -193,6 +201,7 @@ public: podtypes.swap(other.podtypes); smartPointers.swap(other.smartPointers); typeChecks.swap(other.typeChecks); + platformTypes.swap(other.platformTypes); } QString open(QIODevice &file); @@ -204,6 +213,7 @@ public: QList memoryresource; QList podtypes; QList typeChecks; + QList platformTypes; QStringList undefines; QStringList smartPointers; }; diff --git a/gui/test/cppchecklibrarydata/files/memory_resource_unhandled_element.cfg b/gui/test/cppchecklibrarydata/files/memory_resource_unhandled_element.cfg new file mode 100644 index 000000000..9a197cdad --- /dev/null +++ b/gui/test/cppchecklibrarydata/files/memory_resource_unhandled_element.cfg @@ -0,0 +1,12 @@ + + + + malloc + + calloc + aligned_alloc + realloc + reallocarray + free + + diff --git a/gui/test/cppchecklibrarydata/files/memory_resource_valid.cfg b/gui/test/cppchecklibrarydata/files/memory_resource_valid.cfg new file mode 100644 index 000000000..fe0e93290 --- /dev/null +++ b/gui/test/cppchecklibrarydata/files/memory_resource_valid.cfg @@ -0,0 +1,15 @@ + + + + malloc + calloc + realloc + UuidToString + HeapFree + + + + fclose + _wfopen_s + + diff --git a/gui/test/cppchecklibrarydata/files/platform_type_unhandled_element.cfg b/gui/test/cppchecklibrarydata/files/platform_type_unhandled_element.cfg new file mode 100644 index 000000000..b6b0245ce --- /dev/null +++ b/gui/test/cppchecklibrarydata/files/platform_type_unhandled_element.cfg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gui/test/cppchecklibrarydata/files/platform_type_valid.cfg b/gui/test/cppchecklibrarydata/files/platform_type_valid.cfg new file mode 100644 index 000000000..ccbd51f5a --- /dev/null +++ b/gui/test/cppchecklibrarydata/files/platform_type_valid.cfg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/gui/test/cppchecklibrarydata/resources.qrc b/gui/test/cppchecklibrarydata/resources.qrc index 521edd834..e38997e1e 100644 --- a/gui/test/cppchecklibrarydata/resources.qrc +++ b/gui/test/cppchecklibrarydata/resources.qrc @@ -6,5 +6,9 @@ files/typechecks_valid.cfg files/podtype_valid.cfg files/smartptr_valid.cfg + files/platform_type_valid.cfg + files/platform_type_unhandled_element.cfg + files/memory_resource_unhandled_element.cfg + files/memory_resource_valid.cfg diff --git a/gui/test/cppchecklibrarydata/testcppchecklibrarydata.cpp b/gui/test/cppchecklibrarydata/testcppchecklibrarydata.cpp index f6bf32fb2..06272a040 100644 --- a/gui/test/cppchecklibrarydata/testcppchecklibrarydata.cpp +++ b/gui/test/cppchecklibrarydata/testcppchecklibrarydata.cpp @@ -39,6 +39,14 @@ void TestCppcheckLibraryData::unhandledElement() loadCfgFile(":/files/unhandled_element.cfg", fileLibraryData, result); QCOMPARE(result.isNull(), false); qDebug() << result; + + loadCfgFile(":/files/platform_type_unhandled_element.cfg", fileLibraryData, result); + QCOMPARE(result.isNull(), false); + qDebug() << result; + + loadCfgFile(":/files/memory_resource_unhandled_element.cfg", fileLibraryData, result); + QCOMPARE(result.isNull(), false); + qDebug() << result; } void TestCppcheckLibraryData::mandatoryAttributeMissing() @@ -134,11 +142,8 @@ void TestCppcheckLibraryData::typechecksValid() for (int idx=0; idx < libraryData.typeChecks.size(); idx++) { CppcheckLibraryData::TypeChecks lhs = libraryData.typeChecks[idx]; CppcheckLibraryData::TypeChecks rhs = fileLibraryData.typeChecks[idx]; - QCOMPARE(lhs.size(), lhs.size()); - for (int num=0; num < lhs.size(); num++) { - QCOMPARE(lhs[num].first, rhs[num].first); - QCOMPARE(lhs[num].second, rhs[num].second); - } + QCOMPARE(lhs.size(), rhs.size()); + QCOMPARE(lhs, rhs); } } @@ -171,8 +176,164 @@ void TestCppcheckLibraryData::smartPointerValid() // Verify no data got lost or modified QCOMPARE(libraryData.smartPointers.size(), fileLibraryData.smartPointers.size()); QCOMPARE(libraryData.smartPointers.size(), 3); - for (int i=0; i < libraryData.smartPointers.size(); i++) { - QCOMPARE(libraryData.smartPointers[i], fileLibraryData.smartPointers[i]); + QCOMPARE(libraryData.smartPointers, fileLibraryData.smartPointers); +} + +void TestCppcheckLibraryData::platformTypeValid() +{ + // Load library data from file + loadCfgFile(":/files/platform_type_valid.cfg", fileLibraryData, result); + QCOMPARE(result.isNull(), true); + + // Swap libray data read from file to other object + libraryData.swap(fileLibraryData); + + // Do size and content checks against swapped data. + QCOMPARE(libraryData.platformTypes.size(), 3); + + QCOMPARE(libraryData.platformTypes[0].name, "platform"); + QCOMPARE(libraryData.platformTypes[0].value, "with attribute and empty"); + QCOMPARE(libraryData.platformTypes[0].types.size(), 0); + QCOMPARE(libraryData.platformTypes[0].platforms.size(), 2); + QCOMPARE(libraryData.platformTypes[0].platforms[0], "win64"); + QCOMPARE(libraryData.platformTypes[0].platforms[1].isEmpty(), true); + + QCOMPARE(libraryData.platformTypes[1].name, "types"); + QCOMPARE(libraryData.platformTypes[1].value, "all"); + QCOMPARE(libraryData.platformTypes[1].types.size(), 5); + QCOMPARE(libraryData.platformTypes[1].types, + QStringList({"unsigned", "long", "pointer", "const_ptr", "ptr_ptr"})); + QCOMPARE(libraryData.platformTypes[1].platforms.isEmpty(), true); + + QCOMPARE(libraryData.platformTypes[2].name, "types and platform"); + QCOMPARE(libraryData.platformTypes[2].value.isEmpty(), true); + QCOMPARE(libraryData.platformTypes[2].types.size(), 2); + QCOMPARE(libraryData.platformTypes[2].types, QStringList({"pointer", "ptr_ptr"})); + QCOMPARE(libraryData.platformTypes[2].platforms.size(), 1); + QCOMPARE(libraryData.platformTypes[2].platforms[0], "win32"); + + // Save library data to file + saveCfgFile(TempCfgFile, libraryData); + + fileLibraryData.clear(); + QCOMPARE(fileLibraryData.platformTypes.size(), 0); + + // Reload library data from file + loadCfgFile(TempCfgFile, fileLibraryData, result, true); + QCOMPARE(result.isNull(), true); + + // Verify no data got lost or modified + QCOMPARE(libraryData.platformTypes.size(), fileLibraryData.platformTypes.size()); + QCOMPARE(libraryData.platformTypes.size(), 3); + for (int idx=0; idx < libraryData.platformTypes.size(); idx++) { + CppcheckLibraryData::PlatformType lhs = libraryData.platformTypes[idx]; + CppcheckLibraryData::PlatformType rhs = fileLibraryData.platformTypes[idx]; + QCOMPARE(lhs.name, rhs.name); + QCOMPARE(lhs.value, rhs.value); + QCOMPARE(lhs.types.size(), rhs.types.size()); + QCOMPARE(lhs.types, rhs.types); + QCOMPARE(lhs.platforms.size(), rhs.platforms.size()); + QCOMPARE(lhs.platforms, rhs.platforms); + } +} + +void TestCppcheckLibraryData::memoryResourceValid() +{ + // Load library data from file + loadCfgFile(":/files/memory_resource_valid.cfg", fileLibraryData, result); + QCOMPARE(result.isNull(), true); + + // Swap libray data read from file to other object + libraryData.swap(fileLibraryData); + + // Do size and content checks against swapped data. + QCOMPARE(libraryData.memoryresource.size(), 2); + QCOMPARE(libraryData.memoryresource[0].type, "memory"); + QCOMPARE(libraryData.memoryresource[0].alloc.size(), 4); + QCOMPARE(libraryData.memoryresource[0].dealloc.size(), 1); + QCOMPARE(libraryData.memoryresource[0].use.size(), 0); + + QCOMPARE(libraryData.memoryresource[0].alloc[0].name, "malloc"); + QCOMPARE(libraryData.memoryresource[0].alloc[0].bufferSize, "malloc"); + QCOMPARE(libraryData.memoryresource[0].alloc[0].isRealloc, false); + QCOMPARE(libraryData.memoryresource[0].alloc[0].init, false); + QCOMPARE(libraryData.memoryresource[0].alloc[0].arg, -1); + QCOMPARE(libraryData.memoryresource[0].alloc[0].reallocArg, -1); + + QCOMPARE(libraryData.memoryresource[0].alloc[1].name, "calloc"); + QCOMPARE(libraryData.memoryresource[0].alloc[1].bufferSize, "calloc"); + QCOMPARE(libraryData.memoryresource[0].alloc[1].isRealloc, false); + QCOMPARE(libraryData.memoryresource[0].alloc[1].init, true); + QCOMPARE(libraryData.memoryresource[0].alloc[1].arg, -1); + QCOMPARE(libraryData.memoryresource[0].alloc[1].reallocArg, -1); + + QCOMPARE(libraryData.memoryresource[0].alloc[2].name, "realloc"); + QCOMPARE(libraryData.memoryresource[0].alloc[2].bufferSize, "malloc:2"); + QCOMPARE(libraryData.memoryresource[0].alloc[2].isRealloc, true); + QCOMPARE(libraryData.memoryresource[0].alloc[2].init, false); + QCOMPARE(libraryData.memoryresource[0].alloc[2].arg, -1); + QCOMPARE(libraryData.memoryresource[0].alloc[2].reallocArg, -1); + + QCOMPARE(libraryData.memoryresource[0].alloc[3].name, "UuidToString"); + QCOMPARE(libraryData.memoryresource[0].alloc[3].bufferSize.isEmpty(), true); + QCOMPARE(libraryData.memoryresource[0].alloc[3].isRealloc, false); + QCOMPARE(libraryData.memoryresource[0].alloc[3].init, false); + QCOMPARE(libraryData.memoryresource[0].alloc[3].arg, 2); + QCOMPARE(libraryData.memoryresource[0].alloc[3].reallocArg, -1); + + QCOMPARE(libraryData.memoryresource[0].dealloc[0].name, "HeapFree"); + QCOMPARE(libraryData.memoryresource[0].dealloc[0].arg, 3); + + QCOMPARE(libraryData.memoryresource[1].type, "resource"); + QCOMPARE(libraryData.memoryresource[1].alloc.size(), 1); + QCOMPARE(libraryData.memoryresource[1].dealloc.size(), 1); + QCOMPARE(libraryData.memoryresource[1].use.size(), 0); + + QCOMPARE(libraryData.memoryresource[1].alloc[0].name, "_wfopen_s"); + QCOMPARE(libraryData.memoryresource[1].alloc[0].bufferSize.isEmpty(), true); + QCOMPARE(libraryData.memoryresource[1].alloc[0].isRealloc, false); + QCOMPARE(libraryData.memoryresource[1].alloc[0].init, true); + QCOMPARE(libraryData.memoryresource[1].alloc[0].arg, 1); + QCOMPARE(libraryData.memoryresource[1].alloc[0].reallocArg, -1); + + QCOMPARE(libraryData.memoryresource[1].dealloc[0].name, "fclose"); + QCOMPARE(libraryData.memoryresource[1].dealloc[0].arg, -1); + + // Save library data to file + saveCfgFile(TempCfgFile, libraryData); + + fileLibraryData.clear(); + QCOMPARE(fileLibraryData.memoryresource.size(), 0); + + // Reload library data from file + loadCfgFile(TempCfgFile, fileLibraryData, result, true); + QCOMPARE(result.isNull(), true); + + // Verify no data got lost or modified + QCOMPARE(libraryData.memoryresource.size(), fileLibraryData.memoryresource.size()); + QCOMPARE(libraryData.memoryresource.size(), 2); + + for (int idx=0; idx < libraryData.memoryresource.size(); idx++) { + CppcheckLibraryData::MemoryResource lhs = libraryData.memoryresource[idx]; + CppcheckLibraryData::MemoryResource rhs = fileLibraryData.memoryresource[idx]; + + QCOMPARE(lhs.type, rhs.type); + QCOMPARE(lhs.alloc.size(), rhs.alloc.size()); + QCOMPARE(lhs.dealloc.size(), rhs.dealloc.size()); + QCOMPARE(lhs.use, rhs.use); + + for (int num=0; num < lhs.alloc.size(); num++) { + QCOMPARE(lhs.alloc[num].name, rhs.alloc[num].name); + QCOMPARE(lhs.alloc[num].bufferSize, rhs.alloc[num].bufferSize); + QCOMPARE(lhs.alloc[num].isRealloc, rhs.alloc[num].isRealloc); + QCOMPARE(lhs.alloc[num].init, rhs.alloc[num].init); + QCOMPARE(lhs.alloc[num].arg, rhs.alloc[num].arg); + QCOMPARE(lhs.alloc[num].reallocArg, rhs.alloc[num].reallocArg); + } + for (int num=0; num < lhs.dealloc.size(); num++) { + QCOMPARE(lhs.dealloc[num].name, rhs.dealloc[num].name); + QCOMPARE(lhs.dealloc[num].arg, rhs.dealloc[num].arg); + } } } diff --git a/gui/test/cppchecklibrarydata/testcppchecklibrarydata.h b/gui/test/cppchecklibrarydata/testcppchecklibrarydata.h index f7ea48338..7a00c7011 100644 --- a/gui/test/cppchecklibrarydata/testcppchecklibrarydata.h +++ b/gui/test/cppchecklibrarydata/testcppchecklibrarydata.h @@ -32,6 +32,8 @@ private slots: void podtypeValid(); void typechecksValid(); void smartPointerValid(); + void platformTypeValid(); + void memoryResourceValid(); private: void loadCfgFile(QString filename, CppcheckLibraryData &data, QString &result, bool removeFile = false);