Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions cli/cppcheckexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class CppCheckExecutor::StdLogger : public ErrorLogger
/**
* @brief Write the checkers report
*/
void writeCheckersReport() const;
void writeCheckersReport();

bool hasCriticalErrors() const {
return !mCriticalErrors.empty();
Expand Down Expand Up @@ -286,12 +286,13 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
cppcheck.tooManyConfigsError(emptyString,0U);
}

if (settings.safety || settings.severity.isEnabled(Severity::information) || !settings.checkersReportFilename.empty())
mStdLogger->writeCheckersReport();

if (settings.xml) {
mStdLogger->reportErr(ErrorMessage::getXMLFooter());
}

mStdLogger->writeCheckersReport();

if (settings.safety && mStdLogger->hasCriticalErrors())
return EXIT_FAILURE;

Expand All @@ -300,28 +301,39 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck) const
return EXIT_SUCCESS;
}

void CppCheckExecutor::StdLogger::writeCheckersReport() const
void CppCheckExecutor::StdLogger::writeCheckersReport()
{
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 totalCheckers = checkersReport.getAllCheckersCount();

const std::string extra = mSettings.verbose ? " (use --checkers-report=<filename> to see details)" : "";
std::string what;
if (mCriticalErrors.empty())
std::cout << "Active checkers: " << activeCheckers << "/" << totalCheckers << extra << std::endl;
what = std::to_string(activeCheckers) + "/" + std::to_string(totalCheckers);
else
std::cout << "Active checkers: There was critical errors" << extra << std::endl;
}

if (mSettings.checkersReportFilename.empty())
return;
what = "There was critical errors";
msg.setmsg("Active checkers: " + what + " (use --checkers-report=<filename> to see details)");

std::ofstream fout(mSettings.checkersReportFilename);
if (fout.is_open())
fout << checkersReport.getReport(mCriticalErrors);
reportErr(msg);
}

if (!mSettings.checkersReportFilename.empty()) {
std::ofstream fout(mSettings.checkersReportFilename);
if (fout.is_open())
fout << checkersReport.getReport(mCriticalErrors);
}
}

#ifdef _WIN32
Expand Down
11 changes: 9 additions & 2 deletions lib/suppressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

#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> &macroNames)
{
Suppressions::ErrorMessage ret;
Expand Down Expand Up @@ -468,7 +471,9 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedLocalSuppressions
continue;
if (s.hash > 0)
continue;
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
if (s.errorId == ID_CHECKERSREPORT)
continue;
if (!unusedFunctionChecking && s.errorId == ID_UNUSEDFUNCTION)
continue;
if (tmpFile.empty() || !s.isLocal() || s.fileName != tmpFile)
continue;
Expand All @@ -485,7 +490,9 @@ std::list<Suppressions::Suppression> Suppressions::getUnmatchedGlobalSuppression
continue;
if (s.hash > 0)
continue;
if (!unusedFunctionChecking && s.errorId == "unusedFunction")
if (!unusedFunctionChecking && s.errorId == ID_UNUSEDFUNCTION)
continue;
if (s.errorId == ID_CHECKERSREPORT)
continue;
if (s.isLocal())
continue;
Expand Down
5 changes: 1 addition & 4 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ GUI:
-

Changed interface:
-
- Final report of active checkers is reported as a normal information message instead.

Deprecations:
- "--showtime=top5" has been deprecated and will be removed in Cppcheck 2.14. Please use --showtime=top5_file or --showtime=top5_summary instead.
Expand Down Expand Up @@ -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).
- Added file name to ValueFlow "--debug" output.
- Fixed build when using "clang-cl" in CMake.

Safety critical fixes:
- Added "--safety" option. It makes Cppcheck more strict about critical errors.
8 changes: 4 additions & 4 deletions test/cli/test-suppress-syntaxError.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ def test_j2_suppress():
assert len(stderr) == 0

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 '[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():
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 '[syntaxError]' not in stderr
assert 'Active checkers: There was critical errors' in stdout
assert 'Active checkers: There was critical errors' in stderr

18 changes: 15 additions & 3 deletions test/cli/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __lookup_cppcheck_exe():


# 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()
assert exe is not None, 'no cppcheck binary found'

Expand All @@ -80,8 +80,20 @@ def cppcheck(args, env=None, remove_active_checkers=True):
comm = p.communicate()
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')
if remove_active_checkers and stdout.find('\nActive checkers:') > 0:
stdout = stdout[:1 + stdout.find('\nActive checkers:')]
if remove_checkers_report:
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


Expand Down