Fix #674 (Feature request: error filtering)
--suppressions argument added to CLI http://sourceforge.net/apps/trac/cppcheck/ticket/674
This commit is contained in:
parent
a078c9353d
commit
38c2a360ee
|
@ -112,6 +112,7 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
||||||
<arg choice="opt"><option>-j[jobs]</option></arg>
|
<arg choice="opt"><option>-j[jobs]</option></arg>
|
||||||
<arg choice="opt"><option>--quiet</option></arg>
|
<arg choice="opt"><option>--quiet</option></arg>
|
||||||
<arg choice="opt"><option>--style</option></arg>
|
<arg choice="opt"><option>--style</option></arg>
|
||||||
|
<arg choice="opt"><option>--suppressions [file]</option></arg>
|
||||||
<arg choice="opt"><option>--template ['text']</option></arg>
|
<arg choice="opt"><option>--template ['text']</option></arg>
|
||||||
<arg choice="opt"><option>--unused-functions</option></arg>
|
<arg choice="opt"><option>--unused-functions</option></arg>
|
||||||
<arg choice="opt"><option>--verbose</option></arg>
|
<arg choice="opt"><option>--verbose</option></arg>
|
||||||
|
@ -208,6 +209,12 @@ files, this is not needed.</para>
|
||||||
<para>Check coding style.</para>
|
<para>Check coding style.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--suppressions [file]</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Suppress warnings listed in the file. Filename and line as optional. The format of the single line in file is: [error id]:[filename]:[line]</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--template ['text']</option></term>
|
<term><option>--template ['text']</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -98,6 +98,20 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
||||||
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
|
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--style") == 0)
|
||||||
_settings._checkCodingStyle = true;
|
_settings._checkCodingStyle = true;
|
||||||
|
|
||||||
|
// Filter errors
|
||||||
|
else if (strcmp(argv[i], "--suppressions") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (i >= argc)
|
||||||
|
return "No file specified for the --suppressions option\n";
|
||||||
|
|
||||||
|
std::ifstream f(argv[i]);
|
||||||
|
if (!f.is_open())
|
||||||
|
return "couldn't open the file \"" + std::string(argv[i]) + "\"\n";
|
||||||
|
_settings.suppressions(f);
|
||||||
|
}
|
||||||
|
|
||||||
// Verbose error messages (configuration info)
|
// Verbose error messages (configuration info)
|
||||||
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
|
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
|
||||||
_settings._verbose = true;
|
_settings._verbose = true;
|
||||||
|
@ -301,8 +315,8 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
||||||
"Syntax:\n"
|
"Syntax:\n"
|
||||||
" cppcheck [--all] [--append=file] [--auto-dealloc file.lst]\n"
|
" cppcheck [--all] [--append=file] [--auto-dealloc file.lst]\n"
|
||||||
" [--error-exitcode=[n]] [--force] [--help] [-Idir] [-j [jobs]]\n"
|
" [--error-exitcode=[n]] [--force] [--help] [-Idir] [-j [jobs]]\n"
|
||||||
" [--quiet] [--style] [--unused-functions] [--verbose] [--version]\n"
|
" [--quiet] [--style] [--suppressions file.txt] [--unused-functions]\n"
|
||||||
" [--xml] [file or path1] [file or path] ...\n"
|
" [--verbose] [--version] [--xml] [file or path1] [file or path] ...\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
|
"If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
|
||||||
"are checked recursively from given directory.\n\n"
|
"are checked recursively from given directory.\n\n"
|
||||||
|
@ -331,6 +345,9 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
||||||
" -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
|
" -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
|
||||||
" -q, --quiet Only print error messages\n"
|
" -q, --quiet Only print error messages\n"
|
||||||
" -s, --style Check coding style\n"
|
" -s, --style Check coding style\n"
|
||||||
|
" --suppressions file Suppress warnings listed in the file. Filename and line\n"
|
||||||
|
" are optional. The format of the single line in file is:\n"
|
||||||
|
" [error id]:[filename]:[line]\n"
|
||||||
" --template '[text]' Format the error messages. E.g.\n"
|
" --template '[text]' Format the error messages. E.g.\n"
|
||||||
" '{file}:{line},{severity},{id},{message}' or\n"
|
" '{file}:{line},{severity},{id},{message}' or\n"
|
||||||
" '{file}({line}):({severity}) {message}'\n"
|
" '{file}({line}):({severity}) {message}'\n"
|
||||||
|
@ -528,6 +545,17 @@ void CppCheck::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||||
if (std::find(_errorList.begin(), _errorList.end(), errmsg) != _errorList.end())
|
if (std::find(_errorList.begin(), _errorList.end(), errmsg) != _errorList.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::string file;
|
||||||
|
unsigned int line(0);
|
||||||
|
if (!msg._callStack.empty())
|
||||||
|
{
|
||||||
|
file = msg._callStack.back().getfile();
|
||||||
|
line = msg._callStack.back().line;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_settings.isSuppressed(msg._id, file, line))
|
||||||
|
return;
|
||||||
|
|
||||||
_errorList.push_back(errmsg);
|
_errorList.push_back(errmsg);
|
||||||
std::string errmsg2(errmsg);
|
std::string errmsg2(errmsg);
|
||||||
if (_settings._verbose)
|
if (_settings._verbose)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
Settings::Settings()
|
Settings::Settings()
|
||||||
{
|
{
|
||||||
|
@ -59,6 +60,62 @@ void Settings::autoDealloc(std::istream &istr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Settings::suppressions(std::istream &istr)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
while (getline(istr, line))
|
||||||
|
{
|
||||||
|
// Skip empty lines
|
||||||
|
if (line.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::istringstream lineStream(line);
|
||||||
|
std::string id;
|
||||||
|
std::string file;
|
||||||
|
unsigned int lineNumber = 0;
|
||||||
|
if (std::getline(lineStream, id, ':'))
|
||||||
|
{
|
||||||
|
if (std::getline(lineStream, file, ':'))
|
||||||
|
{
|
||||||
|
lineStream >> lineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We could perhaps check if the id is valid and return error if it is not
|
||||||
|
addSuppression(id, file, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::addSuppression(const std::string &errorId, const std::string &file, unsigned int line)
|
||||||
|
{
|
||||||
|
_suppressions[errorId][file].push_back(line);
|
||||||
|
_suppressions[errorId][file].sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isSuppressed(const std::string &errorId, const std::string &file, unsigned int line)
|
||||||
|
{
|
||||||
|
if (_suppressions.find(errorId) == _suppressions.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check are all errors of this type filtered out
|
||||||
|
if (_suppressions[errorId].find("") != _suppressions[errorId].end())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (_suppressions[errorId].find(file) == _suppressions[errorId].end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check should all errors in this file be filtered out
|
||||||
|
if (std::find(_suppressions[errorId][file].begin(), _suppressions[errorId][file].end(), 0) != _suppressions[errorId][file].end())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (std::find(_suppressions[errorId][file].begin(), _suppressions[errorId][file].end(), line) == _suppressions[errorId][file].end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Settings::addAutoAllocClass(const std::string &name)
|
void Settings::addAutoAllocClass(const std::string &name)
|
||||||
{
|
{
|
||||||
_autoDealloc.push_back(name);
|
_autoDealloc.push_back(name);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
/// @addtogroup Core
|
/// @addtogroup Core
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -41,6 +42,9 @@ private:
|
||||||
/** Code to append in the checks */
|
/** Code to append in the checks */
|
||||||
std::string _append;
|
std::string _append;
|
||||||
|
|
||||||
|
/** List of error which the user doesn't want to see. */
|
||||||
|
std::map<std::string, std::map<std::string, std::list<int> > > _suppressions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Settings();
|
Settings();
|
||||||
virtual ~Settings();
|
virtual ~Settings();
|
||||||
|
@ -87,6 +91,28 @@ public:
|
||||||
/** Add class to list of automatically deallocated classes */
|
/** Add class to list of automatically deallocated classes */
|
||||||
void addAutoAllocClass(const std::string &name);
|
void addAutoAllocClass(const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't show errors listed in the file.
|
||||||
|
* @param istr Open file stream where errors can be read.
|
||||||
|
* @return true on success, false in syntax error is noticed.
|
||||||
|
*/
|
||||||
|
bool suppressions(std::istream &istr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't show this error. If file and/or line are optional. In which case
|
||||||
|
* the errorId alone is used for filtering.
|
||||||
|
* @param errorId, the id for the error, e.g. "arrayIndexOutOfBounds"
|
||||||
|
* @param file File name with the path, e.g. "src/main.cpp"
|
||||||
|
* @param line number, e.g. "123"
|
||||||
|
*/
|
||||||
|
void addSuppression(const std::string &errorId, const std::string &file = "", unsigned int line = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this message should not be shown to the user.
|
||||||
|
* @return true if this error is suppressed.
|
||||||
|
*/
|
||||||
|
bool isSuppressed(const std::string &errorId, const std::string &file, unsigned int line);
|
||||||
|
|
||||||
/** is a class automaticly deallocated? */
|
/** is a class automaticly deallocated? */
|
||||||
bool isAutoDealloc(const char classname[]) const;
|
bool isAutoDealloc(const char classname[]) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue