From c58b8b47d2ea38b7cc168c8211317ef7755ee2a6 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 5 Sep 2023 10:16:26 +0200 Subject: [PATCH 1/3] Library: moved private containers into source file --- gui/test/projectfile/testprojectfile.cpp | 3 + lib/library.cpp | 319 +++++++++++++---------- lib/library.h | 38 +-- test/testlibrary.cpp | 15 +- 4 files changed, 204 insertions(+), 171 deletions(-) diff --git a/gui/test/projectfile/testprojectfile.cpp b/gui/test/projectfile/testprojectfile.cpp index 7e301dbc48a..eb8e49b79b5 100644 --- a/gui/test/projectfile/testprojectfile.cpp +++ b/gui/test/projectfile/testprojectfile.cpp @@ -42,6 +42,9 @@ const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions"; const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables"; Settings::Settings() : maxCtuDepth(10) {} Platform::Platform() = default; +Library::Library() = default; +Library::~Library() = default; +struct Library::LibraryData {}; bool ImportProject::sourceFileExists(const std::string & /*file*/) { return true; } diff --git a/lib/library.cpp b/lib/library.cpp index d689ff4f7ac..8bf6e4b7bb9 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -40,9 +40,58 @@ #include #include #include +#include #include "xml.h" +struct Library::LibraryData +{ + std::unordered_map mContainers; + std::unordered_map mFunctions; + std::unordered_map mSmartPointers; + + int mAllocId{}; + std::set mFiles; + std::map mAlloc; // allocation functions + std::map mDealloc; // deallocation functions + std::map mRealloc; // reallocation functions + std::unordered_map mNoReturn; // is function noreturn? + std::map mReturnValue; + std::map mReturnValueType; + std::map mReturnValueContainer; + std::map> mUnknownReturnValues; + std::map mReportErrors; + std::map mProcessAfterCode; + std::set mMarkupExtensions; // file extensions of markup files + std::map> mKeywords; // keywords for code in the library + std::unordered_map mExecutableBlocks; // keywords for blocks of executable code + std::map mExporters; // keywords that export variables/functions to libraries (meta-code/macros) + std::map> mImporters; // keywords that import variables/functions + std::map mReflection; // invocation of reflection + std::unordered_map mPodTypes; // pod types + std::map mPlatformTypes; // platform independent typedefs + std::map mPlatforms; // platform dependent typedefs + std::map, TypeCheck> mTypeChecks; + std::unordered_map mNonOverlappingData; + std::unordered_set mEntrypoints; +}; + +Library::Library() + : mData(new LibraryData()) +{} + +Library::~Library() = default; + +Library::Library(const Library& other) + : mData(new LibraryData(*other.mData)) +{} + +Library& Library::operator=(const Library& other) +{ + mData.reset(new LibraryData(*other.mData)); + return *this; +} + static std::vector getnames(const char *names) { std::vector ret; @@ -136,10 +185,10 @@ Library::Error Library::load(const char exename[], const char path[], bool debug absolute_path = Path::getAbsoluteFilePath(path); if (error == tinyxml2::XML_SUCCESS) { - if (mFiles.find(absolute_path) == mFiles.end()) { + if (mData->mFiles.find(absolute_path) == mData->mFiles.end()) { Error err = load(doc); if (err.errorcode == ErrorCode::OK) - mFiles.insert(absolute_path); + mData->mFiles.insert(absolute_path); return err; } @@ -233,8 +282,8 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (strcmp(memorynode->Name(),"dealloc")==0) { const auto names = getnames(memorynode->GetText()); for (const auto& n : names) { - const std::map::const_iterator it = mDealloc.find(n); - if (it != mDealloc.end()) { + const std::map::const_iterator it = mData->mDealloc.find(n); + if (it != mData->mDealloc.end()) { allocationId = it->second.groupId; break; } @@ -245,10 +294,10 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) } if (allocationId == 0) { if (nodename == "memory") - while (!ismemory(++mAllocId)); + while (!ismemory(++mData->mAllocId)); else - while (!isresource(++mAllocId)); - allocationId = mAllocId; + while (!isresource(++mData->mAllocId)); + allocationId = mData->mAllocId; } // add alloc/dealloc/use functions.. @@ -289,7 +338,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (memorynodename == "realloc") temp.reallocArg = memorynode->IntAttribute("realloc-arg", 1); - auto& map = (memorynodename == "realloc") ? mRealloc : mAlloc; + auto& map = (memorynodename == "realloc") ? mData->mRealloc : mData->mAlloc; for (const auto& n : names) map[n] = temp; } else if (memorynodename == "dealloc") { @@ -297,10 +346,10 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) temp.groupId = allocationId; temp.arg = memorynode->IntAttribute("arg", 1); for (const auto& n : names) - mDealloc[n] = temp; + mData->mDealloc[n] = temp; } else if (memorynodename == "use") for (const auto& n : names) - mFunctions[n].use = true; + mData->mFunctions[n].use = true; else unknown_elements.insert(memorynodename); } @@ -340,7 +389,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (!argString) return Error(ErrorCode::MISSING_ATTRIBUTE, "arg"); - mReflection[reflectionnode->GetText()] = strToInt(argString); + mData->mReflection[reflectionnode->GetText()] = strToInt(argString); } } @@ -348,10 +397,10 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char * const extension = node->Attribute("ext"); if (!extension) return Error(ErrorCode::MISSING_ATTRIBUTE, "ext"); - mMarkupExtensions.insert(extension); + mData->mMarkupExtensions.insert(extension); - mReportErrors[extension] = (node->Attribute("reporterrors", "true") != nullptr); - mProcessAfterCode[extension] = (node->Attribute("aftercode", "true") != nullptr); + mData->mReportErrors[extension] = (node->Attribute("reporterrors", "true") != nullptr); + mData->mProcessAfterCode[extension] = (node->Attribute("aftercode", "true") != nullptr); for (const tinyxml2::XMLElement *markupnode = node->FirstChildElement(); markupnode; markupnode = markupnode->NextSiblingElement()) { const std::string markupnodename = markupnode->Name(); @@ -361,7 +410,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char* nodeName = librarynode->Attribute("name"); if (nodeName == nullptr) return Error(ErrorCode::MISSING_ATTRIBUTE, "name"); - mKeywords[extension].insert(nodeName); + mData->mKeywords[extension].insert(nodeName); } else unknown_elements.insert(librarynode->Name()); } @@ -381,9 +430,9 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) for (const tinyxml2::XMLElement *e = exporter->FirstChildElement(); e; e = e->NextSiblingElement()) { const std::string ename = e->Name(); if (ename == "prefix") - mExporters[prefix].addPrefix(e->GetText()); + mData->mExporters[prefix].addPrefix(e->GetText()); else if (ename == "suffix") - mExporters[prefix].addSuffix(e->GetText()); + mData->mExporters[prefix].addSuffix(e->GetText()); else unknown_elements.insert(ename); } @@ -393,7 +442,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) else if (markupnodename == "imported") { for (const tinyxml2::XMLElement *librarynode = markupnode->FirstChildElement(); librarynode; librarynode = librarynode->NextSiblingElement()) { if (strcmp(librarynode->Name(), "importer") == 0) - mImporters[extension].insert(librarynode->GetText()); + mData->mImporters[extension].insert(librarynode->GetText()); else unknown_elements.insert(librarynode->Name()); } @@ -405,18 +454,18 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (blocknodename == "block") { const char * blockName = blocknode->Attribute("name"); if (blockName) - mExecutableBlocks[extension].addBlock(blockName); + mData->mExecutableBlocks[extension].addBlock(blockName); } else if (blocknodename == "structure") { const char * start = blocknode->Attribute("start"); if (start) - mExecutableBlocks[extension].setStart(start); + mData->mExecutableBlocks[extension].setStart(start); const char * end = blocknode->Attribute("end"); if (end) - mExecutableBlocks[extension].setEnd(end); + mData->mExecutableBlocks[extension].setEnd(end); const char * offset = blocknode->Attribute("offset"); if (offset) { // cppcheck-suppress templateInstantiation - TODO: fix this - see #11631 - mExecutableBlocks[extension].setOffset(strToInt(offset)); + mData->mExecutableBlocks[extension].setOffset(strToInt(offset)); } } @@ -435,12 +484,12 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (!id) return Error(ErrorCode::MISSING_ATTRIBUTE, "id"); - Container& container = mContainers[id]; + Container& container = mData->mContainers[id]; const char* const inherits = node->Attribute("inherits"); if (inherits) { - const std::unordered_map::const_iterator i = mContainers.find(inherits); - if (i != mContainers.end()) + const std::unordered_map::const_iterator i = mData->mContainers.find(inherits); + if (i != mData->mContainers.end()) container = i->second; // Take values from parent and overwrite them if necessary else return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, inherits); @@ -554,7 +603,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char *className = node->Attribute("class-name"); if (!className) return Error(ErrorCode::MISSING_ATTRIBUTE, "class-name"); - SmartPointer& smartPointer = mSmartPointers[className]; + SmartPointer& smartPointer = mData->mSmartPointers[className]; smartPointer.name = className; for (const tinyxml2::XMLElement* smartPointerNode = node->FirstChildElement(); smartPointerNode; smartPointerNode = smartPointerNode->NextSiblingElement()) { @@ -573,11 +622,11 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (!typeName) continue; if (checkTypeName == "check") - mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::check; + mData->mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::check; else if (checkTypeName == "suppress") - mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::suppress; + mData->mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::suppress; else if (checkTypeName == "checkFiniteLifetime") - mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::checkFiniteLifetime; + mData->mTypeChecks[std::pair(checkName, typeName)] = TypeCheck::checkFiniteLifetime; } } } @@ -610,7 +659,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) if (sign) podType.sign = *sign; for (const std::string &s : getnames(name)) - mPodTypes[s] = podType; + mData->mPodTypes[s] = podType; } else if (nodename == "platformtype") { @@ -652,7 +701,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) return Error(ErrorCode::DUPLICATE_PLATFORM_TYPE, type_name); return Error(ErrorCode::PLATFORM_TYPE_REDEFINED, type_name); } - mPlatformTypes[type_name] = std::move(type); + mData->mPlatformTypes[type_name] = std::move(type); } else { for (const std::string &p : platform) { const PlatformType * const type_ptr = platform_type(type_name, p); @@ -661,7 +710,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) return Error(ErrorCode::DUPLICATE_PLATFORM_TYPE, type_name); return Error(ErrorCode::PLATFORM_TYPE_REDEFINED, type_name); } - mPlatforms[p].mPlatformTypes[type_name] = type; + mData->mPlatforms[p].mPlatformTypes[type_name] = type; } } } @@ -670,7 +719,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char * const type_name = node->Attribute("name"); if (type_name == nullptr) return Error(ErrorCode::MISSING_ATTRIBUTE, "name"); - mEntrypoints.emplace(type_name); + mData->mEntrypoints.emplace(type_name); } else @@ -694,18 +743,18 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co return Error(ErrorCode::OK); // TODO: write debug warning if we modify an existing entry - Function& func = mFunctions[name]; + Function& func = mData->mFunctions[name]; for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) { const std::string functionnodename = functionnode->Name(); if (functionnodename == "noreturn") { const char * const text = functionnode->GetText(); if (strcmp(text, "false") == 0) - mNoReturn[name] = FalseTrueMaybe::False; + mData->mNoReturn[name] = FalseTrueMaybe::False; else if (strcmp(text, "maybe") == 0) - mNoReturn[name] = FalseTrueMaybe::Maybe; + mData->mNoReturn[name] = FalseTrueMaybe::Maybe; else - mNoReturn[name] = FalseTrueMaybe::True; // Safe + mData->mNoReturn[name] = FalseTrueMaybe::True; // Safe } else if (functionnodename == "pure") func.ispure = true; else if (functionnodename == "const") { @@ -720,7 +769,7 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co nonOverlappingData.sizeArg = functionnode->IntAttribute("size-arg", -1); nonOverlappingData.strlenArg = functionnode->IntAttribute("strlen-arg", -1); nonOverlappingData.countArg = functionnode->IntAttribute("count-arg", -1); - mNonOverlappingData[name] = nonOverlappingData; + mData->mNonOverlappingData[name] = nonOverlappingData; } else if (functionnodename == "use-retval") { func.useretval = Library::UseRetValType::DEFAULT; if (const char *type = functionnode->Attribute("type")) @@ -728,16 +777,16 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co func.useretval = Library::UseRetValType::ERROR_CODE; } else if (functionnodename == "returnValue") { if (const char *expr = functionnode->GetText()) - mReturnValue[name] = expr; + mData->mReturnValue[name] = expr; if (const char *type = functionnode->Attribute("type")) - mReturnValueType[name] = type; + mData->mReturnValueType[name] = type; if (const char *container = functionnode->Attribute("container")) - mReturnValueContainer[name] = strToInt(container); + mData->mReturnValueContainer[name] = strToInt(container); // cppcheck-suppress shadowFunction - TODO: fix this if (const char *unknownReturnValues = functionnode->Attribute("unknownValues")) { if (std::strcmp(unknownReturnValues, "all") == 0) { std::vector values{LLONG_MIN, LLONG_MAX}; - mUnknownReturnValues[name] = std::move(values); + mData->mUnknownReturnValues[name] = std::move(values); } } } else if (functionnodename == "arg") { @@ -1011,7 +1060,7 @@ std::string Library::getFunctionName(const Token *ftok, bool &error) const tok = tok->next(); } name += "::" + ftok->str(); - if (mFunctions.find(name) != mFunctions.end() && matchArguments(ftok, name)) + if (mData->mFunctions.find(name) != mData->mFunctions.end() && matchArguments(ftok, name)) return name; } } @@ -1072,8 +1121,8 @@ bool Library::isnullargbad(const Token *ftok, int argnr) const if (!arg) { // scan format string argument should not be null const std::string funcname = getFunctionName(ftok); - const std::unordered_map::const_iterator it = mFunctions.find(funcname); - if (it != mFunctions.cend() && it->second.formatstr && it->second.formatstr_scan) + const std::unordered_map::const_iterator it = mData->mFunctions.find(funcname); + if (it != mData->mFunctions.cend() && it->second.formatstr && it->second.formatstr_scan) return true; } return arg && arg->notnull; @@ -1085,8 +1134,8 @@ bool Library::isuninitargbad(const Token *ftok, int argnr, int indirect, bool *h if (!arg) { // non-scan format string argument should not be uninitialized const std::string funcname = getFunctionName(ftok); - const std::unordered_map::const_iterator it = mFunctions.find(funcname); - if (it != mFunctions.cend() && it->second.formatstr && !it->second.formatstr_scan) + const std::unordered_map::const_iterator it = mData->mFunctions.find(funcname); + if (it != mData->mFunctions.cend() && it->second.formatstr && !it->second.formatstr_scan) return true; } if (hasIndirect && arg && arg->notuninit >= 1) @@ -1101,7 +1150,7 @@ const Library::AllocFunc* Library::getAllocFuncInfo(const Token *tok) const while (Token::simpleMatch(tok, "::")) tok = tok->astOperand2() ? tok->astOperand2() : tok->astOperand1(); const std::string funcname = getFunctionName(tok); - return isNotLibraryFunction(tok) && mFunctions.find(funcname) != mFunctions.end() ? nullptr : getAllocDealloc(mAlloc, funcname); + return isNotLibraryFunction(tok) && mData->mFunctions.find(funcname) != mData->mFunctions.end() ? nullptr : getAllocDealloc(mData->mAlloc, funcname); } /** get deallocation info for function */ @@ -1110,7 +1159,7 @@ const Library::AllocFunc* Library::getDeallocFuncInfo(const Token *tok) const while (Token::simpleMatch(tok, "::")) tok = tok->astOperand2() ? tok->astOperand2() : tok->astOperand1(); const std::string funcname = getFunctionName(tok); - return isNotLibraryFunction(tok) && mFunctions.find(funcname) != mFunctions.end() ? nullptr : getAllocDealloc(mDealloc, funcname); + return isNotLibraryFunction(tok) && mData->mFunctions.find(funcname) != mData->mFunctions.end() ? nullptr : getAllocDealloc(mData->mDealloc, funcname); } /** get reallocation info for function */ @@ -1119,7 +1168,7 @@ const Library::AllocFunc* Library::getReallocFuncInfo(const Token *tok) const while (Token::simpleMatch(tok, "::")) tok = tok->astOperand2() ? tok->astOperand2() : tok->astOperand1(); const std::string funcname = getFunctionName(tok); - return isNotLibraryFunction(tok) && mFunctions.find(funcname) != mFunctions.end() ? nullptr : getAllocDealloc(mRealloc, funcname); + return isNotLibraryFunction(tok) && mData->mFunctions.find(funcname) != mData->mFunctions.end() ? nullptr : getAllocDealloc(mData->mRealloc, funcname); } /** get allocation id for function */ @@ -1148,8 +1197,8 @@ const Library::ArgumentChecks * Library::getarg(const Token *ftok, int argnr) co { if (isNotLibraryFunction(ftok)) return nullptr; - const std::unordered_map::const_iterator it1 = mFunctions.find(getFunctionName(ftok)); - if (it1 == mFunctions.cend()) + const std::unordered_map::const_iterator it1 = mData->mFunctions.find(getFunctionName(ftok)); + if (it1 == mData->mFunctions.cend()) return nullptr; const std::map::const_iterator it2 = it1->second.argumentChecks.find(argnr); if (it2 != it1->second.argumentChecks.cend()) @@ -1204,7 +1253,7 @@ bool Library::isScopeNoReturn(const Token *end, std::string *unknownFunc) const // cppcheck-suppress unusedFunction - used in tests only const std::unordered_map& Library::containers() const { - return mContainers; + return mData->mContainers; } const Library::Container* Library::detectContainerInternal(const Token* const typeStart, DetectContainer detect, bool* isIterator, bool withoutStd) const @@ -1218,7 +1267,7 @@ const Library::Container* Library::detectContainerInternal(const Token* const ty break; } - for (const std::pair & c : mContainers) { + for (const std::pair & c : mData->mContainers) { const Container& container = c.second; if (container.startPattern.empty()) continue; @@ -1331,8 +1380,8 @@ bool Library::matchArguments(const Token *ftok, const std::string &functionName) if (functionName.empty()) return false; const int callargs = numberOfArgumentsWithoutAst(ftok); - const std::unordered_map::const_iterator it = mFunctions.find(functionName); - if (it == mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(functionName); + if (it == mData->mFunctions.cend()) return false; int args = 0; int firstOptionalArg = -1; @@ -1408,15 +1457,15 @@ bool Library::formatstr_function(const Token* ftok) const if (isNotLibraryFunction(ftok)) return false; - const std::unordered_map::const_iterator it = mFunctions.find(getFunctionName(ftok)); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(getFunctionName(ftok)); + if (it != mData->mFunctions.cend()) return it->second.formatstr; return false; } int Library::formatstr_argno(const Token* ftok) const { - const std::map& argumentChecksFunc = mFunctions.at(getFunctionName(ftok)).argumentChecks; + const std::map& argumentChecksFunc = mData->mFunctions.at(getFunctionName(ftok)).argumentChecks; auto it = std::find_if(argumentChecksFunc.cbegin(), argumentChecksFunc.cend(), [](const std::pair& a) { return a.second.formatstr; }); @@ -1425,20 +1474,20 @@ int Library::formatstr_argno(const Token* ftok) const bool Library::formatstr_scan(const Token* ftok) const { - return mFunctions.at(getFunctionName(ftok)).formatstr_scan; + return mData->mFunctions.at(getFunctionName(ftok)).formatstr_scan; } bool Library::formatstr_secure(const Token* ftok) const { - return mFunctions.at(getFunctionName(ftok)).formatstr_secure; + return mData->mFunctions.at(getFunctionName(ftok)).formatstr_secure; } const Library::NonOverlappingData* Library::getNonOverlappingData(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return nullptr; - const std::unordered_map::const_iterator it = mNonOverlappingData.find(getFunctionName(ftok)); - return (it != mNonOverlappingData.cend()) ? &it->second : nullptr; + const std::unordered_map::const_iterator it = mData->mNonOverlappingData.find(getFunctionName(ftok)); + return (it != mData->mNonOverlappingData.cend()) ? &it->second : nullptr; } Library::UseRetValType Library::getUseRetValType(const Token *ftok) const @@ -1455,8 +1504,8 @@ Library::UseRetValType Library::getUseRetValType(const Token *ftok) const } return Library::UseRetValType::NONE; } - const std::unordered_map::const_iterator it = mFunctions.find(getFunctionName(ftok)); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(getFunctionName(ftok)); + if (it != mData->mFunctions.cend()) return it->second.useretval; return Library::UseRetValType::NONE; } @@ -1465,8 +1514,8 @@ const std::string& Library::returnValue(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return emptyString; - const std::map::const_iterator it = mReturnValue.find(getFunctionName(ftok)); - return it != mReturnValue.cend() ? it->second : emptyString; + const std::map::const_iterator it = mData->mReturnValue.find(getFunctionName(ftok)); + return it != mData->mReturnValue.cend() ? it->second : emptyString; } const std::string& Library::returnValueType(const Token *ftok) const @@ -1479,32 +1528,32 @@ const std::string& Library::returnValueType(const Token *ftok) const } return emptyString; } - const std::map::const_iterator it = mReturnValueType.find(getFunctionName(ftok)); - return it != mReturnValueType.cend() ? it->second : emptyString; + const std::map::const_iterator it = mData->mReturnValueType.find(getFunctionName(ftok)); + return it != mData->mReturnValueType.cend() ? it->second : emptyString; } int Library::returnValueContainer(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return -1; - const std::map::const_iterator it = mReturnValueContainer.find(getFunctionName(ftok)); - return it != mReturnValueContainer.cend() ? it->second : -1; + const std::map::const_iterator it = mData->mReturnValueContainer.find(getFunctionName(ftok)); + return it != mData->mReturnValueContainer.cend() ? it->second : -1; } std::vector Library::unknownReturnValues(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return std::vector(); - const std::map>::const_iterator it = mUnknownReturnValues.find(getFunctionName(ftok)); - return (it == mUnknownReturnValues.cend()) ? std::vector() : it->second; + const std::map>::const_iterator it = mData->mUnknownReturnValues.find(getFunctionName(ftok)); + return (it == mData->mUnknownReturnValues.cend()) ? std::vector() : it->second; } const Library::Function *Library::getFunction(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return nullptr; - const std::unordered_map::const_iterator it1 = mFunctions.find(getFunctionName(ftok)); - if (it1 == mFunctions.cend()) + const std::unordered_map::const_iterator it1 = mData->mFunctions.find(getFunctionName(ftok)); + if (it1 == mData->mFunctions.cend()) return nullptr; return &it1->second; } @@ -1514,8 +1563,8 @@ bool Library::hasminsize(const Token *ftok) const { if (isNotLibraryFunction(ftok)) return false; - const std::unordered_map::const_iterator it = mFunctions.find(getFunctionName(ftok)); - if (it == mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(getFunctionName(ftok)); + if (it == mData->mFunctions.cend()) return false; return std::any_of(it->second.argumentChecks.cbegin(), it->second.argumentChecks.cend(), [](const std::pair& a) { return !a.second.minsizes.empty(); @@ -1543,33 +1592,33 @@ Library::ArgumentChecks::Direction Library::getArgDirection(const Token* ftok, i bool Library::ignorefunction(const std::string& functionName) const { - const std::unordered_map::const_iterator it = mFunctions.find(functionName); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(functionName); + if (it != mData->mFunctions.cend()) return it->second.ignore; return false; } const std::unordered_map& Library::functions() const { - return mFunctions; + return mData->mFunctions; } bool Library::isUse(const std::string& functionName) const { - const std::unordered_map::const_iterator it = mFunctions.find(functionName); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(functionName); + if (it != mData->mFunctions.cend()) return it->second.use; return false; } bool Library::isLeakIgnore(const std::string& functionName) const { - const std::unordered_map::const_iterator it = mFunctions.find(functionName); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(functionName); + if (it != mData->mFunctions.cend()) return it->second.leakignore; return false; } bool Library::isFunctionConst(const std::string& functionName, bool pure) const { - const std::unordered_map::const_iterator it = mFunctions.find(functionName); - if (it != mFunctions.cend()) + const std::unordered_map::const_iterator it = mData->mFunctions.find(functionName); + if (it != mData->mFunctions.cend()) return pure ? it->second.ispure : it->second.isconst; return false; } @@ -1586,8 +1635,8 @@ bool Library::isFunctionConst(const Token *ftok) const } return false; } - const std::unordered_map::const_iterator it = mFunctions.find(getFunctionName(ftok)); - return (it != mFunctions.cend() && it->second.isconst); + const std::unordered_map::const_iterator it = mData->mFunctions.find(getFunctionName(ftok)); + return (it != mData->mFunctions.cend() && it->second.isconst); } bool Library::isnoreturn(const Token *ftok) const @@ -1603,8 +1652,8 @@ bool Library::isnoreturn(const Token *ftok) const } return false; } - const std::unordered_map::const_iterator it = mNoReturn.find(getFunctionName(ftok)); - if (it == mNoReturn.end()) + const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); + if (it == mData->mNoReturn.end()) return false; if (it->second == FalseTrueMaybe::Maybe) return true; @@ -1617,8 +1666,8 @@ bool Library::isnotnoreturn(const Token *ftok) const return false; if (isNotLibraryFunction(ftok)) return false; - const std::unordered_map::const_iterator it = mNoReturn.find(getFunctionName(ftok)); - if (it == mNoReturn.end()) + const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); + if (it == mData->mNoReturn.end()) return false; if (it->second == FalseTrueMaybe::Maybe) return false; @@ -1627,34 +1676,34 @@ bool Library::isnotnoreturn(const Token *ftok) const bool Library::markupFile(const std::string &path) const { - return mMarkupExtensions.find(Path::getFilenameExtensionInLowerCase(path)) != mMarkupExtensions.end(); + return mData->mMarkupExtensions.find(Path::getFilenameExtensionInLowerCase(path)) != mData->mMarkupExtensions.end(); } bool Library::processMarkupAfterCode(const std::string &path) const { - const std::map::const_iterator it = mProcessAfterCode.find(Path::getFilenameExtensionInLowerCase(path)); - return (it == mProcessAfterCode.cend() || it->second); + const std::map::const_iterator it = mData->mProcessAfterCode.find(Path::getFilenameExtensionInLowerCase(path)); + return (it == mData->mProcessAfterCode.cend() || it->second); } bool Library::reportErrors(const std::string &path) const { - const std::map::const_iterator it = mReportErrors.find(Path::getFilenameExtensionInLowerCase(path)); - return (it == mReportErrors.cend() || it->second); + const std::map::const_iterator it = mData->mReportErrors.find(Path::getFilenameExtensionInLowerCase(path)); + return (it == mData->mReportErrors.cend() || it->second); } bool Library::isexecutableblock(const std::string &file, const std::string &token) const { - const std::unordered_map::const_iterator it = mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); - return (it != mExecutableBlocks.cend() && it->second.isBlock(token)); + const std::unordered_map::const_iterator it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); + return (it != mData->mExecutableBlocks.cend() && it->second.isBlock(token)); } int Library::blockstartoffset(const std::string &file) const { int offset = -1; const std::unordered_map::const_iterator map_it - = mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); + = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); - if (map_it != mExecutableBlocks.end()) { + if (map_it != mData->mExecutableBlocks.end()) { offset = map_it->second.offset(); } return offset; @@ -1663,9 +1712,9 @@ int Library::blockstartoffset(const std::string &file) const const std::string& Library::blockstart(const std::string &file) const { const std::unordered_map::const_iterator map_it - = mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); + = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); - if (map_it != mExecutableBlocks.end()) { + if (map_it != mData->mExecutableBlocks.end()) { return map_it->second.start(); } return emptyString; @@ -1674,9 +1723,9 @@ const std::string& Library::blockstart(const std::string &file) const const std::string& Library::blockend(const std::string &file) const { const std::unordered_map::const_iterator map_it - = mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); + = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); - if (map_it != mExecutableBlocks.end()) { + if (map_it != mData->mExecutableBlocks.end()) { return map_it->second.end(); } return emptyString; @@ -1685,15 +1734,15 @@ const std::string& Library::blockend(const std::string &file) const bool Library::iskeyword(const std::string &file, const std::string &keyword) const { const std::map>::const_iterator it = - mKeywords.find(Path::getFilenameExtensionInLowerCase(file)); - return (it != mKeywords.end() && it->second.count(keyword)); + mData->mKeywords.find(Path::getFilenameExtensionInLowerCase(file)); + return (it != mData->mKeywords.end() && it->second.count(keyword)); } bool Library::isimporter(const std::string& file, const std::string &importer) const { const std::map>::const_iterator it = - mImporters.find(Path::getFilenameExtensionInLowerCase(file)); - return (it != mImporters.end() && it->second.count(importer) > 0); + mData->mImporters.find(Path::getFilenameExtensionInLowerCase(file)); + return (it != mData->mImporters.end() && it->second.count(importer) > 0); } const Token* Library::getContainerFromYield(const Token* tok, Library::Container::Yield yield) const @@ -1747,7 +1796,7 @@ const Token* Library::getContainerFromAction(const Token* tok, Library::Containe const std::unordered_map& Library::smartPointers() const { - return mSmartPointers; + return mData->mSmartPointers; } bool Library::isSmartPointer(const Token* tok) const @@ -1762,8 +1811,8 @@ const Library::SmartPointer* Library::detectSmartPointer(const Token* tok, bool typestr += tok->str(); tok = tok->next(); } - auto it = mSmartPointers.find(typestr); - if (it == mSmartPointers.end()) + auto it = mData->mSmartPointers.find(typestr); + if (it == mData->mSmartPointers.end()) return nullptr; return &it->second; } @@ -1790,13 +1839,13 @@ const Library::Container * getLibraryContainer(const Token * tok) Library::TypeCheck Library::getTypeCheck(std::string check, std::string typeName) const { - auto it = mTypeChecks.find(std::pair(std::move(check), std::move(typeName))); - return it == mTypeChecks.end() ? TypeCheck::def : it->second; + auto it = mData->mTypeChecks.find(std::pair(std::move(check), std::move(typeName))); + return it == mData->mTypeChecks.end() ? TypeCheck::def : it->second; } bool Library::hasAnyTypeCheck(const std::string& typeName) const { - return std::any_of(mTypeChecks.begin(), mTypeChecks.end(), [&](const std::pair, Library::TypeCheck>& tc) { + return std::any_of(mData->mTypeChecks.begin(), mData->mTypeChecks.end(), [&](const std::pair, Library::TypeCheck>& tc) { return tc.first.second == typeName; }); } @@ -1852,82 +1901,82 @@ std::shared_ptr createTokenFromExpression(const std::string& returnValue, const Library::AllocFunc* Library::getAllocFuncInfo(const char name[]) const { - return getAllocDealloc(mAlloc, name); + return getAllocDealloc(mData->mAlloc, name); } const Library::AllocFunc* Library::getDeallocFuncInfo(const char name[]) const { - return getAllocDealloc(mDealloc, name); + return getAllocDealloc(mData->mDealloc, name); } // cppcheck-suppress unusedFunction int Library::allocId(const char name[]) const { - const AllocFunc* af = getAllocDealloc(mAlloc, name); + const AllocFunc* af = getAllocDealloc(mData->mAlloc, name); return af ? af->groupId : 0; } int Library::deallocId(const char name[]) const { - const AllocFunc* af = getAllocDealloc(mDealloc, name); + const AllocFunc* af = getAllocDealloc(mData->mDealloc, name); return af ? af->groupId : 0; } const std::set &Library::markupExtensions() const { - return mMarkupExtensions; + return mData->mMarkupExtensions; } bool Library::isexporter(const std::string &prefix) const { - return mExporters.find(prefix) != mExporters.end(); + return mData->mExporters.find(prefix) != mData->mExporters.end(); } bool Library::isexportedprefix(const std::string &prefix, const std::string &token) const { - const std::map::const_iterator it = mExporters.find(prefix); - return (it != mExporters.end() && it->second.isPrefix(token)); + const std::map::const_iterator it = mData->mExporters.find(prefix); + return (it != mData->mExporters.end() && it->second.isPrefix(token)); } bool Library::isexportedsuffix(const std::string &prefix, const std::string &token) const { - const std::map::const_iterator it = mExporters.find(prefix); - return (it != mExporters.end() && it->second.isSuffix(token)); + const std::map::const_iterator it = mData->mExporters.find(prefix); + return (it != mData->mExporters.end() && it->second.isSuffix(token)); } bool Library::isreflection(const std::string &token) const { - return mReflection.find(token) != mReflection.end(); + return mData->mReflection.find(token) != mData->mReflection.end(); } int Library::reflectionArgument(const std::string &token) const { - const std::map::const_iterator it = mReflection.find(token); - if (it != mReflection.end()) + const std::map::const_iterator it = mData->mReflection.find(token); + if (it != mData->mReflection.end()) return it->second; return -1; } bool Library::isentrypoint(const std::string &func) const { - return func == "main" || mEntrypoints.find(func) != mEntrypoints.end(); + return func == "main" || mData->mEntrypoints.find(func) != mData->mEntrypoints.end(); } const Library::PodType *Library::podtype(const std::string &name) const { - const std::unordered_map::const_iterator it = mPodTypes.find(name); - return (it != mPodTypes.end()) ? &(it->second) : nullptr; + const std::unordered_map::const_iterator it = mData->mPodTypes.find(name); + return (it != mData->mPodTypes.end()) ? &(it->second) : nullptr; } const Library::PlatformType *Library::platform_type(const std::string &name, const std::string & platform) const { - const std::map::const_iterator it = mPlatforms.find(platform); - if (it != mPlatforms.end()) { + const std::map::const_iterator it = mData->mPlatforms.find(platform); + if (it != mData->mPlatforms.end()) { const PlatformType * const type = it->second.platform_type(name); if (type) return type; } - const std::map::const_iterator it2 = mPlatformTypes.find(name); - return (it2 != mPlatformTypes.end()) ? &(it2->second) : nullptr; + const std::map::const_iterator it2 = mData->mPlatformTypes.find(name); + return (it2 != mData->mPlatformTypes.end()) ? &(it2->second) : nullptr; } diff --git a/lib/library.h b/lib/library.h index 8909391da4a..51a85eb4a3d 100644 --- a/lib/library.h +++ b/lib/library.h @@ -25,13 +25,13 @@ #include "mathlib.h" #include "standards.h" +#include #include #include #include #include #include #include -#include #include #include @@ -54,7 +54,11 @@ class CPPCHECKLIB Library { friend struct LibraryHelper; // for testing public: - Library() = default; + Library(); + ~Library(); + + Library(const Library& other); + Library& operator=(const Library& other); enum class ErrorCode : std::uint8_t { OK, @@ -523,34 +527,10 @@ class CPPCHECKLIB Library { int mOffset{}; std::set mBlocks; }; - std::unordered_map mContainers; - std::unordered_map mFunctions; - std::unordered_map mSmartPointers; enum class FalseTrueMaybe : std::uint8_t { False, True, Maybe }; - int mAllocId{}; - std::set mFiles; - std::map mAlloc; // allocation functions - std::map mDealloc; // deallocation functions - std::map mRealloc; // reallocation functions - std::unordered_map mNoReturn; // is function noreturn? - std::map mReturnValue; - std::map mReturnValueType; - std::map mReturnValueContainer; - std::map> mUnknownReturnValues; - std::map mReportErrors; - std::map mProcessAfterCode; - std::set mMarkupExtensions; // file extensions of markup files - std::map> mKeywords; // keywords for code in the library - std::unordered_map mExecutableBlocks; // keywords for blocks of executable code - std::map mExporters; // keywords that export variables/functions to libraries (meta-code/macros) - std::map> mImporters; // keywords that import variables/functions - std::map mReflection; // invocation of reflection - std::unordered_map mPodTypes; // pod types - std::map mPlatformTypes; // platform independent typedefs - std::map mPlatforms; // platform dependent typedefs - std::map, TypeCheck> mTypeChecks; - std::unordered_map mNonOverlappingData; - std::unordered_set mEntrypoints; + + struct LibraryData; + std::unique_ptr mData; const ArgumentChecks * getarg(const Token *ftok, int argnr) const; diff --git a/test/testlibrary.cpp b/test/testlibrary.cpp index bdbe8670fc3..f8843b51e6b 100644 --- a/test/testlibrary.cpp +++ b/test/testlibrary.cpp @@ -244,13 +244,14 @@ class TestLibrary : public TestFixture { Library library; ASSERT(LibraryHelper::loadxmldata(library, xmldata, sizeof(xmldata))); - ASSERT_EQUALS(0, library.functions().at("foo").argumentChecks.at(1).notuninit); - ASSERT_EQUALS(true, library.functions().at("foo").argumentChecks.at(2).notnull); - ASSERT_EQUALS(true, library.functions().at("foo").argumentChecks.at(3).formatstr); - ASSERT_EQUALS(true, library.functions().at("foo").argumentChecks.at(4).strz); - ASSERT_EQUALS(false, library.functions().at("foo").argumentChecks.at(4).optional); - ASSERT_EQUALS(true, library.functions().at("foo").argumentChecks.at(5).notbool); - ASSERT_EQUALS(true, library.functions().at("foo").argumentChecks.at(5).optional); + const auto& foo_fn_args = library.functions().at("foo").argumentChecks; + ASSERT_EQUALS(0, foo_fn_args.at(1).notuninit); + ASSERT_EQUALS(true, foo_fn_args.at(2).notnull); + ASSERT_EQUALS(true, foo_fn_args.at(3).formatstr); + ASSERT_EQUALS(true, foo_fn_args.at(4).strz); + ASSERT_EQUALS(false, foo_fn_args.at(4).optional); + ASSERT_EQUALS(true, foo_fn_args.at(5).notbool); + ASSERT_EQUALS(true, foo_fn_args.at(5).optional); } void function_arg_any() const { From 9b547de418fa782484b5911a4d86a677c5712ce0 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 9 Jul 2024 14:29:01 +0200 Subject: [PATCH 2/3] Library: moved more data into the source file --- lib/library.cpp | 98 +++++++++++++++++++++++++++++++++++++++++-------- lib/library.h | 64 -------------------------------- 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/lib/library.cpp b/lib/library.cpp index 8bf6e4b7bb9..e4a9284500f 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -46,6 +46,72 @@ struct Library::LibraryData { + struct Platform { + const PlatformType *platform_type(const std::string &name) const { + const std::map::const_iterator it = mPlatformTypes.find(name); + return (it != mPlatformTypes.end()) ? &(it->second) : nullptr; + } + std::map mPlatformTypes; + }; + + class ExportedFunctions { + public: + void addPrefix(std::string prefix) { + mPrefixes.insert(std::move(prefix)); + } + void addSuffix(std::string suffix) { + mSuffixes.insert(std::move(suffix)); + } + bool isPrefix(const std::string& prefix) const { + return (mPrefixes.find(prefix) != mPrefixes.end()); + } + bool isSuffix(const std::string& suffix) const { + return (mSuffixes.find(suffix) != mSuffixes.end()); + } + + private: + std::set mPrefixes; + std::set mSuffixes; + }; + + class CodeBlock { + public: + CodeBlock() = default; + + void setStart(const char* s) { + mStart = s; + } + void setEnd(const char* e) { + mEnd = e; + } + void setOffset(const int o) { + mOffset = o; + } + void addBlock(const char* blockName) { + mBlocks.insert(blockName); + } + const std::string& start() const { + return mStart; + } + const std::string& end() const { + return mEnd; + } + int offset() const { + return mOffset; + } + bool isBlock(const std::string& blockName) const { + return mBlocks.find(blockName) != mBlocks.end(); + } + + private: + std::string mStart; + std::string mEnd; + int mOffset{}; + std::set mBlocks; + }; + + enum class FalseTrueMaybe : std::uint8_t { False, True, Maybe }; + std::unordered_map mContainers; std::unordered_map mFunctions; std::unordered_map mSmartPointers; @@ -750,11 +816,11 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co if (functionnodename == "noreturn") { const char * const text = functionnode->GetText(); if (strcmp(text, "false") == 0) - mData->mNoReturn[name] = FalseTrueMaybe::False; + mData->mNoReturn[name] = LibraryData::FalseTrueMaybe::False; else if (strcmp(text, "maybe") == 0) - mData->mNoReturn[name] = FalseTrueMaybe::Maybe; + mData->mNoReturn[name] = LibraryData::FalseTrueMaybe::Maybe; else - mData->mNoReturn[name] = FalseTrueMaybe::True; // Safe + mData->mNoReturn[name] = LibraryData::FalseTrueMaybe::True; // Safe } else if (functionnodename == "pure") func.ispure = true; else if (functionnodename == "const") { @@ -1652,12 +1718,12 @@ bool Library::isnoreturn(const Token *ftok) const } return false; } - const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); + const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); if (it == mData->mNoReturn.end()) return false; - if (it->second == FalseTrueMaybe::Maybe) + if (it->second == LibraryData::FalseTrueMaybe::Maybe) return true; - return it->second == FalseTrueMaybe::True; + return it->second == LibraryData::FalseTrueMaybe::True; } bool Library::isnotnoreturn(const Token *ftok) const @@ -1666,12 +1732,12 @@ bool Library::isnotnoreturn(const Token *ftok) const return false; if (isNotLibraryFunction(ftok)) return false; - const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); + const std::unordered_map::const_iterator it = mData->mNoReturn.find(getFunctionName(ftok)); if (it == mData->mNoReturn.end()) return false; - if (it->second == FalseTrueMaybe::Maybe) + if (it->second == LibraryData::FalseTrueMaybe::Maybe) return false; - return it->second == FalseTrueMaybe::False; + return it->second == LibraryData::FalseTrueMaybe::False; } bool Library::markupFile(const std::string &path) const @@ -1693,14 +1759,14 @@ bool Library::reportErrors(const std::string &path) const bool Library::isexecutableblock(const std::string &file, const std::string &token) const { - const std::unordered_map::const_iterator it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); + const std::unordered_map::const_iterator it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); return (it != mData->mExecutableBlocks.cend() && it->second.isBlock(token)); } int Library::blockstartoffset(const std::string &file) const { int offset = -1; - const std::unordered_map::const_iterator map_it + const std::unordered_map::const_iterator map_it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); if (map_it != mData->mExecutableBlocks.end()) { @@ -1711,7 +1777,7 @@ int Library::blockstartoffset(const std::string &file) const const std::string& Library::blockstart(const std::string &file) const { - const std::unordered_map::const_iterator map_it + const std::unordered_map::const_iterator map_it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); if (map_it != mData->mExecutableBlocks.end()) { @@ -1722,7 +1788,7 @@ const std::string& Library::blockstart(const std::string &file) const const std::string& Library::blockend(const std::string &file) const { - const std::unordered_map::const_iterator map_it + const std::unordered_map::const_iterator map_it = mData->mExecutableBlocks.find(Path::getFilenameExtensionInLowerCase(file)); if (map_it != mData->mExecutableBlocks.end()) { @@ -1934,13 +2000,13 @@ bool Library::isexporter(const std::string &prefix) const bool Library::isexportedprefix(const std::string &prefix, const std::string &token) const { - const std::map::const_iterator it = mData->mExporters.find(prefix); + const std::map::const_iterator it = mData->mExporters.find(prefix); return (it != mData->mExporters.end() && it->second.isPrefix(token)); } bool Library::isexportedsuffix(const std::string &prefix, const std::string &token) const { - const std::map::const_iterator it = mData->mExporters.find(prefix); + const std::map::const_iterator it = mData->mExporters.find(prefix); return (it != mData->mExporters.end() && it->second.isSuffix(token)); } @@ -1970,7 +2036,7 @@ const Library::PodType *Library::podtype(const std::string &name) const const Library::PlatformType *Library::platform_type(const std::string &name, const std::string & platform) const { - const std::map::const_iterator it = mData->mPlatforms.find(platform); + const std::map::const_iterator it = mData->mPlatforms.find(platform); if (it != mData->mPlatforms.end()) { const PlatformType * const type = it->second.platform_type(name); if (type) diff --git a/lib/library.h b/lib/library.h index 51a85eb4a3d..b037c51e6c5 100644 --- a/lib/library.h +++ b/lib/library.h @@ -442,14 +442,6 @@ class CPPCHECKLIB Library { bool mConstPtr{}; }; - struct Platform { - const PlatformType *platform_type(const std::string &name) const { - const std::map::const_iterator it = mPlatformTypes.find(name); - return (it != mPlatformTypes.end()) ? &(it->second) : nullptr; - } - std::map mPlatformTypes; - }; - const PlatformType *platform_type(const std::string &name, const std::string & platform) const; /** @@ -473,62 +465,6 @@ class CPPCHECKLIB Library { // load a xml node Error loadFunction(const tinyxml2::XMLElement * const node, const std::string &name, std::set &unknown_elements); - class ExportedFunctions { - public: - void addPrefix(std::string prefix) { - mPrefixes.insert(std::move(prefix)); - } - void addSuffix(std::string suffix) { - mSuffixes.insert(std::move(suffix)); - } - bool isPrefix(const std::string& prefix) const { - return (mPrefixes.find(prefix) != mPrefixes.end()); - } - bool isSuffix(const std::string& suffix) const { - return (mSuffixes.find(suffix) != mSuffixes.end()); - } - - private: - std::set mPrefixes; - std::set mSuffixes; - }; - class CodeBlock { - public: - CodeBlock() = default; - - void setStart(const char* s) { - mStart = s; - } - void setEnd(const char* e) { - mEnd = e; - } - void setOffset(const int o) { - mOffset = o; - } - void addBlock(const char* blockName) { - mBlocks.insert(blockName); - } - const std::string& start() const { - return mStart; - } - const std::string& end() const { - return mEnd; - } - int offset() const { - return mOffset; - } - bool isBlock(const std::string& blockName) const { - return mBlocks.find(blockName) != mBlocks.end(); - } - - private: - std::string mStart; - std::string mEnd; - int mOffset{}; - std::set mBlocks; - }; - enum class FalseTrueMaybe : std::uint8_t { False, True, Maybe }; - struct LibraryData; std::unique_ptr mData; From 59b0f3bc206dd8ef22360c1b23d364ae610a445f Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 9 Jul 2024 15:51:54 +0200 Subject: [PATCH 3/3] Library: got rid of remaining public members --- lib/checkfunctions.h | 2 +- lib/library.cpp | 21 +++++++++++++++++---- lib/library.h | 4 ++-- lib/preprocessor.cpp | 2 +- test/testlibrary.cpp | 8 ++++---- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/checkfunctions.h b/lib/checkfunctions.h index 2519c5ca4b4..7ab34209a84 100644 --- a/lib/checkfunctions.h +++ b/lib/checkfunctions.h @@ -129,7 +129,7 @@ class CPPCHECKLIB CheckFunctions : public Check { void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override { CheckFunctions c(nullptr, settings, errorLogger); - for (std::map::const_iterator i = settings->library.functionwarn.cbegin(); i != settings->library.functionwarn.cend(); ++i) { + for (std::map::const_iterator i = settings->library.functionwarn().cbegin(); i != settings->library.functionwarn().cend(); ++i) { c.reportError(nullptr, Severity::style, i->first+"Called", i->second.message); } diff --git a/lib/library.cpp b/lib/library.cpp index e4a9284500f..562e0b858f1 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -112,6 +112,9 @@ struct Library::LibraryData enum class FalseTrueMaybe : std::uint8_t { False, True, Maybe }; + std::map mFunctionwarn; + std::set mDefines; + std::unordered_map mContainers; std::unordered_map mFunctions; std::unordered_map mSmartPointers; @@ -428,7 +431,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char *value = node->Attribute("value"); if (value == nullptr) return Error(ErrorCode::MISSING_ATTRIBUTE, "value"); - auto result = defines.insert(std::string(name) + " " + value); + auto result = mData->mDefines.insert(std::string(name) + " " + value); if (!result.second) return Error(ErrorCode::DUPLICATE_DEFINE, name); } @@ -1028,7 +1031,7 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co wi.message = message; } - functionwarn[name] = std::move(wi); + mData->mFunctionwarn[name] = std::move(wi); } else if (functionnodename == "container") { const char* const action_ptr = functionnode->Attribute("action"); Container::Action action = Container::Action::NO_ACTION; @@ -1463,12 +1466,17 @@ bool Library::matchArguments(const Token *ftok, const std::string &functionName) return (firstOptionalArg < 0) ? args == callargs : (callargs >= firstOptionalArg-1 && callargs <= args); } +const std::map& Library::functionwarn() const +{ + return mData->mFunctionwarn; +} + const Library::WarnInfo* Library::getWarnInfo(const Token* ftok) const { if (isNotLibraryFunction(ftok)) return nullptr; - const std::map::const_iterator i = functionwarn.find(getFunctionName(ftok)); - if (i == functionwarn.cend()) + const std::map::const_iterator i = mData->mFunctionwarn.find(getFunctionName(ftok)); + if (i == mData->mFunctionwarn.cend()) return nullptr; return &i->second; } @@ -2028,6 +2036,11 @@ bool Library::isentrypoint(const std::string &func) const return func == "main" || mData->mEntrypoints.find(func) != mData->mEntrypoints.end(); } +const std::set& Library::defines() const +{ + return mData->mDefines; +} + const Library::PodType *Library::podtype(const std::string &name) const { const std::unordered_map::const_iterator it = mData->mPodTypes.find(name); diff --git a/lib/library.h b/lib/library.h index b037c51e6c5..66af3c5ffc4 100644 --- a/lib/library.h +++ b/lib/library.h @@ -160,7 +160,7 @@ class CPPCHECKLIB Library { Standards standards; Severity severity; }; - std::map functionwarn; + const std::map& functionwarn() const; const WarnInfo* getWarnInfo(const Token* ftok) const; @@ -402,7 +402,7 @@ class CPPCHECKLIB Library { bool isentrypoint(const std::string &func) const; - std::set defines; // to provide some library defines + const std::set& defines() const; // to provide some library defines struct SmartPointer { std::string name; diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 58fb06ff0bf..eeb96362898 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -693,7 +693,7 @@ static simplecpp::DUI createDUI(const Settings &mSettings, const std::string &cf if (!cfg.empty()) splitcfg(cfg, dui.defines, emptyString); - for (const std::string &def : mSettings.library.defines) { + for (const std::string &def : mSettings.library.defines()) { const std::string::size_type pos = def.find_first_of(" ("); if (pos == std::string::npos) { dui.defines.push_back(def); diff --git a/test/testlibrary.cpp b/test/testlibrary.cpp index f8843b51e6b..11acc036428 100644 --- a/test/testlibrary.cpp +++ b/test/testlibrary.cpp @@ -623,7 +623,7 @@ class TestLibrary : public TestFixture { const Library::WarnInfo* a = library.getWarnInfo(tokenList.front()); const Library::WarnInfo* b = library.getWarnInfo(tokenList.front()->tokAt(4)); - ASSERT_EQUALS(2, library.functionwarn.size()); + ASSERT_EQUALS(2, library.functionwarn().size()); ASSERT(a && b); if (a && b) { ASSERT_EQUALS("Message", a->message); @@ -1050,15 +1050,15 @@ class TestLibrary : public TestFixture { void loadLibCombinations() const { { const Settings s = settingsBuilder().library("std.cfg").library("gnu.cfg").library("bsd.cfg").build(); - ASSERT_EQUALS(s.library.defines.empty(), false); + ASSERT_EQUALS(s.library.defines().empty(), false); } { const Settings s = settingsBuilder().library("std.cfg").library("microsoft_sal.cfg").build(); - ASSERT_EQUALS(s.library.defines.empty(), false); + ASSERT_EQUALS(s.library.defines().empty(), false); } { const Settings s = settingsBuilder().library("std.cfg").library("windows.cfg").library("mfc.cfg").build(); - ASSERT_EQUALS(s.library.defines.empty(), false); + ASSERT_EQUALS(s.library.defines().empty(), false); } } };