Skip to content
Closed
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
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ MAN_SOURCE=man/cppcheck.1.xml

###### Object Files

LIBOBJ = $(libcppdir)/analyzerinfo.o \
LIBOBJ = $(libcppdir)/addonutils.o \
$(libcppdir)/analyzerinfo.o \
$(libcppdir)/astutils.o \
$(libcppdir)/check.o \
$(libcppdir)/check64bit.o \
Expand Down Expand Up @@ -218,6 +219,7 @@ CLIOBJ = cli/cmdlineparser.o \

TESTOBJ = test/options.o \
test/test64bit.o \
test/testaddonutils.o \
test/testassert.o \
test/testastutils.o \
test/testautovariables.o \
Expand Down Expand Up @@ -393,6 +395,9 @@ validateRules:

###### Build

$(libcppdir)/addonutils.o: lib/addonutils.cpp externals/picojson.h lib/addonutils.h lib/config.h lib/errorlogger.h lib/path.h lib/suppressions.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/addonutils.o $(libcppdir)/addonutils.cpp

$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/importproject.h lib/path.h lib/platform.h lib/suppressions.h lib/utils.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/analyzerinfo.o $(libcppdir)/analyzerinfo.cpp

Expand Down Expand Up @@ -477,7 +482,7 @@ $(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h
$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkvaarg.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/checkvaarg.o $(libcppdir)/checkvaarg.cpp

$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkunusedfunctions.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h
$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/simplecpp/simplecpp.h externals/tinyxml/tinyxml2.h lib/addonutils.h lib/analyzerinfo.h lib/check.h lib/checkunusedfunctions.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/exprengine.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o $(libcppdir)/cppcheck.o $(libcppdir)/cppcheck.cpp

$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h
Expand Down Expand Up @@ -564,6 +569,9 @@ test/options.o: test/options.cpp test/options.h
test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/test64bit.o test/test64bit.cpp

test/testaddonutils.o: test/testaddonutils.cpp lib/addonutils.h lib/config.h lib/errorlogger.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 test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testaddonutils.o test/testaddonutils.cpp

test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/config.h lib/errorlogger.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testassert.o test/testassert.cpp

Expand Down
87 changes: 49 additions & 38 deletions gui/checkthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <QJsonObject>
#include <QProcess>
#include <QSettings>

#include "addonutils.h"
#include "checkthread.h"
#include "erroritem.h"
#include "threadresult.h"
Expand Down Expand Up @@ -112,9 +114,13 @@ void CheckThread::run()
void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSettings, const QString &fileName)
{
QString dumpFile;
auto disabled_addons = QStringList();

foreach (const QString addon_name, mAddonsAndTools) {
if (disabled_addons.contains(addon_name))
continue;

foreach (const QString addon, mAddonsAndTools) {
if (addon == CLANG_ANALYZER || addon == CLANG_TIDY) {
if (addon_name == CLANG_ANALYZER || addon_name == CLANG_TIDY) {
if (!fileSettings)
continue;

Expand Down Expand Up @@ -196,15 +202,15 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti
const QByteArray &ba = process.readAllStandardOutput();
const quint16 chksum = qChecksum(ba.data(), ba.length());

QFile f1(analyzerInfoFile + '.' + addon + "-E");
QFile f1(analyzerInfoFile + '.' + addon_name + "-E");
if (f1.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in1(&f1);
const quint16 oldchksum = in1.readAll().toInt();
if (oldchksum == chksum) {
QFile f2(analyzerInfoFile + '.' + addon + "-results");
QFile f2(analyzerInfoFile + '.' + addon_name + "-results");
if (f2.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in2(&f2);
parseClangErrors(addon, fileName, in2.readAll());
parseClangErrors(addon_name, fileName, in2.readAll());
continue;
}
}
Expand All @@ -214,10 +220,10 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti
QTextStream out1(&f1);
out1 << chksum;

QFile::remove(analyzerInfoFile + '.' + addon + "-results");
QFile::remove(analyzerInfoFile + '.' + addon_name + "-results");
}

if (addon == CLANG_ANALYZER) {
if (addon_name == CLANG_ANALYZER) {
/*
// Using clang
args.insert(0,"--analyze");
Expand Down Expand Up @@ -247,7 +253,7 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti
qDebug() << debug;

if (!analyzerInfoFile.isEmpty()) {
QFile f(analyzerInfoFile + '.' + addon + "-cmd");
QFile f(analyzerInfoFile + '.' + addon_name + "-cmd");
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&f);
out << debug;
Expand All @@ -260,22 +266,32 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti
process.waitForFinished(600*1000);
const QString errout(process.readAllStandardOutput() + "\n\n\n" + process.readAllStandardError());
if (!analyzerInfoFile.isEmpty()) {
QFile f(analyzerInfoFile + '.' + addon + "-results");
QFile f(analyzerInfoFile + '.' + addon_name + "-results");
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&f);
out << errout;
}
}

parseClangErrors(addon, fileName, errout);
parseClangErrors(addon_name, fileName, errout);
} else {
const QString python = CheckThread::pythonCmd();
if (python.isEmpty())
if (python.isEmpty()) {
emit showCheckError("python-error",
tr("Addon error").arg(addon_name),
tr("Python is not available.\nAddons will be disabled for current check.").arg(addon_name));
disabled_addons.append(addon_name);
continue;
}

const QString addonFilePath = CheckThread::getAddonFilePath(mDataDir, addon + ".py");
if (addonFilePath.isEmpty())
const QString addonFilePath = CheckThread::getAddonFilePath(mDataDir, addon_name + ".py");
if (addonFilePath.isEmpty()) {
emit showCheckError(addon_name + "-error",
tr("Addon error"),
tr("Addon file %1 is not available.\n%2 addon will be disabled for current check.").arg(addonFilePath).arg(addon_name));
disabled_addons.append(addon_name);
continue;
}

if (dumpFile.isEmpty()) {
const std::string buildDir = mCppcheck.settings().buildDir;
Expand All @@ -296,32 +312,27 @@ void CheckThread::runAddonsAndTools(const ImportProject::FileSettings *fileSetti
mCppcheck.settings().buildDir = buildDir;
}

QStringList args;
args << addonFilePath << "--cli" << dumpFile;
if (addon == "misra" && !mMisraFile.isEmpty() && QFileInfo(mMisraFile).exists()) {
if (mMisraFile.endsWith(".pdf", Qt::CaseInsensitive))
args << "--misra-pdf=" + mMisraFile;
else
args << "--rule-texts=" + mMisraFile;
}
qDebug() << python << args;
try {
auto addon = Addon(addonFilePath.toStdString(), mCppcheck.settings().exename);
if (addon_name == "misra" && !mMisraFile.isEmpty() && QFileInfo(mMisraFile).exists())
addon.appendArgs("--rule-texts=" + mMisraFile.toStdString());

QProcess process;
QProcessEnvironment env = process.processEnvironment();
if (!env.contains("PYTHONHOME") && !python.startsWith("python")) {
env.insert("PYTHONHOME", QFileInfo(python).canonicalPath());
process.setProcessEnvironment(env);
}
process.start(python, args);
process.waitForFinished();
const QString output(process.readAllStandardOutput());
QFile f(dumpFile + '-' + addon + "-results");
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&f);
out << output;
f.close();
// Set appropriate PYTHONPATH if user was choice non-standard value in settings
QProcess process;
QProcessEnvironment env = process.processEnvironment();
if (!env.contains("PYTHONHOME") && !python.startsWith("python"))
addon.setEnv("PYTHONHOME", QFileInfo(python).canonicalPath().toStdString());

auto results = QString::fromStdString(addon.execute(dumpFile.toStdString()));
parseAddonErrors(results, addon_name);
} catch (const InternalError &e) {
emit showCheckError(addon_name + "-error",
tr("Addon error"),

tr("There is some problems with '%1' addon: %2.\nIt will be disabled for current check.").arg(QString::fromStdString(e.errorMessage)));
disabled_addons.append(addon_name);
continue;
}
parseAddonErrors(output, addon);
}
}
}
Expand All @@ -332,7 +343,7 @@ void CheckThread::stop()
mCppcheck.terminate();
}

void CheckThread::parseAddonErrors(QString err, const QString &tool)
void CheckThread::parseAddonErrors(QString &err, const QString &tool)
{
Q_UNUSED(tool);
QTextStream in(&err, QIODevice::ReadOnly);
Expand Down
12 changes: 11 additions & 1 deletion gui/checkthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class CheckThread : public QThread {
void done();

void fileChecked(const QString &file);

/** @brief Show error occurred during check. */
void showCheckError(const QString &id, const QString &title, const QString &text, bool once = true);

protected:

/**
Expand Down Expand Up @@ -144,7 +148,13 @@ class CheckThread : public QThread {
private:
void runAddonsAndTools(const ImportProject::FileSettings *fileSettings, const QString &fileName);

void parseAddonErrors(QString err, const QString &tool);
/**
* @brief Fill GUI representation with errors from addon output
* @param err Addon output
* @param tool Name of addon
*/
void parseAddonErrors(QString &err, const QString &tool);

void parseClangErrors(const QString &tool, const QString &file0, QString err);

bool isSuppressed(const Suppressions::ErrorMessage &errorMessage) const;
Expand Down
4 changes: 4 additions & 0 deletions gui/threadhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ void ThreadHandler::setThreadCount(const int count)
this, &ThreadHandler::threadDone);
connect(mThreads.last(), &CheckThread::fileChecked,
&mResults, &ThreadResult::fileChecked);
connect(mThreads.last(), &CheckThread::showCheckError,
&mResults, &ThreadResult::showCheckError);
}
}

Expand All @@ -143,6 +145,8 @@ void ThreadHandler::removeThreads()
this, &ThreadHandler::threadDone);
disconnect(mThreads[i], &CheckThread::fileChecked,
&mResults, &ThreadResult::fileChecked);
disconnect(mThreads[i], &CheckThread::showCheckError,
&mResults, &ThreadResult::showCheckError);
delete mThreads[i];
}

Expand Down
10 changes: 10 additions & 0 deletions gui/threadresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <QList>
#include <QStringList>
#include <QDebug>
#include <QMessageBox>
#include <QSet>
#include "common.h"
#include "erroritem.h"
#include "errorlogger.h"
Expand Down Expand Up @@ -57,6 +59,14 @@ void ThreadResult::fileChecked(const QString &file)
}
}

