This primarily adds the corresponding report in the GUI that we have in the command line already
This commit is contained in:
parent
22547beaaf
commit
44c149e51b
6
Makefile
6
Makefile
|
@ -200,6 +200,7 @@ LIBOBJ = $(libcppdir)/analyzerinfo.o \
|
|||
$(libcppdir)/checkbufferoverrun.o \
|
||||
$(libcppdir)/checkclass.o \
|
||||
$(libcppdir)/checkcondition.o \
|
||||
$(libcppdir)/checkersreport.o \
|
||||
$(libcppdir)/checkexceptionsafety.o \
|
||||
$(libcppdir)/checkfunctions.o \
|
||||
$(libcppdir)/checkinternal.o \
|
||||
|
@ -488,6 +489,9 @@ $(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/
|
|||
$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkother.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp
|
||||
|
||||
$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/checkers.h lib/checkersreport.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp
|
||||
|
||||
$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp
|
||||
|
||||
|
@ -638,7 +642,7 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli
|
|||
cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp
|
||||
|
||||
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
|
||||
cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp
|
||||
|
||||
cli/cppcheckexecutorseh.o: cli/cppcheckexecutorseh.cpp cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/utils.h
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="HeaderFiles">
|
||||
<ClInclude Include="..\lib\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cmdlineparser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -44,6 +41,9 @@
|
|||
<ClInclude Include="stacktrace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="singleexecutor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="SourceFiles">
|
||||
<ClCompile Include="main.cpp">
|
||||
|
@ -76,6 +76,9 @@
|
|||
<ClCompile Include="stacktrace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="singleexecutor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="version.rc">
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "analyzerinfo.h"
|
||||
#include "checkers.h"
|
||||
#include "checkersreport.h"
|
||||
#include "cmdlineparser.h"
|
||||
#include "color.h"
|
||||
#include "config.h"
|
||||
|
@ -337,60 +338,13 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool isCppcheckPremium(const Settings& settings) {
|
||||
return (settings.cppcheckCfgProductName.compare(0, 16, "Cppcheck Premium") == 0);
|
||||
}
|
||||
|
||||
static std::string getMisraRuleSeverity(const std::string& rule) {
|
||||
if (checkers::misraRuleSeverity.count(rule) > 0)
|
||||
return checkers::misraRuleSeverity.at(rule);
|
||||
return "style";
|
||||
}
|
||||
|
||||
static bool isMisraRuleInconclusive(const std::string& rule) {
|
||||
return rule == "8.3";
|
||||
}
|
||||
|
||||
static bool isMisraRuleActive(const std::string& rule, int amendment, const std::string& severity, const Settings& settings) {
|
||||
if (!isCppcheckPremium(settings) && amendment >= 3)
|
||||
return false;
|
||||
const bool inconclusive = isMisraRuleInconclusive(rule);
|
||||
if (inconclusive && !settings.certainty.isEnabled(Certainty::inconclusive))
|
||||
return false;
|
||||
if (severity == "warning")
|
||||
return settings.severity.isEnabled(Severity::warning);
|
||||
if (severity == "style")
|
||||
return settings.severity.isEnabled(Severity::style);
|
||||
return true; // error severity
|
||||
}
|
||||
|
||||
void CppCheckExecutor::writeCheckersReport(const Settings& settings) const
|
||||
{
|
||||
CheckersReport checkersReport(settings, mActiveCheckers);
|
||||
|
||||
if (!settings.quiet) {
|
||||
int activeCheckers = 0;
|
||||
int totalCheckers = 0;
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
if (mActiveCheckers.count(checkReq.first) > 0)
|
||||
++activeCheckers;
|
||||
++totalCheckers;
|
||||
}
|
||||
if (isCppcheckPremium(settings)) {
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
if (mActiveCheckers.count(checkReq.first) > 0)
|
||||
++activeCheckers;
|
||||
++totalCheckers;
|
||||
}
|
||||
}
|
||||
if (mSettings->premiumArgs.find("misra-c-") != std::string::npos || mSettings->addons.count("misra")) {
|
||||
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
|
||||
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
|
||||
const std::string severity = getMisraRuleSeverity(rule);
|
||||
const bool active = isMisraRuleActive(rule, info.amendment, severity, settings);
|
||||
if (active)
|
||||
++activeCheckers;
|
||||
++totalCheckers;
|
||||
}
|
||||
}
|
||||
const int activeCheckers = checkersReport.getActiveCheckersCount();
|
||||
const int totalCheckers = checkersReport.getAllCheckersCount();
|
||||
|
||||
const std::string extra = settings.verbose ? " (use --checkers-report=<filename> to see details)" : "";
|
||||
if (mCriticalErrors.empty())
|
||||
|
@ -403,111 +357,9 @@ void CppCheckExecutor::writeCheckersReport(const Settings& settings) const
|
|||
return;
|
||||
|
||||
std::ofstream fout(settings.checkersReportFilename);
|
||||
if (!fout.is_open())
|
||||
return;
|
||||
if (fout.is_open())
|
||||
fout << checkersReport.getReport(mCriticalErrors);
|
||||
|
||||
fout << "Critical errors" << std::endl;
|
||||
fout << "---------------" << std::endl;
|
||||
if (!mCriticalErrors.empty()) {
|
||||
fout << "There was critical errors (" << mCriticalErrors << ")" << std::endl;
|
||||
fout << "All checking is skipped for a file with such error" << std::endl;
|
||||
} else {
|
||||
fout << "No critical errors, all files were checked." << std::endl;
|
||||
fout << "Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives." << std::endl;
|
||||
}
|
||||
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Open source checkers" << std::endl;
|
||||
fout << "--------------------" << std::endl;
|
||||
|
||||
int maxCheckerSize = 0;
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
if (checker.size() > maxCheckerSize)
|
||||
maxCheckerSize = checker.size();
|
||||
}
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
const bool active = mActiveCheckers.count(checkReq.first) > 0;
|
||||
const std::string& req = checkReq.second;
|
||||
fout << (active ? "Yes " : "No ") << checker;
|
||||
if (!active && !req.empty())
|
||||
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
|
||||
fout << std::endl;
|
||||
}
|
||||
|
||||
const bool cppcheckPremium = isCppcheckPremium(settings);
|
||||
|
||||
if (cppcheckPremium) {
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Premium checkers" << std::endl;
|
||||
fout << "----------------" << std::endl;
|
||||
|
||||
maxCheckerSize = 0;
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
if (checker.size() > maxCheckerSize)
|
||||
maxCheckerSize = checker.size();
|
||||
}
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
std::string req = checkReq.second;
|
||||
bool active = cppcheckPremium;
|
||||
if (req == "warning")
|
||||
active &= mSettings->severity.isEnabled(Severity::warning);
|
||||
else if (req == "style")
|
||||
active &= mSettings->severity.isEnabled(Severity::style);
|
||||
fout << (active ? "Yes " : "No ") << checker;
|
||||
if (!req.empty())
|
||||
req = "premium," + req;
|
||||
else
|
||||
req = "premium";
|
||||
if (!active)
|
||||
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
|
||||
fout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int misra = 0;
|
||||
if (mSettings->premiumArgs.find("misra-c-2012") != std::string::npos)
|
||||
misra = 2012;
|
||||
else if (mSettings->premiumArgs.find("misra-c-2023") != std::string::npos)
|
||||
misra = 2023;
|
||||
else if (mSettings->addons.count("misra"))
|
||||
misra = 2012;
|
||||
|
||||
if (misra == 0) {
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Misra C" << std::endl;
|
||||
fout << "-------" << std::endl;
|
||||
fout << "Misra is not enabled" << std::endl;
|
||||
} else {
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Misra C " << misra << std::endl;
|
||||
fout << "------------" << std::endl;
|
||||
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
|
||||
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
|
||||
const std::string severity = getMisraRuleSeverity(rule);
|
||||
const bool active = isMisraRuleActive(rule, info.amendment, severity, settings);
|
||||
const bool inconclusive = isMisraRuleInconclusive(rule);
|
||||
fout << (active ? "Yes " : "No ") << rule;
|
||||
std::string extra;
|
||||
if (misra == 2012 && info.amendment >= 1)
|
||||
extra = " amendment:" + std::to_string(info.amendment);
|
||||
std::string reqs;
|
||||
if (info.amendment >= 3)
|
||||
reqs += ",premium";
|
||||
if (severity != "error")
|
||||
reqs += "," + severity;
|
||||
if (inconclusive)
|
||||
reqs += ",inconclusive";
|
||||
if (!active && !reqs.empty())
|
||||
extra += " require:" + reqs.substr(1);
|
||||
if (!extra.empty())
|
||||
fout << std::string(7 - rule.size(), ' ') << extra;
|
||||
fout << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CppCheckExecutor::loadLibraries(Settings& settings)
|
||||
|
@ -607,7 +459,7 @@ void CppCheckExecutor::reportErr(const ErrorMessage &msg)
|
|||
{
|
||||
assert(mSettings != nullptr);
|
||||
|
||||
if (msg.severity == Severity::none && msg.id == "logChecker") {
|
||||
if (msg.severity == Severity::none && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
|
||||
const std::string& checker = msg.shortMessage();
|
||||
mActiveCheckers.emplace(checker);
|
||||
return;
|
||||
|
|
|
@ -65,6 +65,11 @@ void CheckStatistics::addItem(const QString &tool, ShowTypes::ShowType type)
|
|||
}
|
||||
}
|
||||
|
||||
void CheckStatistics::addChecker(const QString &checker)
|
||||
{
|
||||
mActiveCheckers.insert(checker.toStdString());
|
||||
}
|
||||
|
||||
void CheckStatistics::clear()
|
||||
{
|
||||
mStyle.clear();
|
||||
|
@ -73,6 +78,8 @@ void CheckStatistics::clear()
|
|||
mPortability.clear();
|
||||
mInformation.clear();
|
||||
mError.clear();
|
||||
mActiveCheckers.clear();
|
||||
mCheckersReport.clear();
|
||||
}
|
||||
|
||||
unsigned CheckStatistics::getCount(const QString &tool, ShowTypes::ShowType type) const
|
||||
|
|
|
@ -23,9 +23,13 @@
|
|||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
/// @addtogroup GUI
|
||||
/// @{
|
||||
|
||||
|
@ -44,6 +48,11 @@ public:
|
|||
*/
|
||||
void addItem(const QString &tool, ShowTypes::ShowType type);
|
||||
|
||||
/**
|
||||
* @brief Add checker to statistics
|
||||
*/
|
||||
void addChecker(const QString& checker);
|
||||
|
||||
/**
|
||||
* @brief Clear the statistics.
|
||||
*
|
||||
|
@ -59,9 +68,24 @@ public:
|
|||
*/
|
||||
unsigned getCount(const QString &tool, ShowTypes::ShowType type) const;
|
||||
|
||||
std::set<std::string> getActiveCheckers() const {
|
||||
return mActiveCheckers;
|
||||
}
|
||||
|
||||
int getNumberOfActiveCheckers() const {
|
||||
return mActiveCheckers.size();
|
||||
}
|
||||
|
||||
/** Get tools with results */
|
||||
QStringList getTools() const;
|
||||
|
||||
void setCheckersReport(QString report) {
|
||||
mCheckersReport = std::move(report);
|
||||
}
|
||||
QString getCheckersReport() const {
|
||||
return mCheckersReport;
|
||||
}
|
||||
|
||||
private:
|
||||
QMap<QString, unsigned> mStyle;
|
||||
QMap<QString, unsigned> mWarning;
|
||||
|
@ -69,6 +93,8 @@ private:
|
|||
QMap<QString, unsigned> mPortability;
|
||||
QMap<QString, unsigned> mInformation;
|
||||
QMap<QString, unsigned> mError;
|
||||
std::set<std::string> mActiveCheckers;
|
||||
QString mCheckersReport;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -540,6 +540,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
|
|||
}
|
||||
mThread->setProject(p);
|
||||
mThread->check(checkSettings);
|
||||
mUI->mResults->setCheckSettings(checkSettings);
|
||||
}
|
||||
|
||||
void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrary, const bool checkConfiguration)
|
||||
|
@ -603,6 +604,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar
|
|||
|
||||
mThread->setCheckFiles(true);
|
||||
mThread->check(checkSettings);
|
||||
mUI->mResults->setCheckSettings(checkSettings);
|
||||
}
|
||||
|
||||
void MainWindow::analyzeCode(const QString& code, const QString& filename)
|
||||
|
@ -1208,7 +1210,9 @@ void MainWindow::reAnalyzeSelected(const QStringList& files)
|
|||
// considered in "Modified Files Check" performed after "Selected Files Check"
|
||||
// TODO: Should we store per file CheckStartTime?
|
||||
QDateTime saveCheckStartTime = mThread->getCheckStartTime();
|
||||
mThread->check(getCppcheckSettings());
|
||||
const Settings& checkSettings = getCppcheckSettings();
|
||||
mThread->check(checkSettings);
|
||||
mUI->mResults->setCheckSettings(checkSettings);
|
||||
mThread->setCheckStartTime(saveCheckStartTime);
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1236,9 @@ void MainWindow::reAnalyze(bool all)
|
|||
qDebug() << "Rechecking project file" << mProjectFile->getFilename();
|
||||
|
||||
mThread->setCheckFiles(all);
|
||||
mThread->check(getCppcheckSettings());
|
||||
const Settings& checkSettings = getCppcheckSettings();
|
||||
mThread->check(checkSettings);
|
||||
mUI->mResults->setCheckSettings(checkSettings);
|
||||
}
|
||||
|
||||
void MainWindow::clearResults()
|
||||
|
|
|
@ -193,7 +193,7 @@ public slots:
|
|||
/** @brief Slot for showing the library editor */
|
||||
void showLibraryEditor();
|
||||
|
||||
protected slots:
|
||||
private slots:
|
||||
|
||||
/** @brief Slot for checkthread's done signal */
|
||||
void analysisDone();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "resultsview.h"
|
||||
|
||||
#include "checkstatistics.h"
|
||||
#include "checkersreport.h"
|
||||
#include "codeeditor.h"
|
||||
#include "codeeditorstyle.h"
|
||||
#include "common.h"
|
||||
|
@ -105,6 +106,7 @@ void ResultsView::initialize(QSettings *settings, ApplicationList *list, ThreadH
|
|||
ResultsView::~ResultsView()
|
||||
{
|
||||
delete mUI;
|
||||
delete mCheckSettings;
|
||||
}
|
||||
|
||||
void ResultsView::clear(bool results)
|
||||
|
@ -116,6 +118,8 @@ void ResultsView::clear(bool results)
|
|||
mUI->mDetails->setText(QString());
|
||||
|
||||
mStatistics->clear();
|
||||
delete mCheckSettings;
|
||||
mCheckSettings = nullptr;
|
||||
|
||||
//Clear the progressbar
|
||||
mUI->mProgress->setMaximum(PROGRESS_MAX);
|
||||
|
@ -150,6 +154,11 @@ void ResultsView::progress(int value, const QString& description)
|
|||
|
||||
void ResultsView::error(const ErrorItem &item)
|
||||
{
|
||||
if (item.severity == Severity::none && (item.errorId == "logChecker" || item.errorId.endsWith("-logChecker"))) {
|
||||
mStatistics->addChecker(item.message);
|
||||
return;
|
||||
}
|
||||
|
||||
handleCriticalError(item);
|
||||
|
||||
if (mUI->mTree->addErrorItem(item)) {
|
||||
|
@ -282,6 +291,13 @@ QString ResultsView::getCheckDirectory()
|
|||
return mUI->mTree->getCheckDirectory();
|
||||
}
|
||||
|
||||
void ResultsView::setCheckSettings(const Settings &settings)
|
||||
{
|
||||
delete mCheckSettings;
|
||||
mCheckSettings = new Settings;
|
||||
*mCheckSettings = settings;
|
||||
}
|
||||
|
||||
void ResultsView::checkingStarted(int count)
|
||||
{
|
||||
mSuccess = true;
|
||||
|
@ -296,6 +312,13 @@ void ResultsView::checkingFinished()
|
|||
mUI->mProgress->setVisible(false);
|
||||
mUI->mProgress->setFormat("%p%");
|
||||
|
||||
{
|
||||
Settings checkSettings;
|
||||
const std::set<std::string> activeCheckers = mStatistics->getActiveCheckers();
|
||||
CheckersReport checkersReport(mCheckSettings ? *mCheckSettings : checkSettings, activeCheckers);
|
||||
mStatistics->setCheckersReport(QString::fromStdString(checkersReport.getReport(mCriticalErrors.toStdString())));
|
||||
}
|
||||
|
||||
// TODO: Items can be mysteriously hidden when checking is finished, this function
|
||||
// call should be redundant but it "unhides" the wrongly hidden items.
|
||||
mUI->mTree->refreshTree();
|
||||
|
@ -528,6 +551,11 @@ void ResultsView::stopAnalysis()
|
|||
void ResultsView::handleCriticalError(const ErrorItem &item)
|
||||
{
|
||||
if (ErrorLogger::isCriticalErrorId(item.errorId.toStdString())) {
|
||||
if (!mCriticalErrors.contains(item.errorId)) {
|
||||
if (!mCriticalErrors.isEmpty())
|
||||
mCriticalErrors += ",";
|
||||
mCriticalErrors += item.errorId;
|
||||
}
|
||||
QString msg = tr("There was a critical error with id '%1'").arg(item.errorId);
|
||||
if (!item.file0.isEmpty())
|
||||
msg += ", " + tr("when checking %1").arg(item.file0);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <QWidget>
|
||||
|
||||
class ErrorItem;
|
||||
class Settings;
|
||||
class ApplicationList;
|
||||
class ThreadHandler;
|
||||
class QModelIndex;
|
||||
|
@ -136,6 +137,11 @@ public:
|
|||
|
||||
QString getCheckDirectory();
|
||||
|
||||
/**
|
||||
* Set settings used in checking
|
||||
*/
|
||||
void setCheckSettings(const Settings& settings);
|
||||
|
||||
/**
|
||||
* @brief Inform the view that checking has started
|
||||
*
|
||||
|
@ -368,11 +374,16 @@ private:
|
|||
|
||||
CheckStatistics *mStatistics;
|
||||
|
||||
Settings* mCheckSettings = nullptr;
|
||||
|
||||
/**
|
||||
* Set to true when checking finish successfully. Set to false whenever analysis starts.
|
||||
*/
|
||||
bool mSuccess = false;
|
||||
|
||||
/** Critical error ids */
|
||||
QString mCriticalErrors;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Custom context menu for Analysis Log
|
||||
|
|
|
@ -75,6 +75,10 @@ StatsDialog::StatsDialog(QWidget *parent)
|
|||
{
|
||||
mUI->setupUi(this);
|
||||
|
||||
QFont font("courier");
|
||||
font.setStyleHint(QFont::Monospace);
|
||||
mUI->mCheckersReport->setFont(font);
|
||||
|
||||
setWindowFlags(Qt::Window);
|
||||
|
||||
connect(mUI->mCopyToClipboard, &QPushButton::pressed, this, &StatsDialog::copyToClipboard);
|
||||
|
@ -366,12 +370,14 @@ void StatsDialog::copyToClipboard()
|
|||
void StatsDialog::setStatistics(const CheckStatistics *stats)
|
||||
{
|
||||
mStatistics = stats;
|
||||
mUI->mLblErrors->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowErrors)));
|
||||
mUI->mLblWarnings->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowWarnings)));
|
||||
mUI->mLblStyle->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowStyle)));
|
||||
mUI->mLblPortability->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowPortability)));
|
||||
mUI->mLblPerformance->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowPerformance)));
|
||||
mUI->mLblInformation->setText(QString("%1").arg(stats->getCount(CPPCHECK,ShowTypes::ShowInformation)));
|
||||
mUI->mLblErrors->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowErrors)));
|
||||
mUI->mLblWarnings->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowWarnings)));
|
||||
mUI->mLblStyle->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowStyle)));
|
||||
mUI->mLblPortability->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowPortability)));
|
||||
mUI->mLblPerformance->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowPerformance)));
|
||||
mUI->mLblInformation->setText(QString::number(stats->getCount(CPPCHECK,ShowTypes::ShowInformation)));
|
||||
mUI->mLblActiveCheckers->setText(QString::number(stats->getNumberOfActiveCheckers()));
|
||||
mUI->mCheckersReport->setPlainText(stats->getCheckersReport());
|
||||
}
|
||||
|
||||
#ifdef QT_CHARTS_LIB
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>502</width>
|
||||
<height>274</height>
|
||||
<width>500</width>
|
||||
<height>414</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -247,114 +247,150 @@
|
|||
<attribute name="title">
|
||||
<string>Statistics</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Errors:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblErrors">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Errors:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="mLblErrors">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Warnings:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblWarnings">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Warnings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="mLblWarnings">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Stylistic warnings:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblStyle">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Stylistic warnings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="mLblStyle">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Portability warnings:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblPortability">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Portability warnings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="mLblPortability">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Performance issues:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblPerformance">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Performance issues:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="mLblPerformance">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Information messages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLblInformation">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Information messages:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="mLblInformation">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Active checkers:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="mLblActiveCheckers">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mCheckersTab">
|
||||
<attribute name="title">
|
||||
<string>Checkers</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="mCheckersReport">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier 10 Pitch</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -206,22 +206,21 @@ namespace checkers {
|
|||
|
||||
|
||||
static std::map<std::string, std::string> premiumCheckers{
|
||||
{"CheckBufferOverrun::addressOfPointerArithmetic","warning"},
|
||||
{"CheckBufferOverrun::negativeBufferSizeCheckedNonZero","warning"},
|
||||
{"CheckBufferOverrun::negativeBufferSizeCheckedNonZero","warning"},
|
||||
{"CheckHang::infiniteLoop",""},
|
||||
{"CheckHang::infiniteLoopContinue",""},
|
||||
{"CheckOther::arrayPointerComparison","style"},
|
||||
{"CheckOther::knownResult","style"},
|
||||
{"CheckOther::lossOfPrecision","style"},
|
||||
{"CheckOther::pointerCast","style"},
|
||||
{"CheckOther::reassignInLoop","style"},
|
||||
{"CheckOther::unreachableCode","style"},
|
||||
{"CheckStrictAlias::strictAliasCondition","warning"},
|
||||
{"CheckUninitVar::uninitvar",""},
|
||||
{"CheckUninitVar::uninitmember",""},
|
||||
{"CheckUnusedVar::unreadVariable","style"},
|
||||
{"CheckUnusedVar::unusedPrivateMember","style"},
|
||||
{"PremiumCheckBufferOverrun::addressOfPointerArithmetic","warning"},
|
||||
{"PremiumCheckBufferOverrun::negativeBufferSizeCheckedNonZero","warning"},
|
||||
{"PremiumCheckBufferOverrun::negativeBufferSizeCheckedNonZero","warning"},
|
||||
{"PremiumCheckHang::infiniteLoop",""},
|
||||
{"PremiumCheckHang::infiniteLoopContinue",""},
|
||||
{"PremiumCheckOther::arrayPointerComparison","style"},
|
||||
{"PremiumCheckOther::knownResult","style"},
|
||||
{"PremiumCheckOther::lossOfPrecision","style"},
|
||||
{"PremiumCheckOther::pointerCast","style"},
|
||||
{"PremiumCheckOther::reassignInLoop","style"},
|
||||
{"PremiumCheckOther::unreachableCode","style"},
|
||||
{"PremiumCheckUninitVar::uninitvar",""},
|
||||
{"PremiumCheckUninitVar::uninitmember",""},
|
||||
{"PremiumCheckUnusedVar::unreadVariable","style"},
|
||||
{"PremiumCheckUnusedVar::unusedPrivateMember","style"},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2023 Cppcheck team.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "checkersreport.h"
|
||||
#include "checkers.h"
|
||||
#include <sstream>
|
||||
|
||||
static bool isCppcheckPremium(const Settings& settings) {
|
||||
return (settings.cppcheckCfgProductName.compare(0, 16, "Cppcheck Premium") == 0);
|
||||
}
|
||||
|
||||
static std::string getMisraRuleSeverity(const std::string& rule) {
|
||||
if (checkers::misraRuleSeverity.count(rule) > 0)
|
||||
return checkers::misraRuleSeverity.at(rule);
|
||||
return "style";
|
||||
}
|
||||
|
||||
static bool isMisraRuleInconclusive(const std::string& rule) {
|
||||
return rule == "8.3";
|
||||
}
|
||||
|
||||
static bool isMisraRuleActive(const std::string& rule, int amendment, const std::string& severity, const Settings& settings) {
|
||||
if (!isCppcheckPremium(settings) && amendment >= 3)
|
||||
return false;
|
||||
const bool inconclusive = isMisraRuleInconclusive(rule);
|
||||
if (inconclusive && !settings.certainty.isEnabled(Certainty::inconclusive))
|
||||
return false;
|
||||
if (severity == "warning")
|
||||
return settings.severity.isEnabled(Severity::warning);
|
||||
if (severity == "style")
|
||||
return settings.severity.isEnabled(Severity::style);
|
||||
return true; // error severity
|
||||
}
|
||||
|
||||
CheckersReport::CheckersReport(const Settings& settings, const std::set<std::string>& activeCheckers)
|
||||
: mSettings(settings), mActiveCheckers(activeCheckers)
|
||||
{}
|
||||
|
||||
int CheckersReport::getActiveCheckersCount()
|
||||
{
|
||||
if (mAllCheckersCount == 0) {
|
||||
countCheckers();
|
||||
}
|
||||
return mActiveCheckersCount;
|
||||
}
|
||||
|
||||
int CheckersReport::getAllCheckersCount()
|
||||
{
|
||||
if (mAllCheckersCount == 0) {
|
||||
countCheckers();
|
||||
}
|
||||
return mAllCheckersCount;
|
||||
}
|
||||
|
||||
void CheckersReport::countCheckers()
|
||||
{
|
||||
mActiveCheckersCount = mAllCheckersCount = 0;
|
||||
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
if (mActiveCheckers.count(checkReq.first) > 0)
|
||||
++mActiveCheckersCount;
|
||||
++mAllCheckersCount;
|
||||
}
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
if (mActiveCheckers.count(checkReq.first) > 0)
|
||||
++mActiveCheckersCount;
|
||||
++mAllCheckersCount;
|
||||
}
|
||||
if (mSettings.premiumArgs.find("misra-c-") != std::string::npos || mSettings.addons.count("misra")) {
|
||||
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
|
||||
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
|
||||
const std::string severity = getMisraRuleSeverity(rule);
|
||||
const bool active = isMisraRuleActive(rule, info.amendment, severity, mSettings);
|
||||
if (active)
|
||||
++mActiveCheckersCount;
|
||||
++mAllCheckersCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CheckersReport::getReport(const std::string& criticalErrors) const
|
||||
{
|
||||
std::ostringstream fout;
|
||||
|
||||
fout << "Critical errors" << std::endl;
|
||||
fout << "---------------" << std::endl;
|
||||
if (!criticalErrors.empty()) {
|
||||
fout << "There was critical errors (" << criticalErrors << ")" << std::endl;
|
||||
fout << "All checking is skipped for a file with such error" << std::endl;
|
||||
} else {
|
||||
fout << "No critical errors, all files were checked." << std::endl;
|
||||
fout << "Important: Analysis is still not guaranteed to be 'complete' it is possible there are false negatives." << std::endl;
|
||||
}
|
||||
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Open source checkers" << std::endl;
|
||||
fout << "--------------------" << std::endl;
|
||||
|
||||
int maxCheckerSize = 0;
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
if (checker.size() > maxCheckerSize)
|
||||
maxCheckerSize = checker.size();
|
||||
}
|
||||
for (const auto& checkReq: checkers::allCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
const bool active = mActiveCheckers.count(checkReq.first) > 0;
|
||||
const std::string& req = checkReq.second;
|
||||
fout << (active ? "Yes " : "No ") << checker;
|
||||
if (!active && !req.empty())
|
||||
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
|
||||
fout << std::endl;
|
||||
}
|
||||
|
||||
const bool cppcheckPremium = isCppcheckPremium(mSettings);
|
||||
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Premium checkers" << std::endl;
|
||||
fout << "----------------" << std::endl;
|
||||
if (!cppcheckPremium) {
|
||||
fout << "Cppcheck Premium is not used" << std::endl;
|
||||
} else {
|
||||
maxCheckerSize = 0;
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
if (checker.size() > maxCheckerSize)
|
||||
maxCheckerSize = checker.size();
|
||||
}
|
||||
for (const auto& checkReq: checkers::premiumCheckers) {
|
||||
const std::string& checker = checkReq.first;
|
||||
std::string req = checkReq.second;
|
||||
bool active = cppcheckPremium && mActiveCheckers.count(checkReq.first) > 0;
|
||||
if (req == "warning")
|
||||
active &= mSettings.severity.isEnabled(Severity::warning);
|
||||
else if (req == "style")
|
||||
active &= mSettings.severity.isEnabled(Severity::style);
|
||||
else if (!req.empty())
|
||||
active = false; // FIXME: handle req
|
||||
fout << (active ? "Yes " : "No ") << checker;
|
||||
if (!req.empty())
|
||||
req = "premium," + req;
|
||||
else
|
||||
req = "premium";
|
||||
if (!active)
|
||||
fout << std::string(maxCheckerSize + 4 - checker.size(), ' ') << "require:" + req;
|
||||
fout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int misra = 0;
|
||||
if (mSettings.premiumArgs.find("misra-c-2012") != std::string::npos)
|
||||
misra = 2012;
|
||||
else if (mSettings.premiumArgs.find("misra-c-2023") != std::string::npos)
|
||||
misra = 2023;
|
||||
else if (mSettings.addons.count("misra"))
|
||||
misra = 2012;
|
||||
|
||||
if (misra == 0) {
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Misra C" << std::endl;
|
||||
fout << "-------" << std::endl;
|
||||
fout << "Misra is not enabled" << std::endl;
|
||||
} else {
|
||||
fout << std::endl << std::endl;
|
||||
fout << "Misra C " << misra << std::endl;
|
||||
fout << "------------" << std::endl;
|
||||
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
|
||||
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
|
||||
const std::string severity = getMisraRuleSeverity(rule);
|
||||
const bool active = isMisraRuleActive(rule, info.amendment, severity, mSettings);
|
||||
const bool inconclusive = isMisraRuleInconclusive(rule);
|
||||
fout << (active ? "Yes " : "No ") << rule;
|
||||
std::string extra;
|
||||
if (misra == 2012 && info.amendment >= 1)
|
||||
extra = " amendment:" + std::to_string(info.amendment);
|
||||
std::string reqs;
|
||||
if (info.amendment >= 3)
|
||||
reqs += ",premium";
|
||||
if (severity != "error")
|
||||
reqs += "," + severity;
|
||||
if (inconclusive)
|
||||
reqs += ",inconclusive";
|
||||
if (!active && !reqs.empty())
|
||||
extra += " require:" + reqs.substr(1);
|
||||
if (!extra.empty())
|
||||
fout << std::string(7 - rule.size(), ' ') << extra;
|
||||
fout << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return fout.str();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2023 Cppcheck team.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "settings.h"
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
class CPPCHECKLIB CheckersReport {
|
||||
public:
|
||||
CheckersReport(const Settings& settings, const std::set<std::string>& activeCheckers);
|
||||
|
||||
int getActiveCheckersCount();
|
||||
int getAllCheckersCount();
|
||||
|
||||
std::string getReport(const std::string& criticalErrors) const;
|
||||
|
||||
private:
|
||||
const Settings& mSettings;
|
||||
const std::set<std::string>& mActiveCheckers;
|
||||
|
||||
void countCheckers();
|
||||
|
||||
int mActiveCheckersCount = 0;
|
||||
int mAllCheckersCount = 0;
|
||||
};
|
||||
|
||||
|
|
@ -1492,9 +1492,11 @@ void CppCheck::executeAddons(const std::vector<std::string>& files)
|
|||
errmsg.setmsg(text);
|
||||
const std::string severity = obj["severity"].get<std::string>();
|
||||
errmsg.severity = Severity::fromString(severity);
|
||||
if (errmsg.severity == Severity::SeverityType::none)
|
||||
continue;
|
||||
if (!mSettings.severity.isEnabled(errmsg.severity))
|
||||
if (errmsg.severity == Severity::SeverityType::none) {
|
||||
if (!endsWith(errmsg.id, "-logChecker"))
|
||||
continue;
|
||||
}
|
||||
else if (!mSettings.severity.isEnabled(errmsg.severity))
|
||||
continue;
|
||||
errmsg.file0 = ((files.size() == 1) ? files[0] : "");
|
||||
|
||||
|
@ -1596,7 +1598,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st
|
|||
|
||||
void CppCheck::reportErr(const ErrorMessage &msg)
|
||||
{
|
||||
if (msg.severity == Severity::none && msg.id == "logChecker") {
|
||||
if (msg.severity == Severity::none && (msg.id == "logChecker" || endsWith(msg.id, "-logChecker"))) {
|
||||
mErrorLogger.reportErr(msg);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<ClCompile Include="checkbufferoverrun.cpp" />
|
||||
<ClCompile Include="checkclass.cpp" />
|
||||
<ClCompile Include="checkcondition.cpp" />
|
||||
<ClCompile Include="checkersreport.cpp" />
|
||||
<ClCompile Include="checkexceptionsafety.cpp" />
|
||||
<ClCompile Include="checkfunctions.cpp" />
|
||||
<ClCompile Include="checkinternal.cpp" />
|
||||
|
@ -122,6 +123,7 @@
|
|||
<ClInclude Include="checkbufferoverrun.h" />
|
||||
<ClInclude Include="checkclass.h" />
|
||||
<ClInclude Include="checkcondition.h" />
|
||||
<ClInclude Include="checkersreport.h" />
|
||||
<ClInclude Include="checkexceptionsafety.h" />
|
||||
<ClInclude Include="checkfunctions.h" />
|
||||
<ClInclude Include="checkinternal.h" />
|
||||
|
|
|
@ -194,6 +194,12 @@
|
|||
<ClCompile Include="vfvalue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="checkersreport.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="keywords.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="HeaderFiles">
|
||||
<ClInclude Include="checkbufferoverrun.h">
|
||||
|
@ -406,6 +412,15 @@
|
|||
<ClInclude Include="vfvalue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="keywords.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="checkersreport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="version.rc" />
|
||||
|
|
|
@ -45,6 +45,7 @@ const std::set<std::string> ErrorLogger::mCriticalErrorIds{
|
|||
"internalAstError",
|
||||
"instantiationError",
|
||||
"internalError",
|
||||
"premium-internalError",
|
||||
"preprocessorErrorDirective",
|
||||
"syntaxError",
|
||||
"unknownMacro"
|
||||
|
|
|
@ -16,6 +16,7 @@ HEADERS += $${PWD}/analyzer.h \
|
|||
$${PWD}/checkbufferoverrun.h \
|
||||
$${PWD}/checkclass.h \
|
||||
$${PWD}/checkcondition.h \
|
||||
$${PWD}/checkersreport.h \
|
||||
$${PWD}/checkexceptionsafety.h \
|
||||
$${PWD}/checkfunctions.h \
|
||||
$${PWD}/checkinternal.h \
|
||||
|
@ -85,6 +86,7 @@ SOURCES += $${PWD}/analyzerinfo.cpp \
|
|||
$${PWD}/checkbufferoverrun.cpp \
|
||||
$${PWD}/checkclass.cpp \
|
||||
$${PWD}/checkcondition.cpp \
|
||||
$${PWD}/checkersreport.cpp \
|
||||
$${PWD}/checkexceptionsafety.cpp \
|
||||
$${PWD}/checkfunctions.cpp \
|
||||
$${PWD}/checkinternal.cpp \
|
||||
|
|
|
@ -10,8 +10,12 @@ Improved checking:
|
|||
- constParameter*/constVariable* checks find more instances of pointers/references that can be const, e.g. when calling library functions
|
||||
|
||||
GUI:
|
||||
- Show in statistics which checkers have been activated in latest analysis
|
||||
- Make it more visible if there has been critical errors that caused checkers to be skipped
|
||||
|
||||
Changed interface:
|
||||
- Write how many checkers was activated after a run
|
||||
- Added --checkers-report that can be used to generate a report in a file that shows what checkers was activated and disabled
|
||||
|
||||
Deprecations:
|
||||
- The qmake build system has been deprecated and will be removed in a future version.
|
||||
|
|
|
@ -256,6 +256,9 @@
|
|||
<ClCompile Include="testsingleexecutor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="testcheck.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="HeaderFiles">
|
||||
<ClInclude Include="options.h">
|
||||
|
|
|
@ -44,22 +44,22 @@ print('static std::map<std::string, std::string> premiumCheckers{')
|
|||
|
||||
premium_checkers = """
|
||||
$ grep logChecker *.cpp | sed 's/.*logChecker/logChecker/'
|
||||
logChecker("CheckBufferOverrun::addressOfPointerArithmetic"); // warning
|
||||
logChecker("CheckBufferOverrun::negativeBufferSizeCheckedNonZero"); // warning
|
||||
logChecker("CheckBufferOverrun::negativeBufferSizeCheckedNonZero"); // warning
|
||||
logChecker("CheckHang::infiniteLoop");
|
||||
logChecker("CheckHang::infiniteLoopContinue");
|
||||
logChecker("CheckOther::arrayPointerComparison"); // style
|
||||
logChecker("CheckOther::knownResult"); // style
|
||||
logChecker("CheckOther::lossOfPrecision"); // style
|
||||
logChecker("CheckOther::pointerCast"); // style
|
||||
logChecker("CheckOther::reassignInLoop"); // style
|
||||
logChecker("CheckOther::unreachableCode"); // style
|
||||
logChecker("CheckStrictAlias::strictAliasCondition"); // warning
|
||||
logChecker("CheckUninitVar::uninitvar");
|
||||
logChecker("CheckUninitVar::uninitmember");
|
||||
logChecker("CheckUnusedVar::unreadVariable"); // style
|
||||
logChecker("CheckUnusedVar::unusedPrivateMember"); // style
|
||||
logChecker("PremiumCheckBufferOverrun::addressOfPointerArithmetic"); // warning
|
||||
logChecker("PremiumCheckBufferOverrun::negativeBufferSizeCheckedNonZero"); // warning
|
||||
logChecker("PremiumCheckBufferOverrun::negativeBufferSizeCheckedNonZero"); // warning
|
||||
logChecker("PremiumCheckHang::infiniteLoop");
|
||||
logChecker("PremiumCheckHang::infiniteLoopContinue");
|
||||
logChecker("PremiumCheckOther::arrayPointerComparison"); // style
|
||||
logChecker("PremiumCheckOther::knownResult"); // style
|
||||
logChecker("PremiumCheckOther::lossOfPrecision"); // style
|
||||
logChecker("PremiumCheckOther::pointerCast"); // style
|
||||
logChecker("PremiumCheckOther::reassignInLoop"); // style
|
||||
logChecker("PremiumCheckOther::unreachableCode"); // style
|
||||
logChecker("PremiumCheckStrictAlias::strictAliasCondition"); // warning
|
||||
logChecker("PremiumCheckUninitVar::uninitvar");
|
||||
logChecker("PremiumCheckUninitVar::uninitmember");
|
||||
logChecker("PremiumCheckUnusedVar::unreadVariable"); // style
|
||||
logChecker("PremiumCheckUnusedVar::unusedPrivateMember"); // style
|
||||
"""
|
||||
|
||||
for line in premium_checkers.split('\n'):
|
||||
|
|
Loading…
Reference in New Issue