diff --git a/config/globalconfigpage.cpp b/config/globalconfigpage.cpp index 3dd0cc7..f736c1d 100644 --- a/config/globalconfigpage.cpp +++ b/config/globalconfigpage.cpp @@ -1,62 +1,62 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "globalconfigpage.h" #include "ui_globalconfigpage.h" #include "globalsettings.h" #include namespace Valgrind { GlobalConfigPage::GlobalConfigPage(KDevelop::IPlugin* plugin, QWidget* parent) : ConfigPage(plugin, GlobalSettings::self(), parent) { Ui::GlobalConfigPage ui; ui.setupUi(this); } GlobalConfigPage::~GlobalConfigPage() { } KDevelop::ConfigPage::ConfigPageType GlobalConfigPage::configPageType() const { return KDevelop::ConfigPage::AnalyzerConfigPage; } QString GlobalConfigPage::name() const { return i18n("Valgrind"); } QString GlobalConfigPage::fullName() const { return i18n("Configure Valgrind Settings"); } QIcon GlobalConfigPage::icon() const { return QIcon::fromTheme(QStringLiteral("kdevelop")); } } diff --git a/config/globalconfigpage.h b/config/globalconfigpage.h index ce36238..e4bb498 100644 --- a/config/globalconfigpage.h +++ b/config/globalconfigpage.h @@ -1,43 +1,43 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { class GlobalConfigPage: public KDevelop::ConfigPage { Q_OBJECT public: GlobalConfigPage(KDevelop::IPlugin* plugin, QWidget* parent); ~GlobalConfigPage() override; KDevelop::ConfigPage::ConfigPageType configPageType() const override; QString name() const override; QString fullName() const override; QIcon icon() const override; }; } diff --git a/include/ijob.h b/include/ijob.h index 1879748..95abe63 100644 --- a/include/ijob.h +++ b/include/ijob.h @@ -1,22 +1,22 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "tools/generic/core/ijob.h" diff --git a/include/isettings.h b/include/isettings.h index 9b68a49..6a5b366 100644 --- a/include/isettings.h +++ b/include/isettings.h @@ -1,101 +1,101 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { class ISettingsBase { public: virtual ~ISettingsBase(); protected: explicit ISettingsBase(const QString& configKeyPrefix); class IValue; template class Value; using IntValue = Value; using BoolValue = Value; using StringValue = Value; QString m_configKeyPrefix; QList m_values; }; class ISettingsBase::IValue { friend class ISettings; public: virtual ~IValue(); protected: virtual void load(const KConfigGroup& config, const QString& configKeyPrefix) = 0; virtual void save(KConfigGroup& config, const QString& configKeyPrefix) = 0; virtual QString cmdArg() = 0; }; template class ISettingsBase::Value : public ISettingsBase::IValue { friend class ISettings; public: Value(ISettingsBase* settings, const QString& configKey, const QString& cmdKey, const T& defaultValue); ~Value() override; operator const T& () const; Value& operator=(const T& value); protected: void load(const KConfigGroup& config, const QString& configKeyPrefix) override; void save(KConfigGroup& config, const QString& configKeyPrefix) override; QString cmdArg() override; QString m_configKey; QString m_cmdKey; T m_value; T m_defaultValue; }; class ISettings : public ISettingsBase { public: StringValue extraParameters; void load(const KConfigGroup& config); void save(KConfigGroup& config); QStringList cmdArgs(); protected: explicit ISettings(const QString& configKeyPrefix); ~ISettings() override; }; } diff --git a/include/itool.h b/include/itool.h index 128ca0e..af51517 100644 --- a/include/itool.h +++ b/include/itool.h @@ -1,90 +1,90 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace KDevelop { class ILauncher; class ILaunchConfiguration; class LaunchConfigurationPageFactory; } namespace Valgrind { class IJob; class ITool { public: virtual ~ITool(); /// Short name, used in UI. /// Example: i18n("Memcheck"). QString name() const; /// Full name, used in UI (description). /// Example: i18n("Memcheck: a memory error detector"). QString fullName() const; /// Internal Valgrind tool name, used in jobs. /// Example: "memcheck". QString valgrindToolName() const; /// Internal id, used as id for launcher and setting names prefix. /// Example: "Memcheck". QString id() const; /// "Analyze" menu action name, used when tool action added to action collection. /// Example: "memcheck_tool". QString menuActionName() const; /// True if tool has view bool hasView() const; KDevelop::ILauncher* createLauncher() const; virtual IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const = 0; virtual KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const = 0; protected: ITool( const QString& id, const QString& name, const QString& fullName, const QString& valgrindToolName, const QString& menuActionName, bool hasView ); QString m_id; QString m_name; QString m_fullName; QString m_valgrindToolName; QString m_menuActionName; bool m_hasView; }; } diff --git a/include/ixmljob.h b/include/ixmljob.h index f82edd5..59a2744 100644 --- a/include/ixmljob.h +++ b/include/ixmljob.h @@ -1,22 +1,22 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "tools/generic/core/xml/ixmljob.h" diff --git a/include/ixmlsettings.h b/include/ixmlsettings.h index 076ee8d..3aabbf4 100644 --- a/include/ixmlsettings.h +++ b/include/ixmlsettings.h @@ -1,38 +1,38 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "isettings.h" namespace Valgrind { class IXmlSettings : public ISettings { public: ~IXmlSettings() override; BoolValue showInstructionPointer; protected: explicit IXmlSettings(const QString& configKeyPrefix); }; } diff --git a/include/utils.h b/include/utils.h index aba588d..7d2f7db 100644 --- a/include/utils.h +++ b/include/utils.h @@ -1,57 +1,57 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include class QAbstractTableModel; class QProcess; class QPushButton; class QWidget; namespace Valgrind { QString eventFullName(const QString& eventShortName); enum ItemDataRole { SortRole = Qt::UserRole + 1 }; static const int rightAlign = int(Qt::AlignRight | Qt::AlignVCenter); QString displayValue(int value); QString displayValue(double value); void emitDataChanged(QAbstractTableModel* model); void setupVisualizerProcess(QProcess* visualizerProcess, QPushButton* startButton, std::function startFunction, bool startImmediately); QWidget* activeMainWindow(); QString findExecutable(const QString &executableName); } diff --git a/launchmode.cpp b/launchmode.cpp index 21bdd6b..37ada40 100644 --- a/launchmode.cpp +++ b/launchmode.cpp @@ -1,49 +1,49 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2009 Andreas Pakulat Copyright 2011 Lionel Duc Copyright 2011 Mathieu Lornac Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "launchmode.h" #include "debug.h" #include #include namespace Valgrind { QIcon LaunchMode::icon() const { return QIcon::fromTheme(QStringLiteral("debug-run")); } QString LaunchMode::id() const { return QStringLiteral("Valgrind"); } QString LaunchMode::name() const { return i18n("Valgrind"); } } diff --git a/launchmode.h b/launchmode.h index 24323f9..48e3420 100644 --- a/launchmode.h +++ b/launchmode.h @@ -1,41 +1,41 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2009 Andreas Pakulat Copyright 2011 Lionel Duc Copyright 2011 Mathieu Lornac - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include namespace Valgrind { class LaunchMode : public KDevelop::ILaunchMode { public: QIcon icon() const override; QString id() const override; QString name() const override; }; } diff --git a/plugin.cpp b/plugin.cpp index 76a6abf..9b038a7 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -1,253 +1,253 @@ /* This file is part of KDevelop Copyright 2002 Harald Fernengel Copyright 2007 Hamish Rodda - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "plugin.h" #include "config/globalconfigpage.h" #include "debug.h" #include "ijob.h" #include "launchmode.h" #include "problemmodel.h" #include "toolviewfactory.h" #include "cachegrind/tool.h" #include "callgrind/tool.h" #include "drd/tool.h" #include "helgrind/tool.h" #include "massif/tool.h" #include "memcheck/tool.h" #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(ValgrindFactory, "kdevvalgrind.json", registerPlugin();) namespace Valgrind { Plugin* Plugin::m_self = nullptr; Plugin::Plugin(QObject* parent, const QVariantList&) : IPlugin("kdevvalgrind", parent) , m_toolViewFactory(new ToolViewFactory) , m_launchMode(new LaunchMode) , m_problemModel(new ProblemModel) , m_isRunning(false) { m_self = this; qCDebug(KDEV_VALGRIND) << "setting valgrind rc file"; setXMLFile("kdevvalgrind.rc"); core()->uiController()->addToolView(i18n("Valgrind"), m_toolViewFactory); core()->runController()->addLaunchMode(m_launchMode); m_tools += Memcheck::Tool::self(); m_tools += Cachegrind::Tool::self(); m_tools += Callgrind::Tool::self(); m_tools += Helgrind::Tool::self(); m_tools += DRD::Tool::self(); m_tools += Massif::Tool::self(); for (auto tool : qAsConst(m_tools)) { auto action = new QAction(i18n("Run %1", tool->fullName()), this); connect(action, &QAction::triggered, this, [this, tool]() { executeDefaultLaunch(tool->id()); }); actionCollection()->addAction(tool->menuActionName(), action); } auto pluginController = core()->pluginController(); const auto plugins = pluginController->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin")); for (auto plugin : plugins) { setupExecutePlugin(plugin, true); } connect(pluginController, &KDevelop::IPluginController::pluginLoaded, this, [this](KDevelop::IPlugin* plugin) { setupExecutePlugin(plugin, true); }); connect(pluginController, &KDevelop::IPluginController::unloadingPlugin, this, [this](KDevelop::IPlugin* plugin) { setupExecutePlugin(plugin, false); }); } Plugin::~Plugin() { m_self = nullptr; } Plugin* Plugin::self() { return m_self; } void Plugin::unload() { core()->uiController()->removeToolView(m_toolViewFactory); const auto plugins = core()->pluginController()->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin")); for (auto plugin : plugins) { setupExecutePlugin(plugin, false); } Q_ASSERT(m_launchers.isEmpty()); core()->runController()->removeLaunchMode(m_launchMode); delete m_launchMode; qDeleteAll(m_tools); } void Plugin::setupExecutePlugin(KDevelop::IPlugin* plugin, bool load) { if (plugin == this) { return; } auto iface = plugin->extension(); if (!iface) { return; } auto type = core()->runController()->launchConfigurationTypeForId(iface->nativeAppConfigTypeId()); Q_ASSERT(type); if (load) { for (auto tool : qAsConst(m_tools)) { auto launcher = tool->createLauncher(); m_launchers.insert(plugin, launcher); type->addLauncher(launcher); } } else { auto pluginLaunchers = m_launchers.values(plugin); for (auto launcher : pluginLaunchers) { Q_ASSERT(launcher); m_launchers.remove(plugin, launcher); type->removeLauncher(launcher); delete launcher; } } } int Plugin::configPages() const { return 1; } KDevelop::ConfigPage* Plugin::configPage(int number, QWidget* parent) { if (number) { return nullptr; } return new GlobalConfigPage(this, parent); } Valgrind::LaunchMode* Plugin::launchMode() const { return m_launchMode; } ProblemModel* Plugin::problemModel() const { return m_problemModel; } void Plugin::jobReadyToStart(IJob* job) { m_isRunning = true; const auto actions = actionCollection()->actions(); for (auto action : actions) { action->setEnabled(false); } Q_ASSERT(job); if (!job->tool()->hasView()) { m_problemModel->reset(job->tool()); } } void Plugin::jobReadyToFinish(IJob* job, bool ok) { if (!ok) { return; } Q_ASSERT(job); if (job->tool()->hasView()) { emit addView(job->createView(), job->statusName()); core()->uiController()->findToolView(i18n("Valgrind"), m_toolViewFactory); } else { m_problemModel->show(); } } void Plugin::jobFinished(KJob* job) { Q_UNUSED(job); const auto actions = actionCollection()->actions(); for (auto action : actions) { action->setEnabled(true); } m_isRunning = false; } bool Plugin::isRunning() { return m_isRunning; } void Plugin::executeDefaultLaunch(const QString& launcherId) { auto runController = KDevelop::Core::self()->runControllerInternal(); Q_ASSERT(runController); if (runController->launchConfigurations().isEmpty()) { runController->showConfigurationDialog(); } auto defaultLaunch = runController->defaultLaunch(); if (defaultLaunch) { defaultLaunch->setLauncherForMode(m_launchMode->id(), launcherId); runController->executeDefaultLaunch(m_launchMode->id()); } } } #include "plugin.moc" diff --git a/plugin.h b/plugin.h index d707296..edc236d 100644 --- a/plugin.h +++ b/plugin.h @@ -1,92 +1,92 @@ /* This file is part of KDevelop Copyright 2002 Harald Fernengel Copyright 2007 Hamish Rodda - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include class KJob; namespace KDevelop { class ProblemModel; class ILauncher; } namespace Valgrind { class IJob; class ITool; class LaunchMode; class ProblemModel; class ToolViewFactory; class Plugin : public KDevelop::IPlugin { Q_OBJECT public: explicit Plugin(QObject* parent, const QVariantList& = QVariantList()); ~Plugin() override; static Plugin* self(); void unload() override; int configPages() const override; KDevelop::ConfigPage* configPage(int number, QWidget* parent) override; LaunchMode* launchMode() const; ProblemModel* problemModel() const; void executeDefaultLaunch(const QString& launcherId); void jobReadyToStart(IJob* job); void jobReadyToFinish(IJob* job, bool ok); void jobFinished(KJob* job); bool isRunning(); Q_SIGNALS: void addView(QWidget* view, const QString& name); private: void setupExecutePlugin(KDevelop::IPlugin* plugin, bool load); ToolViewFactory* m_toolViewFactory; LaunchMode* m_launchMode; QMultiHash m_launchers; ProblemModel* m_problemModel; bool m_isRunning; QList m_tools; static Plugin* m_self; }; } diff --git a/problemmodel.cpp b/problemmodel.cpp index a3027b7..fa30b9f 100644 --- a/problemmodel.cpp +++ b/problemmodel.cpp @@ -1,83 +1,83 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "problemmodel.h" #include "itool.h" #include "plugin.h" #include "utils.h" #include #include #include #include namespace Valgrind { inline KDevelop::ProblemModelSet* problemModelSet() { return KDevelop::ICore::self()->languageController()->problemModelSet(); } inline QString problemModelId() { return QStringLiteral("Valgrind"); } ProblemModel::ProblemModel() : KDevelop::ProblemModel(Plugin::self()) { setFeatures(CanDoFullUpdate | ScopeFilter | SeverityFilter | Grouping | CanByPassScopeFilter | ShowSource); reset(nullptr); problemModelSet()->addModel(problemModelId(), i18n("Valgrind"), this); } ProblemModel::~ProblemModel() { problemModelSet()->removeModel(problemModelId()); } void ProblemModel::reset(const ITool* tool) { m_tool = tool; clearProblems(); QString toolName = tool ? tool->name() : QStringLiteral("Valgrind"); setFullUpdateTooltip(i18nc("@info:tooltip", "Re-Run %1 Analysis for Current Launch Configuration", toolName)); } void ProblemModel::show() { problemModelSet()->showModel(problemModelId()); } void ProblemModel::forceFullUpdate() { if (m_tool && !Plugin::self()->isRunning()) { Plugin::self()->executeDefaultLaunch(m_tool->id()); } } } diff --git a/problemmodel.h b/problemmodel.h index 9554adf..ae4477e 100644 --- a/problemmodel.h +++ b/problemmodel.h @@ -1,46 +1,46 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { class ITool; class ProblemModel : public KDevelop::ProblemModel { Q_OBJECT public: ProblemModel(); ~ProblemModel() override; void reset(const ITool* tool); void show(); void forceFullUpdate() override; private: const ITool* m_tool; }; } diff --git a/tools/cachegrind/configpage.cpp b/tools/cachegrind/configpage.cpp index 31c9a1c..e46f61e 100644 --- a/tools/cachegrind/configpage.cpp +++ b/tools/cachegrind/configpage.cpp @@ -1,118 +1,118 @@ /* This file is part of KDevelop Copyright 2011 Sebastien Rannou Copyright 2011 Lionel Duc - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace Cachegrind { ConfigPage::ConfigPage(QWidget *parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->extraParameters, &QLineEdit::textChanged, this, &ConfigPage::changed); connect(ui->cacheSimulation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->branchSimulation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->cgAnnotateParameters, &QLineEdit::textChanged, this, &ConfigPage::changed); connect(ui->cacheSimulation, &QCheckBox::toggled, this, &ConfigPage::check); connect(ui->branchSimulation, &QCheckBox::toggled, this, &ConfigPage::check); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->extraParameters->setText(settings.extraParameters); ui->cacheSimulation->setChecked(settings.cacheSimulation); ui->branchSimulation->setChecked(settings.branchSimulation); ui->cgAnnotateParameters->setText(settings.cgAnnotateParameters); check(); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.extraParameters = ui->extraParameters->text(); settings.cacheSimulation = ui->cacheSimulation->isChecked(); settings.branchSimulation = ui->branchSimulation->isChecked(); settings.cgAnnotateParameters = ui->cgAnnotateParameters->text(); settings.save(cfg); } void ConfigPage::check() { if (!ui->cacheSimulation->isChecked() && !ui->branchSimulation->isChecked()) { ui->messageWidget->setVisible(true); return; } ui->messageWidget->setVisible(false); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/cachegrind/configpage.h b/tools/cachegrind/configpage.h index cc89e0b..9de64ae 100644 --- a/tools/cachegrind/configpage.h +++ b/tools/cachegrind/configpage.h @@ -1,69 +1,69 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Cachegrind { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: void check(); Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/cachegrind/job.cpp b/tools/cachegrind/job.cpp index f277164..df9abf1 100644 --- a/tools/cachegrind/job.cpp +++ b/tools/cachegrind/job.cpp @@ -1,95 +1,95 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "model.h" #include "parser.h" #include "plugin.h" #include "settings.h" #include "tool.h" #include "view.h" #include #include #include #include #include #include namespace Valgrind { namespace Cachegrind { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IJob(Tool::self(), launchConfig) , m_model(new FunctionsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } Job::~Job() { } bool Job::processEnded() { Settings settings; settings.load(m_config); QStringList cgArgs; cgArgs += KShell::splitArgs(settings.cgAnnotateParameters); cgArgs += m_outputFile->fileName(); QByteArray cgOutput; if (executeProcess(settings.cgAnnotateExecutablePath(), cgArgs, cgOutput) != 0) { return false; } parse(cgOutput, m_model); return true; } void Job::addToolArgs(QStringList& args) const { Settings settings; settings.load(m_config); args += settings.cmdArgs(); args += QStringLiteral("--cachegrind-out-file=%1").arg(m_outputFile->fileName()); } QWidget* Job::createView() { return new View(m_model); } } } diff --git a/tools/cachegrind/job.h b/tools/cachegrind/job.h index f486029..23d75a7 100644 --- a/tools/cachegrind/job.h +++ b/tools/cachegrind/job.h @@ -1,58 +1,58 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ijob.h" class QTemporaryFile; namespace Valgrind { namespace Cachegrind { class FunctionsModel; class Job : public IJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; FunctionsModel* m_model; QTemporaryFile* m_outputFile; }; } } diff --git a/tools/cachegrind/model.cpp b/tools/cachegrind/model.cpp index bc4ee6d..7726120 100644 --- a/tools/cachegrind/model.cpp +++ b/tools/cachegrind/model.cpp @@ -1,177 +1,177 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "model.h" #include "debug.h" #include "utils.h" #include #include #include #include namespace Valgrind { namespace Cachegrind { FunctionsModel::FunctionsModel(QObject* parent) : QAbstractTableModel(parent) , m_totalItem(nullptr) , m_percentageValues(false) { } FunctionsModel::~FunctionsModel() { qDeleteAll(m_items); } void FunctionsModel::addItem(Function* newItem, bool isTotal) { Q_ASSERT(newItem); if (isTotal) { m_totalItem = newItem; return; } bool exists = false; for (auto item : qAsConst(m_items)) { if (item->functionName == newItem->functionName) { exists = true; item->fileNames += newItem->fileNames; item->fileNames.removeDuplicates(); item->fileNames.sort(); for (int i = 0; i < newItem->eventValues.size(); ++i) { item->eventValues[i] += newItem->eventValues[i]; } delete newItem; } } if (!exists) { m_items.append(newItem); } } void FunctionsModel::setEventsList(const QStringList& eventsList) { m_eventList = eventsList; } void FunctionsModel::setPercentageValues(bool value) { m_percentageValues = value; emitDataChanged(this); } QModelIndex FunctionsModel::index(int row, int column, const QModelIndex&) const { if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) { return createIndex(row, column, m_items.at(row)); } return QModelIndex(); } int FunctionsModel::rowCount(const QModelIndex&) const { return m_items.size(); } int FunctionsModel::columnCount(const QModelIndex&) const { return m_eventList.size() + 1; } QVariant FunctionsModel::data(const QModelIndex& index, int role) const { Q_ASSERT(m_totalItem); if (!index.isValid()) { return QVariant(); } auto item = static_cast(index.internalPointer()); int column = index.column(); if (role == Qt::TextAlignmentRole && column > 0) { return rightAlign; } if (column == 0) { if (role == Qt::DisplayRole || role == SortRole) { return item->functionName; } } else { if (role == Qt::DisplayRole) { int intValue = item->eventValues.at(column - 1); if (!m_percentageValues) { return displayValue(intValue); } return displayValue(intValue * 100.0 / m_totalItem->eventValues.at(column - 1)); } if (role == SortRole) { return item->eventValues.at(column - 1); } } return QVariant(); } QVariant FunctionsModel::headerData(int section, Qt::Orientation, int role) const { if (section == 0) { if (role == Qt::DisplayRole) { return i18n("Function"); } } else { if (role == Qt::DisplayRole) { return m_eventList[section - 1]; } if (role == Qt::ToolTipRole) { return eventFullName(m_eventList[section - 1]); } } return QVariant(); } } } diff --git a/tools/cachegrind/model.h b/tools/cachegrind/model.h index 5173cc3..7f9ce1b 100644 --- a/tools/cachegrind/model.h +++ b/tools/cachegrind/model.h @@ -1,74 +1,74 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Cachegrind { struct Function { QString functionName; QStringList fileNames; QList eventValues; }; class FunctionsModel : public QAbstractTableModel { Q_OBJECT public: explicit FunctionsModel(QObject* parent = nullptr); ~FunctionsModel() override; void setEventsList(const QStringList& events); void addItem(Function* item, bool isTotal = false); void setPercentageValues(bool value); QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; private: QList m_items; Function* m_totalItem; bool m_percentageValues; QStringList m_eventList; }; } } diff --git a/tools/cachegrind/parser.cpp b/tools/cachegrind/parser.cpp index 73fffc3..6cca6c2 100644 --- a/tools/cachegrind/parser.cpp +++ b/tools/cachegrind/parser.cpp @@ -1,124 +1,124 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Lucas Sarie - Copyright 2016 Anton Anikin + Copyright 2016 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parser.h" #include "debug.h" #include "model.h" #include #include namespace Valgrind { namespace Cachegrind { Function* parseCachegrindItem(const QString& line, QStringList& eventsList) { auto item = new Function; QStringList lineEventList = line.split(QChar(' '), QString::SkipEmptyParts); Q_ASSERT(lineEventList.size() >= eventsList.size()); for (int i = 0; i < eventsList.size(); ++i) { item->eventValues += lineEventList.takeFirst().remove(QLatin1Char(',')).toInt(); } QString fileCall = lineEventList.join(QChar(' ')); int colonPosition = fileCall.indexOf(QChar(':')); if (colonPosition >= 0) { // file name auto fileUrl = QUrl::fromLocalFile(fileCall.mid(0, colonPosition)).adjusted(QUrl::NormalizePathSegments); item->fileNames += fileUrl.toLocalFile(); // call name item->functionName = fileCall.mid(colonPosition + 1); } return item; } enum ParserState { ParseRoot, ParseProgramTotalHeader, ParseProgramTotal, ParseProgramHeader, ParseProgram }; void parse(QByteArray& baData, FunctionsModel* model) { Q_ASSERT(model); ParserState parserState = ParseRoot; QStringList eventsList; QString eventsString; QString line; QBuffer data(&baData); data.open(QIODevice::ReadOnly); while (!data.atEnd()) { // remove useless characters line = data.readLine().simplified(); if (parserState == ParseRoot) { if (line.startsWith(QLatin1String("Events shown:"))) { // 13 is 'Events shown:' length eventsString = line.mid(13).simplified(); eventsList = eventsString.split(QChar(' '), QString::SkipEmptyParts); parserState = ParseProgramTotalHeader; } } else if (parserState == ParseProgramTotalHeader) { if (line == eventsString) { parserState = ParseProgramTotal; } } else if (parserState == ParseProgramHeader) { if (line.startsWith(eventsString)) { parserState = ParseProgram; } } else if (!line.isEmpty() && line.at(0).isDigit()) { bool isTotal = (parserState == ParseProgramTotal); model->addItem(parseCachegrindItem(line, eventsList), isTotal); if (isTotal) { parserState = ParseProgramHeader; } } } model->setEventsList(eventsList); } } } diff --git a/tools/cachegrind/parser.h b/tools/cachegrind/parser.h index 3cb20a3..31b8151 100644 --- a/tools/cachegrind/parser.h +++ b/tools/cachegrind/parser.h @@ -1,39 +1,39 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc - Copyright 2016 Anton Anikin + Copyright 2016 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Cachegrind { class FunctionsModel; void parse(QByteArray& data, FunctionsModel* model); } } diff --git a/tools/cachegrind/settings.cpp b/tools/cachegrind/settings.cpp index c86c8ee..a090edd 100644 --- a/tools/cachegrind/settings.cpp +++ b/tools/cachegrind/settings.cpp @@ -1,65 +1,65 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "globalsettings.h" #include "tool.h" namespace Valgrind { namespace Cachegrind { Settings::Settings() : ISettings(Tool::self()->id()) , cacheSimulation( this, QStringLiteral("Cache Simulation"), QStringLiteral("cache-sim"), true) , branchSimulation( this, QStringLiteral("Branch Simulation"), QStringLiteral("branch-sim"), false) , cgAnnotateParameters( this, QStringLiteral("cg_annotate Parameters"), QStringLiteral(""), QStringLiteral("")) { } Settings::~Settings() { } QString Settings::cgAnnotateExecutablePath() { return KDevelop::Path(GlobalSettings::cg_annotateExecutablePath()).toLocalFile(); } } } diff --git a/tools/cachegrind/settings.h b/tools/cachegrind/settings.h index 6d86e80..a67e961 100644 --- a/tools/cachegrind/settings.h +++ b/tools/cachegrind/settings.h @@ -1,47 +1,47 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "isettings.h" namespace Valgrind { namespace Cachegrind { class Settings : public ISettings { public: Settings(); ~Settings() override; BoolValue cacheSimulation; BoolValue branchSimulation; StringValue cgAnnotateParameters; static QString cgAnnotateExecutablePath(); }; } } diff --git a/tools/cachegrind/tool.cpp b/tools/cachegrind/tool.cpp index f8b7af7..9e6bdbd 100644 --- a/tools/cachegrind/tool.cpp +++ b/tools/cachegrind/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace Cachegrind { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("Cachegrind"), i18n("Cachegrind"), i18n("Cachegrind (Cache and Branch-Prediction Profiler)"), QStringLiteral("cachegrind"), QStringLiteral("cachegrind_tool"), true) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/cachegrind/tool.h b/tools/cachegrind/tool.h index c0b9603..f8b4690 100644 --- a/tools/cachegrind/tool.h +++ b/tools/cachegrind/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace Cachegrind { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/tools/cachegrind/view.cpp b/tools/cachegrind/view.cpp index 5edddb1..a8ab756 100644 --- a/tools/cachegrind/view.cpp +++ b/tools/cachegrind/view.cpp @@ -1,94 +1,94 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "view.h" #include "ui_view.h" #include "debug.h" #include "model.h" #include "utils.h" #include #include #include namespace Valgrind { namespace Cachegrind { View::View(FunctionsModel* model, QWidget* parent) : QWidget(parent) { Q_ASSERT(model); model->setParent(this); ui = new Ui::View; ui->setupUi(this); connect(ui->percenageValues, &QCheckBox::stateChanged, model, &FunctionsModel::setPercentageValues); model->setPercentageValues(ui->percenageValues->checkState()); auto functionsProxyModel = new QSortFilterProxyModel(this); functionsProxyModel->setSourceModel(model); functionsProxyModel->setSortRole(SortRole); functionsProxyModel->setFilterKeyColumn(-1); ui->functionsView->setModel(functionsProxyModel); ui->functionsView->setSortingEnabled(true); ui->functionsView->sortByColumn(1); ui->functionsView->header()->resizeSections(QHeaderView::ResizeToContents); ui->functionsView->header()->setStretchLastSection(false); ui->functionsView->header()->setSectionResizeMode(0, QHeaderView::Stretch); connect(ui->searchEdit, &QLineEdit::textChanged, functionsProxyModel, &QSortFilterProxyModel::setFilterWildcard); connect(ui->functionsView->selectionModel(), &QItemSelectionModel::currentChanged, this, [=](const QModelIndex& currentProxyIndex, const QModelIndex&) { auto sourceIndex = functionsProxyModel->mapToSource(currentProxyIndex); auto item = static_cast(sourceIndex.internalPointer()); if (item) { ui->nameLabel->setText(item->functionName); ui->sourceLabel->setText(item->fileNames.join("\n\n")); } else { ui->nameLabel->clear(); ui->sourceLabel->clear(); } }); ui->nameLabel->clear(); ui->sourceLabel->clear(); } View::~View() { delete ui; } } } diff --git a/tools/cachegrind/view.h b/tools/cachegrind/view.h index 85718e7..90da402 100644 --- a/tools/cachegrind/view.h +++ b/tools/cachegrind/view.h @@ -1,57 +1,57 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include namespace Valgrind { namespace Cachegrind { namespace Ui { class View; } class FunctionsModel; class View : public QWidget { Q_OBJECT public: explicit View(FunctionsModel* model, QWidget* parent = nullptr); ~View() override; private: Ui::View* ui; }; } } diff --git a/tools/callgrind/configpage.cpp b/tools/callgrind/configpage.cpp index 9822a3b..ec6eb98 100644 --- a/tools/callgrind/configpage.cpp +++ b/tools/callgrind/configpage.cpp @@ -1,105 +1,105 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace Callgrind { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->extraParameters, &QLineEdit::textChanged, this, &ConfigPage::changed); connect(ui->cacheSimulation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->branchSimulation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->launchKCachegrind, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->callgrindAnnotateParameters, &QLineEdit::textChanged, this, &ConfigPage::changed); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->extraParameters->setText(settings.extraParameters); ui->cacheSimulation->setChecked(settings.cacheSimulation); ui->branchSimulation->setChecked(settings.branchSimulation); ui->launchKCachegrind->setChecked(settings.launchKCachegrind); ui->callgrindAnnotateParameters->setText(settings.callgrindAnnotateParameters); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.extraParameters = ui->extraParameters->text(); settings.cacheSimulation = ui->cacheSimulation->isChecked(); settings.branchSimulation = ui->branchSimulation->isChecked(); settings.launchKCachegrind = ui->launchKCachegrind->isChecked(); settings.callgrindAnnotateParameters = ui->callgrindAnnotateParameters->text(); settings.save(cfg); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/callgrind/configpage.h b/tools/callgrind/configpage.h index 7b1e48a..2f10940 100644 --- a/tools/callgrind/configpage.h +++ b/tools/callgrind/configpage.h @@ -1,67 +1,67 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Callgrind { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/callgrind/job.cpp b/tools/callgrind/job.cpp index 4934b6c..c36a5c3 100644 --- a/tools/callgrind/job.cpp +++ b/tools/callgrind/job.cpp @@ -1,97 +1,97 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou Copyright 2011 Lucas Sarie - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "model.h" #include "parser.h" #include "plugin.h" #include "settings.h" #include "tool.h" #include "view.h" #include #include #include #include #include #include namespace Valgrind { namespace Callgrind { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IJob(Tool::self(), launchConfig) , m_model(new FunctionsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } Job::~Job() { } bool Job::processEnded() { Settings settings; settings.load(m_config); QStringList caArgs; caArgs += KShell::splitArgs(settings.callgrindAnnotateParameters); caArgs += QStringLiteral("--tree=calling"); caArgs += QStringLiteral("--threshold=100"); caArgs += m_outputFile->fileName(); QByteArray caOutput; if (executeProcess(settings.callgrindAnnotateExecutablePath(), caArgs, caOutput)) { return false; } parse(caOutput, m_model); return true; } void Job::addToolArgs(QStringList& args) const { Settings settings; settings.load(m_config); args += settings.cmdArgs(); args += QStringLiteral("--callgrind-out-file=%1").arg(m_outputFile->fileName()); } QWidget* Job::createView() { return new View(m_config, m_outputFile, m_model); } } } diff --git a/tools/callgrind/job.h b/tools/callgrind/job.h index dbdb017..86c3bc9 100644 --- a/tools/callgrind/job.h +++ b/tools/callgrind/job.h @@ -1,59 +1,59 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou Copyright 2011 Lucas Sarie - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ijob.h" class QTemporaryFile; namespace Valgrind { namespace Callgrind { class FunctionsModel; class Job : public IJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; FunctionsModel* m_model; QTemporaryFile* m_outputFile; }; } } diff --git a/tools/callgrind/model.cpp b/tools/callgrind/model.cpp index 3f8fdcd..7bd0b1e 100644 --- a/tools/callgrind/model.cpp +++ b/tools/callgrind/model.cpp @@ -1,526 +1,526 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "model.h" #include "debug.h" #include "utils.h" #include #include #include namespace Valgrind { namespace Callgrind { void addValues(const QStringList& stringValues, QVector& intValues) { for (int i = 0; i < stringValues.size(); ++i) { intValues[i] += stringValues[i].toInt(); } } CallInformation::CallInformation(const QStringList& stringValues) { Q_ASSERT(!stringValues.isEmpty()); m_eventValues.resize(stringValues.size()); addValues(stringValues, m_eventValues); } int CallInformation::eventValue(int type) { Q_ASSERT(type < m_eventValues.size()); return m_eventValues[type]; } Function::Function(int eventsCount) { m_eventValues.resize(eventsCount); } int Function::callCount() { int count = 0; for (auto info : qAsConst(callersInformation)) { count += info->callCount; } return count; } int Function::eventValue(int type, bool inclusive) { Q_ASSERT(type < m_eventValues.size()); int value = m_eventValues[type]; if (!inclusive) { return value; } if (callersInformation.isEmpty()) { // The function is NOT CALLED by others, therefore we calc // the event inclusive value as sum of self value and all callees. for (auto info : qAsConst(calleesInformation)) { value += info->eventValue(type); } return value; } // The function is CALLED by others, therefore we calc // the event inclusive value as sum of all callers. value = 0; for (auto info : qAsConst(callersInformation)) { value += info->eventValue(type); } return value; } void Function::addEventValues(const QStringList& stringValues) { Q_ASSERT(stringValues.size() == m_eventValues.size()); addValues(stringValues, m_eventValues); } FunctionsModel::FunctionsModel() : m_currentEventType(0) , m_percentageValues(false) { } FunctionsModel::~FunctionsModel() { qDeleteAll(m_functions); qDeleteAll(m_information); } const QStringList & FunctionsModel::eventTypes() { return m_eventTypes; } void FunctionsModel::setEventTypes(const QStringList& eventTypes) { Q_ASSERT(!eventTypes.isEmpty()); m_eventTypes = eventTypes; m_eventTotals.resize(m_eventTypes.size()); } void FunctionsModel::setEventTotals(const QStringList& stringValues) { Q_ASSERT(stringValues.size() == m_eventTotals.size()); addValues(stringValues, m_eventTotals); } int FunctionsModel::currentEventType() { return m_currentEventType; } void FunctionsModel::setCurrentEventType(int type) { Q_ASSERT(type < m_eventTotals.size()); m_currentEventType = type; emitDataChanged(this); } void FunctionsModel::setPercentageValues(bool value) { m_percentageValues = value; emitDataChanged(this); } Function* FunctionsModel::addFunction( const QString& name, const QString& sourceFile, const QString& binaryFile) { Q_ASSERT(!name.isEmpty()); Q_ASSERT(!m_eventTypes.isEmpty()); Function* function = nullptr; for (auto currentFunction : qAsConst(m_functions)) { if (currentFunction->name == name && (currentFunction->binaryFile.isEmpty() || binaryFile.isEmpty() || currentFunction->binaryFile == binaryFile)) { function = currentFunction; break; } } if (function) { if (function->binaryFile.isEmpty()) { function->binaryFile = binaryFile; } function->sourceFiles += sourceFile; function->sourceFiles.removeDuplicates(); function->sourceFiles.sort(); } else { function = new Function(m_eventTypes.size()); function->name = name; function->binaryFile = binaryFile; function->sourceFiles += sourceFile; m_functions.append(function); } return function; } void FunctionsModel::addCall( Function* caller, Function* callee, int callCount, const QStringList& eventValues) { Q_ASSERT(caller); Q_ASSERT(callee); auto info = new CallInformation(eventValues); m_information.append(info); info->caller = caller; info->callee = callee; info->callCount = callCount; caller->calleesInformation.append(info); callee->callersInformation.append(info); } QModelIndex FunctionsModel::index(int row, int column, const QModelIndex&) const { if (hasIndex(row, column)) { return createIndex(row, column, m_functions.at(row)); } return QModelIndex(); } int FunctionsModel::rowCount(const QModelIndex&) const { return m_functions.size(); } int FunctionsModel::columnCount(const QModelIndex&) const { return 4; } QString FunctionsModel::displayValue(int eventIntValue, int eventType) const { if (m_percentageValues) { return Valgrind::displayValue(eventIntValue * 100.0 / m_eventTotals[eventType]); } return Valgrind::displayValue(eventIntValue); } QVariant FunctionsModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } auto function = static_cast(index.internalPointer()); if (role == Qt::TextAlignmentRole && index.column() < 3) { return rightAlign; } if (index.column() < 2) { int intValue = function->eventValue(m_currentEventType, (index.column() == 0)); if (role == SortRole) { return intValue; } if (role == Qt::DisplayRole) { return displayValue(intValue, m_currentEventType); } } if (index.column() == 2 && (role == Qt::DisplayRole || role == SortRole)) { return function->callCount(); } if (index.column() == 3 && (role == Qt::DisplayRole || role == SortRole)) { return function->name; } return QVariant(); } QVariant FunctionsModel::headerData(int section, Qt::Orientation, int role) const { if (role == Qt::DisplayRole) { switch (section) { case 0: return i18n("Incl."); case 1: return i18n("Self"); case 2: return i18n("Called"); case 3: return i18n("Function"); } } return QVariant(); } FunctionEventsModel::FunctionEventsModel(FunctionsModel* baseModel) : QAbstractTableModel(baseModel) , m_baseModel(baseModel) , m_function(nullptr) { Q_ASSERT(m_baseModel); connect(m_baseModel, &FunctionsModel::dataChanged, this, [this](const QModelIndex&, const QModelIndex&, const QVector&) { emitDataChanged(this); }); } FunctionEventsModel::~FunctionEventsModel() { } void FunctionEventsModel::setFunction(Function* function) { m_function = function; emitDataChanged(this); } QModelIndex FunctionEventsModel::index(int row, int column, const QModelIndex&) const { if (hasIndex(row, column)) { return createIndex(row, column); } return QModelIndex(); } int FunctionEventsModel::rowCount(const QModelIndex&) const { return m_baseModel->eventTypes().size(); } int FunctionEventsModel::columnCount(const QModelIndex&) const { return 4; } QVariant FunctionEventsModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } int row = index.row(); int column = index.column(); if (column == 0 && role == Qt::DisplayRole) { return eventFullName(m_baseModel->eventTypes().at(row)); } if (column == 3 && role == Qt::DisplayRole) { return m_baseModel->eventTypes().at(row); } if (m_function && (column == 1 || column == 2)) { if (role == Qt::TextAlignmentRole) { return rightAlign; } int intValue = m_function->eventValue(row, (column == 1)); if (role == SortRole) { return intValue; } if (role == Qt::DisplayRole) { return m_baseModel->displayValue(intValue, row); } } return QVariant(); } QVariant FunctionEventsModel::headerData(int section, Qt::Orientation, int role) const { if (role == Qt::DisplayRole) { switch (section) { case 0: return i18n("Event"); case 1: return i18n("Incl."); case 2: return i18n("Self"); case 3: return i18n("Short"); } } return QVariant(); } FunctionCallersCalleesModel::FunctionCallersCalleesModel(FunctionsModel* baseModel, bool isCallerModel) : QAbstractTableModel(baseModel) , m_baseModel(baseModel) , m_isCallerModel(isCallerModel) , m_function(nullptr) { Q_ASSERT(m_baseModel); connect(m_baseModel, &FunctionsModel::dataChanged, this, [this](const QModelIndex&, const QModelIndex&, const QVector&) { emitDataChanged(this); emit headerDataChanged(Qt::Horizontal, 0, 1); }); } FunctionCallersCalleesModel::~FunctionCallersCalleesModel() { } void FunctionCallersCalleesModel::setFunction(Function* function) { beginResetModel(); m_function = function; endResetModel(); } QModelIndex FunctionCallersCalleesModel::index(int row, int column, const QModelIndex&) const { if (hasIndex(row, column)) { return createIndex(row, column); } return QModelIndex(); } int FunctionCallersCalleesModel::rowCount(const QModelIndex&) const { if (!m_function) { return 0; } if (m_isCallerModel) { return m_function->callersInformation.size(); } return m_function->calleesInformation.size(); } int FunctionCallersCalleesModel::columnCount(const QModelIndex&) const { return 4; } QVariant FunctionCallersCalleesModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } int row = index.row(); int column = index.column(); if (role == Qt::TextAlignmentRole && column < 3) { return rightAlign; } auto info = m_isCallerModel ? m_function->callersInformation.at(row) : m_function->calleesInformation.at(row); int eventType = m_baseModel->currentEventType(); int intValue = info->eventValue(eventType); int callCount = info->callCount; if (column == 0) { if (role == SortRole) { return intValue; } if (role == Qt::DisplayRole) { return m_baseModel->displayValue(intValue, eventType); } } if (column == 1) { int perCallValue = intValue / callCount; if (role == SortRole) { return perCallValue; } if (role == Qt::DisplayRole) { return displayValue(perCallValue); } } if (column == 2) { if (role == SortRole || role == Qt::DisplayRole) { return callCount; } } if (column == 3) { if (role == SortRole || role == Qt::DisplayRole) { if (m_isCallerModel) { return info->caller->name; } return info->callee->name; } } return QVariant(); } QVariant FunctionCallersCalleesModel::headerData(int section, Qt::Orientation, int role) const { if (role == Qt::DisplayRole) { const QString& eventType = m_baseModel->eventTypes().at(m_baseModel->currentEventType()); switch (section) { case 0: return eventType; case 1: return i18n("%1 per call", eventType); case 2: return i18n("Count"); case 3: if (m_isCallerModel) { return i18n("Caller"); } return i18n("Callee"); } } return QVariant(); } } } diff --git a/tools/callgrind/model.h b/tools/callgrind/model.h index 5b38c5e..d59d475 100644 --- a/tools/callgrind/model.h +++ b/tools/callgrind/model.h @@ -1,176 +1,176 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include class QItemSelectionModel; namespace Valgrind { namespace Callgrind { class Function; class CallInformation { public: explicit CallInformation(const QStringList& stringValues); Function* caller = nullptr; Function* callee = nullptr; int callCount = 0; int eventValue(int type); private: QVector m_eventValues; }; class Function { public: explicit Function(int eventsCount); QString name; QString binaryFile; QStringList sourceFiles; int callCount(); int eventValue(int type, bool inclusive); void addEventValues(const QStringList& stringValues); QList callersInformation; QList calleesInformation; private: QVector m_eventValues; }; class FunctionsModel : public QAbstractTableModel { Q_OBJECT public: FunctionsModel(); ~FunctionsModel() override; const QStringList& eventTypes(); void setEventTypes(const QStringList& eventTypes); int currentEventType(); void setCurrentEventType(int type); void setEventTotals(const QStringList& stringValues); void setPercentageValues(bool value); Function* addFunction(const QString& name, const QString& sourceFile, const QString& binaryFile); void addCall(Function* caller, Function* callee, int callCount, const QStringList& eventValues); QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant eventData(int type, int intValue, int role) const; QString displayValue(int eventIntValue, int eventType) const; private: QStringList m_eventTypes; int m_currentEventType; QVector m_eventTotals; bool m_percentageValues; QList m_functions; QList m_information; }; class FunctionEventsModel : public QAbstractTableModel { Q_OBJECT public: explicit FunctionEventsModel(FunctionsModel* baseModel); ~FunctionEventsModel() override; void setFunction(Function* function); QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; private: FunctionsModel* m_baseModel; Function* m_function; }; class FunctionCallersCalleesModel : public QAbstractTableModel { Q_OBJECT public: FunctionCallersCalleesModel(FunctionsModel* baseModel, bool isCallerModel); ~FunctionCallersCalleesModel() override; void setFunction(Function* function); QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; private: FunctionsModel* m_baseModel; bool m_isCallerModel; Function* m_function; }; } } diff --git a/tools/callgrind/parser.cpp b/tools/callgrind/parser.cpp index 69f59fb..8fcfc94 100644 --- a/tools/callgrind/parser.cpp +++ b/tools/callgrind/parser.cpp @@ -1,187 +1,187 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Lucas Sarie - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parser.h" #include "debug.h" #include "model.h" #include #include #include namespace Valgrind { namespace Callgrind { void parseCallInformation( const QString& line, bool programTotal, const QStringList& eventTypes, Function*& caller, FunctionsModel* model) { static const QRegularExpression binaryExpression("^(.*)\\[(.*)\\]$"); static const QRegularExpression callCountExpression("^(.*)\\((\\d+)x\\)$"); const int eventsCount = eventTypes.size(); QStringList lineItems = line.split(QChar(' '), QString::SkipEmptyParts); for (int i = 0; i < eventsCount; ++i) { lineItems[i].remove(QLatin1Char(',')); } if (programTotal) { while (lineItems.size() > eventsCount) { lineItems.removeLast(); } model->setEventTotals(lineItems); return; } const char lineType = lineItems.takeAt(eventsCount).at(0).toLatin1(); // skip caller lines if (lineType == '<') { return; } QString idString; while (lineItems.size() > eventsCount) { idString += QStringLiteral("%1 ").arg(lineItems.at(eventsCount)); lineItems.removeAt(eventsCount); } idString = idString.trimmed(); QString binaryFile; auto match = binaryExpression.match(idString); if (match.hasMatch()) { binaryFile = match.captured(2).trimmed(); idString = match.captured(1).trimmed(); } int callCount = 0; match = callCountExpression.match(idString); if (match.hasMatch()) { callCount = match.captured(2).toInt(); idString = match.captured(1).trimmed(); } int colonPos = idString.indexOf(':'); Q_ASSERT(colonPos >= 0); auto sourceUrl = QUrl::fromLocalFile(idString.mid(0, colonPos)).adjusted(QUrl::NormalizePathSegments); QString sourceFile = sourceUrl.toLocalFile(); QString functionName = idString.mid(colonPos + 1); auto function = model->addFunction(functionName, sourceFile, binaryFile); // the function itself if (lineType == '*') { caller = function; caller->addEventValues(lineItems); } // the callee else if (lineType == '>') { model->addCall(caller, function, callCount, lineItems); } else { qCWarning(KDEV_VALGRIND) << "unknown line type:" << lineType; } } enum ParserState { ParseRoot, ParseProgramTotalHeader, ParseProgramTotal, ParseProgramHeader, ParseProgram }; void parse(QByteArray& baData, FunctionsModel* model) { Q_ASSERT(model); ParserState parserState = ParseRoot; QStringList eventTypes; QString eventsString; QString line; Function* caller = nullptr; QBuffer data(&baData); data.open(QIODevice::ReadOnly); while (!data.atEnd()) { line = data.readLine().simplified(); if (line.startsWith(QLatin1String("--")) && line.contains(QLatin1String("annotated source:"))) { break; } if (parserState == ParseRoot) { if (line.startsWith(QLatin1String("Events shown:"))) { // 13 is 'Events shown:' size; eventsString = line.mid(13).simplified(); eventTypes = eventsString.split(QChar(' '), QString::SkipEmptyParts); model->setEventTypes(eventTypes); parserState = ParseProgramTotalHeader; } } else if (parserState == ParseProgramTotalHeader) { if (line == eventsString) { parserState = ParseProgramTotal; } } else if (parserState == ParseProgramHeader) { if (line.startsWith(eventsString)) { parserState = ParseProgram; } } else if (!line.isEmpty() && line.at(0).isDigit()) { if (parserState == ParseProgramTotal) { parseCallInformation(line, true, eventTypes, caller, model); parserState = ParseProgramHeader; } else { parseCallInformation(line, false, eventTypes, caller, model); } } } } } } diff --git a/tools/callgrind/parser.h b/tools/callgrind/parser.h index fe92c98..b2a9d4a 100644 --- a/tools/callgrind/parser.h +++ b/tools/callgrind/parser.h @@ -1,39 +1,39 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc - Copyright 201-2017 Anton Anikin + Copyright 201-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Callgrind { class FunctionsModel; void parse(QByteArray& data, FunctionsModel* model); } } diff --git a/tools/callgrind/settings.cpp b/tools/callgrind/settings.cpp index cfb7b6d..40bd68a 100644 --- a/tools/callgrind/settings.cpp +++ b/tools/callgrind/settings.cpp @@ -1,76 +1,76 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "globalsettings.h" #include "tool.h" namespace Valgrind { namespace Callgrind { Settings::Settings() : ISettings(Tool::self()->id()) , cacheSimulation( this, QStringLiteral("Cache Simulation"), QStringLiteral("cache-sim"), false) , branchSimulation( this, QStringLiteral("Branch Simulation"), QStringLiteral("branch-sim"), false) , callgrindAnnotateParameters( this, QStringLiteral("callgrind_annotate Parameters"), QStringLiteral(""), QStringLiteral("")) , launchKCachegrind( this, QStringLiteral("Launch KCachegrind"), QStringLiteral(""), false) { } Settings::~Settings() { } QString Settings::callgrindAnnotateExecutablePath() { return KDevelop::Path(GlobalSettings::callgrind_annotateExecutablePath()).toLocalFile(); } QString Settings::kcachegrindExecutablePath() { return KDevelop::Path(GlobalSettings::kcachegrindExecutablePath()).toLocalFile(); } } } diff --git a/tools/callgrind/settings.h b/tools/callgrind/settings.h index ca000e8..16cac5b 100644 --- a/tools/callgrind/settings.h +++ b/tools/callgrind/settings.h @@ -1,49 +1,49 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "isettings.h" namespace Valgrind { namespace Callgrind { class Settings : public ISettings { public: Settings(); ~Settings() override; BoolValue cacheSimulation; BoolValue branchSimulation; StringValue callgrindAnnotateParameters; BoolValue launchKCachegrind; static QString callgrindAnnotateExecutablePath(); static QString kcachegrindExecutablePath(); }; } } diff --git a/tools/callgrind/tool.cpp b/tools/callgrind/tool.cpp index b210c0c..52cb4c9 100644 --- a/tools/callgrind/tool.cpp +++ b/tools/callgrind/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace Callgrind { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("Callgrind"), i18n("Callgrind"), i18n("Callgrind (Call-Graph Generating Cache and Branch Prediction Profiler)"), QStringLiteral("callgrind"), QStringLiteral("callgrind_tool"), true) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/callgrind/tool.h b/tools/callgrind/tool.h index 1466a18..c3a4fe9 100644 --- a/tools/callgrind/tool.h +++ b/tools/callgrind/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace Callgrind { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/tools/callgrind/view.cpp b/tools/callgrind/view.cpp index eeadf37..bda8ee4 100644 --- a/tools/callgrind/view.cpp +++ b/tools/callgrind/view.cpp @@ -1,151 +1,151 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "view.h" #include "ui_view.h" #include "debug.h" #include "model.h" #include "settings.h" #include "utils.h" #include #include #include namespace Valgrind { namespace Callgrind { View::View(KConfigGroup config, QTemporaryFile* outputFile, FunctionsModel* model, QWidget* parent) : QWidget(parent) , m_kcachegrindProcess(new QProcess) { Q_ASSERT(model); model->setParent(this); Q_ASSERT(outputFile); outputFile->setParent(this); ui = new Ui::View(); ui->setupUi(this); for (const QString& eventType : model->eventTypes()) { ui->eventTypes->addItem(eventFullName(eventType)); } connect(ui->eventTypes, static_cast(&QComboBox::currentIndexChanged), model, &FunctionsModel::setCurrentEventType); model->setCurrentEventType(ui->eventTypes->currentIndex()); connect(ui->percenageValues, &QCheckBox::stateChanged, model, &FunctionsModel::setPercentageValues); model->setPercentageValues(ui->percenageValues->checkState()); auto functionsProxyModel = new QSortFilterProxyModel(this); functionsProxyModel->setSourceModel(model); functionsProxyModel->setSortRole(SortRole); functionsProxyModel->setFilterKeyColumn(-1); ui->functionsView->setModel(functionsProxyModel); ui->functionsView->setSortingEnabled(true); connect(ui->searchEdit, &QLineEdit::textChanged, functionsProxyModel, &QSortFilterProxyModel::setFilterWildcard); auto eventsModel = new FunctionEventsModel(model); ui->eventsView->setModel(eventsModel); ui->eventsView->header()->resizeSections(QHeaderView::ResizeToContents); auto callersModel = new FunctionCallersCalleesModel(model, true); auto callersProxyModel = new QSortFilterProxyModel(this); callersProxyModel->setSourceModel(callersModel); callersProxyModel->setSortRole(SortRole); ui->callersView->setModel(callersProxyModel); ui->callersView->setSortingEnabled(true); connect(callersModel, &FunctionCallersCalleesModel::headerDataChanged, this, [this](Qt::Orientation, int, int) { ui->callersView->header()->resizeSections(QHeaderView::ResizeToContents); }); auto calleesModel = new FunctionCallersCalleesModel(model, false); auto calleesProxyModel = new QSortFilterProxyModel(this); calleesProxyModel->setSourceModel(calleesModel); calleesProxyModel->setSortRole(SortRole); ui->calleesView->setModel(calleesProxyModel); ui->calleesView->setSortingEnabled(true); connect(calleesModel, &FunctionCallersCalleesModel::headerDataChanged, this, [this](Qt::Orientation, int, int) { ui->calleesView->header()->resizeSections(QHeaderView::ResizeToContents); }); connect(ui->functionsView->selectionModel(), &QItemSelectionModel::currentChanged, this, [=](const QModelIndex& currentProxyIndex, const QModelIndex&) { auto sourceIndex = functionsProxyModel->mapToSource(currentProxyIndex); auto function = static_cast(sourceIndex.internalPointer()); eventsModel->setFunction(function); callersModel->setFunction(function); calleesModel->setFunction(function); if (function) { ui->binaryLabel->setText(function->binaryFile); ui->sourceLabel->setText(function->sourceFiles.join('\n')); } else { ui->binaryLabel->clear(); ui->sourceLabel->clear(); } }); ui->binaryLabel->clear(); ui->sourceLabel->clear(); if (functionsProxyModel->rowCount()) { ui->functionsView->setCurrentIndex(functionsProxyModel->index(0,0)); } auto startVisualizer = [this, outputFile]() { m_kcachegrindProcess->start(Settings::kcachegrindExecutablePath(), { outputFile->fileName() }); }; Settings settings; settings.load(config); setupVisualizerProcess(m_kcachegrindProcess, ui->launchKCachegrindButton, startVisualizer, settings.launchKCachegrind); } View::~View() { m_kcachegrindProcess->disconnect(); delete m_kcachegrindProcess; delete ui; } } } diff --git a/tools/callgrind/view.h b/tools/callgrind/view.h index 7849886..bc0283a 100644 --- a/tools/callgrind/view.h +++ b/tools/callgrind/view.h @@ -1,62 +1,62 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include class QProcess; class QTemporaryFile; namespace Valgrind { namespace Callgrind { namespace Ui { class View; } class FunctionsModel; class View : public QWidget { Q_OBJECT public: View(KConfigGroup config, QTemporaryFile* outputFile, FunctionsModel* model, QWidget* parent = nullptr); ~View() override; private: Ui::View* ui; QProcess* m_kcachegrindProcess; }; } } diff --git a/tools/drd/configpage.cpp b/tools/drd/configpage.cpp index 11d0498..08bed3b 100644 --- a/tools/drd/configpage.cpp +++ b/tools/drd/configpage.cpp @@ -1,157 +1,157 @@ /* This file is part of KDevelop - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace DRD { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->joinListVol, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->segmentMergingInterval, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->checkStackVar, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->firstRaceOnly, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->freeIsWrite, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->reportSignalUnlocked, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->segmentMerging, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showConflSeg, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showStackUsage, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->ignoreThreadCreation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showInstructionPointer, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceAlloc, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceBarrier, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceCond, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceForkJoin, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceHb, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceMutex, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceRwlock, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->traceSemaphore, &QCheckBox::toggled, this, &ConfigPage::changed); ui->joinListVolLabel->setToolTip(ui->joinListVol->toolTip()); ui->segmentMergingIntervalLabel->setToolTip(ui->segmentMergingInterval->toolTip()); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->joinListVol->setValue(settings.joinListVol); ui->segmentMergingInterval->setValue(settings.segmentMergingInterval); ui->checkStackVar->setChecked(settings.checkStackVar); ui->firstRaceOnly->setChecked(settings.firstRaceOnly); ui->freeIsWrite->setChecked(settings.freeIsWrite); ui->reportSignalUnlocked->setChecked(settings.reportSignalUnlocked); ui->segmentMerging->setChecked(settings.segmentMerging); ui->showConflSeg->setChecked(settings.showConflSeg); ui->showStackUsage->setChecked(settings.showStackUsage); ui->ignoreThreadCreation->setChecked(settings.ignoreThreadCreation); ui->showInstructionPointer->setChecked(settings.showInstructionPointer); ui->traceAlloc->setChecked(settings.traceAlloc); ui->traceBarrier->setChecked(settings.traceBarrier); ui->traceCond->setChecked(settings.traceCond); ui->traceForkJoin->setChecked(settings.traceForkJoin); ui->traceHb->setChecked(settings.traceHb); ui->traceMutex->setChecked(settings.traceMutex); ui->traceRwlock->setChecked(settings.traceRwlock); ui->traceSemaphore->setChecked(settings.traceSemaphore); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.joinListVol = ui->joinListVol->value(); settings.segmentMergingInterval = ui->segmentMergingInterval->value(); settings.checkStackVar = ui->checkStackVar->isChecked(); settings.firstRaceOnly = ui->firstRaceOnly->isChecked(); settings.freeIsWrite = ui->freeIsWrite->isChecked(); settings.reportSignalUnlocked = ui->reportSignalUnlocked->isChecked(); settings.segmentMerging = ui->segmentMerging->isChecked(); settings.showConflSeg = ui->showConflSeg->isChecked(); settings.showStackUsage = ui->showStackUsage->isChecked(); settings.ignoreThreadCreation = ui->ignoreThreadCreation->isChecked(); settings.showInstructionPointer = ui->showInstructionPointer->isChecked(); settings.traceAlloc = ui->traceAlloc->isChecked(); settings.traceBarrier = ui->traceBarrier->isChecked(); settings.traceCond = ui->traceCond->isChecked(); settings.traceForkJoin = ui->traceForkJoin->isChecked(); settings.traceHb = ui->traceHb->isChecked(); settings.traceMutex = ui->traceMutex->isChecked(); settings.traceRwlock = ui->traceRwlock->isChecked(); settings.traceSemaphore = ui->traceSemaphore->isChecked(); settings.save(cfg); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/drd/configpage.h b/tools/drd/configpage.h index e6cf87a..96f26c9 100644 --- a/tools/drd/configpage.h +++ b/tools/drd/configpage.h @@ -1,66 +1,66 @@ /* This file is part of KDevelop - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace DRD { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/drd/job.cpp b/tools/drd/job.cpp index 5233954..1920cf2 100644 --- a/tools/drd/job.cpp +++ b/tools/drd/job.cpp @@ -1,43 +1,43 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "debug.h" #include "settings.h" #include "tool.h" namespace Valgrind { namespace DRD { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IXmlJob(Tool::self(), launchConfig, new Settings) { } Job::~Job() { } } } diff --git a/tools/drd/job.h b/tools/drd/job.h index d64ca63..240d340 100644 --- a/tools/drd/job.h +++ b/tools/drd/job.h @@ -1,41 +1,41 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmljob.h" namespace Valgrind { namespace DRD { class Job : public IXmlJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; }; } } diff --git a/tools/drd/settings.cpp b/tools/drd/settings.cpp index 7f1e80e..7b0c585 100644 --- a/tools/drd/settings.cpp +++ b/tools/drd/settings.cpp @@ -1,149 +1,149 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "tool.h" namespace Valgrind { namespace DRD { Settings::Settings() : IXmlSettings(Tool::self()->id()) , checkStackVar( this, QStringLiteral("Check Stack Variables"), QStringLiteral("check-stack-var"), false) , firstRaceOnly( this, QStringLiteral("First Race Only"), QStringLiteral("first-race-only"), false) , freeIsWrite( this, QStringLiteral("Free is Write"), QStringLiteral("free-is-write"), false) , reportSignalUnlocked( this, QStringLiteral("Report Signal Unlocked"), QStringLiteral("report-signal-unlocked"), true) , segmentMerging( this, QStringLiteral("Segment Merging"), QStringLiteral("segment-merging"), true) , showConflSeg( this, QStringLiteral("Show Conflicting Segments"), QStringLiteral("show-confl-seg"), true) , showStackUsage( this, QStringLiteral("Show Stack Usage"), QStringLiteral("show-stack-usage"), false) , ignoreThreadCreation( this, QStringLiteral("Ignore Thread Creation"), QStringLiteral("ignore-thread-creation"), false) , traceAlloc( this, QStringLiteral("Trace Allocations"), QStringLiteral("trace-alloc"), false) , traceBarrier( this, QStringLiteral("Trace Barrier Activity"), QStringLiteral("trace-barrier"), false) , traceCond( this, QStringLiteral("Trace Condition Variable Activity"), QStringLiteral("trace-cond"), false) , traceForkJoin( this, QStringLiteral("Trace Thread Creation and Termination"), QStringLiteral("trace-fork-join"), false) , traceHb( this, QStringLiteral("Trace HB"), QStringLiteral("trace-hb"), false) , traceMutex( this, QStringLiteral("Trace Mutex Activity"), QStringLiteral("trace-mutex"), false) , traceRwlock( this, QStringLiteral("Trace ReaderWriter Lock Activity"), QStringLiteral("trace-rwlock"), false) , traceSemaphore( this, QStringLiteral("Trace Semaphore Activity"), QStringLiteral("trace-semaphore"), false) , joinListVol( this, QStringLiteral("Joined Threads Memory Access List Volume"), QStringLiteral("join-list-vol"), 10) , segmentMergingInterval( this, QStringLiteral("Segment Merging Interval"), QStringLiteral("segment-merging-interval"), 10) { } Settings::~Settings() { } } } diff --git a/tools/drd/settings.h b/tools/drd/settings.h index 36e9247..2b33692 100644 --- a/tools/drd/settings.h +++ b/tools/drd/settings.h @@ -1,59 +1,59 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmlsettings.h" namespace Valgrind { namespace DRD { class Settings : public IXmlSettings { public: Settings(); ~Settings() override; BoolValue checkStackVar; BoolValue firstRaceOnly; BoolValue freeIsWrite; BoolValue reportSignalUnlocked; BoolValue segmentMerging; BoolValue showConflSeg; BoolValue showStackUsage; BoolValue ignoreThreadCreation; BoolValue traceAlloc; BoolValue traceBarrier; BoolValue traceCond; BoolValue traceForkJoin; BoolValue traceHb; BoolValue traceMutex; BoolValue traceRwlock; BoolValue traceSemaphore; IntValue joinListVol; IntValue segmentMergingInterval; }; } } diff --git a/tools/drd/tool.cpp b/tools/drd/tool.cpp index 69b0415..c7a6d21 100644 --- a/tools/drd/tool.cpp +++ b/tools/drd/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace DRD { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("DRD"), i18n("DRD"), i18n("DRD (Thread Error Detector)"), QStringLiteral("drd"), QStringLiteral("drd_tool"), false) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/drd/tool.h b/tools/drd/tool.h index a2316ed..f632d23 100644 --- a/tools/drd/tool.h +++ b/tools/drd/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace DRD { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/tools/generic/configpage.cpp b/tools/generic/configpage.cpp index d36b80f..ae66f13 100644 --- a/tools/generic/configpage.cpp +++ b/tools/generic/configpage.cpp @@ -1,105 +1,105 @@ /* This file is part of KDevelop Copyright 2011 Lionel Duc - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include namespace Valgrind { namespace Generic { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->extraParameters, &QLineEdit::textEdited, this, &ConfigPage::changed); connect(ui->limitErrors, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->maxStackframe, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->numCallers, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); ui->numCallersLabel->setToolTip(ui->numCallers->toolTip()); ui->maxStackframeLabel->setToolTip(ui->maxStackframe->toolTip()); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return i18n("Valgrind Generic Settings"); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->extraParameters->setText(settings.extraParameters); ui->numCallers->setValue(settings.numCallers); ui->maxStackframe->setValue(settings.maxStackframe); ui->limitErrors->setChecked(settings.limitErrors); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.extraParameters = ui->extraParameters->text(); settings.numCallers = ui->numCallers->value(); settings.maxStackframe = ui->maxStackframe->value(); settings.limitErrors = ui->limitErrors->isChecked(); settings.save(cfg); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/generic/configpage.h b/tools/generic/configpage.h index b2d5e48..ef592b4 100644 --- a/tools/generic/configpage.h +++ b/tools/generic/configpage.h @@ -1,68 +1,68 @@ /* This file is part of KDevelop Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Generic { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/generic/core/ijob.cpp b/tools/generic/core/ijob.cpp index e625fc0..5db04cc 100644 --- a/tools/generic/core/ijob.cpp +++ b/tools/generic/core/ijob.cpp @@ -1,311 +1,311 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou Copyright 2011 Lucas Sarie Copyright 2006-2008 Hamish Rodda Copyright 2002 Harald Fernengel - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ijob.h" #include "debug.h" #include "globalsettings.h" #include "itool.h" #include "plugin.h" #include "settings.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Valgrind { inline QString valgrindErrorsPrefix() { return QStringLiteral("valgrind: "); } IJob::IJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig) : KDevelop::OutputExecuteJob(KDevelop::ICore::self()->runController()) , m_tool(tool) , m_config(launchConfig->config()) , m_tcpServerPort(0) { Q_ASSERT(tool); Q_ASSERT(launchConfig); setProperties(KDevelop::OutputExecuteJob::JobProperty::DisplayStdout); setProperties(KDevelop::OutputExecuteJob::JobProperty::DisplayStderr); setProperties(KDevelop::OutputExecuteJob::JobProperty::PostProcessOutput); setCapabilities(KJob::Killable); setStandardToolView(KDevelop::IOutputView::TestView); setBehaviours(KDevelop::IOutputView::AutoScroll); auto pluginController = KDevelop::ICore::self()->pluginController(); auto iface = pluginController->pluginForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"))->extension(); Q_ASSERT(iface); QString envProfile = iface->environmentProfileName(launchConfig); if (envProfile.isEmpty()) { envProfile = KDevelop::EnvironmentProfileList(KSharedConfig::openConfig()).defaultProfileName(); } setEnvironmentProfile(envProfile); QString errorString; m_analyzedExecutable = iface->executable(launchConfig, errorString).toLocalFile(); if (!errorString.isEmpty()) { setError(-1); setErrorText(errorString); } m_analyzedExecutableArguments = iface->arguments(launchConfig, errorString); if (!errorString.isEmpty()) { setError(-1); setErrorText(errorString); } QUrl workDir = iface->workingDirectory(launchConfig); if (workDir.isEmpty() || !workDir.isValid()) { workDir = QUrl::fromLocalFile(QFileInfo(m_analyzedExecutable).absolutePath()); } setWorkingDirectory(workDir); connect(this, &IJob::finished, Plugin::self(), &Plugin::jobFinished); auto tcpServer = new QTcpServer(this); tcpServer->listen(QHostAddress::LocalHost); m_tcpServerPort = tcpServer->serverPort(); connect(tcpServer, &QTcpServer::newConnection, this, [this, tcpServer]() { auto tcpSocket = tcpServer->nextPendingConnection(); connect(tcpSocket, &QTcpSocket::readyRead, this, [this, tcpSocket]() { QStringList lines; while (!tcpSocket->atEnd()) { lines += tcpSocket->readLine().trimmed(); } processValgrindOutput(lines); }); }); connect(this, &IJob::finished, this, [this]() { emit hideProgress(this); }); KDevelop::ICore::self()->uiController()->registerStatus(this); } IJob::~IJob() { } const ITool* IJob::tool() const { return m_tool; } QString IJob::statusName() const { return i18n("%1 Analysis (%2)", m_tool->name(), QFileInfo(m_analyzedExecutable).fileName()); } void IJob::addLoggingArgs(QStringList& args) const { args += QStringLiteral("--log-socket=127.0.0.1:%1").arg(m_tcpServerPort); } QStringList IJob::buildCommandLine() const { Generic::Settings settings; settings.load(m_config); QStringList args; args += QStringLiteral("--tool=") + m_tool->valgrindToolName(); addLoggingArgs(args); args += settings.cmdArgs(); addToolArgs(args); return args; } void IJob::start() { *this << Generic::Settings::valgrindExecutablePath(); *this << buildCommandLine(); *this << m_analyzedExecutable; *this << m_analyzedExecutableArguments; qCDebug(KDEV_VALGRIND) << "executing:" << commandLine().join(' '); Plugin::self()->jobReadyToStart(this); emit showProgress(this, 0, 0, 0); KDevelop::OutputExecuteJob::start(); } void IJob::postProcessStderr(const QStringList& lines) { for (const QString& line : lines) { if (line.startsWith(valgrindErrorsPrefix())) { m_valgrindOutput += line; } } KDevelop::OutputExecuteJob::postProcessStderr(lines); } void IJob::processValgrindOutput(const QStringList& lines) { m_valgrindOutput += lines; if (GlobalSettings::showValgrindOutput()) { KDevelop::OutputExecuteJob::postProcessStderr(lines); } } void IJob::childProcessExited(int exitCode, QProcess::ExitStatus exitStatus) { qCDebug(KDEV_VALGRIND) << "Process Finished, exitCode" << exitCode << "process exit status" << exitStatus; bool ok = !exitCode; if (ok) { ok = processEnded(); } Plugin::self()->jobReadyToFinish(this, ok); KDevelop::OutputExecuteJob::childProcessExited(exitCode, exitStatus); } void IJob::childProcessError(QProcess::ProcessError processError) { QString errorMessage; switch (processError) { case QProcess::FailedToStart: errorMessage = i18n("Failed to start valgrind from \"%1\".", commandLine().at(0)); break; case QProcess::Crashed: // if the process was killed by the user, the crash was expected // don't notify the user if (status() != KDevelop::OutputExecuteJob::JobStatus::JobCanceled) { errorMessage = i18n("Valgrind crashed."); } break; case QProcess::Timedout: errorMessage = i18n("Valgrind process timed out."); break; case QProcess::WriteError: errorMessage = i18n("Write to Valgrind process failed."); break; case QProcess::ReadError: errorMessage = i18n("Read from Valgrind process failed."); break; case QProcess::UnknownError: // Here, check if Valgrind failed (because of bad parameters or whatever). // Because Valgrind always returns 1 on failure, and the profiled application's return // on success, we cannot know for sure which process returned != 0. // // The only way to guess that it is Valgrind which failed is to check stderr and look for // "valgrind: " at the beginning of the first line, even though it can still be the // profiled process that writes it on stderr. It is, however, unlikely enough to be // reliable in most cases. if (!m_valgrindOutput.isEmpty() && m_valgrindOutput.at(0).startsWith(valgrindErrorsPrefix())) { errorMessage = m_valgrindOutput.join('\n').remove(valgrindErrorsPrefix()); errorMessage += QStringLiteral("\n\n"); errorMessage += i18n("Please review your Valgrind launch configuration."); } else { errorMessage = i18n("Unknown Valgrind process error."); } break; } if (!errorMessage.isEmpty()) { KMessageBox::error(activeMainWindow(), errorMessage, i18n("Valgrind Error")); } KDevelop::OutputExecuteJob::childProcessError(processError); } bool IJob::processEnded() { return true; } int IJob::executeProcess(const QString& executable, const QStringList& args, QByteArray& processOutput) { QString commandLine = executable + QLatin1Char(' ') + args.join(QLatin1Char(' ')); if (GlobalSettings::showValgrindOutput()) { KDevelop::OutputExecuteJob::postProcessStdout({i18n("Executing command: ") + commandLine }); } QProcess process; process.start(executable, args); if (!process.waitForFinished()){ return -1; } processOutput = process.readAllStandardOutput(); QString errOutput(process.readAllStandardError()); if (GlobalSettings::showValgrindOutput()) { KDevelop::OutputExecuteJob::postProcessStdout(QString(processOutput).split('\n')); } KDevelop::OutputExecuteJob::postProcessStderr(errOutput.split('\n')); if (process.exitCode()) { QString message = i18n("Failed to execute the command:"); message += "\n\n"; message += commandLine; message += "\n\n"; message += i18n("Please review your Valgrind launch configuration."); KMessageBox::error(activeMainWindow(), message, i18n("Valgrind Error")); } return process.exitCode(); } } diff --git a/tools/generic/core/ijob.h b/tools/generic/core/ijob.h index f11ccf3..05bcce0 100644 --- a/tools/generic/core/ijob.h +++ b/tools/generic/core/ijob.h @@ -1,98 +1,98 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2002 Harald Fernengel Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include #include class QWidget; namespace KDevelop { class ILaunchConfiguration; } namespace Valgrind { class ITool; class IJob : public KDevelop::OutputExecuteJob, public KDevelop::IStatus { Q_OBJECT Q_INTERFACES(KDevelop::IStatus) public: IJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig); ~IJob() override; void start() override; using KDevelop::OutputExecuteJob::doKill; const ITool* tool() const; virtual QWidget* createView() = 0; QString statusName() const override; Q_SIGNALS: void clearMessage(KDevelop::IStatus*) override; void hideProgress(KDevelop::IStatus*) override; void showErrorMessage(const QString& message, int timeout = 0) override; void showMessage(KDevelop::IStatus*, const QString& message, int timeout = 0) override; void showProgress(KDevelop::IStatus*, int minimum, int maximum, int value) override; protected: void postProcessStderr(const QStringList& lines) override; virtual void processValgrindOutput(const QStringList& lines); void childProcessExited(int exitCode, QProcess::ExitStatus exitStatus) override; void childProcessError(QProcess::ProcessError processError) override; virtual bool processEnded(); virtual void addLoggingArgs(QStringList& args) const; virtual void addToolArgs(QStringList& args) const = 0; int executeProcess(const QString& executable, const QStringList& args, QByteArray& processOutput); QStringList buildCommandLine() const; const ITool* m_tool; KConfigGroup m_config; QString m_analyzedExecutable; QStringList m_analyzedExecutableArguments; QStringList m_valgrindOutput; quint16 m_tcpServerPort; }; } diff --git a/tools/generic/core/isettings.cpp b/tools/generic/core/isettings.cpp index 96bca16..66e123f 100644 --- a/tools/generic/core/isettings.cpp +++ b/tools/generic/core/isettings.cpp @@ -1,162 +1,162 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "isettings.h" #include #include namespace Valgrind { ISettingsBase::ISettingsBase(const QString& configKeyPrefix) : m_configKeyPrefix(configKeyPrefix) { } ISettingsBase::~ISettingsBase() { } ISettingsBase::IValue::~IValue() { } template ISettingsBase::Value::Value( ISettingsBase* settings, const QString& configKey, const QString& cmdKey, const T& defaultValue) : m_configKey(configKey) , m_cmdKey(cmdKey) , m_value(defaultValue) , m_defaultValue(defaultValue) { Q_ASSERT(settings); Q_ASSERT(!configKey.isEmpty()); settings->m_values.append(this); } template ISettingsBase::Value::~Value() { } template ISettingsBase::Value::operator const T& () const { return m_value; } template ISettingsBase::Value& ISettingsBase::Value::operator=(const T& value) { m_value = value; return *this; } template void ISettingsBase::Value::load(const KConfigGroup& config, const QString& configKeyPrefix) { m_value = config.readEntry(QStringLiteral("%1 %2").arg(configKeyPrefix).arg(m_configKey), m_defaultValue); } template void ISettingsBase::Value::save(KConfigGroup& config, const QString& configKeyPrefix) { config.writeEntry(QStringLiteral("%1 %2").arg(configKeyPrefix).arg(m_configKey), m_value); } inline QString toCmdArg(int value) { return QString::number(value); } inline QString toCmdArg(bool value) { return value ? QStringLiteral("yes") : QStringLiteral("no"); } inline QString toCmdArg(const QString& value) { return value; } template QString ISettingsBase::Value::cmdArg() { if (m_cmdKey.isEmpty()) { return QStringLiteral(""); } else { return QString("--%1=%2").arg(m_cmdKey).arg(toCmdArg(m_value)); } } template class ISettingsBase::Value; template class ISettingsBase::Value; template class ISettingsBase::Value; ISettings::ISettings(const QString& configKeyPrefix) : ISettingsBase(configKeyPrefix) , extraParameters( this, QStringLiteral("Extra Parameters"), QStringLiteral(""), QStringLiteral("")) { } ISettings::~ISettings() { } void ISettings::load(const KConfigGroup& config) { for (auto value : qAsConst(m_values)) { value->load(config, m_configKeyPrefix); } } void ISettings::save(KConfigGroup& config) { for (auto value : qAsConst(m_values)) { value->save(config, m_configKeyPrefix); } } QStringList ISettings::cmdArgs() { QStringList args; for (auto value : qAsConst(m_values)) { args += value->cmdArg(); } args += KShell::splitArgs(extraParameters); args.removeAll(QStringLiteral("")); return args; } } diff --git a/tools/generic/core/itool.cpp b/tools/generic/core/itool.cpp index 60b5df8..bd53a01 100644 --- a/tools/generic/core/itool.cpp +++ b/tools/generic/core/itool.cpp @@ -1,83 +1,83 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "itool.h" #include "launcher.h" namespace Valgrind { ITool::ITool( const QString& id, const QString& name, const QString& fullName, const QString& valgrindToolName, const QString& menuActionName, bool hasView) : m_id(id) , m_name(name) , m_fullName(fullName) , m_valgrindToolName(valgrindToolName) , m_menuActionName(menuActionName) , m_hasView(hasView) { } ITool::~ITool() { } QString ITool::name() const { return m_name; } QString ITool::fullName() const { return m_fullName; } QString ITool::valgrindToolName() const { return m_valgrindToolName; } QString ITool::id() const { return m_id; } QString ITool::menuActionName() const { return m_menuActionName; } bool ITool::hasView() const { return m_hasView; } KDevelop::ILauncher* ITool::createLauncher() const { return new Launcher(this); } } diff --git a/tools/generic/core/launcher.cpp b/tools/generic/core/launcher.cpp index 981873d..0d8543f 100644 --- a/tools/generic/core/launcher.cpp +++ b/tools/generic/core/launcher.cpp @@ -1,109 +1,109 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2009 Andreas Pakulat Copyright 2011 Lionel Duc Copyright 2011 Mathieu Lornac Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "launcher.h" #include "configpage.h" #include "debug.h" #include "ijob.h" #include "itool.h" #include "launchmode.h" #include "plugin.h" #include #include #include #include #include #include #include namespace Valgrind { Launcher::Launcher(const ITool* tool) : m_tool(tool) { Q_ASSERT(tool); m_configPageFactories += tool->createConfigPageFactory(); m_configPageFactories += new Generic::ConfigPageFactory; } Launcher::~Launcher() { qDeleteAll(m_configPageFactories); } KJob* Launcher::start(const QString& launchMode, KDevelop::ILaunchConfiguration* launchConfig) { Q_ASSERT(launchConfig); if (Plugin::self()->launchMode()->id() != launchMode) { return nullptr; } auto iface = KDevelop::ICore::self()->pluginController()->pluginForExtension("org.kdevelop.IExecutePlugin")->extension(); Q_ASSERT(iface); QList jobList; if (KJob* depJob = iface->dependencyJob(launchConfig)) { jobList += depJob; } auto valgrindJob = m_tool->createJob(launchConfig); jobList += valgrindJob; auto ecJob = new KDevelop::ExecuteCompositeJob(KDevelop::ICore::self()->runController(), jobList); ecJob->setObjectName(valgrindJob->statusName()); return ecJob; } QStringList Launcher::supportedModes() const { return { Plugin::self()->launchMode()->id() }; } QList Launcher::configPages() const { return m_configPageFactories; } QString Launcher::name() const { return m_tool->name(); } QString Launcher::description() const { return m_tool->fullName(); } QString Launcher::id() { return m_tool->id(); } } diff --git a/tools/generic/core/launcher.h b/tools/generic/core/launcher.h index 3339a48..db14bca 100644 --- a/tools/generic/core/launcher.h +++ b/tools/generic/core/launcher.h @@ -1,57 +1,57 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2009 Andreas Pakulat Copyright 2011 Lionel Duc Copyright 2011 Mathieu Lornac - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include class KJob; namespace Valgrind { class ITool; class Launcher : public KDevelop::ILauncher { public: explicit Launcher(const ITool* tool); ~Launcher() override; QString name() const override final; QString description() const override final; QString id() override final; QStringList supportedModes() const override final; QList configPages() const override final; KJob* start(const QString& launchMode, KDevelop::ILaunchConfiguration* launchConfig) override final; protected: const ITool* m_tool; QList m_configPageFactories; }; } diff --git a/tools/generic/core/utils.cpp b/tools/generic/core/utils.cpp index ba4e806..fae8b47 100644 --- a/tools/generic/core/utils.cpp +++ b/tools/generic/core/utils.cpp @@ -1,150 +1,150 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "utils.h" #include #include #include #include #include #include #include #include #include #include namespace Valgrind { QString eventFullName(const QString& eventShortName) { static QMap fullNames; static bool initDone = false; if (!initDone) { initDone = true; // full names are from KCachegrind fullNames["Ir" ] = i18n("Instruction Fetch"); fullNames["Dr" ] = i18n("Data Read Access"); fullNames["Dw" ] = i18n("Data Write Access"); fullNames["I1mr"] = i18n("L1 Instr. Fetch Miss"); fullNames["D1mr"] = i18n("L1 Data Read Miss"); fullNames["D1mw"] = i18n("L1 Data Write Miss"); fullNames["ILmr"] = i18n("LL Instr. Fetch Miss"); fullNames["DLmr"] = i18n("LL Data Read Miss"); fullNames["DLmw"] = i18n("LL Data Write Miss"); fullNames["Bc" ] = i18n("Conditional Branch"); fullNames["Bcm" ] = i18n("Mispredicted Cond. Branch"); fullNames["Bi" ] = i18n("Indirect Branch"); fullNames["Bim" ] = i18n("Mispredicted Ind. Branch"); } return fullNames.value(eventShortName, eventShortName); } QString displayValue(int value) { QString result = QString::number(value); int length = result.length(); for (int i = 0; i < (length / 3); ++i) { int pos = result.length() - (4 * i + 3); if (!pos) { break; } result.insert(pos, ' '); } return result; } QString displayValue(double value) { return QString::number(value, 'f', 2); } void emitDataChanged(QAbstractTableModel* model) { Q_ASSERT(model); emit model->dataChanged(model->index(0,0), model->index(model->rowCount() - 1, model->columnCount() - 1), { Qt::DisplayRole }); } void setupVisualizerProcess( QProcess* visualizerProcess, QPushButton* startButton, std::function startFunction, bool startImmediately) { Q_ASSERT(visualizerProcess); Q_ASSERT(startButton); QObject::connect(startButton, &QPushButton::clicked, startButton, [startFunction]() { startFunction(); }); QObject::connect(visualizerProcess, &QProcess::started, startButton, [startButton]() { startButton->setEnabled(false); }); QObject::connect(visualizerProcess, &QProcess::errorOccurred, startButton, [visualizerProcess, startButton]() { QString errorMessage; if (visualizerProcess->error() == QProcess::FailedToStart) { errorMessage += i18n("Failed to start visualizer from \"%1\".", visualizerProcess->program()); errorMessage += QStringLiteral("\n\n"); errorMessage += i18n("Check your settings and install the visualizer if necessary."); } else { errorMessage += i18n("Error during visualizer execution:"); errorMessage += QStringLiteral("\n\n"); errorMessage += visualizerProcess->errorString(); } KMessageBox::error(activeMainWindow(), errorMessage, i18n("Valgrind Error")); startButton->setEnabled(true); }); QObject::connect(visualizerProcess, static_cast(&QProcess::finished), startButton, [startButton]() { startButton->setEnabled(true); }); if (startImmediately) { startFunction(); } } QWidget* activeMainWindow() { return KDevelop::ICore::self()->uiController()->activeMainWindow(); } QString findExecutable(const QString &executableName) { QString executablePath = QStandardPaths::findExecutable(executableName); return executablePath.isEmpty() ? executableName : executablePath; } } diff --git a/tools/generic/core/xml/error.cpp b/tools/generic/core/xml/error.cpp index b80b692..8e09f8e 100644 --- a/tools/generic/core/xml/error.cpp +++ b/tools/generic/core/xml/error.cpp @@ -1,231 +1,231 @@ /* This file is part of KDevelop * Copyright 2006-2008 Hamish Rodda * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Sarie Lucas - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "error.h" #include "debug.h" #include #include #include namespace Valgrind { namespace XmlParser { void Frame::setValue(const QString& name, const QString& value) { if (name == "ip") { instructionPointer = value; } else if (name == "obj") { objectFile = value; } else if (name == "fn") { function = value; } else if (name == "dir") { directory = value; } else if (name == "file") { file = value; } else if (name == "line") { line = value.toInt(); } } KDevelop::IProblem::Ptr Frame::toIProblem(const QString& toolName, bool showInstructionPointer) const { KDevelop::IProblem::Ptr frameProblem(new KDevelop::DetectedProblem(toolName)); KDevelop::DocumentRange range; range.setBothLines(line - 1); if (directory.isEmpty() && file.isEmpty()) { range.document = KDevelop::IndexedString(objectFile); } else { range.document = KDevelop::IndexedString(directory + QLatin1Char('/') + file); } frameProblem->setFinalLocation(range); frameProblem->setFinalLocationMode(KDevelop::IProblem::TrimmedLine); QString description; if (showInstructionPointer) { description = QStringLiteral("%1: ").arg(instructionPointer); } description += function; frameProblem->setDescription(description); return frameProblem; } Frame* Stack::addFrame() { frames.append(Frame{}); return &frames.last(); } KDevelop::IProblem::Ptr Stack::toIProblem(const QString& toolName, bool showInstructionPointer) const { KDevelop::IProblem::Ptr stackProblem(new KDevelop::DetectedProblem(toolName)); KDevelop::DocumentRange range(KDevelop::DocumentRange::invalid()); for (const Frame& frame : frames) { auto frameProblem = frame.toIProblem(toolName, showInstructionPointer); stackProblem->addDiagnostic(frameProblem); if (!range.isValid() && !frame.file.isEmpty()) { range = frameProblem->finalLocation(); } } stackProblem->setFinalLocation(range); stackProblem->setFinalLocationMode(KDevelop::IProblem::TrimmedLine); return stackProblem; } Stack* OtherSegment::addStack() { stacks.append(Stack{}); return &stacks.last(); } KDevelop::IProblem::Ptr OtherSegment::toIProblem(const QString& toolName, bool showInstructionPointer) const { QString description = isStart ? QStringLiteral("Other segment start") : QStringLiteral("Other segment end"); // Simplify view for segments with single stack if (stacks.size() == 1) { auto segmentProblem = stacks.first().toIProblem(toolName, showInstructionPointer); segmentProblem->setDescription(description); return segmentProblem; } KDevelop::IProblem::Ptr segmentProblem(new KDevelop::DetectedProblem(toolName)); segmentProblem->setDescription(description); for (int i = 0; i < stacks.size(); ++i) { auto stackProblem = stacks.at(i).toIProblem(toolName, showInstructionPointer); stackProblem->setDescription(QStringLiteral("Stack_%1").arg(i)); segmentProblem->addDiagnostic(stackProblem); } return segmentProblem; } void Error::clear() { stacks.clear(); messages.clear(); otherSegments.clear(); } Stack* Error::addStack() { stacks.append(Stack{}); return &stacks.last(); } OtherSegment* Error::addOtherSegment(bool isStart) { otherSegments.append({ isStart, {} }); return &otherSegments.last(); } void Error::setValue(const QString& name, const QString& value) { // Fix for memcheck messages static const QRegularExpression memcheckSuffix(" in loss record \\d+ of \\d+$"); if (!value.isEmpty() && (name == QStringLiteral("text") || name == QStringLiteral("auxwhat") || name == QStringLiteral("what"))) { messages += value.trimmed().remove(memcheckSuffix); } } KDevelop::IProblem::Ptr Error::toIProblem(const QString& toolName, bool showInstructionPointer) const { Q_ASSERT(!messages.isEmpty()); Q_ASSERT(!stacks.isEmpty()); // Simplify view for errors with single stack / message if (stacks.size() == 1 && messages.size() == 1) { auto problem = stacks.first().toIProblem(toolName, showInstructionPointer); problem->setDescription(messages.first()); return problem; } KDevelop::IProblem::Ptr problem(new KDevelop::DetectedProblem(toolName)); problem->setDescription(messages.first()); // Add all stacks for (const Stack& stack : stacks) { problem->addDiagnostic(stack.toIProblem(toolName, showInstructionPointer)); } // First stack is the one that shows the actual error // Hence why the problem gets it's file/line pair from here problem->setFinalLocation(problem->diagnostics().first()->finalLocation()); problem->setFinalLocationMode(KDevelop::IProblem::TrimmedLine); // Set descriptions for all stacks. If we have some "extra" messages, then // we add them as "empty" (text-only) problems. for (int i = 0; i < messages.size(); ++i) { if (i < stacks.size()) { problem->diagnostics().at(i)->setDescription(messages.at(i)); } else { KDevelop::IProblem::Ptr messageOnlyProblem(new KDevelop::DetectedProblem(toolName)); messageOnlyProblem->setDescription(messages.at(i)); messageOnlyProblem->setFinalLocation(problem->finalLocation()); problem->addDiagnostic(messageOnlyProblem); } } // Add other segments ad diagnostics (DRD tool) for (const auto& segment : otherSegments) { if (!segment.stacks.isEmpty()) { problem->addDiagnostic(segment.toIProblem(toolName, showInstructionPointer)); } } return problem; } } } diff --git a/tools/generic/core/xml/error.h b/tools/generic/core/xml/error.h index 3023b7d..1825f81 100644 --- a/tools/generic/core/xml/error.h +++ b/tools/generic/core/xml/error.h @@ -1,93 +1,93 @@ /* This file is part of KDevelop * Copyright 2006-2008 Hamish Rodda * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * Copyright 2011 Sarie Lucas -* Copyright 2017 Anton Anikin +* Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include namespace Valgrind { namespace XmlParser { struct Frame { void setValue(const QString& name, const QString& value); KDevelop::IProblem::Ptr toIProblem(const QString& toolName, bool showInstructionPointer) const; int line = 0; QString function = QStringLiteral("???"); QString instructionPointer; QString objectFile; QString directory; QString file; }; struct Stack { Frame* addFrame(); KDevelop::IProblem::Ptr toIProblem(const QString& toolName, bool showInstructionPointer) const; QList frames; }; // DRD tool struct OtherSegment { Stack* addStack(); KDevelop::IProblem::Ptr toIProblem(const QString& toolName, bool showInstructionPointer) const; bool isStart; QList stacks; }; struct Error { Stack* addStack(); OtherSegment* addOtherSegment(bool isStart); void setValue(const QString& name, const QString& value); KDevelop::IProblem::Ptr toIProblem(const QString& toolName, bool showInstructionPointer) const; void clear(); QList stacks; QList otherSegments; QStringList messages; }; } } diff --git a/tools/generic/core/xml/ixmljob.cpp b/tools/generic/core/xml/ixmljob.cpp index cc7da54..5fc1fc6 100644 --- a/tools/generic/core/xml/ixmljob.cpp +++ b/tools/generic/core/xml/ixmljob.cpp @@ -1,94 +1,94 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ixmljob.h" #include "ixmlsettings.h" #include "debug.h" #include "itool.h" #include "parser.h" #include "plugin.h" #include "problemmodel.h" #include namespace Valgrind { IXmlJob::IXmlJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig, IXmlSettings* settings) : IJob(tool, launchConfig) , m_settings(settings) { Q_ASSERT(m_settings); } IXmlJob::~IXmlJob() { delete m_settings; } void IXmlJob::processValgrindOutput(const QStringList& lines) { static const auto xmlStartRegex = QRegularExpression("\\s*<"); for (const QString& line : lines) { if (line.isEmpty()) { continue; } if (line.indexOf(xmlStartRegex) >= 0) { // the line contains XML m_xmlOutput << line; } } IJob::processValgrindOutput(lines); } bool IXmlJob::processEnded() { m_settings->load(m_config); auto problems = parseXml(m_tool->name(), m_xmlOutput.join(" "), m_settings->showInstructionPointer); Plugin::self()->problemModel()->setProblems(problems); return true; } void IXmlJob::addLoggingArgs(QStringList& args) const { args += QStringLiteral("--xml=yes"); args += QStringLiteral("--xml-socket=127.0.0.1:%1").arg(m_tcpServerPort); } void IXmlJob::addToolArgs(QStringList& args) const { m_settings->load(m_config); args += m_settings->cmdArgs(); } QWidget* IXmlJob::createView() { return nullptr; } } diff --git a/tools/generic/core/xml/ixmljob.h b/tools/generic/core/xml/ixmljob.h index 94d4572..43600c4 100644 --- a/tools/generic/core/xml/ixmljob.h +++ b/tools/generic/core/xml/ixmljob.h @@ -1,56 +1,56 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ijob.h" namespace Valgrind { class IXmlSettings; class IXmlJob : public IJob { Q_OBJECT public: ~IXmlJob() override; protected: IXmlJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig, IXmlSettings* settings); QWidget* createView() override final; void processValgrindOutput(const QStringList& lines) override final; bool processEnded() override final; void addLoggingArgs(QStringList& args) const override final; void addToolArgs(QStringList& args) const override final; IXmlSettings* m_settings; QStringList m_xmlOutput; }; } diff --git a/tools/generic/core/xml/ixmlsettings.cpp b/tools/generic/core/xml/ixmlsettings.cpp index 9144cf0..7c0c615 100644 --- a/tools/generic/core/xml/ixmlsettings.cpp +++ b/tools/generic/core/xml/ixmlsettings.cpp @@ -1,40 +1,40 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ixmlsettings.h" namespace Valgrind { IXmlSettings::IXmlSettings(const QString& configKeyPrefix) : Valgrind::ISettings(configKeyPrefix) , showInstructionPointer( this, QStringLiteral("Show Instruction Pointer"), QStringLiteral(""), false) { } IXmlSettings::~IXmlSettings() { } } diff --git a/tools/generic/core/xml/parser.cpp b/tools/generic/core/xml/parser.cpp index 3331034..85054ee 100644 --- a/tools/generic/core/xml/parser.cpp +++ b/tools/generic/core/xml/parser.cpp @@ -1,284 +1,284 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2015 Laszlo Kis-Adam - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parser.h" #include "debug.h" #include "error.h" #include "utils.h" #include #include #include #include namespace Valgrind { namespace XmlParser { class Parser : public QXmlStreamReader { public: explicit Parser(const QString& toolName); virtual ~Parser(); QVector parse(bool showInstructionPointer); private: void startElement(); void endElement(QVector& problems, bool showInstructionPointer); void clear(); enum State { Unknown, Session, Status, Preamble, Error, Stack, Frame, // DRD tool OtherSegmentStart, OtherSegmentEnd }; QString m_toolName; QStack m_stateStack; QString m_name; QString m_value; XmlParser::Frame* m_frame; XmlParser::Stack* m_stack; XmlParser::OtherSegment* m_otherSegment; XmlParser::Error* m_error; }; inline QString errorXmlName() { return QStringLiteral("error"); } inline QString stackXmlName() { return QStringLiteral("stack"); } inline QString frameXmlName() { return QStringLiteral("frame"); } inline QString otherSegmentStartXmlName() { return QStringLiteral("other_segment_start"); } inline QString otherSegmentEndXmlName() { return QStringLiteral("other_segment_end"); } Parser::Parser(const QString& toolName) : m_toolName(toolName) , m_frame(nullptr) , m_stack(nullptr) , m_otherSegment(nullptr) , m_error(new XmlParser::Error) { } Parser::~Parser() { delete m_error; } void Parser::clear() { m_stateStack.clear(); m_name.clear(); m_value.clear(); } void Parser::startElement() { State newState = Unknown; if (m_name == QStringLiteral("valgrindoutput")) { newState = Session; } else if (m_name == QStringLiteral("status")) { newState = Status; } else if (m_name == QStringLiteral("preamble")) { newState = Preamble; } else if (m_name == errorXmlName()) { newState = Error; m_error->clear(); } else if (m_name == stackXmlName()) { newState = Stack; // Useful stacks are inside error or other_segment_begin/end if (m_stateStack.top() == Error) { m_stack = m_error->addStack(); } else if (m_stateStack.top() == OtherSegmentStart || m_stateStack.top() == OtherSegmentEnd) { Q_ASSERT(m_otherSegment); m_stack = m_otherSegment->addStack(); } } else if (m_name == frameXmlName()) { newState = Frame; if (m_stack) { m_frame = m_stack->addFrame(); } } else if (m_name == otherSegmentStartXmlName()) { newState = OtherSegmentStart; m_otherSegment = m_error->addOtherSegment(true); } else if (m_name == otherSegmentEndXmlName()) { newState = OtherSegmentEnd; m_otherSegment = m_error->addOtherSegment(false); } else { m_stateStack.push(m_stateStack.top()); return; } m_stateStack.push(newState); return; } void Parser::endElement(QVector& problems, bool showInstructionPointer) { State state = m_stateStack.pop(); switch (state) { case Error: if (m_name == errorXmlName()) { problems.append(m_error->toIProblem(m_toolName, showInstructionPointer)); } else { m_error->setValue(m_name, m_value); } break; case Stack: if (m_stack && m_name == stackXmlName()) { m_stack = nullptr; } break; case Frame: if (m_frame) { if (m_name == frameXmlName()) { m_frame = nullptr; } else { m_frame->setValue(m_name, m_value); } } break; case OtherSegmentStart: if (m_name == otherSegmentStartXmlName()) { m_otherSegment = nullptr; } break; case OtherSegmentEnd: if (m_name == otherSegmentEndXmlName()) { m_otherSegment = nullptr; } break; default: break; } } QVector Parser::parse(bool showInstructionPointer) { QVector problems; while (!atEnd()) { switch (readNext()) { case StartDocument: clear(); break; case StartElement: m_name = name().toString(); m_value.clear(); startElement(); break; case EndElement: m_name = name().toString(); endElement(problems, showInstructionPointer); break; case Characters: m_value += text(); break; default: break; } } if (hasError()) { switch (error()) { case CustomError: case UnexpectedElementError: case NotWellFormedError: KMessageBox::error(activeMainWindow(), i18n("Valgrind XML Parsing: error at line %1, column %2: %3", lineNumber(), columnNumber(), errorString()), i18n("Valgrind Error")); break; case NoError: case PrematureEndOfDocumentError: break; } } return problems; } } QVector parseXml(const QString& toolName, const QString& xmlData, bool showInstructionPointer) { XmlParser::Parser parser(toolName); parser.addData(xmlData); return parser.parse(showInstructionPointer); } } diff --git a/tools/generic/core/xml/parser.h b/tools/generic/core/xml/parser.h index 0e82bb8..c5ca9a7 100644 --- a/tools/generic/core/xml/parser.h +++ b/tools/generic/core/xml/parser.h @@ -1,33 +1,33 @@ /* This file is part of KDevelop Copyright 2006-2008 Hamish Rodda Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { QVector parseXml(const QString& toolName, const QString& xmlData, bool showInstructionPointer); } diff --git a/tools/generic/settings.cpp b/tools/generic/settings.cpp index a80e406..c53747b 100644 --- a/tools/generic/settings.cpp +++ b/tools/generic/settings.cpp @@ -1,64 +1,64 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "globalsettings.h" namespace Valgrind { namespace Generic { Settings::Settings() : ISettings(QStringLiteral("Valgrind")) , numCallers( this, QStringLiteral("Stackframe Depth"), QStringLiteral("num-callers"), 12) , maxStackframe( this, QStringLiteral("Maximum Stackframe Size"), QStringLiteral("max-stackframe"), 2000000) , limitErrors( this, QStringLiteral("Limit Errors"), QStringLiteral("error-limit"), true) { } Settings::~Settings() { } QString Settings::valgrindExecutablePath() { return KDevelop::Path(GlobalSettings::valgrindExecutablePath()).toLocalFile(); } } } diff --git a/tools/generic/settings.h b/tools/generic/settings.h index 50204f5..51477ea 100644 --- a/tools/generic/settings.h +++ b/tools/generic/settings.h @@ -1,46 +1,46 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "isettings.h" namespace Valgrind { namespace Generic { class Settings : public ISettings { public: Settings(); ~Settings() override; IntValue numCallers; IntValue maxStackframe; BoolValue limitErrors; static QString valgrindExecutablePath(); }; } } diff --git a/tools/helgrind/configpage.cpp b/tools/helgrind/configpage.cpp index f7c5a92..c06d627 100644 --- a/tools/helgrind/configpage.cpp +++ b/tools/helgrind/configpage.cpp @@ -1,121 +1,121 @@ /* This file is part of KDevelop - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace Helgrind { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->extraParameters, &QLineEdit::textEdited, this, &ConfigPage::changed); connect(ui->conflictCacheSize, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->historyLevel, static_cast(&QComboBox::currentIndexChanged), this, &ConfigPage::changed); connect(ui->trackLockorders, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->checkStackRefs, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->ignoreThreadCreation, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->freeIsWrite, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showInstructionPointer, &QCheckBox::toggled, this, &ConfigPage::changed); ui->historyLevelLabel->setToolTip(ui->historyLevel->toolTip()); ui->conflictCacheSizeLabel->setToolTip(ui->conflictCacheSize->toolTip()); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->extraParameters->setText(settings.extraParameters); ui->conflictCacheSize->setValue(settings.conflictCacheSize); ui->historyLevel->setCurrentText(settings.historyLevel); ui->trackLockorders->setChecked(settings.trackLockorders); ui->checkStackRefs->setChecked(settings.checkStackRefs); ui->ignoreThreadCreation->setChecked(settings.ignoreThreadCreation); ui->freeIsWrite->setChecked(settings.freeIsWrite); ui->showInstructionPointer->setChecked(settings.showInstructionPointer); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.extraParameters = ui->extraParameters->text(); settings.conflictCacheSize = ui->conflictCacheSize->value(); settings.historyLevel = ui->historyLevel->currentText(); settings.trackLockorders = ui->trackLockorders->isChecked(); settings.checkStackRefs = ui->checkStackRefs->isChecked(); settings.ignoreThreadCreation = ui->ignoreThreadCreation->isChecked(); settings.freeIsWrite = ui->freeIsWrite->isChecked(); settings.showInstructionPointer = ui->showInstructionPointer->isChecked(); settings.save(cfg); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/helgrind/configpage.h b/tools/helgrind/configpage.h index f5f2ebe..22b72a1 100644 --- a/tools/helgrind/configpage.h +++ b/tools/helgrind/configpage.h @@ -1,66 +1,66 @@ /* This file is part of KDevelop - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Helgrind { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/helgrind/job.cpp b/tools/helgrind/job.cpp index e23d84f..66302ce 100644 --- a/tools/helgrind/job.cpp +++ b/tools/helgrind/job.cpp @@ -1,43 +1,43 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "debug.h" #include "settings.h" #include "tool.h" namespace Valgrind { namespace Helgrind { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IXmlJob(Tool::self(), launchConfig, new Settings) { } Job::~Job() { } } } diff --git a/tools/helgrind/job.h b/tools/helgrind/job.h index 6335589..d34d639 100644 --- a/tools/helgrind/job.h +++ b/tools/helgrind/job.h @@ -1,41 +1,41 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmljob.h" namespace Valgrind { namespace Helgrind { class Job : public IXmlJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; }; } } diff --git a/tools/helgrind/settings.cpp b/tools/helgrind/settings.cpp index cd26e29..b9f3590 100644 --- a/tools/helgrind/settings.cpp +++ b/tools/helgrind/settings.cpp @@ -1,77 +1,77 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "tool.h" namespace Valgrind { namespace Helgrind { Settings::Settings() : IXmlSettings(Tool::self()->id()) , historyLevel( this, QStringLiteral("History Level"), QStringLiteral("history-level"), QStringLiteral("full")) , conflictCacheSize( this, QStringLiteral("Conflict Cache Size"), QStringLiteral("conflict-cache-size"), 1000000) , trackLockorders( this, QStringLiteral("Track Lock Orders"), QStringLiteral("track-lockorders"), true) , checkStackRefs( this, QStringLiteral("Check Stack Refs"), QStringLiteral("check-stack-refs"), true) , ignoreThreadCreation( this, QStringLiteral("Ignore Thread Creation"), QStringLiteral("ignore-thread-creation"), false) , freeIsWrite( this, QStringLiteral("Free Is Write"), QStringLiteral("free-is-write"), false) { } Settings::~Settings() { } } } diff --git a/tools/helgrind/settings.h b/tools/helgrind/settings.h index c95fc54..d6c3ec9 100644 --- a/tools/helgrind/settings.h +++ b/tools/helgrind/settings.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmlsettings.h" namespace Valgrind { namespace Helgrind { class Settings : public IXmlSettings { public: Settings(); ~Settings() override; StringValue historyLevel; IntValue conflictCacheSize; BoolValue trackLockorders; BoolValue checkStackRefs; BoolValue ignoreThreadCreation; BoolValue freeIsWrite; }; } } diff --git a/tools/helgrind/tool.cpp b/tools/helgrind/tool.cpp index d152d2f..05055f5 100644 --- a/tools/helgrind/tool.cpp +++ b/tools/helgrind/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace Helgrind { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("Helgrind"), i18n("Helgrind"), i18n("Helgrind (Thread Error Detector)"), QStringLiteral("helgrind"), QStringLiteral("helgrind_tool"), false) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/helgrind/tool.h b/tools/helgrind/tool.h index c0c2058..611b7ac 100644 --- a/tools/helgrind/tool.h +++ b/tools/helgrind/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace Helgrind { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/tools/massif/configpage.cpp b/tools/massif/configpage.cpp index d31e1fd..d6f1933 100644 --- a/tools/massif/configpage.cpp +++ b/tools/massif/configpage.cpp @@ -1,150 +1,150 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2011 Lionel Duc - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace Massif { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->extraParameters, &QLineEdit::textEdited, this, &ConfigPage::changed); connect(ui->launchMassifVisualizer, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->depth, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->threshold, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->peakInaccuracy, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->maxSnapshots, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->snapshotFreq, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->timeUnit, static_cast(&QComboBox::currentIndexChanged), this, &ConfigPage::changed); connect(ui->profileHeap, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->profileStack, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->pagesAsHeap, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->profileStack, &QCheckBox::toggled, this, &ConfigPage::check); connect(ui->pagesAsHeap, &QCheckBox::toggled, this, &ConfigPage::check); check(); ui->timeUnitLabel->setToolTip(ui->timeUnit->toolTip()); ui->depthLabel->setToolTip(ui->depth->toolTip()); ui->thresholdLabel->setToolTip(ui->threshold->toolTip()); ui->peakInaccuracyLabel->setToolTip(ui->peakInaccuracy->toolTip()); ui->maxSnapshotsLabel->setToolTip(ui->maxSnapshots->toolTip()); ui->snapshotFreqLabel->setToolTip(ui->snapshotFreq->toolTip()); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->extraParameters->setText(settings.extraParameters); ui->depth->setValue(settings.snapshotTreeDepth); ui->threshold->setValue(settings.threshold); ui->peakInaccuracy->setValue(settings.peakInaccuracy); ui->maxSnapshots->setValue(settings.maximumSnapshots); ui->snapshotFreq->setValue(settings.detailedSnapshotsFrequency); ui->timeUnit->setCurrentIndex(settings.timeUnit); ui->profileHeap->setChecked(settings.profileHeap); ui->profileStack->setChecked(settings.profileStack); ui->pagesAsHeap->setChecked(settings.pagesAsHeap); ui->launchMassifVisualizer->setChecked(settings.launchVisualizer); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.extraParameters = ui->extraParameters->text(); settings.snapshotTreeDepth = ui->depth->value(); settings.threshold = ui->threshold->value(); settings.peakInaccuracy = ui->peakInaccuracy->value(); settings.maximumSnapshots = ui->maxSnapshots->value(); settings.detailedSnapshotsFrequency = ui->snapshotFreq->value(); settings.timeUnit = ui->timeUnit->currentIndex(); settings.profileHeap = ui->profileHeap->isChecked(); settings.profileStack = ui->profileStack->isChecked(); settings.pagesAsHeap = ui->pagesAsHeap->isChecked(); settings.launchVisualizer = ui->launchMassifVisualizer->isChecked(); settings.save(cfg); } void ConfigPage::check() { if (ui->profileStack->isChecked() && ui->pagesAsHeap->isChecked()) { ui->messageWidget->setVisible(true); return; } ui->messageWidget->setVisible(false); } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/massif/configpage.h b/tools/massif/configpage.h index a43a3a5..ba37ea0 100644 --- a/tools/massif/configpage.h +++ b/tools/massif/configpage.h @@ -1,69 +1,69 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Massif { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: void check(); Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/massif/job.cpp b/tools/massif/job.cpp index 91630c8..9becade 100644 --- a/tools/massif/job.cpp +++ b/tools/massif/job.cpp @@ -1,97 +1,97 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "debug.h" #include "model.h" #include "parser.h" #include "plugin.h" #include "settings.h" #include "tool.h" #include "view.h" #include #include #include #include namespace Valgrind { namespace Massif { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IJob(Tool::self(), launchConfig) , m_model(new SnapshotsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } Job::~Job() { } bool Job::processEnded() { Settings settings; settings.load(m_config); parse(m_outputFile->fileName(), m_model); return true; } void Job::addToolArgs(QStringList& args) const { Settings settings; settings.load(m_config); int tu = settings.timeUnit; if (tu == 0) { args += QStringLiteral("--time-unit=i"); } else if (tu == 1) { args += QStringLiteral("--time-unit=ms"); } else if (tu == 2) { args += QStringLiteral("--time-unit=B"); } args += settings.cmdArgs(); args += QStringLiteral("--massif-out-file=%1").arg(m_outputFile->fileName()); } QWidget* Job::createView() { return new View(m_config, m_outputFile, m_model); } } } diff --git a/tools/massif/job.h b/tools/massif/job.h index 8b8c08d..fea158a 100644 --- a/tools/massif/job.h +++ b/tools/massif/job.h @@ -1,58 +1,58 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ijob.h" class QTemporaryFile; namespace Valgrind { namespace Massif { class SnapshotsModel; class Job : public IJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; SnapshotsModel* m_model; QTemporaryFile* m_outputFile; }; } } diff --git a/tools/massif/model.cpp b/tools/massif/model.cpp index aaa4fa1..c01fd34 100644 --- a/tools/massif/model.cpp +++ b/tools/massif/model.cpp @@ -1,151 +1,151 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "model.h" #include "debug.h" #include "snapshot.h" #include #include namespace Valgrind { namespace Massif { SnapshotsModel::SnapshotsModel(QObject* parent) : QAbstractTableModel(parent) { } SnapshotsModel::~SnapshotsModel() { qDeleteAll(m_snapshots); } void SnapshotsModel::addSnapshot(Snapshot* snapshot) { Q_ASSERT(snapshot); if (snapshot) { m_snapshots.append(snapshot); } } QModelIndex SnapshotsModel::index(int row, int column, const QModelIndex&) const { if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) { return createIndex(row, column, m_snapshots.at(row)); } return QModelIndex(); } int SnapshotsModel::rowCount(const QModelIndex&) const { return m_snapshots.size(); } int SnapshotsModel::columnCount(const QModelIndex&) const { return 5; } QString humanSize(int byteSize) { static const QStringList units{ "KiB", "MiB", "GiB", "TiB" }; if (byteSize < 1024) { return QString::number(byteSize); } float size = byteSize; QStringListIterator i(units); QString unit; while (size >= 1024.0 && i.hasNext()) { unit = i.next(); size /= 1024.0; } return QStringLiteral("%1 %2").arg(size, 0, 'f', 1).arg(unit); } QVariant SnapshotsModel::data(const QModelIndex& index, int role) const { auto snapshot = static_cast(index.internalPointer()); if (!snapshot) { return QVariant(); } if (role == Qt::DisplayRole) { if (index.column() <= Snapshot::Time) { return snapshot->values[index.column()]; } return humanSize(snapshot->values[index.column()].toInt()); } if (role == Qt::FontRole) { QFont f = QFontDatabase::systemFont(QFontDatabase::GeneralFont); if (!snapshot->heapTree.isEmpty()) { f.setBold(true); } return f; } return QVariant(); } QVariant SnapshotsModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(orientation) if (role == Qt::DisplayRole) { switch (section) { case Snapshot::SnapshotId: return i18n("Snapshot"); case Snapshot::Time: return i18n("Time"); case Snapshot::Heap: return i18n("Heap"); case Snapshot::HeapExtra: return i18n("Heap (extra)"); case Snapshot::Stack: return i18n("Stack"); } } return QVariant(); } } } diff --git a/tools/massif/model.h b/tools/massif/model.h index 085a190..568e08b 100644 --- a/tools/massif/model.h +++ b/tools/massif/model.h @@ -1,59 +1,59 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Massif { class Snapshot; class SnapshotsModel : public QAbstractTableModel { Q_OBJECT public: explicit SnapshotsModel(QObject* parent = nullptr); ~SnapshotsModel() override; QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; void addSnapshot(Snapshot* snapshot); private: QList m_snapshots; }; } } diff --git a/tools/massif/parser.cpp b/tools/massif/parser.cpp index 03e01b3..4089b29 100644 --- a/tools/massif/parser.cpp +++ b/tools/massif/parser.cpp @@ -1,91 +1,91 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parser.h" #include "model.h" #include "snapshot.h" #include namespace Valgrind { namespace Massif { void parse(const QString& fileName, SnapshotsModel* model) { Q_ASSERT(model); Snapshot* snapshot = nullptr; QString line; QStringList keyValue; QFile file(fileName); file.open(QIODevice::ReadOnly); while (!file.atEnd()) { line = file.readLine(); if (line.startsWith(QChar('#')) || line.startsWith(QStringLiteral("desc")) || line.startsWith(QStringLiteral("time_unit")) || line.startsWith(QStringLiteral("cmd"))) { continue; // skip comment and useless lines } keyValue = line.split(QChar('=')); const QString& key = keyValue.at(0); const QString& value = keyValue.at(1); if (key == QStringLiteral("snapshot")) { snapshot = new Snapshot; snapshot->setValue(key, value.trimmed()); continue; } Q_ASSERT(snapshot); snapshot->setValue(key, value.trimmed()); if (key == QStringLiteral("heap_tree")) { if (value.startsWith(QStringLiteral("peak")) || value.startsWith(QStringLiteral("detailed"))) { while (!file.atEnd()) { line = file.readLine(); if (line.startsWith(QChar('#'))) { break; } snapshot->heapTree.append(line.remove(QLatin1Char('\n'))); } } model->addSnapshot(snapshot); } } } } } diff --git a/tools/massif/parser.h b/tools/massif/parser.h index 90dcf3d..e7c30dd 100644 --- a/tools/massif/parser.h +++ b/tools/massif/parser.h @@ -1,38 +1,38 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Massif { class SnapshotsModel; void parse(const QString& fileName, SnapshotsModel* model); } } diff --git a/tools/massif/settings.cpp b/tools/massif/settings.cpp index e49ae61..90fbd53 100644 --- a/tools/massif/settings.cpp +++ b/tools/massif/settings.cpp @@ -1,107 +1,107 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "globalsettings.h" #include "tool.h" namespace Valgrind { namespace Massif { Settings::Settings() : ISettings(Tool::self()->id()) , snapshotTreeDepth( this, QStringLiteral("Snapshot Tree Depth"), QStringLiteral("depth"), 30) , threshold( this, QStringLiteral("Threshold"), QStringLiteral("threshold"), 1) , peakInaccuracy( this, QStringLiteral("Peak Inaccuracy"), QStringLiteral("peak-inaccuracy"), 1) , maximumSnapshots( this, QStringLiteral("Maximum Snapshots"), QStringLiteral("max-snapshots"), 100) , detailedSnapshotsFrequency( this, QStringLiteral("Detailed Snapshots Frequency"), QStringLiteral("detailed-freq"), 10) , timeUnit( this, QStringLiteral("Time Unit"), QStringLiteral(""), 0) , profileHeap( this, QStringLiteral("Profile Heap"), QStringLiteral("heap"), true) , profileStack( this, QStringLiteral("Profile Stack"), QStringLiteral("stacks"), false) , pagesAsHeap( this, QStringLiteral("Pages As Heap"), QStringLiteral("pages-as-heap"), false) , launchVisualizer( this, QStringLiteral("Launch Visualizer"), QStringLiteral(""), false) { } Settings::~Settings() { } QString Settings::visualizerExecutablePath() { return KDevelop::Path(GlobalSettings::massifVisualizerExecutablePath()).toLocalFile(); } } } diff --git a/tools/massif/settings.h b/tools/massif/settings.h index 8b7f441..e4be961 100644 --- a/tools/massif/settings.h +++ b/tools/massif/settings.h @@ -1,54 +1,54 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "isettings.h" namespace Valgrind { namespace Massif { class Settings : public ISettings { public: Settings(); ~Settings() override; IntValue snapshotTreeDepth; IntValue threshold; IntValue peakInaccuracy; IntValue maximumSnapshots; IntValue detailedSnapshotsFrequency; IntValue timeUnit; BoolValue profileHeap; BoolValue profileStack; BoolValue pagesAsHeap; BoolValue launchVisualizer; static QString visualizerExecutablePath(); }; } } diff --git a/tools/massif/snapshot.h b/tools/massif/snapshot.h index 950b94c..98eae3a 100644 --- a/tools/massif/snapshot.h +++ b/tools/massif/snapshot.h @@ -1,51 +1,51 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { namespace Massif { class Snapshot { public: enum Columns { SnapshotId, Time, Heap, HeapExtra, Stack }; void setValue(const QString& column, const QString& value); QMap values; QStringList heapTree; }; } } diff --git a/tools/massif/tool.cpp b/tools/massif/tool.cpp index fc62ae1..9977dc8 100644 --- a/tools/massif/tool.cpp +++ b/tools/massif/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace Massif { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("Massif"), i18n("Massif"), i18n("Massif (Heap Profiler)"), QStringLiteral("massif"), QStringLiteral("massif_tool"), true) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/massif/tool.h b/tools/massif/tool.h index 8709b7a..6c3d9aa 100644 --- a/tools/massif/tool.h +++ b/tools/massif/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace Massif { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/tools/massif/view.cpp b/tools/massif/view.cpp index 8502221..3067f10 100644 --- a/tools/massif/view.cpp +++ b/tools/massif/view.cpp @@ -1,88 +1,88 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "view.h" #include "ui_view.h" #include "debug.h" #include "model.h" #include "settings.h" #include "snapshot.h" #include "utils.h" #include #include #include namespace Valgrind { namespace Massif { View::View(KConfigGroup config, QTemporaryFile* outputFile, SnapshotsModel* model, QWidget* parent) : QWidget(parent) , ui(new Ui::View) , m_visualizerProcess(new QProcess) { Q_ASSERT(model); model->setParent(this); Q_ASSERT(outputFile); outputFile->setParent(this); ui->setupUi(this); auto treesModel = new QStringListModel(this); ui->treesView->setModel(treesModel); ui->snapshotsView->setModel(model); ui->snapshotsView->header()->resizeSections(QHeaderView::ResizeToContents); connect(ui->snapshotsView->selectionModel(), &QItemSelectionModel::currentChanged, this, [treesModel](const QModelIndex& current, const QModelIndex&) { auto snapshot = static_cast(current.internalPointer()); treesModel->setStringList(snapshot->heapTree); }); auto startVisualizer = [this, outputFile]() { m_visualizerProcess->start(Settings::visualizerExecutablePath(), { outputFile->fileName() }); }; Settings settings; settings.load(config); setupVisualizerProcess(m_visualizerProcess, ui->launchVisualizerButton, startVisualizer, settings.launchVisualizer); } View::~View() { m_visualizerProcess->disconnect(); delete m_visualizerProcess; delete ui; } } } diff --git a/tools/massif/view.h b/tools/massif/view.h index 3425d44..b0c704d 100644 --- a/tools/massif/view.h +++ b/tools/massif/view.h @@ -1,60 +1,60 @@ /* This file is part of KDevelop * Copyright 2008 Hamish Rodda * Copyright 2011 Sebastien Rannou - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include class QProcess; class QTemporaryFile; namespace Valgrind { namespace Massif { namespace Ui { class View; } class SnapshotsModel; class View : public QWidget { Q_OBJECT public: View(KConfigGroup config, QTemporaryFile* outputFile, SnapshotsModel* model, QWidget* parent = nullptr); ~View() override; private: Ui::View* ui; QProcess* m_visualizerProcess; }; } } diff --git a/tools/memcheck/configpage.cpp b/tools/memcheck/configpage.cpp index 0534778..3b473cd 100644 --- a/tools/memcheck/configpage.cpp +++ b/tools/memcheck/configpage.cpp @@ -1,226 +1,226 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "configpage.h" #include "ui_configpage.h" #include "debug.h" #include "settings.h" #include "tool.h" #include namespace Valgrind { namespace Memcheck { ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { ui = new Ui::ConfigPage(); ui->setupUi(this); connect(ui->leakResolution, &QComboBox::currentTextChanged, this, &ConfigPage::changed); connect(ui->keepStacktraces, &QComboBox::currentTextChanged, this, &ConfigPage::changed); connect(ui->freelistVol, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->freelistBigBlocks, static_cast(&QSpinBox::valueChanged), this, &ConfigPage::changed); connect(ui->extraParameters, &QLineEdit::textEdited, this, &ConfigPage::changed); connect(ui->undefValueErrors, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showMismatchedFrees, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->partialLoadsOk, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->trackOrigins, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->expensiveDefinednessChecks, &QCheckBox::toggled, this, &ConfigPage::changed); connect(ui->showInstructionPointer, &QCheckBox::toggled, this, &ConfigPage::changed); static const QStringList leakKinds = { QStringLiteral("definite"), QStringLiteral("possible"), QStringLiteral("indirect"), QStringLiteral("reachable") }; setupMenuButton(ui->showLeakKinds, leakKinds); static const QStringList heuristics = { QStringLiteral("stdstring"), QStringLiteral("length64"), QStringLiteral("newarray"), QStringLiteral("multipleinheritance") }; setupMenuButton(ui->leakCheckHeuristics, heuristics); ui->leakResolutionLabel->setToolTip(ui->leakResolution->toolTip()); ui->showLeakKindsLabel->setToolTip(ui->showLeakKinds->toolTip()); ui->leakCheckHeuristicsLabel->setToolTip(ui->leakCheckHeuristics->toolTip()); ui->keepStacktracesLabel->setToolTip(ui->keepStacktraces->toolTip()); ui->freelistVolLabel->setToolTip(ui->freelistVol->toolTip()); ui->freelistBigBlocksLabel->setToolTip(ui->freelistBigBlocks->toolTip()); } ConfigPage::~ConfigPage() { delete ui; } QString ConfigPage::title() const { return Tool::self()->name(); } QIcon ConfigPage::icon() const { return QIcon(); } void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); Settings settings; settings.load(cfg); ui->leakResolution->setCurrentText(settings.leakResolution); updateMenuButton(ui->showLeakKinds, settings.showLeakKinds); updateMenuButton(ui->leakCheckHeuristics, settings.leakCheckHeuristics); ui->keepStacktraces->setCurrentText(settings.keepStacktraces); ui->freelistVol->setValue(settings.freelistVol); ui->freelistBigBlocks->setValue(settings.freelistBigBlocks); ui->extraParameters->setText(settings.extraParameters); ui->undefValueErrors->setChecked(settings.undefValueErrors); ui->showMismatchedFrees->setChecked(settings.showMismatchedFrees); ui->partialLoadsOk->setChecked(settings.partialLoadsOk); ui->trackOrigins->setChecked(settings.trackOrigins); ui->expensiveDefinednessChecks->setChecked(settings.expensiveDefinednessChecks); ui->showInstructionPointer->setChecked(settings.showInstructionPointer); } void ConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { Settings settings; settings.leakResolution = ui->leakResolution->currentText(); settings.showLeakKinds = ui->showLeakKinds->text().trimmed().remove(QChar(' ')); settings.leakCheckHeuristics = ui->leakCheckHeuristics->text().trimmed().remove(QChar(' ')); settings.keepStacktraces = ui->keepStacktraces->currentText(); settings.freelistVol = ui->freelistVol->value(); settings.freelistBigBlocks = ui->freelistBigBlocks->value(); settings.extraParameters = ui->extraParameters->text(); settings.undefValueErrors = ui->undefValueErrors->isChecked(); settings.showMismatchedFrees = ui->showMismatchedFrees->isChecked(); settings.partialLoadsOk = ui->partialLoadsOk->isChecked(); settings.trackOrigins = ui->trackOrigins->isChecked(); settings.expensiveDefinednessChecks = ui->expensiveDefinednessChecks->isChecked(); settings.showInstructionPointer = ui->showInstructionPointer->isChecked(); settings.save(cfg); } QString selectedItemsText(QMenu* menu) { Q_ASSERT(menu); QStringList selected; const auto actions = menu->actions(); for (auto action : actions) { if (action->isChecked()) { selected += action->text(); } } if (selected.isEmpty()) { return QStringLiteral("none"); } if (selected.size() == actions.size()) { return QStringLiteral("all"); } return selected.join(QStringLiteral(", ")); } void ConfigPage::setupMenuButton(QPushButton* button, const QStringList& items) { Q_ASSERT(button); auto menu = new QMenu(button); button->setMenu(menu); button->setStyleSheet(QStringLiteral("Text-align:left")); auto slot = [button, menu]() { button->setText(QChar(' ') + selectedItemsText(menu)); }; for (const QString& text : items) { auto action = new QAction(text, menu); action->setCheckable(true); action->setChecked(false); connect(action, &QAction::toggled, this, slot); connect(action, &QAction::toggled, this, &ConfigPage::changed); menu->addAction(action); } slot(); } void ConfigPage::updateMenuButton(QPushButton* button, const QString& text) { Q_ASSERT(button); auto enabled = text.split(QChar(',')); const auto actions = button->menu()->actions(); for (auto action : actions) { if (text == QStringLiteral("all")) { action->setChecked(true); } else if (text == QStringLiteral("none")) { action->setChecked(false); } else { action->setChecked(enabled.contains(action->text())); } } } ConfigPageFactory::ConfigPageFactory() { } ConfigPageFactory::~ConfigPageFactory() { } KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) { return new ConfigPage(parent); } } } diff --git a/tools/memcheck/configpage.h b/tools/memcheck/configpage.h index b9cc309..2b6e42b 100644 --- a/tools/memcheck/configpage.h +++ b/tools/memcheck/configpage.h @@ -1,74 +1,74 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc - * Copyright 2017 Anton Anikin + * Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include class QPushButton; namespace Valgrind { namespace Memcheck { namespace Ui { class ConfigPage; } class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: explicit ConfigPage(QWidget* parent = nullptr); ~ConfigPage() override; QString title() const override; QIcon icon() const override; void loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project = nullptr) override; void saveToConfiguration(KConfigGroup cfg, KDevelop::IProject* project = nullptr) const override; private: void setupMenuButton(QPushButton* button, const QStringList& items); void updateMenuButton(QPushButton* button, const QString& text); Ui::ConfigPage* ui; }; class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: ConfigPageFactory(); ~ConfigPageFactory() override; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } } diff --git a/tools/memcheck/job.cpp b/tools/memcheck/job.cpp index 9b0e17f..bc0bba8 100644 --- a/tools/memcheck/job.cpp +++ b/tools/memcheck/job.cpp @@ -1,47 +1,47 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou - Copyright 2016-2017 Anton Anikin + Copyright 2016-2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "job.h" #include "debug.h" #include "settings.h" #include "tool.h" namespace Valgrind { namespace Memcheck { Job::Job(KDevelop::ILaunchConfiguration* launchConfig) : IXmlJob(Tool::self(), launchConfig, new Settings) { } Job::~Job() { } } } diff --git a/tools/memcheck/job.h b/tools/memcheck/job.h index bbcb0b2..bfee204 100644 --- a/tools/memcheck/job.h +++ b/tools/memcheck/job.h @@ -1,41 +1,41 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmljob.h" namespace Valgrind { namespace Memcheck { class Job : public IXmlJob { Q_OBJECT public: explicit Job(KDevelop::ILaunchConfiguration* launchConfig); ~Job() override; }; } } diff --git a/tools/memcheck/settings.cpp b/tools/memcheck/settings.cpp index a462db0..3c77edd 100644 --- a/tools/memcheck/settings.cpp +++ b/tools/memcheck/settings.cpp @@ -1,107 +1,107 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "settings.h" #include "tool.h" namespace Valgrind { namespace Memcheck { Settings::Settings() : IXmlSettings(Tool::self()->id()) , leakResolution( this, QStringLiteral("Leak Resolution"), QStringLiteral("leak-resolution"), QStringLiteral("high")) , showLeakKinds( this, QStringLiteral("Show Leak Kinds"), QStringLiteral("show-leak-kinds"), QStringLiteral("definite,possible")) , leakCheckHeuristics( this, QStringLiteral("Leak Check Heuristics"), QStringLiteral("leak-check-heuristics"), QStringLiteral("all")) , keepStacktraces( this, QStringLiteral("Keep Stacktraces"), QStringLiteral("keep-stacktraces"), QStringLiteral("alloc-and-free")) , freelistVol( this, QStringLiteral("Freelist Volume"), QStringLiteral("freelist-vol"), 20000000) , freelistBigBlocks( this, QStringLiteral("Freelist Big Blocks"), QStringLiteral("freelist-big-blocks"), 1000000) , undefValueErrors( this, QStringLiteral("Undef Value Errors"), QStringLiteral("undef-value-errors"), true) , showMismatchedFrees( this, QStringLiteral("Show Mismatched Frees"), QStringLiteral("show-mismatched-frees"), true) , partialLoadsOk( this, QStringLiteral("Partial Loads Ok"), QStringLiteral("partial-loads-ok"), true) , trackOrigins( this, QStringLiteral("Track Origins"), QStringLiteral("track-origins"), false) , expensiveDefinednessChecks( this, QStringLiteral("Expensive Definedness Checks"), QStringLiteral("expensive-definedness-checks"), false) { } Settings::~Settings() { } } } diff --git a/tools/memcheck/settings.h b/tools/memcheck/settings.h index 3f59718..c330f73 100644 --- a/tools/memcheck/settings.h +++ b/tools/memcheck/settings.h @@ -1,53 +1,53 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "ixmlsettings.h" namespace Valgrind { namespace Memcheck { class Settings : public IXmlSettings { public: Settings(); ~Settings() override; StringValue leakResolution; StringValue showLeakKinds; StringValue leakCheckHeuristics; StringValue keepStacktraces; IntValue freelistVol; IntValue freelistBigBlocks; BoolValue undefValueErrors; BoolValue showMismatchedFrees; BoolValue partialLoadsOk; BoolValue trackOrigins; BoolValue expensiveDefinednessChecks; }; } } diff --git a/tools/memcheck/tool.cpp b/tools/memcheck/tool.cpp index cdc138d..449467f 100644 --- a/tools/memcheck/tool.cpp +++ b/tools/memcheck/tool.cpp @@ -1,69 +1,69 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tool.h" #include "configpage.h" #include "job.h" #include namespace Valgrind { namespace Memcheck { Tool* Tool::m_self = nullptr; Tool::Tool() : ITool( QStringLiteral("Memcheck"), i18n("Memcheck"), i18n("Memcheck (Memory Error Detector)"), QStringLiteral("memcheck"), QStringLiteral("memcheck_tool"), false) { m_self = this; } Tool::~Tool() { m_self = nullptr; } Tool* Tool::self() { return m_self ? m_self : new Tool; } IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { return new Job(launchConfig); } KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const { return new ConfigPageFactory; } } } diff --git a/tools/memcheck/tool.h b/tools/memcheck/tool.h index 8ae4dca..ae90aae 100644 --- a/tools/memcheck/tool.h +++ b/tools/memcheck/tool.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop - Copyright 2017 Anton Anikin + Copyright 2017 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include "itool.h" namespace Valgrind { namespace Memcheck { class Tool : public ITool { public: ~Tool() override; static Tool* self(); IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: Tool(); static Tool* m_self; }; } } diff --git a/toolviewfactory.cpp b/toolviewfactory.cpp index 6886c4b..04a0547 100644 --- a/toolviewfactory.cpp +++ b/toolviewfactory.cpp @@ -1,92 +1,92 @@ /* This file is part of KDevelop Copyright 2007-2008 Hamish Rodda Copyright 2011 Sebastien Rannou - Copyright 2016 Anton Anikin + Copyright 2016 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "toolviewfactory.h" #include "debug.h" #include "plugin.h" #include #include namespace Valgrind { class ToolView : public QTabWidget { Q_OBJECT public: explicit ToolView(QWidget* parent); ~ToolView() override {} }; ToolView::ToolView(QWidget* parent) : QTabWidget(parent) { setWindowIcon(QIcon::fromTheme("fork")); setWindowTitle(i18n("Valgrind Output")); setWhatsThis(i18n("Valgrind