void ThreadResult::showCheckError(const QString &id, const QString &title, const QString &text, bool once)
{
if (!mShownErrorIds.contains(id) || !once) {
mShownErrorIds.insert(id);
QMessageBox::critical(NULL, title, text);
}
}

void ThreadResult::reportErr(const ErrorLogger::ErrorMessage &msg)
{
QMutexLocker locker(&mutex);
Expand Down
16 changes: 16 additions & 0 deletions gui/threadresult.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <QMutex>
#include <QObject>
#include <QStringList>
#include <QSet>
#include "errorlogger.h"
#include "importproject.h"

Expand Down Expand Up @@ -82,6 +83,16 @@ public slots:
* @param file File that is checked
*/
void fileChecked(const QString &file);

/**
* @brief Display an error occurred during check.
* @param id Unique error identifier
* @param title Error title
* @param text Error text
* @param once If true, show error with this identifier only once
*/
void showCheckError(const QString &id, const QString &title, const QString &text, bool once = true);

signals:
/**
* @brief Progress signal
Expand Down Expand Up @@ -150,6 +161,11 @@ public slots:
*
*/
unsigned long mTotalFiles;

/**
* @brief Identifiers of errors occurred during check that has been shown.
*/
QSet<QString> mShownErrorIds;
};
/// @}
#endif // THREADRESULT_H
Loading