Skip to content

Commit

Permalink
Fix #12389 (GUI: premiumaddon is not executed properly anymore)
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar committed Feb 1, 2024
1 parent 485df98 commit 192c1c2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 24 deletions.
73 changes: 51 additions & 22 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ void MainWindow::saveSettings() const

void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, const bool checkConfiguration)
{
Settings checkSettings = getCppcheckSettings();
if (Settings::terminated())
return;

clearResults();

mIsLogfileLoaded = false;
Expand Down Expand Up @@ -522,7 +526,6 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
checkLockDownUI(); // lock UI while checking

mUI->mResults->setCheckDirectory(checkPath);
Settings checkSettings = getCppcheckSettings();
checkSettings.force = false;
checkSettings.checkLibrary = checkLibrary;
checkSettings.checkConfiguration = checkConfiguration;
Expand Down Expand Up @@ -550,9 +553,13 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons

void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrary, const bool checkConfiguration)
{
if (files.isEmpty()) {
if (files.isEmpty())
return;
}

Settings checkSettings = getCppcheckSettings();
if (Settings::terminated())
return;

clearResults();

mIsLogfileLoaded = false;
Expand Down Expand Up @@ -591,7 +598,6 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar
checkLockDownUI(); // lock UI while checking

mUI->mResults->setCheckDirectory(checkPath);
Settings checkSettings = getCppcheckSettings();
checkSettings.checkLibrary = checkLibrary;
checkSettings.checkConfiguration = checkConfiguration;

Expand All @@ -614,6 +620,10 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLibrar

void MainWindow::analyzeCode(const QString& code, const QString& filename)
{
Settings checkSettings = getCppcheckSettings();
if (Settings::terminated())
return;

// Initialize dummy ThreadResult as ErrorLogger
ThreadResult result;
result.setFiles(QStringList(filename));
Expand All @@ -628,7 +638,7 @@ void MainWindow::analyzeCode(const QString& code, const QString& filename)

// Create CppCheck instance
CppCheck cppcheck(result, true, nullptr);
cppcheck.settings() = getCppcheckSettings();
cppcheck.settings() = checkSettings;

// Check
checkLockDownUI();
Expand Down Expand Up @@ -905,13 +915,12 @@ bool MainWindow::tryLoadLibrary(Library *library, const QString& filename)
return true;
}

void MainWindow::loadAddon(Settings &settings, const QString &filesDir, const QString &pythonCmd, const QString& addon)
QString MainWindow::loadAddon(Settings &settings, const QString &filesDir, const QString &pythonCmd, const QString& addon)
{
QString addonFilePath = ProjectFile::getAddonFilePath(filesDir, addon);
if (addonFilePath.isEmpty())
return; // TODO: report an error
const QString addonFilePath = fromNativePath(ProjectFile::getAddonFilePath(filesDir, addon));

addonFilePath.replace(QChar('\\'), QChar('/'));
if (addonFilePath.isEmpty())
return tr("File not found: '%1'").arg(addon);

picojson::object obj;
obj["script"] = picojson::value(addonFilePath.toStdString());
Expand All @@ -929,42 +938,54 @@ void MainWindow::loadAddon(Settings &settings, const QString &filesDir, const QS
obj["args"] = picojson::value(arg.toStdString());
}
}
picojson::value json;
json.set(std::move(obj));
std::string json_str = json.serialize();

const std::string& json_str = picojson::value(obj).serialize();

AddonInfo addonInfo;
addonInfo.getAddonInfo(json_str, settings.exename); // TODO: handle error
const std::string errmsg = addonInfo.getAddonInfo(json_str, settings.exename);
if (!errmsg.empty())
return tr("Failed to load/setup addon %1: %2").arg(addon, QString::fromStdString(errmsg));
settings.addonInfos.emplace_back(std::move(addonInfo));

settings.addons.emplace(std::move(json_str));
settings.addons.emplace(json_str);
}

Settings MainWindow::getCppcheckSettings()
{
saveSettings(); // Save settings

Settings result;
Settings::terminate(false);

result.exename = QCoreApplication::applicationFilePath().toStdString();

const bool std = tryLoadLibrary(&result.library, "std.cfg");
if (!std)
QMessageBox::critical(this, tr("Error"), tr("Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured.").arg("std.cfg"));
Settings::terminate(true);
return result;
}

const QString filesDir(getDataDir());
const QString pythonCmd = fromNativePath(mSettings->value(SETTINGS_PYTHON_PATH).toString());

{
const QString cfgErr = QString::fromStdString(result.loadCppcheckCfg());
if (!cfgErr.isEmpty())
if (!cfgErr.isEmpty()) {
QMessageBox::critical(this, tr("Error"), tr("Failed to load %1 - %2").arg("cppcheck.cfg").arg(cfgErr));
Settings::terminate(true);
return result;
}

const auto cfgAddons = result.addons;
result.addons.clear();
for (const std::string& addon : cfgAddons) {
// TODO: support addons which are a script and not a file
loadAddon(result, filesDir, pythonCmd, QString::fromStdString(addon));
const QString addonError = loadAddon(result, filesDir, pythonCmd, QString::fromStdString(addon));
if (!addonError.isEmpty()) {
QMessageBox::critical(this, tr("Error"), addonError);
Settings::terminate(true);
}
}
}