Shows the output of valgrind. Valgrind detects:
" "use of uninitialized memory;
" "reading/writing memory after it has been free'd;
" "reading/writing off the end of malloc'd blocks;
" "reading/writing inappropriate areas on the stack;
" "memory leaks — where pointers to malloc'd blocks are lost forever;
" "passing of uninitialised and/or unaddressable memory to system calls;
" "mismatched use of malloc/new/new [] vs free/delete/delete [];
" "some abuses of the POSIX pthread API.

")); setTabsClosable(true); connect(this, &ToolView::tabCloseRequested, this, [this](int index) { delete widget(index); removeTab(index); }); connect(Plugin::self(), &Plugin::addView, this, [this](QWidget* view, const QString& name) { Q_ASSERT(view); addTab(view, name); setCurrentWidget(view); setMovable(true); }); } QWidget* ToolViewFactory::create(QWidget* parent) { return new ToolView(parent); } Qt::DockWidgetArea ToolViewFactory::defaultPosition() { return Qt::BottomDockWidgetArea; } QString ToolViewFactory::id() const { return QStringLiteral("org.kdevelop.ValgrindView"); } } #include "toolviewfactory.moc" diff --git a/toolviewfactory.h b/toolviewfactory.h index a57ed75..fcc86ad 100644 --- a/toolviewfactory.h +++ b/toolviewfactory.h @@ -1,36 +1,36 @@ /* This file is part of KDevelop Copyright 2007-2008 Hamish Rodda - Copyright 2016 Anton Anikin + Copyright 2016 Anton Anikin 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 2 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include namespace Valgrind { class ToolViewFactory : public KDevelop::IToolViewFactory { public: QWidget* create(QWidget* parent = nullptr) override; Qt::DockWidgetArea defaultPosition() override; QString id() const override; }; }