Support cppcheck-suppression in C style comments

This commit is contained in:
Greg Hewgill 2011-02-20 11:36:03 +13:00
parent 7e5d8e42d4
commit 98ab34b2b5
2 changed files with 166 additions and 111 deletions

View File

@ -338,20 +338,32 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
continue;
}
// We have finished a line that didn't contain any comment
// (the '\n' is swallowed when a // comment is detected)
if ((ch == '\n' || str.compare(i,2,"//")==0) && !suppressionIDs.empty())
// First skip over any whitespace that may be present
if (std::isspace(ch))
{
// Add the suppressions.
for (size_t j(0); j < suppressionIDs.size(); ++j)
if (ch == ' ' && previous == ' ')
{
const std::string errmsg(settings->nomsg.addSuppression(suppressionIDs[j], filename, lineno));
if (!errmsg.empty())
// Skip double white space
}
else
{
writeError(filename, lineno, _errorLogger, "cppcheckError", errmsg);
code << char(ch);
previous = ch;
}
// if there has been <backspace><newline> sequences, add extra newlines..
if (ch == '\n')
{
++lineno;
if (newlines > 0)
{
code << std::string(newlines, '\n');
newlines = 0;
previous = '\n';
}
}
suppressionIDs.clear();
continue;
}
// Remove comments..
@ -382,6 +394,7 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
}
else if (str.compare(i, 2, "/*", 0, 2) == 0)
{
size_t commentStart = i + 2;
unsigned char chPrev = 0;
++i;
while (i < str.length() && (chPrev != '*' || ch != '/'))
@ -395,10 +408,44 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
++lineno;
}
}
if (settings && settings->_inlineSuppressions)
{
std::string comment(str, commentStart, i - commentStart);
std::istringstream iss(comment);
std::string word;
iss >> word;
if (word == "cppcheck-suppress")
{
iss >> word;
if (iss)
suppressionIDs.push_back(word);
}
}
}
else
{
// Not whitespace and not a comment. Must be code here!
// Add any pending inline suppressions that have accumulated.
if (!suppressionIDs.empty())
{
if (settings != NULL)
{
// Add the suppressions.
for (size_t j(0); j < suppressionIDs.size(); ++j)
{
const std::string errmsg(settings->nomsg.addSuppression(suppressionIDs[j], filename, lineno));
if (!errmsg.empty())
{
writeError(filename, lineno, _errorLogger, "cppcheckError", errmsg);
}
}
}
suppressionIDs.clear();
}
// String or char constants..
else if (ch == '\"' || ch == '\'')
if (ch == '\"' || ch == '\'')
{
code << char(ch);
char chNext;
@ -489,32 +536,11 @@ std::string Preprocessor::removeComments(const std::string &str, const std::stri
previous = 'R';
}
}
// Just some code..
else
{
if (ch == ' ' && previous == ' ')
{
// Skip double white space
}
else
{
code << char(ch);
previous = ch;
}
// if there has been <backspace><newline> sequences, add extra newlines..
if (ch == '\n')
{
++lineno;
if (newlines > 0)
{
code << std::string(newlines, '\n');
newlines = 0;
previous = '\n';
}
}
}
}

View File

@ -172,6 +172,35 @@ private:
"");
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"
" /* 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, without error present
(this->*check)("void f() {\n"
" int a;\n"