diff --git a/CMakeLists.txt b/CMakeLists.txt index 101a119..95ee1f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,98 +1,153 @@ cmake_minimum_required(VERSION 3.0) project(kdevvalgrind) find_package(ECM "5.14.0" REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMAddTests) include(ECMQtDeclareLoggingCategory) include(KDEInstallDirs) include(KDECMakeSettings) include(FeatureSummary) set(QT_MIN_VERSION "5.5.0") find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED Core Widgets) set(KF5_DEP_VERSION "5.15.0") find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS I18n ItemModels # needed because missing in KDevPlatformConfig.cmake, remove once dep on kdevplatform >=5.2.2 ItemViews ) find_package(KDevPlatform 5.1 CONFIG) set_package_properties(KDevPlatform PROPERTIES TYPE REQUIRED ) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/config - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/tools -) +include_directories(config core) add_definitions( -DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050500 -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_STRICT_ITERATORS -DQT_USE_QSTRINGBUILDER ) add_definitions(-DTRANSLATION_DOMAIN=\"kdevvalgrind\") set(kdevvalgrind_SRCS launchmode.cpp plugin.cpp problemmodel.cpp toolviewfactory.cpp config/globalconfigpage.cpp -) -ecm_qt_declare_logging_category(kdevvalgrind_SRCS - HEADER debug.h - IDENTIFIER KDEV_VALGRIND - CATEGORY_NAME "kdevelop.analyzers.valgrind" + core/configpage.cpp + core/job.cpp + core/settings.cpp + core/tool.cpp + core/xmljob.cpp + core/xmlsettings.cpp + core/utils.cpp + core/private/common_configpage.cpp + core/private/common_settings.cpp + core/private/launcher.cpp + core/private/xmlerror.cpp + core/private/xmlparser.cpp + + tools/cachegrind/cachegrind_configpage.cpp + tools/cachegrind/cachegrind_job.cpp + tools/cachegrind/cachegrind_model.cpp + tools/cachegrind/cachegrind_parser.cpp + tools/cachegrind/cachegrind_settings.cpp + tools/cachegrind/cachegrind_tool.cpp + tools/cachegrind/cachegrind_view.cpp + + tools/callgrind/callgrind_configpage.cpp + tools/callgrind/callgrind_job.cpp + tools/callgrind/callgrind_model.cpp + tools/callgrind/callgrind_parser.cpp + tools/callgrind/callgrind_settings.cpp + tools/callgrind/callgrind_tool.cpp + tools/callgrind/callgrind_view.cpp + + tools/drd/drd_configpage.cpp + tools/drd/drd_configpage.h + tools/drd/drd_configpage.ui + tools/drd/drd_job.cpp + tools/drd/drd_job.h + tools/drd/drd_settings.cpp + tools/drd/drd_settings.h + tools/drd/drd_tool.cpp + tools/drd/drd_tool.h + + tools/helgrind/helgrind_configpage.cpp + tools/helgrind/helgrind_job.cpp + tools/helgrind/helgrind_settings.cpp + tools/helgrind/helgrind_tool.cpp + + tools/massif/massif_configpage.cpp + tools/massif/massif_job.cpp + tools/massif/massif_model.cpp + tools/massif/massif_parser.cpp + tools/massif/massif_settings.cpp + tools/massif/massif_snapshot.cpp + tools/massif/massif_tool.cpp + tools/massif/massif_view.cpp + + tools/memcheck/memcheck_configpage.cpp + tools/memcheck/memcheck_job.cpp + tools/memcheck/memcheck_settings.cpp + tools/memcheck/memcheck_tool.cpp ) - ki18n_wrap_ui(kdevvalgrind_SRCS config/globalconfigpage.ui -) -qt5_add_resources(kdevvalgrind_SRCS - kdevvalgrind.qrc -) + core/private/common_configpage.ui + + tools/cachegrind/cachegrind_configpage.ui + tools/cachegrind/cachegrind_view.ui + + tools/callgrind/callgrind_configpage.ui + tools/callgrind/callgrind_view.ui + + tools/drd/drd_configpage.ui + + tools/helgrind/helgrind_configpage.ui -kconfig_add_kcfg_files(kdevvalgrind_CONFIG_SRCS + tools/massif/massif_configpage.ui + tools/massif/massif_view.ui + + tools/memcheck/memcheck_configpage.ui +) +kconfig_add_kcfg_files(kdevvalgrind_SRCS config/globalsettings.kcfgc ) - -add_library(kdevvalgrind_config STATIC - ${kdevvalgrind_CONFIG_SRCS} +ecm_qt_declare_logging_category(kdevvalgrind_SRCS + HEADER debug.h + IDENTIFIER KDEV_VALGRIND + CATEGORY_NAME "kdevelop.analyzers.valgrind" ) - -target_link_libraries(kdevvalgrind_config - KDev::Shell +qt5_add_resources(kdevvalgrind_SRCS + kdevvalgrind.qrc ) -add_subdirectory(tools) - kdevplatform_add_plugin(kdevvalgrind JSON kdevvalgrind.json SOURCES ${kdevvalgrind_SRCS} ) - target_link_libraries(kdevvalgrind - kdevvalgrind_tools - KDev::Language KDev::Project + KDev::Shell KF5::ItemViews ) # kdebugsettings file install(FILES kdevvalgrind.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/tools/generic/core/iconfigpage.cpp b/core/configpage.cpp similarity index 84% rename from tools/generic/core/iconfigpage.cpp rename to core/configpage.cpp index 9a3bd58..cc43159 100644 --- a/tools/generic/core/iconfigpage.cpp +++ b/core/configpage.cpp @@ -1,57 +1,57 @@ /* This file is part of KDevelop Copyright 2018 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 "iconfigpage.h" +#include "configpage.h" #include #include #include #include namespace Valgrind { -IConfigPage::IConfigPage(QWidget* parent) +ConfigPage::ConfigPage(QWidget* parent) : LaunchConfigurationPage(parent) { } -void IConfigPage::connectToChanged(QCheckBox* box) +void ConfigPage::connectToChanged(QCheckBox* box) { connect(box, &QCheckBox::toggled, this, &LaunchConfigurationPage::changed); } -void IConfigPage::connectToChanged(QComboBox* box) +void ConfigPage::connectToChanged(QComboBox* box) { connect(box, static_cast(&QComboBox::currentIndexChanged), this, &LaunchConfigurationPage::changed); } -void IConfigPage::connectToChanged(QLineEdit* edit) +void ConfigPage::connectToChanged(QLineEdit* edit) { connect(edit, &QLineEdit::textChanged, this, &LaunchConfigurationPage::changed); } -void IConfigPage::connectToChanged(QSpinBox* box) +void ConfigPage::connectToChanged(QSpinBox* box) { connect(box, static_cast(&QSpinBox::valueChanged), this, &LaunchConfigurationPage::changed); } } diff --git a/tools/generic/core/iconfigpage.h b/core/configpage.h similarity index 88% rename from tools/generic/core/iconfigpage.h rename to core/configpage.h index 7510577..5d0d4a2 100644 --- a/tools/generic/core/iconfigpage.h +++ b/core/configpage.h @@ -1,48 +1,48 @@ /* This file is part of KDevelop Copyright 2018 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 QCheckBox; class QComboBox; class QLineEdit; class QSpinBox; namespace Valgrind { -class IConfigPage : public KDevelop::LaunchConfigurationPage +class ConfigPage : public KDevelop::LaunchConfigurationPage { Q_OBJECT public: - ~IConfigPage() override = default; + ~ConfigPage() override = default; protected: - explicit IConfigPage(QWidget* parent = nullptr); + explicit ConfigPage(QWidget* parent = nullptr); void connectToChanged(QCheckBox* box); void connectToChanged(QComboBox* box); void connectToChanged(QLineEdit* edit); void connectToChanged(QSpinBox* box); }; } diff --git a/tools/generic/core/ijob.cpp b/core/job.cpp similarity index 88% rename from tools/generic/core/ijob.cpp rename to core/job.cpp index 5db04cc..f1072aa 100644 --- a/tools/generic/core/ijob.cpp +++ b/core/job.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 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 "job.h" #include "debug.h" #include "globalsettings.h" -#include "itool.h" #include "plugin.h" -#include "settings.h" +#include "private/common_settings.h" +#include "tool.h" #include "utils.h" #include #include #include #include #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) +Job::Job(const Tool* 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); + connect(this, &Job::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]() { + connect(this, &Job::finished, this, [this]() { emit hideProgress(this); }); KDevelop::ICore::self()->uiController()->registerStatus(this); } -IJob::~IJob() +Job::~Job() { } -const ITool* IJob::tool() const +const Tool* Job::tool() const { return m_tool; } -QString IJob::statusName() const +QString Job::statusName() const { return i18n("%1 Analysis (%2)", m_tool->name(), QFileInfo(m_analyzedExecutable).fileName()); } -void IJob::addLoggingArgs(QStringList& args) const +void Job::addLoggingArgs(QStringList& args) const { args += QStringLiteral("--log-socket=127.0.0.1:%1").arg(m_tcpServerPort); } -QStringList IJob::buildCommandLine() const +QStringList Job::buildCommandLine() const { - Generic::Settings settings; + CommonSettings settings; settings.load(m_config); QStringList args; - args += QStringLiteral("--tool=") + m_tool->valgrindToolName(); + args += QStringLiteral("--tool=%1").arg(m_tool->valgrindToolName()); addLoggingArgs(args); args += settings.cmdArgs(); addToolArgs(args); return args; } -void IJob::start() +void Job::start() { - *this << Generic::Settings::valgrindExecutablePath(); + *this << CommonSettings::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) +void Job::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) +void Job::processValgrindOutput(const QStringList& lines) { m_valgrindOutput += lines; if (GlobalSettings::showValgrindOutput()) { KDevelop::OutputExecuteJob::postProcessStderr(lines); } } -void IJob::childProcessExited(int exitCode, QProcess::ExitStatus exitStatus) +void Job::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) +void Job::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() +bool Job::processEnded() { return true; } -int IJob::executeProcess(const QString& executable, const QStringList& args, QByteArray& processOutput) +int Job::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/core/job.h similarity index 89% rename from tools/generic/core/ijob.h rename to core/job.h index 05bcce0..7e9e2b5 100644 --- a/tools/generic/core/ijob.h +++ b/core/job.h @@ -1,98 +1,94 @@ /* 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 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 -{ +#include -class ILaunchConfiguration; +class QWidget; -} +namespace KDevelop { class ILaunchConfiguration; } namespace Valgrind { -class ITool; +class Tool; -class IJob : public KDevelop::OutputExecuteJob, public KDevelop::IStatus +class Job : public KDevelop::OutputExecuteJob, public KDevelop::IStatus { Q_OBJECT Q_INTERFACES(KDevelop::IStatus) public: - IJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig); + Job(const Tool* tool, KDevelop::ILaunchConfiguration* launchConfig); - ~IJob() override; + ~Job() override; void start() override; using KDevelop::OutputExecuteJob::doKill; - const ITool* tool() const; + const Tool* 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; + const Tool* m_tool; KConfigGroup m_config; QString m_analyzedExecutable; QStringList m_analyzedExecutableArguments; QStringList m_valgrindOutput; quint16 m_tcpServerPort; }; } diff --git a/tools/generic/configpage.cpp b/core/private/common_configpage.cpp similarity index 70% rename from tools/generic/configpage.cpp rename to core/private/common_configpage.cpp index 6bbb246..c1d50ca 100644 --- a/tools/generic/configpage.cpp +++ b/core/private/common_configpage.cpp @@ -1,96 +1,91 @@ /* This file is part of KDevelop Copyright 2011 Lionel Duc 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 "common_configpage.h" +#include "ui_common_configpage.h" -#include "settings.h" +#include "common_settings.h" -#include +#include namespace Valgrind { -namespace Generic -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +CommonConfigPage::CommonConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::CommonConfigPage()) { ui->setupUi(this); connectToChanged(ui->extraParameters); connectToChanged(ui->limitErrors); connectToChanged(ui->maxStackframe); connectToChanged(ui->numCallers); ui->numCallersLabel->setToolTip(ui->numCallers->toolTip()); ui->maxStackframeLabel->setToolTip(ui->maxStackframe->toolTip()); } -ConfigPage::~ConfigPage() = default; +CommonConfigPage::~CommonConfigPage() = default; -QString ConfigPage::title() const +QString CommonConfigPage::title() const { return i18n("Valgrind Generic Settings"); } -QIcon ConfigPage::icon() const +QIcon CommonConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void CommonConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + CommonSettings 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 +void CommonConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + CommonSettings 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() +CommonConfigPageFactory::CommonConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* CommonConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new CommonConfigPage(parent); } } diff --git a/tools/generic/configpage.h b/core/private/common_configpage.h similarity index 77% rename from tools/generic/configpage.h rename to core/private/common_configpage.h index 1978b5d..60b3320 100644 --- a/tools/generic/configpage.h +++ b/core/private/common_configpage.h @@ -1,63 +1,58 @@ /* This file is part of KDevelop Copyright 2011 Lionel Duc Copyright 2011 Sebastien Rannou 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace Generic -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class CommonConfigPage; } -class ConfigPage : public IConfigPage +class CommonConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit CommonConfigPage(QWidget* parent = nullptr); + ~CommonConfigPage() 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: - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class CommonConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + CommonConfigPageFactory(); + ~CommonConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/generic/configpage.ui b/core/private/common_configpage.ui similarity index 98% rename from tools/generic/configpage.ui rename to core/private/common_configpage.ui index 44374b1..8d5f389 100644 --- a/tools/generic/configpage.ui +++ b/core/private/common_configpage.ui @@ -1,133 +1,133 @@ - Valgrind::Generic::ConfigPage - + Valgrind::CommonConfigPage + 0 0 512 343 Display stac&k to depth: numCallers <html><head/><body><p>Specifies the maximum number of entries shown in stack traces that identify program locations. Note that errors are commoned up using only the top four function locations (the place in the current function, and that of its three immediate callers). So this doesn't affect the total number of errors reported.</p><p>The maximum value for this is 500. Note that higher settings will make Valgrind run a bit more slowly and take a bit more memory, but can be useful when working with programs with deeply-nested call chains.</p></body></html> 500 12 Maximum size of a stack frame: maxStackframe <html><head/><body><p>The maximum size of a stack frame. If the stack pointer moves by more than this amount then Valgrind will assume that the program is switching to a different stack.</p><p>You may need to use this option if your program has large stack-allocated arrays. Valgrind keeps track of your program's stack pointer. If it changes by more than the threshold amount, Valgrind assumes your program is switching to a different stack, and Memcheck behaves differently than it would for a stack pointer change smaller than the threshold. Usually this heuristic works well. However, if your program allocates large structures on the stack, this heuristic will be fooled, and Memcheck will subsequently report large numbers of invalid stack accesses. This option allows you to change the threshold to a different value.</p><p>You should only consider use of this option if Valgrind's debug output directs you to do so. In that case it will tell you the new threshold you should specify.</p><p>In general, allocating large structures on the stack is a bad idea, because you can easily run out of stack space, especially on systems with limited memory or which expect to support large numbers of threads each with a small stack, and also because the error checking performed by Memcheck is more effective for heap-allocated data than for stack-allocated data. If you have to use this option, you may wish to consider rewriting your code to allocate on the heap rather than on the stack.</p></body></html> 200000000 2000000 &Extra parameters: extraParameters true Qt::Horizontal <html><head/><body><p>When enabled, Valgrind stops reporting errors after 10,000,000 in total, or 1,000 different ones, have been seen. This is to stop the error tracking machinery from becoming a huge performance overhead in programs with many errors.</p></body></html> Limit errors if too many true Qt::Vertical 20 40 numCallers maxStackframe extraParameters limitErrors diff --git a/tools/generic/settings.cpp b/core/private/common_settings.cpp similarity index 88% rename from tools/generic/settings.cpp rename to core/private/common_settings.cpp index c53747b..915f392 100644 --- a/tools/generic/settings.cpp +++ b/core/private/common_settings.cpp @@ -1,64 +1,55 @@ /* This file is part of KDevelop 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 "common_settings.h" #include "globalsettings.h" namespace Valgrind { -namespace Generic -{ - -Settings::Settings() - : ISettings(QStringLiteral("Valgrind")) +CommonSettings::CommonSettings() + : Settings(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() +QString CommonSettings::valgrindExecutablePath() { return KDevelop::Path(GlobalSettings::valgrindExecutablePath()).toLocalFile(); } } - -} diff --git a/tools/generic/settings.h b/core/private/common_settings.h similarity index 88% rename from tools/generic/settings.h rename to core/private/common_settings.h index 51477ea..67b8490 100644 --- a/tools/generic/settings.h +++ b/core/private/common_settings.h @@ -1,46 +1,41 @@ /* This file is part of KDevelop 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" +#include "settings.h" namespace Valgrind { -namespace Generic -{ - -class Settings : public ISettings +class CommonSettings : public Settings { public: - Settings(); - ~Settings() override; + CommonSettings(); + ~CommonSettings() override = default; IntValue numCallers; IntValue maxStackframe; BoolValue limitErrors; static QString valgrindExecutablePath(); }; } - -} diff --git a/tools/generic/core/launcher.cpp b/core/private/launcher.cpp similarity index 93% rename from tools/generic/core/launcher.cpp rename to core/private/launcher.cpp index 0d8543f..8551bea 100644 --- a/tools/generic/core/launcher.cpp +++ b/core/private/launcher.cpp @@ -1,109 +1,111 @@ /* 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 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 "common_configpage.h" #include "configpage.h" #include "debug.h" -#include "ijob.h" -#include "itool.h" +#include "job.h" #include "launchmode.h" #include "plugin.h" +#include "tool.h" #include #include #include #include #include -#include #include +#include + namespace Valgrind { -Launcher::Launcher(const ITool* tool) +Launcher::Launcher(const Tool* tool) : m_tool(tool) { Q_ASSERT(tool); m_configPageFactories += tool->createConfigPageFactory(); - m_configPageFactories += new Generic::ConfigPageFactory; + m_configPageFactories += new CommonConfigPageFactory; } 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/core/private/launcher.h similarity index 95% rename from tools/generic/core/launcher.h rename to core/private/launcher.h index db14bca..755ae6b 100644 --- a/tools/generic/core/launcher.h +++ b/core/private/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 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 Tool; class Launcher : public KDevelop::ILauncher { public: - explicit Launcher(const ITool* tool); + explicit Launcher(const Tool* 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; + const Tool* m_tool; QList m_configPageFactories; }; } diff --git a/tools/generic/core/xml/error.cpp b/core/private/xmlerror.cpp similarity index 99% rename from tools/generic/core/xml/error.cpp rename to core/private/xmlerror.cpp index 8e09f8e..1269f66 100644 --- a/tools/generic/core/xml/error.cpp +++ b/core/private/xmlerror.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 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 "xmlerror.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/core/private/xmlerror.h similarity index 100% rename from tools/generic/core/xml/error.h rename to core/private/xmlerror.h diff --git a/tools/generic/core/xml/parser.cpp b/core/private/xmlparser.cpp similarity index 98% rename from tools/generic/core/xml/parser.cpp rename to core/private/xmlparser.cpp index 85054ee..225f8cf 100644 --- a/tools/generic/core/xml/parser.cpp +++ b/core/private/xmlparser.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 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 "xmlparser.h" #include "debug.h" -#include "error.h" +#include "xmlerror.h" #include "utils.h" -#include -#include +#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/core/private/xmlparser.h similarity index 100% rename from tools/generic/core/xml/parser.h rename to core/private/xmlparser.h diff --git a/tools/generic/core/isettings.cpp b/core/settings.cpp similarity index 70% rename from tools/generic/core/isettings.cpp rename to core/settings.cpp index 66e123f..c0288c5 100644 --- a/tools/generic/core/isettings.cpp +++ b/core/settings.cpp @@ -1,162 +1,145 @@ /* This file is part of KDevelop 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 "settings.h" #include -#include +#include namespace Valgrind { -ISettingsBase::ISettingsBase(const QString& configKeyPrefix) +SettingsBase::SettingsBase(const QString& configKeyPrefix) : m_configKeyPrefix(configKeyPrefix) { } -ISettingsBase::~ISettingsBase() -{ -} - -ISettingsBase::IValue::~IValue() -{ -} - template -ISettingsBase::Value::Value( - ISettingsBase* settings, +SettingsBase::Value::Value( + SettingsBase* 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 +SettingsBase::Value::operator const T& () const { return m_value; } template -ISettingsBase::Value& ISettingsBase::Value::operator=(const T& value) +SettingsBase::Value& SettingsBase::Value::operator=(const T& value) { m_value = value; return *this; } template -void ISettingsBase::Value::load(const KConfigGroup& config, const QString& configKeyPrefix) +void SettingsBase::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) +void SettingsBase::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() +QString SettingsBase::Value::cmdArg() { if (m_cmdKey.isEmpty()) { return QStringLiteral(""); } else { - return QString("--%1=%2").arg(m_cmdKey).arg(toCmdArg(m_value)); + return QStringLiteral("--%1=%2").arg(m_cmdKey, toCmdArg(m_value)); } } -template class ISettingsBase::Value; -template class ISettingsBase::Value; -template class ISettingsBase::Value; +template class SettingsBase::Value; +template class SettingsBase::Value; +template class SettingsBase::Value; -ISettings::ISettings(const QString& configKeyPrefix) - : ISettingsBase(configKeyPrefix) +Settings::Settings(const QString& configKeyPrefix) + : SettingsBase(configKeyPrefix) , extraParameters( this, QStringLiteral("Extra Parameters"), QStringLiteral(""), QStringLiteral("")) { } -ISettings::~ISettings() -{ -} - -void ISettings::load(const KConfigGroup& config) +void Settings::load(const KConfigGroup& config) { for (auto value : qAsConst(m_values)) { value->load(config, m_configKeyPrefix); } } -void ISettings::save(KConfigGroup& config) +void Settings::save(KConfigGroup& config) { for (auto value : qAsConst(m_values)) { value->save(config, m_configKeyPrefix); } } -QStringList ISettings::cmdArgs() +QStringList Settings::cmdArgs() { QStringList args; for (auto value : qAsConst(m_values)) { args += value->cmdArg(); } args += KShell::splitArgs(extraParameters); args.removeAll(QStringLiteral("")); return args; } } diff --git a/include/isettings.h b/core/settings.h similarity index 74% rename from include/isettings.h rename to core/settings.h index 6a5b366..a01ee98 100644 --- a/include/isettings.h +++ b/core/settings.h @@ -1,101 +1,102 @@ /* This file is part of KDevelop 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 { -class ISettingsBase +class SettingsBase { public: - virtual ~ISettingsBase(); + virtual ~SettingsBase() = default; protected: - explicit ISettingsBase(const QString& configKeyPrefix); + explicit SettingsBase(const QString& configKeyPrefix); - class IValue; + class ValueBase; template class Value; using IntValue = Value; using BoolValue = Value; using StringValue = Value; QString m_configKeyPrefix; - QList m_values; + QList m_values; }; -class ISettingsBase::IValue +class SettingsBase::ValueBase { - friend class ISettings; + friend class Settings; public: - virtual ~IValue(); + virtual ~ValueBase() = default; 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 +class SettingsBase::Value : public SettingsBase::ValueBase { - friend class ISettings; + friend class Settings; public: - Value(ISettingsBase* settings, const QString& configKey, const QString& cmdKey, const T& defaultValue); - ~Value() override; + Value(SettingsBase* settings, const QString& configKey, const QString& cmdKey, const T& defaultValue); + ~Value() override = default; 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; +private: QString m_configKey; QString m_cmdKey; T m_value; T m_defaultValue; }; -class ISettings : public ISettingsBase +class Settings : public SettingsBase { public: StringValue extraParameters; void load(const KConfigGroup& config); void save(KConfigGroup& config); QStringList cmdArgs(); protected: - explicit ISettings(const QString& configKeyPrefix); - ~ISettings() override; + explicit Settings(const QString& configKeyPrefix); + ~Settings() override = default; }; } diff --git a/tools/generic/core/itool.cpp b/core/tool.cpp similarity index 81% rename from tools/generic/core/itool.cpp rename to core/tool.cpp index bd53a01..934443d 100644 --- a/tools/generic/core/itool.cpp +++ b/core/tool.cpp @@ -1,83 +1,83 @@ /* This file is part of KDevelop 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 "tool.h" -#include "launcher.h" +#include "private/launcher.h" namespace Valgrind { -ITool::ITool( +Tool::Tool( 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() +Tool::~Tool() { } -QString ITool::name() const +QString Tool::name() const { return m_name; } -QString ITool::fullName() const +QString Tool::fullName() const { return m_fullName; } -QString ITool::valgrindToolName() const +QString Tool::valgrindToolName() const { return m_valgrindToolName; } -QString ITool::id() const +QString Tool::id() const { return m_id; } -QString ITool::menuActionName() const +QString Tool::menuActionName() const { return m_menuActionName; } -bool ITool::hasView() const +bool Tool::hasView() const { return m_hasView; } -KDevelop::ILauncher* ITool::createLauncher() const +KDevelop::ILauncher* Tool::createLauncher() const { return new Launcher(this); } } diff --git a/include/itool.h b/core/tool.h similarity index 93% rename from include/itool.h rename to core/tool.h index af51517..fe819c0 100644 --- a/include/itool.h +++ b/core/tool.h @@ -1,90 +1,91 @@ /* This file is part of KDevelop 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 Job; -class ITool +class Tool { public: - virtual ~ITool(); + virtual ~Tool(); /// 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 Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const = 0; virtual KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const = 0; protected: - ITool( + Tool( const QString& id, const QString& name, const QString& fullName, const QString& valgrindToolName, const QString& menuActionName, bool hasView ); +private: QString m_id; QString m_name; QString m_fullName; QString m_valgrindToolName; QString m_menuActionName; bool m_hasView; }; } diff --git a/tools/generic/core/utils.cpp b/core/utils.cpp similarity index 98% rename from tools/generic/core/utils.cpp rename to core/utils.cpp index fae8b47..38bce9e 100644 --- a/tools/generic/core/utils.cpp +++ b/core/utils.cpp @@ -1,150 +1,151 @@ /* This file is part of KDevelop 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 #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/include/utils.h b/core/utils.h similarity index 100% rename from include/utils.h rename to core/utils.h diff --git a/tools/generic/core/xml/ixmljob.cpp b/core/xmljob.cpp similarity index 79% rename from tools/generic/core/xml/ixmljob.cpp rename to core/xmljob.cpp index 5fc1fc6..95bdfe3 100644 --- a/tools/generic/core/xml/ixmljob.cpp +++ b/core/xmljob.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 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 "xmljob.h" +#include "xmlsettings.h" #include "debug.h" -#include "itool.h" -#include "parser.h" +#include "tool.h" #include "plugin.h" #include "problemmodel.h" +#include "private/xmlparser.h" #include namespace Valgrind { -IXmlJob::IXmlJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig, IXmlSettings* settings) - : IJob(tool, launchConfig) +XmlJob::XmlJob(const Tool* tool, KDevelop::ILaunchConfiguration* launchConfig, XmlSettings* settings) + : Job(tool, launchConfig) , m_settings(settings) { Q_ASSERT(m_settings); } -IXmlJob::~IXmlJob() +XmlJob::~XmlJob() { delete m_settings; } -void IXmlJob::processValgrindOutput(const QStringList& lines) +void XmlJob::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); + Job::processValgrindOutput(lines); } -bool IXmlJob::processEnded() +bool XmlJob::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 +void XmlJob::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 +void XmlJob::addToolArgs(QStringList& args) const { m_settings->load(m_config); args += m_settings->cmdArgs(); } -QWidget* IXmlJob::createView() +QWidget* XmlJob::createView() { return nullptr; } } diff --git a/tools/generic/core/xml/ixmljob.h b/core/xmljob.h similarity index 86% rename from tools/generic/core/xml/ixmljob.h rename to core/xmljob.h index 43600c4..ce6a43f 100644 --- a/tools/generic/core/xml/ixmljob.h +++ b/core/xmljob.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 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" +#include "job.h" namespace Valgrind { -class IXmlSettings; +class XmlSettings; -class IXmlJob : public IJob +class XmlJob : public Job { Q_OBJECT public: - ~IXmlJob() override; + ~XmlJob() override; protected: - IXmlJob(const ITool* tool, KDevelop::ILaunchConfiguration* launchConfig, IXmlSettings* settings); + XmlJob(const Tool* tool, KDevelop::ILaunchConfiguration* launchConfig, XmlSettings* 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; + XmlSettings* m_settings; QStringList m_xmlOutput; }; } diff --git a/tools/generic/core/xml/ixmlsettings.cpp b/core/xmlsettings.cpp similarity index 85% rename from tools/generic/core/xml/ixmlsettings.cpp rename to core/xmlsettings.cpp index 7c0c615..6a839eb 100644 --- a/tools/generic/core/xml/ixmlsettings.cpp +++ b/core/xmlsettings.cpp @@ -1,40 +1,36 @@ /* This file is part of KDevelop 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" +#include "xmlsettings.h" namespace Valgrind { -IXmlSettings::IXmlSettings(const QString& configKeyPrefix) - : Valgrind::ISettings(configKeyPrefix) +XmlSettings::XmlSettings(const QString& configKeyPrefix) + : Valgrind::Settings(configKeyPrefix) , showInstructionPointer( this, QStringLiteral("Show Instruction Pointer"), QStringLiteral(""), false) { } -IXmlSettings::~IXmlSettings() -{ -} - } diff --git a/include/ixmlsettings.h b/core/xmlsettings.h similarity index 85% rename from include/ixmlsettings.h rename to core/xmlsettings.h index 3aabbf4..eee3f74 100644 --- a/include/ixmlsettings.h +++ b/core/xmlsettings.h @@ -1,38 +1,38 @@ /* This file is part of KDevelop 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" +#include "settings.h" namespace Valgrind { -class IXmlSettings : public ISettings +class XmlSettings : public Settings { public: - ~IXmlSettings() override; + ~XmlSettings() override = default; BoolValue showInstructionPointer; protected: - explicit IXmlSettings(const QString& configKeyPrefix); + explicit XmlSettings(const QString& configKeyPrefix); }; } diff --git a/include/iconfigpage.h b/include/iconfigpage.h deleted file mode 100644 index 3fbdac0..0000000 --- a/include/iconfigpage.h +++ /dev/null @@ -1 +0,0 @@ -#include "tools/generic/core/iconfigpage.h" diff --git a/include/ijob.h b/include/ijob.h deleted file mode 100644 index 95abe63..0000000 --- a/include/ijob.h +++ /dev/null @@ -1,22 +0,0 @@ -/* This file is part of KDevelop - 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/ixmljob.h b/include/ixmljob.h deleted file mode 100644 index 59a2744..0000000 --- a/include/ixmljob.h +++ /dev/null @@ -1,22 +0,0 @@ -/* This file is part of KDevelop - 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/launchmode.cpp b/launchmode.cpp index 37ada40..7b496c0 100644 --- a/launchmode.cpp +++ b/launchmode.cpp @@ -1,49 +1,50 @@ /* 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 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 + #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 48e3420..d502bbd 100644 --- a/launchmode.h +++ b/launchmode.h @@ -1,41 +1,43 @@ /* 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 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: + ~LaunchMode() override = default; + QIcon icon() const override; QString id() const override; QString name() const override; }; } diff --git a/plugin.cpp b/plugin.cpp index 9b038a7..db2a842 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 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 "globalconfigpage.h" #include "debug.h" -#include "ijob.h" +#include "job.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 "tools/cachegrind/cachegrind_tool.h" +#include "tools/callgrind/callgrind_tool.h" +#include "tools/drd/drd_tool.h" +#include "tools/helgrind/helgrind_tool.h" +#include "tools/massif/massif_tool.h" +#include "tools/memcheck/memcheck_tool.h" #include #include #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); + core()->runController()->addLaunchMode(m_launchMode.data()); - 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(); + m_tools += MemcheckTool::self(); + m_tools += CachegrindTool::self(); + m_tools += CallgrindTool::self(); + m_tools += HelgrindTool::self(); + m_tools += DrdTool::self(); + m_tools += MassifTool::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); + m_problemModel.reset(nullptr); 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; + core()->runController()->removeLaunchMode(m_launchMode.data()); + m_launchMode.reset(nullptr); 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; + return m_launchMode.data(); } ProblemModel* Plugin::problemModel() const { - return m_problemModel; + return m_problemModel.data(); } -void Plugin::jobReadyToStart(IJob* job) +void Plugin::jobReadyToStart(Job* 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) +void Plugin::jobReadyToFinish(Job* 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 edc236d..974ee25 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 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 Job; +class Tool; 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 jobReadyToStart(Job* job); + void jobReadyToFinish(Job* 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; + QScopedPointer m_launchMode; QMultiHash m_launchers; - ProblemModel* m_problemModel; + QScopedPointer m_problemModel; bool m_isRunning; - QList m_tools; + QList m_tools; static Plugin* m_self; }; } diff --git a/problemmodel.cpp b/problemmodel.cpp index fa30b9f..253f0e0 100644 --- a/problemmodel.cpp +++ b/problemmodel.cpp @@ -1,83 +1,83 @@ /* This file is part of KDevelop 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 "tool.h" #include "plugin.h" #include "utils.h" #include #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) +void ProblemModel::reset(const Tool* tool) { m_tool = tool; clearProblems(); - QString toolName = tool ? tool->name() : QStringLiteral("Valgrind"); + QString toolName = tool ? tool->name() : i18n("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 ae4477e..7fc90f0 100644 --- a/problemmodel.h +++ b/problemmodel.h @@ -1,46 +1,46 @@ /* This file is part of KDevelop 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 Tool; class ProblemModel : public KDevelop::ProblemModel { Q_OBJECT public: ProblemModel(); ~ProblemModel() override; - void reset(const ITool* tool); + void reset(const Tool* tool); void show(); void forceFullUpdate() override; private: - const ITool* m_tool; + const Tool* m_tool; }; } diff --git a/include/qtcompat_p.h b/qtcompat_p.h similarity index 100% rename from include/qtcompat_p.h rename to qtcompat_p.h diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt deleted file mode 100644 index fe94428..0000000 --- a/tools/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -add_subdirectory(cachegrind) -add_subdirectory(callgrind) -add_subdirectory(drd) -add_subdirectory(generic) -add_subdirectory(helgrind) -add_subdirectory(massif) -add_subdirectory(memcheck) - -add_library(kdevvalgrind_tools STATIC -) - -target_link_libraries(kdevvalgrind_tools - cachegrind_tool - callgrind_tool - drd_tool - helgrind_tool - massif_tool - memcheck_tool -) diff --git a/tools/cachegrind/CMakeLists.txt b/tools/cachegrind/CMakeLists.txt deleted file mode 100644 index d2045b4..0000000 --- a/tools/cachegrind/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -ki18n_wrap_ui(cachegrind_UI_SRCS - configpage.ui - view.ui -) - -add_library(cachegrind_tool STATIC - configpage.cpp - job.cpp - model.cpp - parser.cpp - settings.cpp - tool.cpp - view.cpp - - ${cachegrind_UI_SRCS} -) - -target_link_libraries(cachegrind_tool - generic_tool -) diff --git a/tools/cachegrind/configpage.cpp b/tools/cachegrind/cachegrind_configpage.cpp similarity index 69% rename from tools/cachegrind/configpage.cpp rename to tools/cachegrind/cachegrind_configpage.cpp index 65079ff..732b37a 100644 --- a/tools/cachegrind/configpage.cpp +++ b/tools/cachegrind/cachegrind_configpage.cpp @@ -1,111 +1,106 @@ /* This file is part of KDevelop Copyright 2011 Sebastien Rannou Copyright 2011 Lionel Duc 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 "cachegrind_configpage.h" +#include "ui_cachegrind_configpage.h" -#include "settings.h" -#include "tool.h" +#include "cachegrind_settings.h" +#include "cachegrind_tool.h" #include namespace Valgrind { -namespace Cachegrind -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +CachegrindConfigPage::CachegrindConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::CachegrindConfigPage()) { ui->setupUi(this); connectToChanged(ui->extraParameters); connectToChanged(ui->cacheSimulation); connectToChanged(ui->branchSimulation); connectToChanged(ui->cgAnnotateParameters); connectToChanged(ui->cacheSimulation); connectToChanged(ui->branchSimulation); } -ConfigPage::~ConfigPage() = default; +CachegrindConfigPage::~CachegrindConfigPage() = default; -QString ConfigPage::title() const +QString CachegrindConfigPage::title() const { - return Tool::self()->name(); + return CachegrindTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon CachegrindConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void CachegrindConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + CachegrindSettings 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 +void CachegrindConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + CachegrindSettings 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() +void CachegrindConfigPage::check() { if (!ui->cacheSimulation->isChecked() && !ui->branchSimulation->isChecked()) { ui->messageWidget->setVisible(true); return; } ui->messageWidget->setVisible(false); } -ConfigPageFactory::ConfigPageFactory() +CachegrindConfigPageFactory::CachegrindConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* CachegrindConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new CachegrindConfigPage(parent); } } diff --git a/tools/callgrind/configpage.h b/tools/cachegrind/cachegrind_configpage.h similarity index 74% rename from tools/callgrind/configpage.h rename to tools/cachegrind/cachegrind_configpage.h index 23f559c..28b6b7a 100644 --- a/tools/callgrind/configpage.h +++ b/tools/cachegrind/cachegrind_configpage.h @@ -1,62 +1,59 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace Callgrind -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class CachegrindConfigPage; } -class ConfigPage : public IConfigPage +class CachegrindConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit CachegrindConfigPage(QWidget* parent = nullptr); + ~CachegrindConfigPage() 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: - QScopedPointer ui; + void check(); + + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class CachegrindConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + CachegrindConfigPageFactory(); + ~CachegrindConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/cachegrind/configpage.ui b/tools/cachegrind/cachegrind_configpage.ui similarity index 97% rename from tools/cachegrind/configpage.ui rename to tools/cachegrind/cachegrind_configpage.ui index 2a76971..eadb92f 100644 --- a/tools/cachegrind/configpage.ui +++ b/tools/cachegrind/cachegrind_configpage.ui @@ -1,140 +1,140 @@ - Valgrind::Cachegrind::ConfigPage - + Valgrind::CachegrindConfigPage + 0 0 494 369 <html><head/><body><p>Enables or disables collection of cache access and miss counts.</p></body></html> Cache simulation false <html><head/><body><p>Enables or disables collection of branch instruction and misprediction counts. By default this is disabled as it slows Cachegrind down by approximately 25%. Note that you cannot specify <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--cache-sim=no</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--branch-sim=no</span> together, as that would leave Cachegrind with no information to collect.</p></body></html> Branch simulation false You cannot disable both cache and branch simulation, as that would leave Cachegrind with no information to collect. true false KMessageWidget::Warning Qt::Horizontal Extra parameters: extraParameters true cg_annotate parameters: cgAnnotateParameters true Qt::Vertical 20 40 KMessageWidget QFrame
kmessagewidget.h
cacheSimulation branchSimulation extraParameters cgAnnotateParameters
diff --git a/tools/cachegrind/job.cpp b/tools/cachegrind/cachegrind_job.cpp similarity index 71% rename from tools/cachegrind/job.cpp rename to tools/cachegrind/cachegrind_job.cpp index df9abf1..fbab42e 100644 --- a/tools/cachegrind/job.cpp +++ b/tools/cachegrind/cachegrind_job.cpp @@ -1,95 +1,91 @@ /* 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 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 "cachegrind_job.h" -#include "model.h" -#include "parser.h" +#include "cachegrind_model.h" +#include "cachegrind_parser.h" +#include "cachegrind_settings.h" +#include "cachegrind_tool.h" +#include "cachegrind_view.h" #include "plugin.h" -#include "settings.h" -#include "tool.h" -#include "view.h" #include -#include -#include + +#include +#include #include #include #include namespace Valgrind { -namespace Cachegrind -{ - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IJob(Tool::self(), launchConfig) - , m_model(new FunctionsModel) +CachegrindJob::CachegrindJob(KDevelop::ILaunchConfiguration* launchConfig) + : Job(CachegrindTool::self(), launchConfig) + , m_model(new CachegrindFunctionsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } -Job::~Job() +CachegrindJob::~CachegrindJob() { } -bool Job::processEnded() +bool CachegrindJob::processEnded() { - Settings settings; + CachegrindSettings 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); + cachegrindParse(cgOutput, m_model); return true; } -void Job::addToolArgs(QStringList& args) const +void CachegrindJob::addToolArgs(QStringList& args) const { - Settings settings; + CachegrindSettings settings; settings.load(m_config); args += settings.cmdArgs(); args += QStringLiteral("--cachegrind-out-file=%1").arg(m_outputFile->fileName()); } -QWidget* Job::createView() +QWidget* CachegrindJob::createView() { - return new View(m_model); -} - + return new CachegrindView(m_model); } } diff --git a/tools/massif/job.h b/tools/cachegrind/cachegrind_job.h similarity index 85% rename from tools/massif/job.h rename to tools/cachegrind/cachegrind_job.h index fea158a..26b70f5 100644 --- a/tools/massif/job.h +++ b/tools/cachegrind/cachegrind_job.h @@ -1,58 +1,53 @@ /* 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 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" +#include "job.h" class QTemporaryFile; namespace Valgrind { -namespace Massif -{ - -class SnapshotsModel; +class CachegrindFunctionsModel; -class Job : public IJob +class CachegrindJob : public Job { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit CachegrindJob(KDevelop::ILaunchConfiguration* launchConfig); + ~CachegrindJob() override; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; - SnapshotsModel* m_model; + CachegrindFunctionsModel* m_model; QTemporaryFile* m_outputFile; }; } - -} diff --git a/tools/cachegrind/model.cpp b/tools/cachegrind/cachegrind_model.cpp similarity index 79% rename from tools/cachegrind/model.cpp rename to tools/cachegrind/cachegrind_model.cpp index 7726120..4386170 100644 --- a/tools/cachegrind/model.cpp +++ b/tools/cachegrind/cachegrind_model.cpp @@ -1,177 +1,172 @@ /* 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 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 "cachegrind_model.h" #include "debug.h" #include "utils.h" #include -#include -#include +#include +#include #include namespace Valgrind { -namespace Cachegrind -{ - -FunctionsModel::FunctionsModel(QObject* parent) +CachegrindFunctionsModel::CachegrindFunctionsModel(QObject* parent) : QAbstractTableModel(parent) , m_totalItem(nullptr) , m_percentageValues(false) { } -FunctionsModel::~FunctionsModel() +CachegrindFunctionsModel::~CachegrindFunctionsModel() { qDeleteAll(m_items); } -void FunctionsModel::addItem(Function* newItem, bool isTotal) +void CachegrindFunctionsModel::addItem(CachegrindFunction* 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) +void CachegrindFunctionsModel::setEventsList(const QStringList& eventsList) { m_eventList = eventsList; } -void FunctionsModel::setPercentageValues(bool value) +void CachegrindFunctionsModel::setPercentageValues(bool value) { m_percentageValues = value; emitDataChanged(this); } -QModelIndex FunctionsModel::index(int row, int column, const QModelIndex&) const +QModelIndex CachegrindFunctionsModel::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 +int CachegrindFunctionsModel::rowCount(const QModelIndex&) const { return m_items.size(); } -int FunctionsModel::columnCount(const QModelIndex&) const +int CachegrindFunctionsModel::columnCount(const QModelIndex&) const { return m_eventList.size() + 1; } -QVariant FunctionsModel::data(const QModelIndex& index, int role) const +QVariant CachegrindFunctionsModel::data(const QModelIndex& index, int role) const { Q_ASSERT(m_totalItem); if (!index.isValid()) { return QVariant(); } - auto item = static_cast(index.internalPointer()); + 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 +QVariant CachegrindFunctionsModel::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/cachegrind_model.h similarity index 84% rename from tools/cachegrind/model.h rename to tools/cachegrind/cachegrind_model.h index 7f9ce1b..40a2f50 100644 --- a/tools/cachegrind/model.h +++ b/tools/cachegrind/cachegrind_model.h @@ -1,74 +1,69 @@ /* 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 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 +struct CachegrindFunction { QString functionName; QStringList fileNames; QList eventValues; }; -class FunctionsModel : public QAbstractTableModel +class CachegrindFunctionsModel : public QAbstractTableModel { Q_OBJECT public: - explicit FunctionsModel(QObject* parent = nullptr); - ~FunctionsModel() override; + explicit CachegrindFunctionsModel(QObject* parent = nullptr); + ~CachegrindFunctionsModel() override; void setEventsList(const QStringList& events); - void addItem(Function* item, bool isTotal = false); + void addItem(CachegrindFunction* 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; + QList m_items; + CachegrindFunction* m_totalItem; bool m_percentageValues; QStringList m_eventList; }; } - -} diff --git a/tools/cachegrind/parser.cpp b/tools/cachegrind/cachegrind_parser.cpp similarity index 88% rename from tools/cachegrind/parser.cpp rename to tools/cachegrind/cachegrind_parser.cpp index 6cca6c2..26c3aae 100644 --- a/tools/cachegrind/parser.cpp +++ b/tools/cachegrind/cachegrind_parser.cpp @@ -1,124 +1,119 @@ /* 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 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 "cachegrind_parser.h" #include "debug.h" -#include "model.h" +#include "cachegrind_model.h" #include #include namespace Valgrind { -namespace Cachegrind +CachegrindFunction* cachegrindParseCachegrindItem(const QString& line, QStringList& eventsList) { - -Function* parseCachegrindItem(const QString& line, QStringList& eventsList) -{ - auto item = new Function; + auto item = new CachegrindFunction; 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 +enum CachegrindParserState { ParseRoot, ParseProgramTotalHeader, ParseProgramTotal, ParseProgramHeader, ParseProgram }; -void parse(QByteArray& baData, FunctionsModel* model) +void cachegrindParse(QByteArray& baData, CachegrindFunctionsModel* model) { Q_ASSERT(model); - ParserState parserState = ParseRoot; + CachegrindParserState 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); + model->addItem(cachegrindParseCachegrindItem(line, eventsList), isTotal); if (isTotal) { parserState = ParseProgramHeader; } } } model->setEventsList(eventsList); } } - -} diff --git a/tools/cachegrind/parser.h b/tools/cachegrind/cachegrind_parser.h similarity index 87% rename from tools/cachegrind/parser.h rename to tools/cachegrind/cachegrind_parser.h index 31b8151..dcdb307 100644 --- a/tools/cachegrind/parser.h +++ b/tools/cachegrind/cachegrind_parser.h @@ -1,39 +1,35 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc 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; +class CachegrindFunctionsModel; -void parse(QByteArray& data, FunctionsModel* model); - -} +// FIXME move into CachegrindFunctionsModel ? +void cachegrindParse(QByteArray& data, CachegrindFunctionsModel* model); } diff --git a/tools/cachegrind/settings.cpp b/tools/cachegrind/cachegrind_settings.cpp similarity index 87% rename from tools/cachegrind/settings.cpp rename to tools/cachegrind/cachegrind_settings.cpp index a090edd..fd95109 100644 --- a/tools/cachegrind/settings.cpp +++ b/tools/cachegrind/cachegrind_settings.cpp @@ -1,65 +1,56 @@ /* This file is part of KDevelop 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 "cachegrind_settings.h" +#include "cachegrind_tool.h" #include "globalsettings.h" -#include "tool.h" namespace Valgrind { -namespace Cachegrind -{ - -Settings::Settings() - : ISettings(Tool::self()->id()) +CachegrindSettings::CachegrindSettings() + : Settings(CachegrindTool::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() +QString CachegrindSettings::cgAnnotateExecutablePath() { return KDevelop::Path(GlobalSettings::cg_annotateExecutablePath()).toLocalFile(); } } - -} diff --git a/tools/cachegrind/settings.h b/tools/cachegrind/cachegrind_settings.h similarity index 88% rename from tools/cachegrind/settings.h rename to tools/cachegrind/cachegrind_settings.h index a67e961..c7e1ccf 100644 --- a/tools/cachegrind/settings.h +++ b/tools/cachegrind/cachegrind_settings.h @@ -1,47 +1,41 @@ /* This file is part of KDevelop 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" +#include "settings.h" namespace Valgrind { -namespace Cachegrind -{ - -class Settings : public ISettings +class CachegrindSettings : public Settings { public: - Settings(); - ~Settings() override; + CachegrindSettings(); + ~CachegrindSettings() override = default; BoolValue cacheSimulation; BoolValue branchSimulation; StringValue cgAnnotateParameters; static QString cgAnnotateExecutablePath(); - }; } - -} diff --git a/tools/cachegrind/tool.cpp b/tools/cachegrind/cachegrind_tool.cpp similarity index 65% rename from tools/cachegrind/tool.cpp rename to tools/cachegrind/cachegrind_tool.cpp index 9e6bdbd..acb7bc9 100644 --- a/tools/cachegrind/tool.cpp +++ b/tools/cachegrind/cachegrind_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "cachegrind_tool.h" -#include "configpage.h" -#include "job.h" +#include "cachegrind_configpage.h" +#include "cachegrind_job.h" -#include +#include namespace Valgrind { -namespace Cachegrind -{ - -Tool* Tool::m_self = nullptr; +CachegrindTool* CachegrindTool::m_self = nullptr; -Tool::Tool() - : ITool( +CachegrindTool::CachegrindTool() + : Tool( QStringLiteral("Cachegrind"), i18n("Cachegrind"), i18n("Cachegrind (Cache and Branch-Prediction Profiler)"), QStringLiteral("cachegrind"), QStringLiteral("cachegrind_tool"), true) { m_self = this; } -Tool::~Tool() +CachegrindTool::~CachegrindTool() { m_self = nullptr; } -Tool* Tool::self() +CachegrindTool* CachegrindTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new CachegrindTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* CachegrindTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new CachegrindJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* CachegrindTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new CachegrindConfigPageFactory; } } diff --git a/tools/drd/tool.h b/tools/cachegrind/cachegrind_tool.h similarity index 79% copy from tools/drd/tool.h copy to tools/cachegrind/cachegrind_tool.h index f632d23..a5d70c7 100644 --- a/tools/drd/tool.h +++ b/tools/cachegrind/cachegrind_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace DRD -{ - -class Tool : public ITool +class CachegrindTool : public Tool { public: - ~Tool() override; + ~CachegrindTool() override; - static Tool* self(); + static CachegrindTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + CachegrindTool(); - static Tool* m_self; + static CachegrindTool* m_self; }; } - -} diff --git a/tools/cachegrind/view.cpp b/tools/cachegrind/cachegrind_view.cpp similarity index 86% rename from tools/cachegrind/view.cpp rename to tools/cachegrind/cachegrind_view.cpp index a8ab756..702ae40 100644 --- a/tools/cachegrind/view.cpp +++ b/tools/cachegrind/cachegrind_view.cpp @@ -1,94 +1,86 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie * 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 "cachegrind_view.h" +#include "ui_cachegrind_view.h" +#include "cachegrind_model.h" #include "debug.h" -#include "model.h" #include "utils.h" #include #include #include namespace Valgrind { -namespace Cachegrind -{ - -View::View(FunctionsModel* model, QWidget* parent) +CachegrindView::CachegrindView(CachegrindFunctionsModel* model, QWidget* parent) : QWidget(parent) + , ui(new Ui::CachegrindView) { + ui->setupUi(this); + Q_ASSERT(model); model->setParent(this); - ui = new Ui::View; - ui->setupUi(this); - connect(ui->percenageValues, &QCheckBox::stateChanged, - model, &FunctionsModel::setPercentageValues); + model, &CachegrindFunctionsModel::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()); + 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; -} - -} +CachegrindView::~CachegrindView() = default; } diff --git a/tools/cachegrind/view.h b/tools/cachegrind/cachegrind_view.h similarity index 80% rename from tools/cachegrind/view.h rename to tools/cachegrind/cachegrind_view.h index 90da402..719b89c 100644 --- a/tools/cachegrind/view.h +++ b/tools/cachegrind/cachegrind_view.h @@ -1,57 +1,47 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie * 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; +namespace Ui { class CachegrindView; } -} - -class FunctionsModel; +class CachegrindFunctionsModel; -class View : public QWidget +class CachegrindView : public QWidget { Q_OBJECT public: - explicit View(FunctionsModel* model, QWidget* parent = nullptr); - ~View() override; + explicit CachegrindView(CachegrindFunctionsModel* model, QWidget* parent = nullptr); + ~CachegrindView() override; private: - Ui::View* ui; + QScopedPointer ui; }; } - -} diff --git a/tools/cachegrind/view.ui b/tools/cachegrind/cachegrind_view.ui similarity index 97% rename from tools/cachegrind/view.ui rename to tools/cachegrind/cachegrind_view.ui index 150e0dd..c736333 100644 --- a/tools/cachegrind/view.ui +++ b/tools/cachegrind/cachegrind_view.ui @@ -1,149 +1,149 @@ - Valgrind::Cachegrind::View - + Valgrind::CachegrindView + 0 0 842 734 0 0 0 0 Search... true Percentage values true Qt::Horizontal 40 20 0 0 Qt::Horizontal false false 75 true Function name true file.c true Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse Qt::Vertical QSizePolicy::Expanding 75 40 searchEdit percenageValues functionsView diff --git a/tools/callgrind/CMakeLists.txt b/tools/callgrind/CMakeLists.txt deleted file mode 100644 index a349b8e..0000000 --- a/tools/callgrind/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -ki18n_wrap_ui(callgrind_UI_SRCS - configpage.ui - view.ui -) - -add_library(callgrind_tool STATIC - configpage.cpp - job.cpp - model.cpp - parser.cpp - settings.cpp - tool.cpp - view.cpp - - ${callgrind_UI_SRCS} -) - -target_link_libraries(callgrind_tool - generic_tool -) diff --git a/tools/callgrind/configpage.cpp b/tools/callgrind/callgrind_configpage.cpp similarity index 69% rename from tools/callgrind/configpage.cpp rename to tools/callgrind/callgrind_configpage.cpp index c464ed2..a2b484c 100644 --- a/tools/callgrind/configpage.cpp +++ b/tools/callgrind/callgrind_configpage.cpp @@ -1,97 +1,92 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * 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 "callgrind_configpage.h" +#include "ui_callgrind_configpage.h" -#include "settings.h" -#include "tool.h" +#include "callgrind_settings.h" +#include "callgrind_tool.h" #include namespace Valgrind { -namespace Callgrind -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +CallgrindConfigPage::CallgrindConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::CallgrindConfigPage()) { ui->setupUi(this); connectToChanged(ui->extraParameters); connectToChanged(ui->cacheSimulation); connectToChanged(ui->branchSimulation); connectToChanged(ui->launchKCachegrind); connectToChanged(ui->callgrindAnnotateParameters); } -ConfigPage::~ConfigPage() = default; +CallgrindConfigPage::~CallgrindConfigPage() = default; -QString ConfigPage::title() const +QString CallgrindConfigPage::title() const { - return Tool::self()->name(); + return CallgrindTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon CallgrindConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void CallgrindConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + CallgrindSettings 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 +void CallgrindConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + CallgrindSettings 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() +CallgrindConfigPageFactory::CallgrindConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* CallgrindConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new CallgrindConfigPage(parent); } } diff --git a/tools/cachegrind/configpage.h b/tools/callgrind/callgrind_configpage.h similarity index 75% rename from tools/cachegrind/configpage.h rename to tools/callgrind/callgrind_configpage.h index 43d5f3d..b534d73 100644 --- a/tools/cachegrind/configpage.h +++ b/tools/callgrind/callgrind_configpage.h @@ -1,64 +1,57 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace Cachegrind -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class CallgrindConfigPage; } -class ConfigPage : public IConfigPage +class CallgrindConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit CallgrindConfigPage(QWidget* parent = nullptr); + ~CallgrindConfigPage() 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(); - - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class CallgrindConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + CallgrindConfigPageFactory(); + ~CallgrindConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/callgrind/configpage.ui b/tools/callgrind/callgrind_configpage.ui similarity index 97% rename from tools/callgrind/configpage.ui rename to tools/callgrind/callgrind_configpage.ui index aa91252..16011b7 100644 --- a/tools/callgrind/configpage.ui +++ b/tools/callgrind/callgrind_configpage.ui @@ -1,132 +1,132 @@ - Valgrind::Callgrind::ConfigPage - + Valgrind::CallgrindConfigPage + 0 0 655 244 <html><head/><body><p>Specify if you want to do full cache simulation. By default, only instruction read accesses will be counted (&quot;Ir&quot;). With cache simulation, further event counters are enabled: </p><p>Cache misses on instruction reads (&quot;I1mr&quot;/&quot;ILmr&quot;), </p><p>data read accesses (&quot;Dr&quot;) and related cache misses (&quot;D1mr&quot;/&quot;DLmr&quot;), </p><p>data write accesses (&quot;Dw&quot;) and related cache misses (&quot;D1mw&quot;/&quot;DLmw&quot;).</p></body></html> Cache simulation false <html><head/><body><p>Specify if you want to do branch prediction simulation. Further event counters are enabled: Number of executed conditional branches and related predictor misses (&quot;Bc&quot;/&quot;Bcm&quot;), executed indirect jumps and related misses of the jump address predictor (&quot;Bi&quot;/&quot;Bim&quot;).</p></body></html> Branch simulation false Qt::Horizontal Extra parameters: extraParameters true callgrind_annotate parameters: callgrindAnnotateParameters true Qt::Horizontal Launch KCachegrind after analysis finish Qt::Vertical 20 40 cacheSimulation branchSimulation extraParameters callgrindAnnotateParameters launchKCachegrind diff --git a/tools/callgrind/job.cpp b/tools/callgrind/callgrind_job.cpp similarity index 73% rename from tools/callgrind/job.cpp rename to tools/callgrind/callgrind_job.cpp index c36a5c3..af63e97 100644 --- a/tools/callgrind/job.cpp +++ b/tools/callgrind/callgrind_job.cpp @@ -1,97 +1,93 @@ /* 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 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 "callgrind_job.h" -#include "model.h" -#include "parser.h" +#include "callgrind_model.h" +#include "callgrind_parser.h" #include "plugin.h" -#include "settings.h" -#include "tool.h" -#include "view.h" +#include "callgrind_settings.h" +#include "callgrind_tool.h" +#include "callgrind_view.h" #include -#include -#include + +#include +#include #include #include #include namespace Valgrind { -namespace Callgrind -{ - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IJob(Tool::self(), launchConfig) - , m_model(new FunctionsModel) +CallgrindJob::CallgrindJob(KDevelop::ILaunchConfiguration* launchConfig) + : Job(CallgrindTool::self(), launchConfig) + , m_model(new CallgrindFunctionsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } -Job::~Job() +CallgrindJob::~CallgrindJob() { } -bool Job::processEnded() +bool CallgrindJob::processEnded() { - Settings settings; + CallgrindSettings 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); + callgrindParse(caOutput, m_model); return true; } -void Job::addToolArgs(QStringList& args) const +void CallgrindJob::addToolArgs(QStringList& args) const { - Settings settings; + CallgrindSettings settings; settings.load(m_config); args += settings.cmdArgs(); args += QStringLiteral("--callgrind-out-file=%1").arg(m_outputFile->fileName()); } -QWidget* Job::createView() +QWidget* CallgrindJob::createView() { - return new View(m_config, m_outputFile, m_model); -} - + return new CallgrindView(m_config, m_outputFile, m_model); } } diff --git a/tools/callgrind/job.h b/tools/callgrind/callgrind_job.h similarity index 86% rename from tools/callgrind/job.h rename to tools/callgrind/callgrind_job.h index 86c3bc9..2105fd2 100644 --- a/tools/callgrind/job.h +++ b/tools/callgrind/callgrind_job.h @@ -1,59 +1,54 @@ /* 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 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" +#include "job.h" class QTemporaryFile; namespace Valgrind { -namespace Callgrind -{ - -class FunctionsModel; +class CallgrindFunctionsModel; -class Job : public IJob +class CallgrindJob : public Job { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit CallgrindJob(KDevelop::ILaunchConfiguration* launchConfig); + ~CallgrindJob() override; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; - FunctionsModel* m_model; + CallgrindFunctionsModel* m_model; QTemporaryFile* m_outputFile; }; } - -} diff --git a/tools/callgrind/model.cpp b/tools/callgrind/callgrind_model.cpp similarity index 75% rename from tools/callgrind/model.cpp rename to tools/callgrind/callgrind_model.cpp index 7bd0b1e..77051f6 100644 --- a/tools/callgrind/model.cpp +++ b/tools/callgrind/callgrind_model.cpp @@ -1,526 +1,520 @@ /* 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 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 "callgrind_model.h" #include "debug.h" #include "utils.h" #include -#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) +CallgrindCallInformation::CallgrindCallInformation(const QStringList& stringValues) { Q_ASSERT(!stringValues.isEmpty()); m_eventValues.resize(stringValues.size()); addValues(stringValues, m_eventValues); } -int CallInformation::eventValue(int type) +int CallgrindCallInformation::eventValue(int type) { Q_ASSERT(type < m_eventValues.size()); return m_eventValues[type]; } -Function::Function(int eventsCount) +CallgrindFunction::CallgrindFunction(int eventsCount) { m_eventValues.resize(eventsCount); } -int Function::callCount() +int CallgrindFunction::callCount() { int count = 0; for (auto info : qAsConst(callersInformation)) { count += info->callCount; } return count; } -int Function::eventValue(int type, bool inclusive) +int CallgrindFunction::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) +void CallgrindFunction::addEventValues(const QStringList& stringValues) { Q_ASSERT(stringValues.size() == m_eventValues.size()); addValues(stringValues, m_eventValues); } -FunctionsModel::FunctionsModel() +CallgrindFunctionsModel::CallgrindFunctionsModel() : m_currentEventType(0) , m_percentageValues(false) { } -FunctionsModel::~FunctionsModel() +CallgrindFunctionsModel::~CallgrindFunctionsModel() { qDeleteAll(m_functions); qDeleteAll(m_information); } -const QStringList & FunctionsModel::eventTypes() +const QStringList & CallgrindFunctionsModel::eventTypes() { return m_eventTypes; } -void FunctionsModel::setEventTypes(const QStringList& eventTypes) +void CallgrindFunctionsModel::setEventTypes(const QStringList& eventTypes) { Q_ASSERT(!eventTypes.isEmpty()); m_eventTypes = eventTypes; m_eventTotals.resize(m_eventTypes.size()); } -void FunctionsModel::setEventTotals(const QStringList& stringValues) +void CallgrindFunctionsModel::setEventTotals(const QStringList& stringValues) { Q_ASSERT(stringValues.size() == m_eventTotals.size()); addValues(stringValues, m_eventTotals); } -int FunctionsModel::currentEventType() +int CallgrindFunctionsModel::currentEventType() { return m_currentEventType; } -void FunctionsModel::setCurrentEventType(int type) +void CallgrindFunctionsModel::setCurrentEventType(int type) { Q_ASSERT(type < m_eventTotals.size()); m_currentEventType = type; emitDataChanged(this); } -void FunctionsModel::setPercentageValues(bool value) +void CallgrindFunctionsModel::setPercentageValues(bool value) { m_percentageValues = value; emitDataChanged(this); } -Function* FunctionsModel::addFunction( +CallgrindFunction* CallgrindFunctionsModel::addFunction( const QString& name, const QString& sourceFile, const QString& binaryFile) { Q_ASSERT(!name.isEmpty()); Q_ASSERT(!m_eventTypes.isEmpty()); - Function* function = nullptr; + CallgrindFunction* 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 = new CallgrindFunction(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, +void CallgrindFunctionsModel::addCall( + CallgrindFunction* caller, + CallgrindFunction* callee, int callCount, const QStringList& eventValues) { Q_ASSERT(caller); Q_ASSERT(callee); - auto info = new CallInformation(eventValues); + auto info = new CallgrindCallInformation(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 +QModelIndex CallgrindFunctionsModel::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 +int CallgrindFunctionsModel::rowCount(const QModelIndex&) const { return m_functions.size(); } -int FunctionsModel::columnCount(const QModelIndex&) const +int CallgrindFunctionsModel::columnCount(const QModelIndex&) const { return 4; } -QString FunctionsModel::displayValue(int eventIntValue, int eventType) const +QString CallgrindFunctionsModel::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 +QVariant CallgrindFunctionsModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } - auto function = static_cast(index.internalPointer()); + 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 +QVariant CallgrindFunctionsModel::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) +CallgrindFunctionEventsModel::CallgrindFunctionEventsModel(CallgrindFunctionsModel* baseModel) : QAbstractTableModel(baseModel) , m_baseModel(baseModel) , m_function(nullptr) { Q_ASSERT(m_baseModel); - connect(m_baseModel, &FunctionsModel::dataChanged, + connect(m_baseModel, &CallgrindFunctionsModel::dataChanged, this, [this](const QModelIndex&, const QModelIndex&, const QVector&) { - emitDataChanged(this); }); } -FunctionEventsModel::~FunctionEventsModel() +CallgrindFunctionEventsModel::~CallgrindFunctionEventsModel() { } -void FunctionEventsModel::setFunction(Function* function) +void CallgrindFunctionEventsModel::setFunction(CallgrindFunction* function) { m_function = function; emitDataChanged(this); } -QModelIndex FunctionEventsModel::index(int row, int column, const QModelIndex&) const +QModelIndex CallgrindFunctionEventsModel::index(int row, int column, const QModelIndex&) const { if (hasIndex(row, column)) { return createIndex(row, column); } return QModelIndex(); } -int FunctionEventsModel::rowCount(const QModelIndex&) const +int CallgrindFunctionEventsModel::rowCount(const QModelIndex&) const { return m_baseModel->eventTypes().size(); } -int FunctionEventsModel::columnCount(const QModelIndex&) const +int CallgrindFunctionEventsModel::columnCount(const QModelIndex&) const { return 4; } -QVariant FunctionEventsModel::data(const QModelIndex& index, int role) const +QVariant CallgrindFunctionEventsModel::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 +QVariant CallgrindFunctionEventsModel::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) +CallgrindFunctionCallersCalleesModel::CallgrindFunctionCallersCalleesModel(CallgrindFunctionsModel* baseModel, bool isCallerModel) : QAbstractTableModel(baseModel) , m_baseModel(baseModel) , m_isCallerModel(isCallerModel) , m_function(nullptr) { Q_ASSERT(m_baseModel); - connect(m_baseModel, &FunctionsModel::dataChanged, + connect(m_baseModel, &CallgrindFunctionsModel::dataChanged, this, [this](const QModelIndex&, const QModelIndex&, const QVector&) { emitDataChanged(this); emit headerDataChanged(Qt::Horizontal, 0, 1); }); } -FunctionCallersCalleesModel::~FunctionCallersCalleesModel() +CallgrindFunctionCallersCalleesModel::~CallgrindFunctionCallersCalleesModel() { } -void FunctionCallersCalleesModel::setFunction(Function* function) +void CallgrindFunctionCallersCalleesModel::setFunction(CallgrindFunction* function) { beginResetModel(); m_function = function; endResetModel(); } -QModelIndex FunctionCallersCalleesModel::index(int row, int column, const QModelIndex&) const +QModelIndex CallgrindFunctionCallersCalleesModel::index(int row, int column, const QModelIndex&) const { if (hasIndex(row, column)) { return createIndex(row, column); } return QModelIndex(); } -int FunctionCallersCalleesModel::rowCount(const QModelIndex&) const +int CallgrindFunctionCallersCalleesModel::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 +int CallgrindFunctionCallersCalleesModel::columnCount(const QModelIndex&) const { return 4; } -QVariant FunctionCallersCalleesModel::data(const QModelIndex& index, int role) const +QVariant CallgrindFunctionCallersCalleesModel::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 +QVariant CallgrindFunctionCallersCalleesModel::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/callgrind_model.h similarity index 68% rename from tools/callgrind/model.h rename to tools/callgrind/callgrind_model.h index d59d475..06ad0a1 100644 --- a/tools/callgrind/model.h +++ b/tools/callgrind/callgrind_model.h @@ -1,176 +1,173 @@ /* 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 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 CallgrindFunction; -class CallInformation +class CallgrindCallInformation { public: - explicit CallInformation(const QStringList& stringValues); + explicit CallgrindCallInformation(const QStringList& stringValues); - Function* caller = nullptr; - Function* callee = nullptr; + CallgrindFunction* caller = nullptr; + CallgrindFunction* callee = nullptr; int callCount = 0; int eventValue(int type); private: QVector m_eventValues; }; -class Function +class CallgrindFunction { public: - explicit Function(int eventsCount); + explicit CallgrindFunction(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; + QList callersInformation; + QList calleesInformation; private: QVector m_eventValues; }; -class FunctionsModel : public QAbstractTableModel +class CallgrindFunctionsModel : public QAbstractTableModel { Q_OBJECT public: - FunctionsModel(); - ~FunctionsModel() override; + CallgrindFunctionsModel(); + ~CallgrindFunctionsModel() 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); + CallgrindFunction* addFunction( + const QString& name, + const QString& sourceFile, + const QString& binaryFile); - void addCall(Function* caller, - Function* callee, - int callCount, - const QStringList& eventValues); + void addCall( + CallgrindFunction* caller, + CallgrindFunction* 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; + QList m_functions; + QList m_information; }; -class FunctionEventsModel : public QAbstractTableModel +class CallgrindFunctionEventsModel : public QAbstractTableModel { Q_OBJECT public: - explicit FunctionEventsModel(FunctionsModel* baseModel); - ~FunctionEventsModel() override; + explicit CallgrindFunctionEventsModel(CallgrindFunctionsModel* baseModel); + ~CallgrindFunctionEventsModel() override; - void setFunction(Function* function); + void setFunction(CallgrindFunction* 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; + CallgrindFunctionsModel* m_baseModel; + CallgrindFunction* m_function; }; -class FunctionCallersCalleesModel : public QAbstractTableModel +class CallgrindFunctionCallersCalleesModel : public QAbstractTableModel { Q_OBJECT public: - FunctionCallersCalleesModel(FunctionsModel* baseModel, bool isCallerModel); - ~FunctionCallersCalleesModel() override; + CallgrindFunctionCallersCalleesModel(CallgrindFunctionsModel* baseModel, bool isCallerModel); + ~CallgrindFunctionCallersCalleesModel() override; - void setFunction(Function* function); + void setFunction(CallgrindFunction* 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; + CallgrindFunctionsModel* m_baseModel; bool m_isCallerModel; - Function* m_function; + CallgrindFunction* m_function; }; } - -} diff --git a/tools/callgrind/parser.cpp b/tools/callgrind/callgrind_parser.cpp similarity index 90% rename from tools/callgrind/parser.cpp rename to tools/callgrind/callgrind_parser.cpp index 8fcfc94..bec2c95 100644 --- a/tools/callgrind/parser.cpp +++ b/tools/callgrind/callgrind_parser.cpp @@ -1,187 +1,182 @@ /* 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 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 "callgrind_parser.h" #include "debug.h" -#include "model.h" +#include "callgrind_model.h" #include #include #include namespace Valgrind { -namespace Callgrind -{ - -void parseCallInformation( +void callgrindParseCallInformation( const QString& line, bool programTotal, const QStringList& eventTypes, - Function*& caller, - FunctionsModel* model) + CallgrindFunction*& caller, + CallgrindFunctionsModel* 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 +enum CallgrindParserState { ParseRoot, ParseProgramTotalHeader, ParseProgramTotal, ParseProgramHeader, ParseProgram }; -void parse(QByteArray& baData, FunctionsModel* model) +void callgrindParse(QByteArray& baData, CallgrindFunctionsModel* model) { Q_ASSERT(model); - ParserState parserState = ParseRoot; + CallgrindParserState parserState = ParseRoot; QStringList eventTypes; QString eventsString; QString line; - Function* caller = nullptr; + CallgrindFunction* 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); + callgrindParseCallInformation(line, true, eventTypes, caller, model); parserState = ParseProgramHeader; } else { - parseCallInformation(line, false, eventTypes, caller, model); + callgrindParseCallInformation(line, false, eventTypes, caller, model); } } } } } - -} diff --git a/tools/callgrind/parser.h b/tools/callgrind/callgrind_parser.h similarity index 87% rename from tools/callgrind/parser.h rename to tools/callgrind/callgrind_parser.h index b2a9d4a..16ff255 100644 --- a/tools/callgrind/parser.h +++ b/tools/callgrind/callgrind_parser.h @@ -1,39 +1,35 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel Copyright 2011 Lionel Duc 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; +class CallgrindFunctionsModel; -void parse(QByteArray& data, FunctionsModel* model); - -} +// FIXME move into CallgrindFunctionsModel ? +void callgrindParse(QByteArray& data, CallgrindFunctionsModel* model); } diff --git a/tools/callgrind/settings.cpp b/tools/callgrind/callgrind_settings.cpp similarity index 86% rename from tools/callgrind/settings.cpp rename to tools/callgrind/callgrind_settings.cpp index 40bd68a..4960ad1 100644 --- a/tools/callgrind/settings.cpp +++ b/tools/callgrind/callgrind_settings.cpp @@ -1,76 +1,67 @@ /* This file is part of KDevelop 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 "callgrind_settings.h" #include "globalsettings.h" -#include "tool.h" +#include "callgrind_tool.h" namespace Valgrind { -namespace Callgrind -{ - -Settings::Settings() - : ISettings(Tool::self()->id()) +CallgrindSettings::CallgrindSettings() + : Settings(CallgrindTool::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() +QString CallgrindSettings::callgrindAnnotateExecutablePath() { return KDevelop::Path(GlobalSettings::callgrind_annotateExecutablePath()).toLocalFile(); } -QString Settings::kcachegrindExecutablePath() +QString CallgrindSettings::kcachegrindExecutablePath() { return KDevelop::Path(GlobalSettings::kcachegrindExecutablePath()).toLocalFile(); } } - -} diff --git a/tools/callgrind/settings.h b/tools/callgrind/callgrind_settings.h similarity index 89% rename from tools/callgrind/settings.h rename to tools/callgrind/callgrind_settings.h index 16cac5b..7d72c7c 100644 --- a/tools/callgrind/settings.h +++ b/tools/callgrind/callgrind_settings.h @@ -1,49 +1,44 @@ /* This file is part of KDevelop 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" +#include "settings.h" namespace Valgrind { -namespace Callgrind -{ - -class Settings : public ISettings +class CallgrindSettings : public Settings { public: - Settings(); - ~Settings() override; + CallgrindSettings(); + ~CallgrindSettings() override = default; BoolValue cacheSimulation; BoolValue branchSimulation; StringValue callgrindAnnotateParameters; BoolValue launchKCachegrind; static QString callgrindAnnotateExecutablePath(); static QString kcachegrindExecutablePath(); }; } - -} diff --git a/tools/callgrind/tool.cpp b/tools/callgrind/callgrind_tool.cpp similarity index 66% rename from tools/callgrind/tool.cpp rename to tools/callgrind/callgrind_tool.cpp index 52cb4c9..767b264 100644 --- a/tools/callgrind/tool.cpp +++ b/tools/callgrind/callgrind_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "callgrind_tool.h" -#include "configpage.h" -#include "job.h" +#include "callgrind_configpage.h" +#include "callgrind_job.h" -#include +#include namespace Valgrind { -namespace Callgrind -{ - -Tool* Tool::m_self = nullptr; +CallgrindTool* CallgrindTool::m_self = nullptr; -Tool::Tool() - : ITool( +CallgrindTool::CallgrindTool() + : Tool( 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() +CallgrindTool::~CallgrindTool() { m_self = nullptr; } -Tool* Tool::self() +CallgrindTool* CallgrindTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new CallgrindTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* CallgrindTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new CallgrindJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* CallgrindTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new CallgrindConfigPageFactory; } } diff --git a/tools/helgrind/tool.h b/tools/callgrind/callgrind_tool.h similarity index 79% copy from tools/helgrind/tool.h copy to tools/callgrind/callgrind_tool.h index 611b7ac..050ac43 100644 --- a/tools/helgrind/tool.h +++ b/tools/callgrind/callgrind_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace Helgrind -{ - -class Tool : public ITool +class CallgrindTool : public Tool { public: - ~Tool() override; + ~CallgrindTool() override; - static Tool* self(); + static CallgrindTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + CallgrindTool(); - static Tool* m_self; + static CallgrindTool* m_self; }; } - -} diff --git a/tools/callgrind/view.cpp b/tools/callgrind/callgrind_view.cpp similarity index 78% rename from tools/callgrind/view.cpp rename to tools/callgrind/callgrind_view.cpp index bda8ee4..0ef1064 100644 --- a/tools/callgrind/view.cpp +++ b/tools/callgrind/callgrind_view.cpp @@ -1,151 +1,144 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie * 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 "callgrind_view.h" +#include "ui_callgrind_view.h" +#include "callgrind_model.h" +#include "callgrind_settings.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) +CallgrindView::CallgrindView(KConfigGroup config, QTemporaryFile* outputFile, CallgrindFunctionsModel* model, QWidget* parent) : QWidget(parent) + , ui(new Ui::CallgrindView) , m_kcachegrindProcess(new QProcess) { + ui->setupUi(this); + 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, &CallgrindFunctionsModel::setCurrentEventType); model->setCurrentEventType(ui->eventTypes->currentIndex()); connect(ui->percenageValues, &QCheckBox::stateChanged, - model, &FunctionsModel::setPercentageValues); + model, &CallgrindFunctionsModel::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); + auto eventsModel = new CallgrindFunctionEventsModel(model); ui->eventsView->setModel(eventsModel); ui->eventsView->header()->resizeSections(QHeaderView::ResizeToContents); - auto callersModel = new FunctionCallersCalleesModel(model, true); + auto callersModel = new CallgrindFunctionCallersCalleesModel(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, + connect(callersModel, &CallgrindFunctionCallersCalleesModel::headerDataChanged, this, [this](Qt::Orientation, int, int) { ui->callersView->header()->resizeSections(QHeaderView::ResizeToContents); }); - auto calleesModel = new FunctionCallersCalleesModel(model, false); + auto calleesModel = new CallgrindFunctionCallersCalleesModel(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, + connect(calleesModel, &CallgrindFunctionCallersCalleesModel::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()); + 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(), + m_kcachegrindProcess->start(CallgrindSettings::kcachegrindExecutablePath(), { outputFile->fileName() }); }; - Settings settings; + CallgrindSettings settings; settings.load(config); - setupVisualizerProcess(m_kcachegrindProcess, + setupVisualizerProcess(m_kcachegrindProcess.data(), ui->launchKCachegrindButton, startVisualizer, settings.launchKCachegrind); } -View::~View() +CallgrindView::~CallgrindView() { - m_kcachegrindProcess->disconnect(); - delete m_kcachegrindProcess; - delete ui; -} - + m_kcachegrindProcess->disconnect(); // FIXME is this really needed ? } } diff --git a/tools/callgrind/view.h b/tools/callgrind/callgrind_view.h similarity index 74% rename from tools/callgrind/view.h rename to tools/callgrind/callgrind_view.h index bc0283a..ce38dc5 100644 --- a/tools/callgrind/view.h +++ b/tools/callgrind/callgrind_view.h @@ -1,62 +1,52 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * Copyright 2011 Lucas Sarie * 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 +#include class QProcess; class QTemporaryFile; namespace Valgrind { -namespace Callgrind -{ - -namespace Ui -{ - -class View; +namespace Ui { class CallgrindView; } -} - -class FunctionsModel; +class CallgrindFunctionsModel; -class View : public QWidget +class CallgrindView : public QWidget { Q_OBJECT public: - View(KConfigGroup config, QTemporaryFile* outputFile, FunctionsModel* model, QWidget* parent = nullptr); - ~View() override; + CallgrindView(KConfigGroup config, QTemporaryFile* outputFile, CallgrindFunctionsModel* model, QWidget* parent = nullptr); + ~CallgrindView() override; private: - Ui::View* ui; - QProcess* m_kcachegrindProcess; + QScopedPointer ui; + QScopedPointer m_kcachegrindProcess; }; } - -} diff --git a/tools/callgrind/view.ui b/tools/callgrind/callgrind_view.ui similarity index 98% rename from tools/callgrind/view.ui rename to tools/callgrind/callgrind_view.ui index 66bad25..7abf8d4 100644 --- a/tools/callgrind/view.ui +++ b/tools/callgrind/callgrind_view.ui @@ -1,279 +1,279 @@ - Valgrind::Callgrind::View - + Valgrind::CallgrindView + 0 0 997 573 0 0 Qt::LeftToRight 0 0 0 0 Search... true Percentage values true Launch KCachegrind 0 0 Qt::Horizontal false 0 Events 0 0 0 0 false Direct callers 0 0 0 0 QAbstractItemView::NoEditTriggers false true Direct callees 0 0 0 0 QAbstractItemView::NoEditTriggers false true 0 0 Location 75 true Binary file: lib.so false Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 75 true Source file(s): file.c Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse Qt::Vertical 20 337 searchEdit eventTypes percenageValues launchKCachegrindButton functionsView eventsView callersView calleesView tabWidget diff --git a/tools/drd/CMakeLists.txt b/tools/drd/CMakeLists.txt deleted file mode 100644 index 8f33b27..0000000 --- a/tools/drd/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -ki18n_wrap_ui(drd_UI_SRCS - configpage.ui -) - -add_library(drd_tool STATIC - configpage.cpp - job.cpp - settings.cpp - tool.cpp - - ${drd_UI_SRCS} -) - -target_link_libraries(drd_tool - generic_tool -) diff --git a/tools/drd/configpage.cpp b/tools/drd/drd_configpage.cpp similarity index 85% rename from tools/drd/configpage.cpp rename to tools/drd/drd_configpage.cpp index 11a734f..2f03870 100644 --- a/tools/drd/configpage.cpp +++ b/tools/drd/drd_configpage.cpp @@ -1,148 +1,143 @@ /* This file is part of KDevelop * 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 "drd_configpage.h" +#include "ui_drd_configpage.h" -#include "settings.h" -#include "tool.h" +#include "drd_settings.h" +#include "drd_tool.h" #include namespace Valgrind { -namespace DRD -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +DrdConfigPage::DrdConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::DrdConfigPage()) { ui->setupUi(this); connectToChanged(ui->joinListVol); connectToChanged(ui->segmentMergingInterval); connectToChanged(ui->checkStackVar); connectToChanged(ui->firstRaceOnly); connectToChanged(ui->freeIsWrite); connectToChanged(ui->reportSignalUnlocked); connectToChanged(ui->segmentMerging); connectToChanged(ui->showConflSeg); connectToChanged(ui->showStackUsage); connectToChanged(ui->ignoreThreadCreation); connectToChanged(ui->showInstructionPointer); connectToChanged(ui->traceAlloc); connectToChanged(ui->traceBarrier); connectToChanged(ui->traceCond); connectToChanged(ui->traceForkJoin); connectToChanged(ui->traceHb); connectToChanged(ui->traceMutex); connectToChanged(ui->traceRwlock); connectToChanged(ui->traceSemaphore); ui->joinListVolLabel->setToolTip(ui->joinListVol->toolTip()); ui->segmentMergingIntervalLabel->setToolTip(ui->segmentMergingInterval->toolTip()); } -ConfigPage::~ConfigPage() = default; +DrdConfigPage::~DrdConfigPage() = default; -QString ConfigPage::title() const +QString DrdConfigPage::title() const { - return Tool::self()->name(); + return DrdTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon DrdConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void DrdConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + DrdSettings 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 +void DrdConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + DrdSettings 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() +DrdConfigPageFactory::DrdConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* DrdConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new DrdConfigPage(parent); } } diff --git a/tools/drd/configpage.h b/tools/drd/drd_configpage.h similarity index 76% rename from tools/drd/configpage.h rename to tools/drd/drd_configpage.h index aaffbcb..db77c2d 100644 --- a/tools/drd/configpage.h +++ b/tools/drd/drd_configpage.h @@ -1,61 +1,56 @@ /* This file is part of KDevelop * 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace DRD -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class DrdConfigPage; } -class ConfigPage : public IConfigPage +class DrdConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit DrdConfigPage(QWidget* parent = nullptr); + ~DrdConfigPage() 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: - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class DrdConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + DrdConfigPageFactory(); + ~DrdConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/drd/configpage.ui b/tools/drd/drd_configpage.ui similarity index 99% rename from tools/drd/configpage.ui rename to tools/drd/drd_configpage.ui index 1052e40..d900201 100644 --- a/tools/drd/configpage.ui +++ b/tools/drd/drd_configpage.ui @@ -1,350 +1,350 @@ - Valgrind::DRD::ConfigPage - + Valgrind::DrdConfigPage + 0 0 676 558 Joined threads memory access list volume: joinListVol <html><head/><body><p>Data races that occur between a statement at the end of one thread and another thread can be missed if memory access information is discarded immediately after a thread has been joined. This option allows to specify for how many joined threads memory access information should be retained.</p></body></html> 1 1000 10 Segment merging interval: <html><head/><body><p>Perform segment merging only after the specified number of new segments have been created. This is an advanced configuration option that allows to choose whether to minimize DRD's memory usage by choosing a low value or to let DRD run faster by choosing a slightly higher value. The optimal value for this parameter depends on the program being analyzed. The default value works well for most programs.</p></body></html> 1000000 10 Extra parameters: extraParameters true 0 Common options <html><head/><body><p>Controls whether DRD detects data races on stack variables. Verifying stack variables is disabled by default because most programs do not share stack variables over threads.</p></body></html> Detect data races on stack variables <html><head/><body><p>Whether to report only the first data race that has been detected on a memory location or all data races that have been detected on a memory location.</p></body></html> Report only the first data race true <html><head/><body><p>Whether to report races between accessing memory and freeing memory. Enabling this option may cause DRD to run slightly slower. Notes:</p><p>Don't enable this option when using custom memory allocators that use the <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">VG_USERREQ__MALLOCLIKE_BLOCK</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">VG_USERREQ__FREELIKE_BLOCK</span> because that would result in false positives. </p><p>Don't enable this option when using reference-counted objects because that will result in false positives, even when that code has been annotated properly with <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">ANNOTATE_HAPPENS_BEFORE</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">ANNOTATE_HAPPENS_AFTER</span>. See e.g. the output of the following command for an example: <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">valgrind --tool=drd --free-is-write=yes drd/tests/annotate_smart_pointer</span>.</p></body></html> Report races between accessing and freeing memory <html><head/><body><p>Whether to report calls to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">pthread_cond_signal</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">pthread_cond_broadcast</span> where the mutex associated with the signal through <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">pthread_cond_wait</span> or <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">pthread_cond_timed_wait</span> is not locked at the time the signal is sent. Sending a signal without holding a lock on the associated mutex is a common programming error which can cause subtle race conditions and unpredictable behavior. There exist some uncommon synchronization patterns however where it is safe to send a signal without holding a lock on the associated mutex.</p></body></html> Report calls to unlocked signals <html><head/><body><p>Controls segment merging. Segment merging is an algorithm to limit memory usage of the data race detection algorithm. Disabling segment merging may improve the accuracy of the so-called 'other segments' displayed in race reports but can also trigger an out of memory error.</p></body></html> Segment merging <html><head/><body><p>Show conflicting segments in race reports. Since this information can help to find the cause of a data race, this option is enabled by default. Disabling this option makes the output of DRD more compact.</p></body></html> Show conflicting segments <html><head/><body><p>Print stack usage at thread exit time. When a program creates a large number of threads it becomes important to limit the amount of virtual memory allocated for thread stacks. This option makes it possible to observe how much stack memory has been used by each thread of the client program.</p><p>Note: the DRD tool itself allocates some temporary data on the client thread stack. The space necessary for this temporary data must be allocated by the client program when it allocates stack memory, but is not included in stack usage reported by DRD.</p></body></html> Show stack usage <html><head/><body><p>Controls whether all activities during thread creation should be ignored. By default enabled only on Solaris. Solaris provides higher throughput, parallelism and scalability than other operating systems, at the cost of more fine-grained locking activity. This means for example that when a thread is created under glibc, just one big lock is used for all thread setup. Solaris libc uses several fine-grained locks and the creator thread resumes its activities as soon as possible, leaving for example stack and TLS setup sequence to the created thread. This situation confuses DRD as it assumes there is some false ordering in place between creator and created thread; and therefore many types of race conditions in the application would not be reported. To prevent such false ordering, this command line option is set to <span style=" font-family:'Monospace';">yes</span> by default on Solaris. All activity (loads, stores, client requests) is therefore ignored during:</p><p>* pthread_create() call in the creator thread </p><p>* thread creation phase (stack and TLS setup) in the created thread</p></body></html> Ignore thread creation Qt::Horizontal Show stack frame instruction pointer value Qt::Vertical 20 0 Trace options <html><head/><body><p>Trace all memory allocations and deallocations. May produce a huge amount of output.</p></body></html> Trace memory allocations/deallocations <html><head/><body><p>Trace all barrier activity.</p></body></html> Trace barrier activity <html><head/><body><p>Trace all condition variable activity.</p></body></html> Trace condition variable activity <html><head/><body><p>Trace all thread creation and all thread termination events.</p></body></html> Trace thread creation/termination events <html><head/><body><p>Trace execution of the <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">ANNOTATE_HAPPENS_BEFORE()</span>, <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">ANNOTATE_HAPPENS_AFTER()</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">ANNOTATE_HAPPENS_DONE()</span> client requests.</p></body></html> Trace execution of "ANNOTATE_HAPPENS" requests <html><head/><body><p>Trace all mutex activity.</p></body></html> Trace mutex activity <html><head/><body><p>Trace all reader-writer lock activity.</p></body></html> Trace reader-writer lock activity <html><head/><body><p>Trace all semaphore activity.</p></body></html> Trace semaphore activity Qt::Vertical 20 0 Qt::Vertical 20 52 joinListVol segmentMergingInterval extraParameters tabWidget checkStackVar firstRaceOnly freeIsWrite reportSignalUnlocked segmentMerging showConflSeg showStackUsage ignoreThreadCreation showInstructionPointer traceAlloc traceBarrier traceCond traceForkJoin traceHb traceMutex traceRwlock traceSemaphore diff --git a/tools/drd/job.cpp b/tools/drd/drd_job.cpp similarity index 81% rename from tools/drd/job.cpp rename to tools/drd/drd_job.cpp index 1920cf2..e0ab2d8 100644 --- a/tools/drd/job.cpp +++ b/tools/drd/drd_job.cpp @@ -1,43 +1,34 @@ /* This file is part of KDevelop 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 "drd_job.h" #include "debug.h" -#include "settings.h" -#include "tool.h" +#include "drd_settings.h" +#include "drd_tool.h" namespace Valgrind { -namespace DRD +DrdJob::DrdJob(KDevelop::ILaunchConfiguration* launchConfig) + : XmlJob(DrdTool::self(), launchConfig, new DrdSettings) { - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IXmlJob(Tool::self(), launchConfig, new Settings) -{ -} - -Job::~Job() -{ -} - } } diff --git a/tools/drd/job.h b/tools/drd/drd_job.h similarity index 85% rename from tools/drd/job.h rename to tools/drd/drd_job.h index 240d340..b1e7007 100644 --- a/tools/drd/job.h +++ b/tools/drd/drd_job.h @@ -1,41 +1,36 @@ /* This file is part of KDevelop 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" +#include "xmljob.h" namespace Valgrind { -namespace DRD -{ - -class Job : public IXmlJob +class DrdJob : public XmlJob { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit DrdJob(KDevelop::ILaunchConfiguration* launchConfig); + ~DrdJob() override = default; }; } - -} diff --git a/tools/drd/settings.cpp b/tools/drd/drd_settings.cpp similarity index 95% rename from tools/drd/settings.cpp rename to tools/drd/drd_settings.cpp index 7b0c585..a6c6534 100644 --- a/tools/drd/settings.cpp +++ b/tools/drd/drd_settings.cpp @@ -1,149 +1,140 @@ /* This file is part of KDevelop 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 "drd_settings.h" -#include "tool.h" +#include "drd_tool.h" namespace Valgrind { -namespace DRD -{ - -Settings::Settings() - : IXmlSettings(Tool::self()->id()) +DrdSettings::DrdSettings() + : XmlSettings(DrdTool::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/drd_settings.h similarity index 91% rename from tools/drd/settings.h rename to tools/drd/drd_settings.h index 2b33692..82a1e61 100644 --- a/tools/drd/settings.h +++ b/tools/drd/drd_settings.h @@ -1,59 +1,54 @@ /* This file is part of KDevelop 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" +#include "xmlsettings.h" namespace Valgrind { -namespace DRD -{ - -class Settings : public IXmlSettings +class DrdSettings : public XmlSettings { public: - Settings(); - ~Settings() override; + DrdSettings(); + ~DrdSettings() override = default; 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/drd_tool.cpp similarity index 69% rename from tools/drd/tool.cpp rename to tools/drd/drd_tool.cpp index c7a6d21..b5d1365 100644 --- a/tools/drd/tool.cpp +++ b/tools/drd/drd_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "drd_tool.h" -#include "configpage.h" -#include "job.h" +#include "drd_configpage.h" +#include "drd_job.h" -#include +#include namespace Valgrind { -namespace DRD -{ - -Tool* Tool::m_self = nullptr; +DrdTool* DrdTool::m_self = nullptr; -Tool::Tool() - : ITool( +DrdTool::DrdTool() + : Tool( QStringLiteral("DRD"), i18n("DRD"), i18n("DRD (Thread Error Detector)"), QStringLiteral("drd"), QStringLiteral("drd_tool"), false) { m_self = this; } -Tool::~Tool() +DrdTool::~DrdTool() { m_self = nullptr; } -Tool* Tool::self() +DrdTool* DrdTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new DrdTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* DrdTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new DrdJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* DrdTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new DrdConfigPageFactory; } } diff --git a/tools/drd/tool.h b/tools/drd/drd_tool.h similarity index 80% rename from tools/drd/tool.h rename to tools/drd/drd_tool.h index f632d23..08ded2e 100644 --- a/tools/drd/tool.h +++ b/tools/drd/drd_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace DRD -{ - -class Tool : public ITool +class DrdTool : public Tool { public: - ~Tool() override; + ~DrdTool() override; - static Tool* self(); + static DrdTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + DrdTool(); - static Tool* m_self; + static DrdTool* m_self; }; } - -} diff --git a/tools/generic/CMakeLists.txt b/tools/generic/CMakeLists.txt deleted file mode 100644 index 34be6da..0000000 --- a/tools/generic/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -ki18n_wrap_ui(generic_UI_SRCS - configpage.ui -) - -add_library(generic_tool STATIC - core/iconfigpage.cpp - core/ijob.cpp - core/isettings.cpp - core/itool.cpp - core/launcher.cpp - core/utils.cpp - - core/xml/ixmljob.cpp - core/xml/ixmlsettings.cpp - core/xml/error.cpp - core/xml/parser.cpp - - configpage.cpp - settings.cpp - - ${generic_UI_SRCS} -) - -target_link_libraries(generic_tool - kdevvalgrind_config -) diff --git a/tools/helgrind/CMakeLists.txt b/tools/helgrind/CMakeLists.txt deleted file mode 100644 index d59fa7e..0000000 --- a/tools/helgrind/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -ki18n_wrap_ui(helgrind_UI_SRCS - configpage.ui -) - -add_library(helgrind_tool STATIC - configpage.cpp - job.cpp - settings.cpp - tool.cpp - - ${helgrind_UI_SRCS} -) - -target_link_libraries(helgrind_tool - generic_tool -) diff --git a/tools/helgrind/configpage.cpp b/tools/helgrind/helgrind_configpage.cpp similarity index 75% rename from tools/helgrind/configpage.cpp rename to tools/helgrind/helgrind_configpage.cpp index 68a8343..3392d36 100644 --- a/tools/helgrind/configpage.cpp +++ b/tools/helgrind/helgrind_configpage.cpp @@ -1,112 +1,107 @@ /* This file is part of KDevelop * 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 "helgrind_configpage.h" +#include "ui_helgrind_configpage.h" -#include "settings.h" -#include "tool.h" +#include "helgrind_settings.h" +#include "helgrind_tool.h" #include namespace Valgrind { -namespace Helgrind -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +HelgrindConfigPage::HelgrindConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::HelgrindConfigPage()) { ui->setupUi(this); connectToChanged(ui->extraParameters); connectToChanged(ui->conflictCacheSize); connectToChanged(ui->historyLevel); connectToChanged(ui->trackLockorders); connectToChanged(ui->checkStackRefs); connectToChanged(ui->ignoreThreadCreation); connectToChanged(ui->freeIsWrite); connectToChanged(ui->showInstructionPointer); ui->historyLevelLabel->setToolTip(ui->historyLevel->toolTip()); ui->conflictCacheSizeLabel->setToolTip(ui->conflictCacheSize->toolTip()); } -ConfigPage::~ConfigPage() = default; +HelgrindConfigPage::~HelgrindConfigPage() = default; -QString ConfigPage::title() const +QString HelgrindConfigPage::title() const { - return Tool::self()->name(); + return HelgrindTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon HelgrindConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void HelgrindConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + HelgrindSettings 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 +void HelgrindConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + HelgrindSettings 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() +HelgrindConfigPageFactory::HelgrindConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* HelgrindConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new HelgrindConfigPage(parent); } } diff --git a/tools/helgrind/configpage.h b/tools/helgrind/helgrind_configpage.h similarity index 75% rename from tools/helgrind/configpage.h rename to tools/helgrind/helgrind_configpage.h index b86c0b5..6774ef3 100644 --- a/tools/helgrind/configpage.h +++ b/tools/helgrind/helgrind_configpage.h @@ -1,61 +1,56 @@ /* This file is part of KDevelop * 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace Helgrind -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class HelgrindConfigPage; } -class ConfigPage : public IConfigPage +class HelgrindConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit HelgrindConfigPage(QWidget* parent = nullptr); + ~HelgrindConfigPage() 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: - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class HelgrindConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + HelgrindConfigPageFactory(); + ~HelgrindConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/helgrind/configpage.ui b/tools/helgrind/helgrind_configpage.ui similarity index 99% rename from tools/helgrind/configpage.ui rename to tools/helgrind/helgrind_configpage.ui index 0fac81b..c41d0ea 100644 --- a/tools/helgrind/configpage.ui +++ b/tools/helgrind/helgrind_configpage.ui @@ -1,205 +1,205 @@ - Valgrind::Helgrind::ConfigPage - + Valgrind::HelgrindConfigPage + 0 0 469 380 History level: historyLevel <html><head/><body><p><span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=full</span> (the default) causes Helgrind collects enough information about &quot;old&quot; accesses that it can produce two stack traces in a race report -- both the stack trace for the current access, and the trace for the older, conflicting access. To limit memory usage, &quot;old&quot; accesses stack traces are limited to a maximum of 8 entries, even if <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--num-callers</span> value is bigger.</p><p>Collecting such information is expensive in both speed and memory, particularly for programs that do many inter-thread synchronization events (locks, unlocks, etc). Without such information, it is more difficult to track down the root causes of races. Nonetheless, you may not need it in situations where you just want to check for the presence or absence of races, for example, when doing regression testing of a previously race-free program.</p><p><span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=none</span> is the opposite extreme. It causes Helgrind not to collect any information about previous accesses. This can be dramatically faster than <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=full</span>.</p><p><span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=approx</span> provides a compromise between these two extremes. It causes Helgrind to show a full trace for the later access, and approximate information regarding the earlier access. This approximate information consists of two stacks, and the earlier access is guaranteed to have occurred somewhere between program points denoted by the two stacks. This is not as useful as showing the exact stack for the previous access (as <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=full</span> does), but it is better than nothing, and it is almost as fast as <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=none</span>.</p></body></html> full approx none Conflict cache size: conflictCacheSize <html><head/><body><p>This flag only has any effect at <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--history-level=full</span>.</p><p>Information about &quot;old&quot; conflicting accesses is stored in a cache of limited size, with LRU-style management. This is necessary because it isn't practical to store a stack trace for every single memory access made by the program. Historical information on not recently accessed locations is periodically discarded, to free up space in the cache.</p><p>This option controls the size of the cache, in terms of the number of different memory addresses for which conflicting access information is stored. If you find that Helgrind is showing race errors with only one stack instead of the expected two stacks, try increasing this value.</p><p>The minimum value is 10,000 and the maximum is 30,000,000 (thirty times the default value). Increasing the value by 1 increases Helgrind's memory requirement by very roughly 100 bytes, so the maximum value will easily eat up three extra gigabytes or so of memory.</p></body></html> 10000 30000000 1000000 Extra parameters: extraParameters true Qt::Horizontal true <html><head/><body><p>When enabled (the default), Helgrind performs lock order consistency checking. For some buggy programs, the large number of lock order errors reported can become annoying, particularly if you're only interested in race errors. You may therefore find it helpful to disable lock order checking.</p></body></html> Track lock orders true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:14pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">By default Helgrind checks all data memory accesses made by your program. This flag enables you to skip checking for accesses to thread stacks (local variables). This can improve performance, but comes at the cost of missing races on stack-allocated data.</p></body></html> Check stack refs true <html><head/><body><p>Controls whether all activities during thread creation should be ignored. By default enabled only on Solaris. Solaris provides higher throughput, parallelism and scalability than other operating systems, at the cost of more fine-grained locking activity. This means for example that when a thread is created under glibc, just one big lock is used for all thread setup. Solaris libc uses several fine-grained locks and the creator thread resumes its activities as soon as possible, leaving for example stack and TLS setup sequence to the created thread. This situation confuses Helgrind as it assumes there is some false ordering in place between creator and created thread; and therefore many types of race conditions in the application would not be reported. To prevent such false ordering, this command line option is set to yes by default on Solaris. All activity (loads, stores, client requests) is therefore ignored during:</p><p>* pthread_create() call in the creator thread</p><p>* thread creation phase (stack and TLS setup) in the created thread</p><p>Also new memory allocated during thread creation is untracked, that is race reporting is suppressed there. DRD does the same thing implicitly. This is necessary because Solaris libc caches many objects and reuses them for different threads and that confuses Helgrind.</p></body></html> Ignore thread creation true <html><head/><body><p>When enabled (not the default), Helgrind treats freeing of heap memory as if the memory was written immediately before the free. This exposes races where memory is referenced by one thread, and freed by another, but there is no observable synchronization event to ensure that the reference happens before the free.</p><p>This functionality is new in Valgrind 3.7.0, and is regarded as experimental. It is not enabled by default because its interaction with custom memory allocators is not well understood at present. User feedback is welcomed.</p></body></html> Free is write (experimental) Qt::Horizontal Show stack frame instruction pointer value Qt::Vertical 20 71 historyLevel conflictCacheSize extraParameters trackLockorders checkStackRefs ignoreThreadCreation freeIsWrite diff --git a/tools/helgrind/job.cpp b/tools/helgrind/helgrind_job.cpp similarity index 79% rename from tools/helgrind/job.cpp rename to tools/helgrind/helgrind_job.cpp index 66302ce..7a56fce 100644 --- a/tools/helgrind/job.cpp +++ b/tools/helgrind/helgrind_job.cpp @@ -1,43 +1,34 @@ /* This file is part of KDevelop 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 "helgrind_job.h" #include "debug.h" -#include "settings.h" -#include "tool.h" +#include "helgrind_settings.h" +#include "helgrind_tool.h" namespace Valgrind { -namespace Helgrind +HelgrindJob::HelgrindJob(KDevelop::ILaunchConfiguration* launchConfig) + : XmlJob(HelgrindTool::self(), launchConfig, new HelgrindSettings) { - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IXmlJob(Tool::self(), launchConfig, new Settings) -{ -} - -Job::~Job() -{ -} - } } diff --git a/tools/memcheck/job.h b/tools/helgrind/helgrind_job.h similarity index 84% rename from tools/memcheck/job.h rename to tools/helgrind/helgrind_job.h index bfee204..6ba3a66 100644 --- a/tools/memcheck/job.h +++ b/tools/helgrind/helgrind_job.h @@ -1,41 +1,36 @@ /* This file is part of KDevelop 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" +#include "xmljob.h" namespace Valgrind { -namespace Memcheck -{ - -class Job : public IXmlJob +class HelgrindJob : public XmlJob { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit HelgrindJob(KDevelop::ILaunchConfiguration* launchConfig); + ~HelgrindJob() override = default; }; } - -} diff --git a/tools/helgrind/settings.cpp b/tools/helgrind/helgrind_settings.cpp similarity index 91% rename from tools/helgrind/settings.cpp rename to tools/helgrind/helgrind_settings.cpp index b9f3590..20e7a85 100644 --- a/tools/helgrind/settings.cpp +++ b/tools/helgrind/helgrind_settings.cpp @@ -1,77 +1,68 @@ /* This file is part of KDevelop 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 "helgrind_settings.h" -#include "tool.h" +#include "helgrind_tool.h" namespace Valgrind { -namespace Helgrind -{ - -Settings::Settings() - : IXmlSettings(Tool::self()->id()) +HelgrindSettings::HelgrindSettings() + : XmlSettings(HelgrindTool::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/helgrind_settings.h similarity index 88% rename from tools/helgrind/settings.h rename to tools/helgrind/helgrind_settings.h index d6c3ec9..b1025d6 100644 --- a/tools/helgrind/settings.h +++ b/tools/helgrind/helgrind_settings.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "xmlsettings.h" namespace Valgrind { -namespace Helgrind -{ - -class Settings : public IXmlSettings +class HelgrindSettings : public XmlSettings { public: - Settings(); - ~Settings() override; + HelgrindSettings(); + ~HelgrindSettings() override = default; StringValue historyLevel; IntValue conflictCacheSize; BoolValue trackLockorders; BoolValue checkStackRefs; BoolValue ignoreThreadCreation; BoolValue freeIsWrite; }; } - -} diff --git a/tools/helgrind/tool.cpp b/tools/helgrind/helgrind_tool.cpp similarity index 66% rename from tools/helgrind/tool.cpp rename to tools/helgrind/helgrind_tool.cpp index 05055f5..734bb00 100644 --- a/tools/helgrind/tool.cpp +++ b/tools/helgrind/helgrind_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "helgrind_tool.h" -#include "configpage.h" -#include "job.h" +#include "helgrind_configpage.h" +#include "helgrind_job.h" -#include +#include namespace Valgrind { -namespace Helgrind -{ - -Tool* Tool::m_self = nullptr; +HelgrindTool* HelgrindTool::m_self = nullptr; -Tool::Tool() - : ITool( +HelgrindTool::HelgrindTool() + : Tool( QStringLiteral("Helgrind"), i18n("Helgrind"), i18n("Helgrind (Thread Error Detector)"), QStringLiteral("helgrind"), QStringLiteral("helgrind_tool"), false) { m_self = this; } -Tool::~Tool() +HelgrindTool::~HelgrindTool() { m_self = nullptr; } -Tool* Tool::self() +HelgrindTool* HelgrindTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new HelgrindTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* HelgrindTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new HelgrindJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* HelgrindTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new HelgrindConfigPageFactory; } } diff --git a/tools/callgrind/tool.h b/tools/helgrind/helgrind_tool.h similarity index 79% rename from tools/callgrind/tool.h rename to tools/helgrind/helgrind_tool.h index c3a4fe9..200c4fc 100644 --- a/tools/callgrind/tool.h +++ b/tools/helgrind/helgrind_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace Callgrind -{ - -class Tool : public ITool +class HelgrindTool : public Tool { public: - ~Tool() override; + ~HelgrindTool() override; - static Tool* self(); + static HelgrindTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + HelgrindTool(); - static Tool* m_self; + static HelgrindTool* m_self; }; } - -} diff --git a/tools/massif/CMakeLists.txt b/tools/massif/CMakeLists.txt deleted file mode 100644 index ab760a0..0000000 --- a/tools/massif/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -ki18n_wrap_ui(massif_UI_SRCS - configpage.ui - view.ui -) - -add_library(massif_tool STATIC - configpage.cpp - job.cpp - model.cpp - parser.cpp - settings.cpp - snapshot.cpp - tool.cpp - view.cpp - - ${massif_UI_SRCS} -) - -target_link_libraries(massif_tool - generic_tool -) diff --git a/tools/massif/configpage.cpp b/tools/massif/massif_configpage.cpp similarity index 80% rename from tools/massif/configpage.cpp rename to tools/massif/massif_configpage.cpp index ae26593..d5ada29 100644 --- a/tools/massif/configpage.cpp +++ b/tools/massif/massif_configpage.cpp @@ -1,137 +1,132 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2011 Lionel Duc * 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 "massif_configpage.h" +#include "ui_massif_configpage.h" -#include "settings.h" -#include "tool.h" +#include "massif_settings.h" +#include "massif_tool.h" #include namespace Valgrind { -namespace Massif -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +MassifConfigPage::MassifConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::MassifConfigPage()) { ui->setupUi(this); connectToChanged(ui->extraParameters); connectToChanged(ui->launchMassifVisualizer); connectToChanged(ui->depth); connectToChanged(ui->threshold); connectToChanged(ui->peakInaccuracy); connectToChanged(ui->maxSnapshots); connectToChanged(ui->snapshotFreq); connectToChanged(ui->timeUnit); connectToChanged(ui->profileHeap); connectToChanged(ui->profileStack); connectToChanged(ui->pagesAsHeap); connectToChanged(ui->profileStack); connectToChanged(ui->pagesAsHeap); 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() = default; +MassifConfigPage::~MassifConfigPage() = default; -QString ConfigPage::title() const +QString MassifConfigPage::title() const { - return Tool::self()->name(); + return MassifTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon MassifConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void MassifConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + MassifSettings 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 +void MassifConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + MassifSettings 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() +void MassifConfigPage::check() { if (ui->profileStack->isChecked() && ui->pagesAsHeap->isChecked()) { ui->messageWidget->setVisible(true); return; } ui->messageWidget->setVisible(false); } -ConfigPageFactory::ConfigPageFactory() +MassifConfigPageFactory::MassifConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* MassifConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new MassifConfigPage(parent); } } diff --git a/tools/massif/configpage.h b/tools/massif/massif_configpage.h similarity index 76% rename from tools/massif/configpage.h rename to tools/massif/massif_configpage.h index d43c2ed..462a65e 100644 --- a/tools/massif/configpage.h +++ b/tools/massif/massif_configpage.h @@ -1,64 +1,59 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * 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 "iconfigpage.h" +#include "configpage.h" namespace Valgrind { -namespace Massif -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class MassifConfigPage; } -class ConfigPage : public IConfigPage +class MassifConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit MassifConfigPage(QWidget* parent = nullptr); + ~MassifConfigPage() 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(); - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class MassifConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + MassifConfigPageFactory(); + ~MassifConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/massif/configpage.ui b/tools/massif/massif_configpage.ui similarity index 98% rename from tools/massif/configpage.ui rename to tools/massif/massif_configpage.ui index feb5d08..cdde443 100644 --- a/tools/massif/configpage.ui +++ b/tools/massif/massif_configpage.ui @@ -1,301 +1,301 @@ - Valgrind::Massif::ConfigPage - + Valgrind::MassifConfigPage + 0 0 465 - 580 + 582 Time unit: timeUnit <html><head/><body><p>The time unit used for the profiling. There are three possibilities: </p><p><span style=" font-weight:600;">instructions</span> executed (i), which is good for most cases; </p><p>real (wallclock) time (ms, i.e. <span style=" font-weight:600;">milliseconds</span>), which is sometimes useful; </p><p>and <span style=" font-weight:600;">bytes</span> allocated/deallocated on the heap and/or stack (B), which is useful for very short-run programs, and for testing purposes, because it is the most reproducible across different machines.</p></body></html> CPU instructions Milliseconds Bytes allocated Snapshot tree depth: depth <html><head/><body><p>Maximum depth of the allocation trees recorded for detailed snapshots. Increasing it will make Massif run somewhat more slowly, use more memory, and produce bigger output files.</p></body></html> 2000000000 30 Threshold: threshold <html><head/><body><p>The significance threshold for heap allocations, as a percentage of total memory size. Allocation tree entries that account for less than this will be aggregated. Note that this should be specified in tandem with ms_print's option of the same name.</p></body></html> % 1 Peak inaccuracy: peakInaccuracy <html><head/><body><p>Massif does not necessarily record the actual global memory allocation peak; by default it records a peak only when the global memory allocation size exceeds the previous peak by at least 1.0%. This is because there can be many local allocation peaks along the way, and doing a detailed snapshot for every one would be expensive and wasteful, as all but one of them will be later discarded. This inaccuracy can be changed (even to 0.0%) via this option, but Massif will run drastically slower as the number approaches zero.</p></body></html> % 100 1 Maximum snapshots: maxSnapshots <html><head/><body><p>The maximum number of snapshots recorded. If set to N, for all programs except very short-running ones, the final number of snapshots will be between N/2 and N.</p></body></html> 2000000000 100 Detailed snapshot frequency: snapshotFreq <html><head/><body><p>Frequency of detailed snapshots. With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--detailed-freq=1</span>, every snapshot is detailed.</p></body></html> 2000000000 10 E&xtra parameters: extraParameters true Qt::Horizontal <html><head/><body><p>Specifies whether heap profiling should be done.</p></body></html> Profile heap true <html><head/><body><p>Specifies whether stack profiling should be done. This option slows Massif down greatly, and so is off by default. Note that Massif assumes that the main stack has size zero at start-up. This is not true, but doing otherwise accurately is difficult. Furthermore, starting at zero better indicates the size of the part of the main stack that a user program actually has control over.</p></body></html> Profile stack (slows profiling down greatly) <html><head/><body><p>Tells Massif to profile memory at the page level rather than at the malloc'd block level.</p></body></html> Pages as heap <html><head/><body><p>&quot;Pages as heap&quot; cannot be used together with &quot;Profile stack&quot;.</p></body></html> true false KMessageWidget::Error Qt::Horizontal Launch Massif Visualizer after analysis finish Qt::Vertical 20 40 KMessageWidget QFrame
kmessagewidget.h
timeUnit depth threshold peakInaccuracy maxSnapshots snapshotFreq extraParameters profileHeap profileStack pagesAsHeap launchMassifVisualizer
diff --git a/tools/massif/job.cpp b/tools/massif/massif_job.cpp similarity index 74% rename from tools/massif/job.cpp rename to tools/massif/massif_job.cpp index 9becade..d661b4c 100644 --- a/tools/massif/job.cpp +++ b/tools/massif/massif_job.cpp @@ -1,97 +1,89 @@ /* 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 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 "massif_job.h" #include "debug.h" -#include "model.h" -#include "parser.h" +#include "massif_model.h" +#include "massif_parser.h" +#include "massif_settings.h" +#include "massif_tool.h" +#include "massif_view.h" #include "plugin.h" -#include "settings.h" -#include "tool.h" -#include "view.h" #include -#include + +#include #include #include namespace Valgrind { -namespace Massif -{ - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IJob(Tool::self(), launchConfig) - , m_model(new SnapshotsModel) +MassifJob::MassifJob(KDevelop::ILaunchConfiguration* launchConfig) + : Job(MassifTool::self(), launchConfig) + , m_model(new MassifSnapshotsModel) , m_outputFile(new QTemporaryFile(this)) { m_outputFile->open(); } -Job::~Job() -{ -} - -bool Job::processEnded() +bool MassifJob::processEnded() { - Settings settings; + MassifSettings settings; settings.load(m_config); - parse(m_outputFile->fileName(), m_model); + massifParse(m_outputFile->fileName(), m_model); return true; } -void Job::addToolArgs(QStringList& args) const +void MassifJob::addToolArgs(QStringList& args) const { - Settings settings; + MassifSettings 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() +QWidget* MassifJob::createView() { - return new View(m_config, m_outputFile, m_model); -} - + return new MassifView(m_config, m_outputFile, m_model); } } diff --git a/tools/cachegrind/job.h b/tools/massif/massif_job.h similarity index 83% rename from tools/cachegrind/job.h rename to tools/massif/massif_job.h index 23d75a7..f7d0df7 100644 --- a/tools/cachegrind/job.h +++ b/tools/massif/massif_job.h @@ -1,58 +1,54 @@ /* 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 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" +#include "job.h" class QTemporaryFile; namespace Valgrind { -namespace Cachegrind -{ - -class FunctionsModel; +class MassifSnapshotsModel; -class Job : public IJob +class MassifJob : public Job { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit MassifJob(KDevelop::ILaunchConfiguration* launchConfig); + ~MassifJob() override = default; QWidget* createView() override; protected: bool processEnded() override; void addToolArgs(QStringList& args) const override; - FunctionsModel* m_model; + // FIXME check code for deletion + MassifSnapshotsModel* m_model; QTemporaryFile* m_outputFile; }; } - -} diff --git a/tools/massif/model.cpp b/tools/massif/massif_model.cpp similarity index 73% rename from tools/massif/model.cpp rename to tools/massif/massif_model.cpp index c01fd34..7f57a10 100644 --- a/tools/massif/model.cpp +++ b/tools/massif/massif_model.cpp @@ -1,151 +1,146 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * 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 "massif_model.h" #include "debug.h" -#include "snapshot.h" +#include "massif_snapshot.h" -#include +#include #include namespace Valgrind { -namespace Massif -{ - -SnapshotsModel::SnapshotsModel(QObject* parent) +MassifSnapshotsModel::MassifSnapshotsModel(QObject* parent) : QAbstractTableModel(parent) { } -SnapshotsModel::~SnapshotsModel() +MassifSnapshotsModel::~MassifSnapshotsModel() { qDeleteAll(m_snapshots); } -void SnapshotsModel::addSnapshot(Snapshot* snapshot) +void MassifSnapshotsModel::addSnapshot(MassifSnapshot* snapshot) { Q_ASSERT(snapshot); if (snapshot) { m_snapshots.append(snapshot); } } -QModelIndex SnapshotsModel::index(int row, int column, const QModelIndex&) const +QModelIndex MassifSnapshotsModel::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 +int MassifSnapshotsModel::rowCount(const QModelIndex&) const { return m_snapshots.size(); } -int SnapshotsModel::columnCount(const QModelIndex&) const +int MassifSnapshotsModel::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 +QVariant MassifSnapshotsModel::data(const QModelIndex& index, int role) const { - auto snapshot = static_cast(index.internalPointer()); + auto snapshot = static_cast(index.internalPointer()); if (!snapshot) { return QVariant(); } if (role == Qt::DisplayRole) { - if (index.column() <= Snapshot::Time) { + if (index.column() <= MassifSnapshot::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 +QVariant MassifSnapshotsModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(orientation) if (role == Qt::DisplayRole) { switch (section) { - case Snapshot::SnapshotId: + case MassifSnapshot::SnapshotId: return i18n("Snapshot"); - case Snapshot::Time: + case MassifSnapshot::Time: return i18n("Time"); - case Snapshot::Heap: + case MassifSnapshot::Heap: return i18n("Heap"); - case Snapshot::HeapExtra: + case MassifSnapshot::HeapExtra: return i18n("Heap (extra)"); - case Snapshot::Stack: + case MassifSnapshot::Stack: return i18n("Stack"); } } return QVariant(); } } - -} diff --git a/tools/massif/model.h b/tools/massif/massif_model.h similarity index 85% rename from tools/massif/model.h rename to tools/massif/massif_model.h index 568e08b..ad9a4ac 100644 --- a/tools/massif/model.h +++ b/tools/massif/massif_model.h @@ -1,59 +1,54 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * 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 MassifSnapshot; -class SnapshotsModel : public QAbstractTableModel +class MassifSnapshotsModel : public QAbstractTableModel { Q_OBJECT public: - explicit SnapshotsModel(QObject* parent = nullptr); - ~SnapshotsModel() override; + explicit MassifSnapshotsModel(QObject* parent = nullptr); + ~MassifSnapshotsModel() 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); + void addSnapshot(MassifSnapshot* snapshot); private: - QList m_snapshots; + QList m_snapshots; }; } - -} diff --git a/tools/massif/parser.cpp b/tools/massif/massif_parser.cpp similarity index 90% rename from tools/massif/parser.cpp rename to tools/massif/massif_parser.cpp index 4089b29..978184d 100644 --- a/tools/massif/parser.cpp +++ b/tools/massif/massif_parser.cpp @@ -1,91 +1,86 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel 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 "massif_parser.h" -#include "model.h" -#include "snapshot.h" +#include "massif_model.h" +#include "massif_snapshot.h" #include namespace Valgrind { -namespace Massif -{ - -void parse(const QString& fileName, SnapshotsModel* model) +void massifParse(const QString& fileName, MassifSnapshotsModel* model) { Q_ASSERT(model); - Snapshot* snapshot = nullptr; + MassifSnapshot* 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 = new MassifSnapshot; 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/massif_parser.h similarity index 87% rename from tools/massif/parser.h rename to tools/massif/massif_parser.h index e7c30dd..57a33d9 100644 --- a/tools/massif/parser.h +++ b/tools/massif/massif_parser.h @@ -1,38 +1,35 @@ /* This file is part of KDevelop Copyright 2011 Mathieu Lornac Copyright 2011 Damien Coppel 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; +class MassifSnapshotsModel; -void parse(const QString& fileName, SnapshotsModel* model); -} +// FIXME move into MassifSnapshotsModel ? +void massifParse(const QString& fileName, MassifSnapshotsModel* model); } diff --git a/tools/massif/settings.cpp b/tools/massif/massif_settings.cpp similarity index 92% rename from tools/massif/settings.cpp rename to tools/massif/massif_settings.cpp index 90fbd53..8a61cf6 100644 --- a/tools/massif/settings.cpp +++ b/tools/massif/massif_settings.cpp @@ -1,107 +1,98 @@ /* This file is part of KDevelop 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 "massif_settings.h" #include "globalsettings.h" -#include "tool.h" +#include "massif_tool.h" namespace Valgrind { -namespace Massif -{ - -Settings::Settings() - : ISettings(Tool::self()->id()) +MassifSettings::MassifSettings() + : Settings(MassifTool::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() +QString MassifSettings::visualizerExecutablePath() { return KDevelop::Path(GlobalSettings::massifVisualizerExecutablePath()).toLocalFile(); } } - -} diff --git a/tools/massif/settings.h b/tools/massif/massif_settings.h similarity index 90% rename from tools/massif/settings.h rename to tools/massif/massif_settings.h index e4be961..bdf95f8 100644 --- a/tools/massif/settings.h +++ b/tools/massif/massif_settings.h @@ -1,54 +1,49 @@ /* This file is part of KDevelop 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" +#include "settings.h" namespace Valgrind { -namespace Massif -{ - -class Settings : public ISettings +class MassifSettings : public Settings { public: - Settings(); - ~Settings() override; + MassifSettings(); + ~MassifSettings() override = default; 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.cpp b/tools/massif/massif_snapshot.cpp similarity index 93% rename from tools/massif/snapshot.cpp rename to tools/massif/massif_snapshot.cpp index b48f56c..2313bcc 100644 --- a/tools/massif/snapshot.cpp +++ b/tools/massif/massif_snapshot.cpp @@ -1,64 +1,59 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel 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 "snapshot.h" +#include "massif_snapshot.h" #include "debug.h" namespace Valgrind { -namespace Massif -{ - -void Snapshot::setValue(const QString& columnName, const QString& value) +void MassifSnapshot::setValue(const QString& columnName, const QString& value) { int column = -1; if (columnName == QStringLiteral("snapshot")) { column = SnapshotId; } else if (columnName == QStringLiteral("time")) { column = Time; } else if (columnName == QStringLiteral("mem_heap_B")) { column = Heap; } else if (columnName == QStringLiteral("mem_heap_extra_B")) { column = HeapExtra; } else if (columnName == QStringLiteral("mem_stacks_B")) { column = Stack; } if (column < 0) { qCDebug(KDEV_VALGRIND) << "Massif::Snapshot::setValue(); unknown column name:" << columnName; return; } values[column] = value; } } - -} diff --git a/tools/massif/snapshot.h b/tools/massif/massif_snapshot.h similarity index 97% rename from tools/massif/snapshot.h rename to tools/massif/massif_snapshot.h index 98eae3a..0eabf10 100644 --- a/tools/massif/snapshot.h +++ b/tools/massif/massif_snapshot.h @@ -1,51 +1,46 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * 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 MassifSnapshot { 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/massif_tool.cpp similarity index 67% rename from tools/massif/tool.cpp rename to tools/massif/massif_tool.cpp index 9977dc8..a61c72c 100644 --- a/tools/massif/tool.cpp +++ b/tools/massif/massif_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "massif_tool.h" -#include "configpage.h" -#include "job.h" +#include "massif_configpage.h" +#include "massif_job.h" -#include +#include namespace Valgrind { -namespace Massif -{ - -Tool* Tool::m_self = nullptr; +MassifTool* MassifTool::m_self = nullptr; -Tool::Tool() - : ITool( +MassifTool::MassifTool() + : Tool( QStringLiteral("Massif"), i18n("Massif"), i18n("Massif (Heap Profiler)"), QStringLiteral("massif"), QStringLiteral("massif_tool"), true) { m_self = this; } -Tool::~Tool() +MassifTool::~MassifTool() { m_self = nullptr; } -Tool* Tool::self() +MassifTool* MassifTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new MassifTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* MassifTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new MassifJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* MassifTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new MassifConfigPageFactory; } } diff --git a/tools/helgrind/tool.h b/tools/massif/massif_tool.h similarity index 80% rename from tools/helgrind/tool.h rename to tools/massif/massif_tool.h index 611b7ac..e772077 100644 --- a/tools/helgrind/tool.h +++ b/tools/massif/massif_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace Helgrind -{ - -class Tool : public ITool +class MassifTool : public Tool { public: - ~Tool() override; + ~MassifTool() override; - static Tool* self(); + static MassifTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + MassifTool(); - static Tool* m_self; + static MassifTool* m_self; }; } - -} diff --git a/tools/massif/view.cpp b/tools/massif/massif_view.cpp similarity index 76% rename from tools/massif/view.cpp rename to tools/massif/massif_view.cpp index 3067f10..c61196f 100644 --- a/tools/massif/view.cpp +++ b/tools/massif/massif_view.cpp @@ -1,88 +1,81 @@ /* This file is part of KDevelop * Copyright 2011 Sebastien Rannou * Copyright 2008 Hamish Rodda * 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 "massif_view.h" +#include "ui_massif_view.h" #include "debug.h" -#include "model.h" -#include "settings.h" -#include "snapshot.h" +#include "massif_model.h" +#include "massif_settings.h" +#include "massif_snapshot.h" #include "utils.h" #include #include #include namespace Valgrind { -namespace Massif -{ - -View::View(KConfigGroup config, QTemporaryFile* outputFile, SnapshotsModel* model, QWidget* parent) +MassifView::MassifView(KConfigGroup config, QTemporaryFile* outputFile, MassifSnapshotsModel* model, QWidget* parent) : QWidget(parent) - , ui(new Ui::View) + , ui(new Ui::MassifView) , 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()); + auto snapshot = static_cast(current.internalPointer()); treesModel->setStringList(snapshot->heapTree); }); auto startVisualizer = [this, outputFile]() { - m_visualizerProcess->start(Settings::visualizerExecutablePath(), + m_visualizerProcess->start(MassifSettings::visualizerExecutablePath(), { outputFile->fileName() }); }; - Settings settings; + MassifSettings settings; settings.load(config); - setupVisualizerProcess(m_visualizerProcess, + setupVisualizerProcess(m_visualizerProcess.data(), ui->launchVisualizerButton, startVisualizer, settings.launchVisualizer); } -View::~View() +MassifView::~MassifView() { - m_visualizerProcess->disconnect(); - delete m_visualizerProcess; - delete ui; -} - + m_visualizerProcess->disconnect(); // FIXME is this really needed ? } } diff --git a/tools/massif/view.h b/tools/massif/massif_view.h similarity index 74% rename from tools/massif/view.h rename to tools/massif/massif_view.h index b0c704d..334d3c1 100644 --- a/tools/massif/view.h +++ b/tools/massif/massif_view.h @@ -1,60 +1,51 @@ /* This file is part of KDevelop * Copyright 2008 Hamish Rodda * Copyright 2011 Sebastien Rannou * 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 + +#include class QProcess; class QTemporaryFile; namespace Valgrind { -namespace Massif -{ +namespace Ui { class MassifView; } -namespace Ui -{ +class MassifSnapshotsModel; -class View; - -} - -class SnapshotsModel; - -class View : public QWidget +class MassifView : public QWidget { Q_OBJECT public: - View(KConfigGroup config, QTemporaryFile* outputFile, SnapshotsModel* model, QWidget* parent = nullptr); - ~View() override; + MassifView(KConfigGroup config, QTemporaryFile* outputFile, MassifSnapshotsModel* model, QWidget* parent = nullptr); + ~MassifView() override; private: - Ui::View* ui; - QProcess* m_visualizerProcess; + QScopedPointer ui; + QScopedPointer m_visualizerProcess; }; } - -} diff --git a/tools/massif/view.ui b/tools/massif/massif_view.ui similarity index 94% rename from tools/massif/view.ui rename to tools/massif/massif_view.ui index 02d014e..0ab7c4b 100644 --- a/tools/massif/view.ui +++ b/tools/massif/massif_view.ui @@ -1,89 +1,89 @@ - Valgrind::Massif::View - + Valgrind::MassifView + 0 0 600 393 0 0 0 0 Qt::Horizontal Snapshots QAbstractItemView::NoEditTriggers - + Heap trees QAbstractItemView::NoEditTriggers Launch visualizer snapshotsView treesView launchVisualizerButton diff --git a/tools/massif/tool.h b/tools/massif/tool.h deleted file mode 100644 index 6c3d9aa..0000000 --- a/tools/massif/tool.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of KDevelop - 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/memcheck/CMakeLists.txt b/tools/memcheck/CMakeLists.txt deleted file mode 100644 index 4bd0e52..0000000 --- a/tools/memcheck/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -ki18n_wrap_ui(memcheck_UI_SRCS - configpage.ui -) - -add_library(memcheck_tool STATIC - configpage.cpp - job.cpp - settings.cpp - tool.cpp - - ${memcheck_UI_SRCS} -) - -target_link_libraries(memcheck_tool - generic_tool -) diff --git a/tools/memcheck/configpage.cpp b/tools/memcheck/memcheck_configpage.cpp similarity index 84% rename from tools/memcheck/configpage.cpp rename to tools/memcheck/memcheck_configpage.cpp index 4e4d3db..d85b0da 100644 --- a/tools/memcheck/configpage.cpp +++ b/tools/memcheck/memcheck_configpage.cpp @@ -1,216 +1,211 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * 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 "memcheck_configpage.h" +#include "ui_memcheck_configpage.h" #include "debug.h" -#include "settings.h" -#include "tool.h" +#include "memcheck_settings.h" +#include "memcheck_tool.h" #include namespace Valgrind { -namespace Memcheck -{ - -ConfigPage::ConfigPage(QWidget* parent) - : IConfigPage(parent) - , ui(new Ui::ConfigPage()) +MemcheckConfigPage::MemcheckConfigPage(QWidget* parent) + : ConfigPage(parent) + , ui(new Ui::MemcheckConfigPage()) { ui->setupUi(this); connectToChanged(ui->leakResolution); connectToChanged(ui->keepStacktraces); connectToChanged(ui->freelistVol); connectToChanged(ui->freelistBigBlocks); connectToChanged(ui->extraParameters); connectToChanged(ui->undefValueErrors); connectToChanged(ui->showMismatchedFrees); connectToChanged(ui->partialLoadsOk); connectToChanged(ui->trackOrigins); connectToChanged(ui->expensiveDefinednessChecks); connectToChanged(ui->showInstructionPointer); 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() = default; +MemcheckConfigPage::~MemcheckConfigPage() = default; -QString ConfigPage::title() const +QString MemcheckConfigPage::title() const { - return Tool::self()->name(); + return MemcheckTool::self()->name(); } -QIcon ConfigPage::icon() const +QIcon MemcheckConfigPage::icon() const { return QIcon(); } -void ConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) +void MemcheckConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject*) { QSignalBlocker blocker(this); - Settings settings; + MemcheckSettings 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 +void MemcheckConfigPage::saveToConfiguration(KConfigGroup cfg, KDevelop::IProject*) const { - Settings settings; + MemcheckSettings 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) +void MemcheckConfigPage::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); + connect(action, &QAction::toggled, this, &MemcheckConfigPage::changed); menu->addAction(action); } slot(); } -void ConfigPage::updateMenuButton(QPushButton* button, const QString& text) +void MemcheckConfigPage::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() +MemcheckConfigPageFactory::MemcheckConfigPageFactory() { } -KDevelop::LaunchConfigurationPage* ConfigPageFactory::createWidget(QWidget* parent) +KDevelop::LaunchConfigurationPage* MemcheckConfigPageFactory::createWidget(QWidget* parent) { - return new ConfigPage(parent); -} - + return new MemcheckConfigPage(parent); } } diff --git a/tools/memcheck/configpage.h b/tools/memcheck/memcheck_configpage.h similarity index 79% rename from tools/memcheck/configpage.h rename to tools/memcheck/memcheck_configpage.h index 28e65ed..271c50e 100644 --- a/tools/memcheck/configpage.h +++ b/tools/memcheck/memcheck_configpage.h @@ -1,69 +1,64 @@ /* This file is part of KDevelop * Copyright 2011 Mathieu Lornac * Copyright 2011 Damien Coppel * Copyright 2011 Lionel Duc * 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 "iconfigpage.h" +#include "configpage.h" class QPushButton; namespace Valgrind { -namespace Memcheck -{ - -namespace Ui { class ConfigPage; } +namespace Ui { class MemcheckConfigPage; } -class ConfigPage : public IConfigPage +class MemcheckConfigPage : public ConfigPage { Q_OBJECT public: - explicit ConfigPage(QWidget* parent = nullptr); - ~ConfigPage() override; + explicit MemcheckConfigPage(QWidget* parent = nullptr); + ~MemcheckConfigPage() 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); - QScopedPointer ui; + QScopedPointer ui; }; -class ConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory +class MemcheckConfigPageFactory : public KDevelop::LaunchConfigurationPageFactory { public: - ConfigPageFactory(); - ~ConfigPageFactory() override = default; + MemcheckConfigPageFactory(); + ~MemcheckConfigPageFactory() override = default; KDevelop::LaunchConfigurationPage* createWidget(QWidget* parent) override; }; } - -} diff --git a/tools/memcheck/configpage.ui b/tools/memcheck/memcheck_configpage.ui similarity index 99% rename from tools/memcheck/configpage.ui rename to tools/memcheck/memcheck_configpage.ui index 753ca73..6bb9d91 100644 --- a/tools/memcheck/configpage.ui +++ b/tools/memcheck/memcheck_configpage.ui @@ -1,304 +1,304 @@ - Valgrind::Memcheck::ConfigPage - + Valgrind::MemcheckConfigPage + 0 0 794 732 Leak resolution: <html><head/><body><p>When doing leak checking, determines how willing Memcheck is to consider different backtraces to be the same for the purposes of merging multiple leaks into a single leak report. When set to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">low</span>, only the first two entries need match. When <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">med</span>, four entries have to match. When <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">high</span>, all entries need to match.</p><p>For hardcore leak debugging, you probably want to use <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--leak-resolution=high</span> together with <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--num-callers=40</span> or some such large number.</p><p>Note that the <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--leak-resolution</span> setting does not affect Memcheck's ability to find leaks. It only changes how the results are presented.</p></body></html> high med low Show leak kinds: Specifies the leak kinds to show. false Used heuristics: <html><head/><body><p>Specifies the set of leak check heuristics to be used during leak searches. The heuristics control which interior pointers to a block cause it to be considered as reachable.</p></body></html> Stacktraces keeping: <html><head/><body><p>Controls which stack trace(s) to keep for malloc'd and/or free'd blocks. </p><p>With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">alloc-then-free</span>, a stack trace is recorded at allocation time, and is associated with the block. When the block is freed, a second stack trace is recorded, and this replaces the allocation stack trace. As a result, any &quot;use after free&quot; errors relating to this block can only show a stack trace for where the block was freed. </p><p>With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">alloc-and-free</span>, both allocation and the deallocation stack traces for the block are stored. Hence a &quot;use after free&quot; error will show both, which may make the error easier to diagnose. Compared to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">alloc-then-free</span>, this setting slightly increases Valgrind's memory use as the block contains two references instead of one. </p><p>With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">alloc</span>, only the allocation stack trace is recorded (and reported). With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">free</span>, only the deallocation stack trace is recorded (and reported). These values somewhat decrease Valgrind's memory and cpu usage. They can be useful depending on the error types you are searching for and the level of detail you need to analyze them. For example, if you are only interested in memory leak errors, it is sufficient to record the allocation stack traces. </p><p>With <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">none</span>, no stack traces are recorded for malloc and free operations. If your program allocates a lot of blocks and/or allocates/frees from many different stack traces, this can significantly decrease cpu and/or memory required. Of course, few details will be reported for errors related to heap blocks. </p><p>Note that once a stack trace is recorded, Valgrind keeps the stack trace in memory even if it is not referenced by any block. Some programs (for example, recursive algorithms) can generate a huge number of stack traces. If Valgrind uses too much memory in such circumstances, you can reduce the memory required with the options <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--keep-stacktraces</span> and/or by using a smaller value for the option <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--num-callers</span>. </p></body></html> alloc free alloc-and-free alloc-then-free none Freelist maximum size: freelistVol <html><head/><body><p>When the client program releases memory using <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">free</span> (in <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">C</span>) or <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete</span> (<span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">C++</span>), that memory is not immediately made available for re-allocation. Instead, it is marked inaccessible and placed in a queue of freed blocks. The purpose is to defer as long as possible the point at which freed-up memory comes back into circulation. This increases the chance that Memcheck will be able to detect invalid accesses to blocks for some significant period of time after they have been freed.</p><p>This option specifies the maximum total size, in bytes, of the blocks in the queue. The default value is twenty million bytes. Increasing this increases the total amount of memory used by Memcheck but may detect invalid uses of freed blocks which would otherwise go undetected.</p></body></html> 2000000000 20000000 Freelist big-blocks: <html><head/><body><p>When making blocks from the queue of freed blocks available for re-allocation, Memcheck will in priority re-circulate the blocks with a size greater or equal to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--freelist-big-blocks</span>. This ensures that freeing big blocks (in particular freeing blocks bigger than <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--freelist-vol</span>) does not immediately lead to a re-circulation of all (or a lot of) the small blocks in the free list. In other words, this option increases the likelihood to discover dangling pointers for the &quot;small&quot; blocks, even when big blocks are freed.</p><p>Setting a value of 0 means that all the blocks are re-circulated in a FIFO order.</p></body></html> 0 100000000 1000000 E&xtra parameters: extraParameters true Qt::Horizontal true <html><head/><body><p>Controls whether Memcheck reports uses of undefined value errors. Set this to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">no</span> if you don't want to see undefined value errors. It also has the side effect of speeding up Memcheck somewhat.</p></body></html> Show undefined values usage false <html><head/><body><p>When enabled, Memcheck checks that heap blocks are deallocated using a function that matches the allocating function. That is, it expects <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">free</span> to be used to deallocate blocks allocated by <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">malloc</span>, <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete</span> for blocks allocated by <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">new</span>, and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete[]</span> for blocks allocated by <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">new[]</span>. If a mismatch is detected, an error is reported. This is in general important because in some environments, freeing with a non-matching function can cause crashes.</p><p>There is however a scenario where such mismatches cannot be avoided. That is when the user provides implementations of <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">new</span>/<span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">new[]</span> that call <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">malloc</span> and of <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete</span>/<span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete[]</span> that call <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">free</span>, and these functions are asymmetrically inlined. For example, imagine that <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete[]</span> is inlined but <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">new[]</span> is not. The result is that Memcheck &quot;sees&quot; all <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">delete[]</span> calls as direct calls to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">free</span>, even when the program source contains no mismatched calls.</p><p>This causes a lot of confusing and irrelevant error reports. <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--show-mismatched-frees=no</span> disables these checks. It is not generally advisable to disable them, though, because you may miss real errors as a result.</p></body></html> Show mismatched frees <html><head/><body><p>Controls how Memcheck handles 32-, 64-, 128- and 256-bit naturally aligned loads from addresses for which some bytes are addressable and others are not. When <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">yes</span>, such loads do not produce an address error. Instead, loaded bytes originating from illegal addresses are marked as uninitialised, and those corresponding to legal addresses are handled in the normal way.</p><p>When <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">no</span>, loads from partially invalid addresses are treated the same as loads from completely invalid addresses: an illegal-address error is issued, and the resulting bytes are marked as initialised.</p><p>Note that code that behaves in this way is in violation of the ISO C/C++ standards, and should be considered broken. If at all possible, such code should be fixed.</p></body></html> Allow partial loads <html><head/><body><p>Controls whether Memcheck tracks the origin of uninitialised values. By default, it does not, which means that although it can tell you that an uninitialised value is being used in a dangerous way, it cannot tell you where the uninitialised value came from. This often makes it difficult to track down the root problem.</p><p>When set to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">yes</span>, Memcheck keeps track of the origins of all uninitialised values. Then, when an uninitialised value error is reported, Memcheck will try to show the origin of the value. An origin can be one of the following four places: a heap block, a stack allocation, a client request, or miscellaneous other sources (eg, a call to <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">brk</span>).</p><p>For uninitialised values originating from a heap block, Memcheck shows where the block was allocated. For uninitialised values originating from a stack allocation, Memcheck can tell you which function allocated the value, but no more than that -- typically it shows you the source location of the opening brace of the function. So you should carefully check that all of the function's local variables are initialised properly. </p><p>Performance overhead: origin tracking is expensive. It halves Memcheck's speed and increases memory use by a minimum of 100MB, and possibly more. Nevertheless it can drastically reduce the effort required to identify the root cause of uninitialised value errors, and so is often a programmer productivity win, despite running more slowly. </p><p>Accuracy: Memcheck tracks origins quite accurately. To avoid very large space and time overheads, some approximations are made. It is possible, although unlikely, that Memcheck will report an incorrect origin, or not be able to identify any origin. </p><p>Note that the combination <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--track-origins=yes</span> and <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--undef-value-errors=no</span> is nonsensical. Memcheck checks for and rejects this combination at startup.</p></body></html> Track origins of all uninitialised values <html><head/><body><p>Controls whether Memcheck should employ more precise but also more expensive (time consuming) algorithms when checking the definedness of a value. The default setting is not to do that and it is usually sufficient. However, for highly optimised code valgrind may sometimes incorrectly complain. Invoking valgrind with <span style=" font-family:'Monospace'; font-weight:600; font-style:italic;">--expensive-definedness-checks=yes</span> helps but comes at a performance cost. Runtime degradation of 25% have been observed but the extra cost depends a lot on the application at hand.</p></body></html> Expensive definedness checks Qt::Horizontal Show stack frame instruction pointer value Qt::Vertical 20 71 leakResolution showLeakKinds leakCheckHeuristics keepStacktraces freelistVol freelistBigBlocks extraParameters undefValueErrors showMismatchedFrees partialLoadsOk trackOrigins expensiveDefinednessChecks showInstructionPointer diff --git a/tools/memcheck/job.cpp b/tools/memcheck/memcheck_job.cpp similarity index 82% rename from tools/memcheck/job.cpp rename to tools/memcheck/memcheck_job.cpp index bc0bba8..b7a44d7 100644 --- a/tools/memcheck/job.cpp +++ b/tools/memcheck/memcheck_job.cpp @@ -1,47 +1,38 @@ /* 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 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 "memcheck_job.h" #include "debug.h" -#include "settings.h" -#include "tool.h" +#include "memcheck_settings.h" +#include "memcheck_tool.h" namespace Valgrind { -namespace Memcheck +MemcheckJob::MemcheckJob(KDevelop::ILaunchConfiguration* launchConfig) + : XmlJob(MemcheckTool::self(), launchConfig, new MemcheckSettings) { - -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) - : IXmlJob(Tool::self(), launchConfig, new Settings) -{ -} - -Job::~Job() -{ -} - } } diff --git a/tools/helgrind/job.h b/tools/memcheck/memcheck_job.h similarity index 84% rename from tools/helgrind/job.h rename to tools/memcheck/memcheck_job.h index d34d639..241ea40 100644 --- a/tools/helgrind/job.h +++ b/tools/memcheck/memcheck_job.h @@ -1,41 +1,36 @@ /* This file is part of KDevelop 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" +#include "xmljob.h" namespace Valgrind { -namespace Helgrind -{ - -class Job : public IXmlJob +class MemcheckJob : public XmlJob { Q_OBJECT public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); - ~Job() override; + explicit MemcheckJob(KDevelop::ILaunchConfiguration* launchConfig); + ~MemcheckJob() override = default; }; } - -} diff --git a/tools/memcheck/settings.cpp b/tools/memcheck/memcheck_settings.cpp similarity index 94% rename from tools/memcheck/settings.cpp rename to tools/memcheck/memcheck_settings.cpp index 3c77edd..1abd6f7 100644 --- a/tools/memcheck/settings.cpp +++ b/tools/memcheck/memcheck_settings.cpp @@ -1,107 +1,98 @@ /* This file is part of KDevelop 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 "memcheck_settings.h" -#include "tool.h" +#include "memcheck_tool.h" namespace Valgrind { -namespace Memcheck -{ - -Settings::Settings() - : IXmlSettings(Tool::self()->id()) +MemcheckSettings::MemcheckSettings() + : XmlSettings(MemcheckTool::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/memcheck_settings.h similarity index 90% rename from tools/memcheck/settings.h rename to tools/memcheck/memcheck_settings.h index c330f73..0ff7d02 100644 --- a/tools/memcheck/settings.h +++ b/tools/memcheck/memcheck_settings.h @@ -1,53 +1,48 @@ /* This file is part of KDevelop 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" +#include "xmlsettings.h" namespace Valgrind { -namespace Memcheck -{ - -class Settings : public IXmlSettings +class MemcheckSettings : public XmlSettings { public: - Settings(); - ~Settings() override; + MemcheckSettings(); + ~MemcheckSettings() override = default; 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/memcheck_tool.cpp similarity index 66% rename from tools/memcheck/tool.cpp rename to tools/memcheck/memcheck_tool.cpp index 449467f..3dc0149 100644 --- a/tools/memcheck/tool.cpp +++ b/tools/memcheck/memcheck_tool.cpp @@ -1,69 +1,64 @@ /* This file is part of KDevelop 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 "memcheck_tool.h" -#include "configpage.h" -#include "job.h" +#include "memcheck_configpage.h" +#include "memcheck_job.h" -#include +#include namespace Valgrind { -namespace Memcheck -{ - -Tool* Tool::m_self = nullptr; +MemcheckTool* MemcheckTool::m_self = nullptr; -Tool::Tool() - : ITool( +MemcheckTool::MemcheckTool() + : Tool( QStringLiteral("Memcheck"), i18n("Memcheck"), i18n("Memcheck (Memory Error Detector)"), QStringLiteral("memcheck"), QStringLiteral("memcheck_tool"), false) { m_self = this; } -Tool::~Tool() +MemcheckTool::~MemcheckTool() { m_self = nullptr; } -Tool* Tool::self() +MemcheckTool* MemcheckTool::self() { - return m_self ? m_self : new Tool; + return m_self ? m_self : new MemcheckTool; } -IJob* Tool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const +Job* MemcheckTool::createJob(KDevelop::ILaunchConfiguration* launchConfig) const { - return new Job(launchConfig); + return new MemcheckJob(launchConfig); } -KDevelop::LaunchConfigurationPageFactory* Tool::createConfigPageFactory() const +KDevelop::LaunchConfigurationPageFactory* MemcheckTool::createConfigPageFactory() const { - return new ConfigPageFactory; -} - + return new MemcheckConfigPageFactory; } } diff --git a/tools/cachegrind/tool.h b/tools/memcheck/memcheck_tool.h similarity index 79% rename from tools/cachegrind/tool.h rename to tools/memcheck/memcheck_tool.h index f8b4690..dce326b 100644 --- a/tools/cachegrind/tool.h +++ b/tools/memcheck/memcheck_tool.h @@ -1,48 +1,43 @@ /* This file is part of KDevelop 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" +#include "tool.h" namespace Valgrind { -namespace Cachegrind -{ - -class Tool : public ITool +class MemcheckTool : public Tool { public: - ~Tool() override; + ~MemcheckTool() override; - static Tool* self(); + static MemcheckTool* self(); - IJob* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; + Job* createJob(KDevelop::ILaunchConfiguration* launchConfig) const override; KDevelop::LaunchConfigurationPageFactory* createConfigPageFactory() const override; protected: - Tool(); + MemcheckTool(); - static Tool* m_self; + static MemcheckTool* m_self; }; } - -} diff --git a/tools/memcheck/tool.h b/tools/memcheck/tool.h deleted file mode 100644 index ae90aae..0000000 --- a/tools/memcheck/tool.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of KDevelop - 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 04a0547..526c23d 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 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 #include namespace Valgrind { class ToolView : public QTabWidget { Q_OBJECT public: explicit ToolView(QWidget* parent); - ~ToolView() override {} + ~ToolView() override = default; }; 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"