diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index c6e0b7f9ecd..b158ac48107 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -153,6 +153,36 @@ std::string SuppressionList::parseXmlFile(const char *filename) return ""; } +static std::string getExtraComment(const std::string &comment, std::string::size_type startPos, std::string::size_type *delimPos = nullptr) +{ + const std::string::size_type semiPos = comment.find(';', startPos); + const std::string::size_type slashPos = comment.find("//", startPos); + std::string::size_type pos; + + if (delimPos) + *delimPos = std::min(semiPos, slashPos); + + if (semiPos < slashPos) { + pos = semiPos + 1; + } else if (slashPos < semiPos) { + pos = slashPos + 2; + } else { + return ""; + } + + std::string extra = comment.substr(pos); + + if (startsWith(comment, "/*") && endsWith(comment, "*/")) + extra.erase(extra.size() - 2, 2); + + extra = trim(extra); + + for (auto it = extra.begin(); it != extra.end();) + it = (*it & 0x80) ? extra.erase(it) : it + 1; + + return extra; +} + std::vector SuppressionList::parseMultiSuppressComment(const std::string &comment, std::string *errorMessage) { std::vector suppressions; @@ -207,6 +237,14 @@ std::vector SuppressionList::parseMultiSuppressCom suppressions.push_back(std::move(s)); } + const std::string extraComment = getExtraComment(comment, end_position); + + if (extraComment.empty()) + return suppressions; + + for (auto &suppression : suppressions) + suppression.extraComment = extraComment; + return suppressions; } @@ -360,20 +398,11 @@ bool SuppressionList::Suppression::parseComment(std::string comment, std::string if (comment.compare(comment.size() - 2, 2, "*/") == 0) comment.erase(comment.size() - 2, 2); - std::string::size_type extraPos = comment.find(';'); - std::string::size_type extraDelimiterSize = 1; - - if (extraPos == std::string::npos) { - extraPos = comment.find("//", 2); - extraDelimiterSize = 2; - } + std::string::size_type extraPos; + extraComment = getExtraComment(comment, 2, &extraPos); - if (extraPos != std::string::npos) { - extraComment = trim(comment.substr(extraPos + extraDelimiterSize)); - for (auto it = extraComment.begin(); it != extraComment.end();) - it = *it & 0x80 ? extraComment.erase(it) : it + 1; + if (!extraComment.empty()) comment.erase(extraPos); - } const std::set cppchecksuppress{ "cppcheck-suppress", diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index de990c9fd91..22ab9e200b2 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -1240,14 +1240,37 @@ class TestSuppressions : public TestFixture { } void inlinesuppress_comment() const { - SuppressionList::Suppression s; std::string errMsg; - ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc ; some comment", &errMsg)); - ASSERT_EQUALS("", errMsg); - ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc // some comment", &errMsg)); - ASSERT_EQUALS("", errMsg); - ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc -- some comment", &errMsg)); - ASSERT_EQUALS("", errMsg); + { + SuppressionList::Suppression s; + ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc ; some comment // extra stuff", &errMsg)); + ASSERT_EQUALS("", errMsg); + ASSERT_EQUALS("some comment // extra stuff", s.extraComment); + } + { + SuppressionList::Suppression s; + ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc; some comment // extra stuff", &errMsg)); + ASSERT_EQUALS("", errMsg); + ASSERT_EQUALS("some comment // extra stuff", s.extraComment); + } + { + SuppressionList::Suppression s; + ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc // some comment ; extra stuff", &errMsg)); + ASSERT_EQUALS("", errMsg); + ASSERT_EQUALS("some comment ; extra stuff", s.extraComment); + } + { + SuppressionList::Suppression s; + ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc// some comment ; extra stuff", &errMsg)); + ASSERT_EQUALS("", errMsg); + ASSERT_EQUALS("some comment ; extra stuff", s.extraComment); + } + { + SuppressionList::Suppression s; + ASSERT_EQUALS(true, s.parseComment("// cppcheck-suppress abc -- some comment", &errMsg)); + ASSERT_EQUALS("", errMsg); + ASSERT_EQUALS("", s.extraComment); + } } // TODO: tests internal function - should it be private? @@ -1388,6 +1411,48 @@ class TestSuppressions : public TestFixture { suppressions=SuppressionList::parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr]*/", &errMsg); ASSERT_EQUALS(2, suppressions.size()); ASSERT_EQUALS(true, errMsg.empty()); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("//cppcheck-suppress[errorId1, errorId2 symbolName=arr] ; extra comment", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment", suppressions[1].extraComment); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("//cppcheck-suppress[errorId1, errorId2 symbolName=arr] // extra comment", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment", suppressions[1].extraComment); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr] ; extra comment */", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment", suppressions[1].extraComment); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr] // extra comment */", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment", suppressions[1].extraComment); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr] ; extra comment // more */", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment // more", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment // more", suppressions[1].extraComment); + + errMsg = ""; + suppressions=SuppressionList::parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr] // extra comment ; more */", &errMsg); + ASSERT_EQUALS(2, suppressions.size()); + ASSERT_EQUALS(true, errMsg.empty()); + ASSERT_EQUALS("extra comment ; more", suppressions[0].extraComment); + ASSERT_EQUALS("extra comment ; more", suppressions[1].extraComment); } void globalSuppressions() { // Testing that Cppcheck::useGlobalSuppressions works (#8515)