This commit is contained in:
parent
3b1c701766
commit
49da3e3821
|
@ -116,7 +116,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Write the checkers report
|
* @brief Write the checkers report
|
||||||
*/
|
*/
|
||||||
void writeCheckersReport() const;
|
void writeCheckersReport();
|
||||||
|
|
||||||
bool hasCriticalErrors() const {
|
bool hasCriticalErrors() const {
|
||||||
return !mCriticalErrors.empty();
|
return !mCriticalErrors.empty();
|
||||||
|
@ -286,12 +286,13 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
|
||||||
cppcheck.tooManyConfigsError(emptyString,0U);
|
cppcheck.tooManyConfigsError(emptyString,0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.safety || settings.severity.isEnabled(Severity::information) || !settings.checkersReportFilename.empty())
|
||||||
|
mStdLogger->writeCheckersReport();
|
||||||
|
|
||||||
if (settings.xml) {
|
if (settings.xml) {
|
||||||
mStdLogger->reportErr(ErrorMessage::getXMLFooter());
|
mStdLogger->reportErr(ErrorMessage::getXMLFooter());
|
||||||
}
|
}
|
||||||
|
|
||||||
mStdLogger->writeCheckersReport();
|
|
||||||
|
|
||||||
if (settings.safety && mStdLogger->hasCriticalErrors())
|
if (settings.safety && mStdLogger->hasCriticalErrors())
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
@ -300,28 +301,39 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppCheckExecutor::StdLogger::writeCheckersReport() const
|
void CppCheckExecutor::StdLogger::writeCheckersReport()
|
||||||
{
|
{
|
||||||
CheckersReport checkersReport(mSettings, mActiveCheckers);
|
CheckersReport checkersReport(mSettings, mActiveCheckers);
|
||||||
|
|
||||||
if (!mSettings.quiet) {
|
bool suppressed = false;
|
||||||
|
for (const Suppressions::Suppression& s : mSettings.nomsg.getSuppressions()) {
|
||||||
|
if (s.errorId == "checkersReport")
|
||||||
|
suppressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!suppressed) {
|
||||||
|
ErrorMessage msg;
|
||||||
|
msg.severity = Severity::information;
|
||||||
|
msg.id = "checkersReport";
|
||||||
|
|
||||||
const int activeCheckers = checkersReport.getActiveCheckersCount();
|
const int activeCheckers = checkersReport.getActiveCheckersCount();
|
||||||
const int totalCheckers = checkersReport.getAllCheckersCount();
|
const int totalCheckers = checkersReport.getAllCheckersCount();
|
||||||
|
|
||||||
const std::string extra = mSettings.verbose ? " (use --checkers-report=<filename> to see details)" : "";
|
std::string what;
|
||||||
if (mCriticalErrors.empty())
|
if (mCriticalErrors.empty())
|
||||||
std::cout << "Active checkers: " << activeCheckers << "/" << totalCheckers << extra << std::endl;
|
what = std::to_string(activeCheckers) + "/" + std::to_string(totalCheckers);
|
||||||
else
|
else
|
||||||
std::cout << "Active checkers: There was critical errors" << extra << std::endl;
|
what = "There was critical errors";
|
||||||
|
msg.setmsg("Active checkers: " + what + " (use --checkers-report=<filename> to see details)");
|
||||||
|
|
||||||
|
reportErr(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSettings.checkersReportFilename.empty())
|
if (!mSettings.checkersReportFilename.empty()) {
|
||||||
return;
|
std::ofstream fout(mSettings.checkersReportFilename);
|
||||||
|
if (fout.is_open())
|
||||||
std::ofstream fout(mSettings.checkersReportFilename);
|
fout << checkersReport.getReport(mCriticalErrors);
|
||||||
if (fout.is_open())
|
}
|
||||||
fout << checkersReport.getReport(mCriticalErrors);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
|
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
|
||||||
|
static const char ID_UNUSEDFUNCTION[] = "unusedFunction";
|
||||||
|
static const char ID_CHECKERSREPORT[] = "checkersReport";
|
||||||
|
|
||||||
Suppressions::ErrorMessage Suppressions::ErrorMessage::fromErrorMessage(const ::ErrorMessage &msg, const std::set<std::string> ¯oNames)
|
Suppressions::ErrorMessage Suppressions::ErrorMessage::fromErrorMessage(const ::ErrorMessage &msg, const std::set<std::string> ¯oNames)
|
||||||
{
|
{
|
||||||
Suppressions::ErrorMessage ret;
|
Suppressions::ErrorMessage ret;
|
||||||
|
@ -468,7 +471,9 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedLocalSuppressions
|
||||||
continue;
|
continue;
|
||||||
if (s.hash > 0)
|
if (s.hash > 0)
|
||||||
continue;
|
continue;
|
||||||
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
if (s.errorId == ID_CHECKERSREPORT)
|
||||||
|
continue;
|
||||||
|
if (!unusedFunctionChecking && s.errorId == ID_UNUSEDFUNCTION)
|
||||||
continue;
|
continue;
|
||||||
if (tmpFile.empty() || !s.isLocal() || s.fileName != tmpFile)
|
if (tmpFile.empty() || !s.isLocal() || s.fileName != tmpFile)
|
||||||
continue;
|
continue;
|
||||||
|
@ -485,7 +490,9 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedGlobalSuppression
|
||||||
continue;
|
continue;
|
||||||
if (s.hash > 0)
|
if (s.hash > 0)
|
||||||
continue;
|
continue;
|
||||||
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
|
if (!unusedFunctionChecking && s.errorId == ID_UNUSEDFUNCTION)
|
||||||
|
continue;
|
||||||
|
if (s.errorId == ID_CHECKERSREPORT)
|
||||||
continue;
|
continue;
|
||||||
if (s.isLocal())
|
if (s.isLocal())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -12,7 +12,7 @@ GUI:
|
||||||
-
|
-
|
||||||
|
|
||||||
Changed interface:
|
Changed interface:
|
||||||
-
|
- Final report of active checkers is reported as a normal information message instead.
|
||||||
|
|
||||||
Deprecations:
|
Deprecations:
|
||||||
- "--showtime=top5" has been deprecated and will be removed in Cppcheck 2.14. Please use --showtime=top5_file or --showtime=top5_summary instead.
|
- "--showtime=top5" has been deprecated and will be removed in Cppcheck 2.14. Please use --showtime=top5_file or --showtime=top5_summary instead.
|
||||||
|
@ -44,6 +44,3 @@ Other:
|
||||||
- Markup files will now be processed after the regular source files when using multiple threads/processes (some issues remain - see Trac #12167 for details).
|
- Markup files will now be processed after the regular source files when using multiple threads/processes (some issues remain - see Trac #12167 for details).
|
||||||
- Added file name to ValueFlow "--debug" output.
|
- Added file name to ValueFlow "--debug" output.
|
||||||
- Fixed build when using "clang-cl" in CMake.
|
- Fixed build when using "clang-cl" in CMake.
|
||||||
|
|
||||||
Safety critical fixes:
|
|
||||||
- Added "--safety" option. It makes Cppcheck more strict about critical errors.
|
|
||||||
|
|
|
@ -14,14 +14,14 @@ def test_j2_suppress():
|
||||||
assert len(stderr) == 0
|
assert len(stderr) == 0
|
||||||
|
|
||||||
def test_safety_suppress_syntax_error_implicitly(tmpdir):
|
def test_safety_suppress_syntax_error_implicitly(tmpdir):
|
||||||
ret, stdout, stderr = cppcheck(['--safety', '--suppress=*', 'proj-suppress-syntaxError'], remove_active_checkers=False)
|
ret, stdout, stderr = cppcheck(['--safety', '--suppress=*', 'proj-suppress-syntaxError'], remove_checkers_report=False)
|
||||||
assert ret == 1
|
assert ret == 1
|
||||||
assert '[syntaxError]' in stderr
|
assert '[syntaxError]' in stderr
|
||||||
assert 'Active checkers: There was critical errors' in stdout
|
assert 'Active checkers: There was critical errors' in stderr
|
||||||
|
|
||||||
def test_safety_suppress_syntax_error_explicitly():
|
def test_safety_suppress_syntax_error_explicitly():
|
||||||
ret, stdout, stderr = cppcheck(['--safety', '--suppress=syntaxError', 'proj-suppress-syntaxError'], remove_active_checkers=False)
|
ret, stdout, stderr = cppcheck(['--safety', '--suppress=syntaxError', 'proj-suppress-syntaxError'], remove_checkers_report=False)
|
||||||
assert ret == 1
|
assert ret == 1
|
||||||
assert '[syntaxError]' not in stderr
|
assert '[syntaxError]' not in stderr
|
||||||
assert 'Active checkers: There was critical errors' in stdout
|
assert 'Active checkers: There was critical errors' in stderr
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ def __lookup_cppcheck_exe():
|
||||||
|
|
||||||
|
|
||||||
# Run Cppcheck with args
|
# Run Cppcheck with args
|
||||||
def cppcheck(args, env=None, remove_active_checkers=True):
|
def cppcheck(args, env=None, remove_checkers_report=True):
|
||||||
exe = __lookup_cppcheck_exe()
|
exe = __lookup_cppcheck_exe()
|
||||||
assert exe is not None, 'no cppcheck binary found'
|
assert exe is not None, 'no cppcheck binary found'
|
||||||
|
|
||||||
|
@ -80,8 +80,20 @@ def cppcheck(args, env=None, remove_active_checkers=True):
|
||||||
comm = p.communicate()
|
comm = p.communicate()
|
||||||
stdout = comm[0].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
|
stdout = comm[0].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
|
||||||
stderr = comm[1].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
|
stderr = comm[1].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
|
||||||
if remove_active_checkers and stdout.find('\nActive checkers:') > 0:
|
if remove_checkers_report:
|
||||||
stdout = stdout[:1 + stdout.find('\nActive checkers:')]
|
if stderr.find('[checkersReport]\n') > 0:
|
||||||
|
start_id = stderr.find('[checkersReport]\n')
|
||||||
|
start_line = stderr.rfind('\n', 0, start_id)
|
||||||
|
if start_line <= 0:
|
||||||
|
stderr = ''
|
||||||
|
else:
|
||||||
|
stderr = stderr[:start_line + 1]
|
||||||
|
elif stderr.find(': (information) Active checkers: ') >= 0:
|
||||||
|
pos = stderr.find(': (information) Active checkers: ')
|
||||||
|
if pos == 0:
|
||||||
|
stderr = ''
|
||||||
|
elif stderr[pos - 1] == '\n':
|
||||||
|
stderr = stderr[:pos]
|
||||||
return p.returncode, stdout, stderr
|
return p.returncode, stdout, stderr
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue