a new method to declare inline suppress which is more readable and more convenient. (#2533)
This commit is contained in:
parent
ef26b55737
commit
5479c7340b
|
@ -76,27 +76,69 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> *bad)
|
||||
static void parseCommentToken(const simplecpp::Token *tok, std::list<Suppressions::Suppression> &inlineSuppressions, std::list<BadInlineSuppression> *bad)
|
||||
{
|
||||
std::list<Suppressions::Suppression> inlineSuppressions;
|
||||
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
|
||||
if (tok->comment) {
|
||||
Suppressions::Suppression s;
|
||||
const std::size_t position=tok->str().find("cppcheck-suppress");
|
||||
if (position != std::string::npos) {
|
||||
if ((tok->str().length() > position+17) && (tok->str()[position+17] == '[')) { //multi suppress format
|
||||
std::string errmsg;
|
||||
if (!s.parseComment(tok->str(), &errmsg))
|
||||
continue;
|
||||
std::vector<Suppressions::Suppression> ss;
|
||||
ss = Suppressions::parseMultiSuppressComment(tok->str(), &errmsg);
|
||||
|
||||
if (!errmsg.empty())
|
||||
bad->push_back(BadInlineSuppression(tok->location, errmsg));
|
||||
|
||||
for (std::vector<Suppressions::Suppression>::iterator iter = ss.begin(); iter!=ss.end(); ++iter) {
|
||||
if (!(*iter).errorId.empty())
|
||||
inlineSuppressions.push_back(*iter);
|
||||
}
|
||||
}
|
||||
else { //single suppress format
|
||||
std::string errmsg;
|
||||
Suppressions::Suppression s;
|
||||
if (!s.parseComment(tok->str(), &errmsg))
|
||||
return;
|
||||
|
||||
if (!s.errorId.empty())
|
||||
inlineSuppressions.push_back(s);
|
||||
|
||||
if (!errmsg.empty())
|
||||
bad->push_back(BadInlineSuppression(tok->location, errmsg));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> *bad)
|
||||
{
|
||||
const simplecpp::Token *current_non_comment_tok;
|
||||
std::list<Suppressions::Suppression> inlineSuppressions;
|
||||
|
||||
for (const simplecpp::Token *tok = tokens.cfront(); tok; /*none*/) {
|
||||
//parse all comment before current non-comment tok
|
||||
if (tok->comment) {
|
||||
parseCommentToken(tok, inlineSuppressions, bad);
|
||||
tok = tok->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inlineSuppressions.empty())
|
||||
current_non_comment_tok = tok;
|
||||
|
||||
//parse all comment tok after current non-comment tok in the same line
|
||||
for (tok = tok->next; tok; tok = tok->next) {
|
||||
if ((tok->location.line != current_non_comment_tok->location.line) || !(tok->comment))
|
||||
break;
|
||||
parseCommentToken(tok, inlineSuppressions, bad);
|
||||
}
|
||||
|
||||
//if there is no suppress, jump it!
|
||||
if (inlineSuppressions.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Relative filename
|
||||
std::string relativeFilename(tok->location.file());
|
||||
std::string relativeFilename(current_non_comment_tok->location.file());
|
||||
if (mSettings.relativePaths) {
|
||||
for (const std::string & basePath : mSettings.basePaths) {
|
||||
const std::string bp = basePath + "/";
|
||||
|
@ -110,7 +152,7 @@ static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSe
|
|||
// Add the suppressions.
|
||||
for (Suppressions::Suppression &suppr : inlineSuppressions) {
|
||||
suppr.fileName = relativeFilename;
|
||||
suppr.lineNumber = tok->location.line;
|
||||
suppr.lineNumber = current_non_comment_tok->location.line;
|
||||
mSettings.nomsg.addSuppression(suppr);
|
||||
}
|
||||
inlineSuppressions.clear();
|
||||
|
|
|
@ -112,6 +112,99 @@ std::string Suppressions::parseXmlFile(const char *filename)
|
|||
return "";
|
||||
}
|
||||
|
||||
std::vector<Suppressions::Suppression> Suppressions::parseMultiSuppressComment(std::string comment, std::string *errorMessage)
|
||||
{
|
||||
std::vector<Suppression> suppressions;
|
||||
if (comment.size() < 2)
|
||||
return suppressions;
|
||||
|
||||
const std::size_t first_non_blank_position = comment.find_first_not_of(" \t\n", 2);
|
||||
const std::size_t suppress_position = comment.find("cppcheck-suppress", 2);
|
||||
if (suppress_position == std::string::npos)
|
||||
return suppressions;
|
||||
if (suppress_position != first_non_blank_position) {
|
||||
if (errorMessage && errorMessage->empty())
|
||||
*errorMessage = "Bad multi suppression '" + comment + "'. there shouldn't have non-blank character before cppcheck-suppress";
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
const std::size_t start_position = comment.find("[", suppress_position);
|
||||
const std::size_t end_position = comment.find("]", suppress_position);
|
||||
if ( start_position == std::string::npos
|
||||
|| end_position == std::string::npos
|
||||
|| start_position != suppress_position+17 //there must be no space before "["
|
||||
|| start_position >= end_position)
|
||||
{
|
||||
if (errorMessage && errorMessage->empty())
|
||||
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
//extract supressions
|
||||
std::size_t current_comma_position = 0;
|
||||
//multi_suppressions_word maybe "[errorId1, errorId2 symbolName=arr", who just has left bracket
|
||||
std::string multi_suppressions_word = comment.substr(start_position, end_position-start_position);
|
||||
do
|
||||
{
|
||||
std::string suppression_word;
|
||||
|
||||
//single suppression word
|
||||
const std::size_t previous_comma_position=current_comma_position;
|
||||
current_comma_position=multi_suppressions_word.find(",", previous_comma_position+1); //find "," after previous comma
|
||||
if (current_comma_position == std::string::npos)
|
||||
{
|
||||
suppression_word = multi_suppressions_word.substr(previous_comma_position+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
suppression_word = multi_suppressions_word.substr(previous_comma_position+1, current_comma_position-previous_comma_position-1);
|
||||
}
|
||||
|
||||
//parse single suppression word
|
||||
Suppression s;
|
||||
std::string word;
|
||||
std::string errorId;
|
||||
std::string symbolName;
|
||||
std::istringstream iss(suppression_word);
|
||||
|
||||
iss >> errorId;
|
||||
if (!iss)
|
||||
{
|
||||
if (errorMessage && errorMessage->empty())
|
||||
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
|
||||
suppressions.clear();
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
while (iss)
|
||||
{
|
||||
iss >> word;
|
||||
if (!iss)
|
||||
break;
|
||||
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
|
||||
break;
|
||||
if (word.compare(0, 11, "symbolName=") == 0)
|
||||
{
|
||||
symbolName = word.substr(11);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errorMessage && errorMessage->empty())
|
||||
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
|
||||
suppressions.clear();
|
||||
return suppressions;
|
||||
}
|
||||
}
|
||||
|
||||
s.errorId = errorId;
|
||||
s.symbolName = symbolName;
|
||||
suppressions.push_back(s);
|
||||
|
||||
} while(current_comma_position!=std::string::npos);
|
||||
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
std::string Suppressions::addSuppressionLine(const std::string &line)
|
||||
{
|
||||
std::istringstream lineStream(line);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
@ -115,6 +116,14 @@ public:
|
|||
*/
|
||||
std::string parseXmlFile(const char *filename);
|
||||
|
||||
/**
|
||||
* Parse multi inline suppression in comment
|
||||
* @param comment the full comment text
|
||||
* @param errorMessage output parameter for error message (wrong suppression attribute)
|
||||
* @return empty vector if something wrong.
|
||||
*/
|
||||
static std::vector<Suppression> parseMultiSuppressComment(std::string comment, std::string *errorMessage);
|
||||
|
||||
/**
|
||||
* @brief Don't show the given error.
|
||||
* @param line Description of error to suppress (in id:file:line format).
|
||||
|
|
|
@ -54,6 +54,9 @@ private:
|
|||
TEST_CASE(inlinesuppress_symbolname);
|
||||
TEST_CASE(inlinesuppress_comment);
|
||||
|
||||
TEST_CASE(multi_inlinesuppress);
|
||||
TEST_CASE(multi_inlinesuppress_comment);
|
||||
|
||||
TEST_CASE(globalSuppressions); // Testing that global suppressions work (#8515)
|
||||
|
||||
TEST_CASE(inlinesuppress_unusedFunction); // #4210 - unusedFunction
|
||||
|
@ -323,6 +326,14 @@ private:
|
|||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" a++;// cppcheck-suppress uninitvar\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
|
@ -342,6 +353,69 @@ private:
|
|||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" a++;/* cppcheck-suppress uninitvar */\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" // cppcheck-suppress[uninitvar]\n"
|
||||
" a++;\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" // cppcheck-suppress[uninitvar]\n"
|
||||
" a++;\n"
|
||||
"\n"
|
||||
" a++;\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" a++;// cppcheck-suppress[uninitvar]\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" /* cppcheck-suppress[uninitvar]*/\n"
|
||||
" a++;\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" /* cppcheck-suppress[uninitvar]*/\n"
|
||||
"\n"
|
||||
" a++;\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline
|
||||
(this->*check)("void f() {\n"
|
||||
" int a;\n"
|
||||
" a++;/* cppcheck-suppress[uninitvar]*/\n"
|
||||
"}\n",
|
||||
"");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// suppress uninitvar inline, with asm before (#6813)
|
||||
(this->*check)("void f() {\n"
|
||||
" __asm {\n"
|
||||
|
@ -467,6 +541,110 @@ private:
|
|||
ASSERT_EQUALS("", errMsg);
|
||||
}
|
||||
|
||||
void multi_inlinesuppress() {
|
||||
Suppressions ss;
|
||||
std::vector<Suppressions::Suppression> suppressions;
|
||||
std::string errMsg;
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId]", &errMsg);
|
||||
ASSERT_EQUALS(1, suppressions.size());
|
||||
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||
ASSERT_EQUALS("", errMsg);
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId symbolName=arr]", &errMsg);
|
||||
ASSERT_EQUALS(1, suppressions.size());
|
||||
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||
ASSERT_EQUALS("arr", suppressions[0].symbolName);
|
||||
ASSERT_EQUALS("", errMsg);
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId symbolName=]", &errMsg);
|
||||
ASSERT_EQUALS(1, suppressions.size());
|
||||
ASSERT_EQUALS("errorId", suppressions[0].errorId);
|
||||
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||
ASSERT_EQUALS("", errMsg);
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId1, errorId2 symbolName=arr]", &errMsg);
|
||||
ASSERT_EQUALS(2, suppressions.size());
|
||||
ASSERT_EQUALS("errorId1", suppressions[0].errorId);
|
||||
ASSERT_EQUALS("", suppressions[0].symbolName);
|
||||
ASSERT_EQUALS("errorId2", suppressions[1].errorId);
|
||||
ASSERT_EQUALS("arr", suppressions[1].symbolName);
|
||||
ASSERT_EQUALS("", errMsg);
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress [errorId]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress errorId", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId1 errorId2 symbolName=arr]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId1, errorId2 symbol=arr]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("// cppcheck-suppress[errorId1, errorId2 symbolName]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
}
|
||||
|
||||
void multi_inlinesuppress_comment() {
|
||||
Suppressions ss;
|
||||
std::vector<Suppressions::Suppression> suppressions;
|
||||
std::string errMsg;
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("//cppcheck-suppress[errorId1, errorId2 symbolName=arr]", &errMsg);
|
||||
ASSERT_EQUALS(2, suppressions.size());
|
||||
ASSERT_EQUALS(true, errMsg.empty());
|
||||
|
||||
//error, shouldn't have "some text" at beginning
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("//some text cppcheck-suppress[errorId1, errorId2 symbolName=arr]", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("//cppcheck-suppress[errorId1, errorId2 symbolName=arr] some text", &errMsg);
|
||||
ASSERT_EQUALS(2, suppressions.size());
|
||||
ASSERT_EQUALS(true, errMsg.empty());
|
||||
|
||||
//error, shouldn't have "some text" at beginning
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("//some text cppcheck-suppress[errorId1, errorId2 symbolName=arr] some text", &errMsg);
|
||||
ASSERT_EQUALS(0, suppressions.size());
|
||||
ASSERT_EQUALS(false, errMsg.empty());
|
||||
|
||||
errMsg = "";
|
||||
suppressions=ss.parseMultiSuppressComment("/*cppcheck-suppress[errorId1, errorId2 symbolName=arr]*/", &errMsg);
|
||||
ASSERT_EQUALS(2, suppressions.size());
|
||||
ASSERT_EQUALS(true, errMsg.empty());
|
||||
}
|
||||
|
||||
void globalSuppressions() { // Testing that Cppcheck::useGlobalSuppressions works (#8515)
|
||||
errout.str("");
|
||||
|
||||
|
|
Loading…
Reference in New Issue