Expand Down Expand Up @@ -1045,7 +1066,11 @@ Settings MainWindow::getCppcheckSettings()
result.checkUnknownFunctionReturn.insert(s.toStdString());

for (const QString& addon : mProjectFile->getAddons()) {
loadAddon(result, filesDir, pythonCmd, addon);
const QString addonError = loadAddon(result, filesDir, pythonCmd, addon);
if (!addonError.isEmpty()) {
QMessageBox::critical(this, tr("Error"), addonError);
Settings::terminate(true);
}
}

if (isCppcheckPremium()) {
Expand Down Expand Up @@ -1097,8 +1122,6 @@ Settings MainWindow::getCppcheckSettings()
result.jobs = 1;
}

Settings::terminate(false);

return result;
}

Expand Down Expand Up @@ -1223,6 +1246,10 @@ void MainWindow::reAnalyzeSelected(const QStringList& files)
if (mThread->isChecking())
return;

const Settings& checkSettings = getCppcheckSettings();
if (Settings::terminated())
return;

// Clear details, statistics and progress
mUI->mResults->clear(false);
for (int i = 0; i < files.size(); ++i)
Expand All @@ -1242,7 +1269,6 @@ 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();
const Settings& checkSettings = getCppcheckSettings();
mThread->check(checkSettings);
mUI->mResults->setCheckSettings(checkSettings);
mThread->setCheckStartTime(saveCheckStartTime);
Expand All @@ -1254,6 +1280,10 @@ void MainWindow::reAnalyze(bool all)
if (files.empty())
return;

const Settings& checkSettings = getCppcheckSettings();
if (Settings::terminated())
return;

// Clear details, statistics and progress
mUI->mResults->clear(all);

Expand All @@ -1268,7 +1298,6 @@ void MainWindow::reAnalyze(bool all)
qDebug() << "Rechecking project file" << mProjectFile->getFilename();

mThread->setCheckFiles(all);
const Settings& checkSettings = getCppcheckSettings();
mThread->check(checkSettings);
mUI->mResults->setCheckSettings(checkSettings);
}
Expand Down
2 changes: 1 addition & 1 deletion gui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ private slots:
*/
bool tryLoadLibrary(Library *library, const QString& filename);

void loadAddon(Settings &settings, const QString &filesDir, const QString &pythonCmd, const QString& addon);
QString loadAddon(Settings &settings, const QString &filesDir, const QString &pythonCmd, const QString& addon);

/**
* @brief Update project MRU items in File-menu.
Expand Down
3 changes: 3 additions & 0 deletions gui/projectfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,9 @@ void ProjectFile::SafeChecks::saveToXml(QXmlStreamWriter &xmlWriter) const

QString ProjectFile::getAddonFilePath(QString filesDir, const QString &addon)
{
if (QFile(addon).exists())
return addon;

if (!filesDir.endsWith("/"))
filesDir += "/";

Expand Down
20 changes: 20 additions & 0 deletions gui/test/projectfile/testprojectfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <QList>
#include <QStringList>
#include <QTemporaryDir>
#include <QtTest>

// Mock...
Expand Down Expand Up @@ -116,4 +117,23 @@ void TestProjectFile::loadSimpleNoroot() const
QCOMPARE(defines[0], QString("FOO"));
}

void TestProjectFile::getAddonFilePath() const
{
QTemporaryDir tempdir;
QVERIFY(tempdir.isValid());
const QString filepath(tempdir.path() + "/addon.py");

QFile file(filepath);
QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
file.close();

// Relative path to addon
QCOMPARE(ProjectFile::getAddonFilePath(tempdir.path(), "addon"), filepath);
QCOMPARE(ProjectFile::getAddonFilePath(tempdir.path(), "not exist"), QString());

// Absolute path to addon
QCOMPARE(ProjectFile::getAddonFilePath("/not/exist", filepath), filepath);
QCOMPARE(ProjectFile::getAddonFilePath(tempdir.path(), filepath), filepath);
}

QTEST_MAIN(TestProjectFile)
2 changes: 2 additions & 0 deletions gui/test/projectfile/testprojectfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ private slots:
void loadSimple() const;
void loadSimpleWithIgnore() const;
void loadSimpleNoroot() const;

void getAddonFilePath() const;
};
2 changes: 1 addition & 1 deletion lib/addoninfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static std::string parseAddonInfo(AddonInfo& addoninfo, const picojson::value &j
if (!val.is<std::string>())
return "Loading " + fileName + " failed. 'executable' must be a string.";
addoninfo.executable = getFullPath(val.get<std::string>(), fileName);
return ""; // TODO: why bail out?
return ""; // <- do not load both "executable" and "script".
}
}

Expand Down

0 comments on commit 192c1c2

Please sign in to comment.