diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 5cd7ed519ce9210042b5fc4cffdf997d76fff0ec..6277c5477cda6ddea509e1bd34dfdd7c981f382f 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -32,6 +32,9 @@ // this relies on contents copied from qobject_p.h #define PRIVATE_OBJECT_ALLOWED 1 +#ifdef HAS_QOBJECT_P_H +# include <QtCore/private/qobject_p.h> +#endif #include <QtCore/QDateTime> #include <QtCore/QDebug> #include <QtCore/QDir> @@ -146,8 +149,7 @@ int qtGhVersion = QT_VERSION; # define NSY "" #endif - -#if PRIVATE_OBJECT_ALLOWED +#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H #if defined(QT_BEGIN_NAMESPACE) QT_BEGIN_NAMESPACE @@ -1532,6 +1534,13 @@ static void qDumpQObject(QDumper &d) const QObject *ob = reinterpret_cast<const QObject *>(d.data); const QMetaObject *mo = ob->metaObject(); unsigned childrenOffset = d.extraInt[0]; +#ifdef HAS_QOBJECT_P_H + // QObject child offset if known + if (!childrenOffset) { + QObjectPrivate qop; + childrenOffset = (char*)&qop.children - (char*)&qop; + } +#endif P(d, "value", ob->objectName()); P(d, "valueencoded", "2"); P(d, "type", NS"QObject"); @@ -1588,7 +1597,8 @@ static void qDumpQObject(QDumper &d) P(d, "numchild", slotCount); d.endHash(); #endif - d.beginHash(); + if (childrenOffset) { + d.beginHash(); P(d, "name", "children"); // works always, but causes additional traffic on the list //P(d, "exp", "((class '"NS"QObject'*)" << d.data << ")->children()"); @@ -1597,9 +1607,10 @@ static void qDumpQObject(QDumper &d) //P(d, "type", NS"QList<QObject *>"); //P(d, "value", "<" << children.size() << " items>"); qDumpInnerValue(d, NS"QList<"NS"QObject *>", - addOffset(dfunc(ob), childrenOffset)); + addOffset(dfunc(ob), childrenOffset)); P(d, "numchild", children.size()); - d.endHash(); + d.endHash(); + } #if 0 // Unneeded (and not working): Connections are listes as childen // of the signal or slot they are connected to. diff --git a/share/qtcreator/gdbmacros/gdbmacros.pro b/share/qtcreator/gdbmacros/gdbmacros.pro index 00c7b2403c86cb10f52722974615476d4774e784..5aacbfb84ad759718f92dddc19d227548bd063eb 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.pro +++ b/share/qtcreator/gdbmacros/gdbmacros.pro @@ -5,3 +5,7 @@ CONFIG -= release CONFIG += debug } SOURCES=gdbmacros.cpp + +exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) { + DEFINES+=HAS_QOBJECT_P_H +} diff --git a/share/qtcreator/gdbmacros/test/dumpertest.pro b/share/qtcreator/gdbmacros/test/dumpertest.pro new file mode 100644 index 0000000000000000000000000000000000000000..7b5fd3e582aacb2283b2679439b70968524b020e --- /dev/null +++ b/share/qtcreator/gdbmacros/test/dumpertest.pro @@ -0,0 +1,21 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2009-05-05T11:16:25 +# +#------------------------------------------------- + +QT -= gui + +TARGET = dumpertest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += main.cpp \ +../gdbmacros.cpp + +exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) { + DEFINES+=HAS_QOBJECT_P_H +} + diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f760e40aa980b9329349d5cf47a5fb65bd2cec3a --- /dev/null +++ b/share/qtcreator/gdbmacros/test/main.cpp @@ -0,0 +1,263 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include <QtCore/QStringList> +#include <QtCore/QVector> +#include <QtCore/QTimer> +#include <QtCore/private/qobject_p.h> + +#include <string> +#include <list> +#include <vector> + +#include <stdio.h> +#include <string.h> + + +/* Test program for Dumper development/porting. + * Takes the type as first argument. */ + +// --------------- Dumper symbols +extern char qDumpInBuffer[10000]; +extern char qDumpOutBuffer[100000]; + +extern "C" void *qDumpObjectData440( + int protocolVersion, + int token, + void *data, +#ifdef Q_CC_MSVC // CDB cannot handle boolean parameters + int dumpChildren, +#else + bool dumpChildren, +#endif + int extraInt0, int extraInt1, int extraInt2, int extraInt3); + +static void prepareInBuffer(const char *outerType, + const char *iname, + const char *expr, + const char *innerType) +{ + // Leave trailing '\0' + char *ptr = qDumpInBuffer; + strcpy(ptr, outerType); + ptr += strlen(outerType); + ptr++; + strcpy(ptr, iname); + ptr += strlen(iname); + ptr++; + strcpy(ptr, expr); + ptr += strlen(expr); + ptr++; + strcpy(ptr, innerType); + ptr += strlen(innerType); + ptr++; + strcpy(ptr, iname); +} + +// --------------- Qt types +static int dumpQString() +{ + QString test = QLatin1String("hallo"); + prepareInBuffer("QString", "local.qstring", "local.qstring", ""); + qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpQStringList() +{ + QStringList test = QStringList() << QLatin1String("item1") << QLatin1String("item2"); + prepareInBuffer("QList", "local.qstringlist", "local.qstringlist", "QString"); + qDumpObjectData440(2, 42, &test, 1, sizeof(QString), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpQIntList() +{ + QList<int> test = QList<int>() << 1 << 2; + prepareInBuffer("QList", "local.qintlist", "local.qintlist", "int"); + qDumpObjectData440(2, 42, &test, 1, sizeof(int), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpQIntVector() +{ + QVector<int> test = QVector<int>() << 1 << 2; + prepareInBuffer("QVector", "local.qintvector", "local.qintvector", "int"); + qDumpObjectData440(2, 42, &test, 1, sizeof(int), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +// --------------- std types + +static int dumpStdString() +{ + std::string test = "hallo"; + prepareInBuffer("std::string", "local.string", "local.string", ""); + qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdWString() +{ + std::wstring test = L"hallo"; + prepareInBuffer("std::wstring", "local.wstring", "local.wstring", ""); + qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + + +static int dumpStdStringList() +{ + std::list<std::string> test; + test.push_back("item1"); + test.push_back("item2"); + prepareInBuffer("std::list", "local.stringlist", "local.stringlist", "std::string"); + qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<std::string>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdStringQList() +{ + QList<std::string> test; + test.push_back("item1"); + test.push_back("item2"); + prepareInBuffer("QList", "local.stringqlist", "local.stringqlist", "std::string"); + qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdIntList() +{ + std::list<int> test; + test.push_back(1); + test.push_back(2); + prepareInBuffer("std::list", "local.intlist", "local.intlist", "int"); + qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdIntVector() +{ + std::vector<int> test; + test.push_back(1); + test.push_back(2); + prepareInBuffer("std::vector", "local.intvector", "local.intvector", "int"); + qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdStringVector() +{ + std::vector<std::string> test; + test.push_back("item1"); + test.push_back("item2"); + prepareInBuffer("std::vector", "local.stringvector", "local.stringvector", "std::string"); + qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + + +static int dumpQObject() +{ + QTimer t; + QObjectPrivate *tp = reinterpret_cast<QObjectPrivate *>(&t); +#ifdef KNOWS_OFFSET + const int childOffset = (char*)&tp->children - (char*)tp; +#else + const int childOffset = 0; +#endif + printf("Qt version %s Child offset: %d\n", QT_VERSION_STR, childOffset); + prepareInBuffer("QObject", "local.qobject", "local.qobject", ""); + qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +int main(int argc, char *argv[]) +{ + printf("Running query protocol\n"); + qDumpObjectData440(1, 42, 0, 1, 0, 0, 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + fputc('\n', stdout); + if (argc < 2) + return 0; + for (int i = 1; i < argc; i++) { + const char *arg = argv[i]; + printf("\nTesting %s\n", arg); + if (!qstrcmp(arg, "QString")) + dumpQString(); + if (!qstrcmp(arg, "QStringList")) + dumpQStringList(); + if (!qstrcmp(arg, "QList<int>")) + dumpQIntList(); + if (!qstrcmp(arg, "QList<std::string>")) + dumpStdStringQList(); + if (!qstrcmp(arg, "QVector<int>")) + dumpQIntVector(); + if (!qstrcmp(arg, "string")) + dumpStdString(); + if (!qstrcmp(arg, "wstring")) + dumpStdWString(); + if (!qstrcmp(arg, "list<int>")) + dumpStdIntList(); + if (!qstrcmp(arg, "list<string>")) + dumpStdStringList(); + if (!qstrcmp(arg, "vector<int>")) + dumpStdIntVector(); + if (!qstrcmp(arg, "vector<string>")) + dumpStdStringVector(); + if (!qstrcmp(arg, "QObject")) + dumpQObject(); + } + return 0; +} diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index 90fcc25924d483637cd6cad817f3e4f66e4c8f9a..6b173b30819105e7ac43af98f8738f361652f04a 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -31,64 +31,29 @@ #include "cmakeprojectconstants.h" #include "cmakeproject.h" -#include <extensionsystem/pluginmanager.h> -#include <utils/qtcassert.h> - #include <QtGui/QFormLayout> #include <QtGui/QGroupBox> #include <QtGui/QCheckBox> #include <QtGui/QLineEdit> #include <QtGui/QListWidget> -namespace { -bool debug = false; -} - using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; MakeStep::MakeStep(CMakeProject *pro) - : AbstractProcessStep(pro), m_pro(pro), m_buildParser(0) + : AbstractMakeStep(pro), m_pro(pro) { m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]"); } MakeStep::~MakeStep() { - delete m_buildParser; - m_buildParser = 0; + } bool MakeStep::init(const QString &buildConfiguration) { - delete m_buildParser; - m_buildParser = 0; - QString buildParser = m_pro->buildParser(buildConfiguration); - QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories = - ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); - - foreach (ProjectExplorer::IBuildParserFactory * factory, buildParserFactories) - if (factory->canCreate(buildParser)) { - m_buildParser = factory->create(buildParser); - break; - } - if (m_buildParser) { - connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)), - this, SIGNAL(addToOutputWindow(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), - this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(enterDirectory(const QString &)), - this, SLOT(addDirectory(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)), - this, SLOT(removeDirectory(const QString &)), - Qt::DirectConnection); - } - - m_openDirectories.clear(); - addDirectory(m_pro->buildDirectory(buildConfiguration)); + setBuildParser(m_pro->buildParser(buildConfiguration)); setEnabled(buildConfiguration, true); setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); @@ -106,14 +71,14 @@ bool MakeStep::init(const QString &buildConfiguration) setArguments(buildConfiguration, arguments); // TODO setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration)); } - return AbstractProcessStep::init(buildConfiguration); + return AbstractMakeStep::init(buildConfiguration); } void MakeStep::run(QFutureInterface<bool> &fi) { m_futureInterface = &fi; m_futureInterface->setProgressRange(0, 100); - AbstractProcessStep::run(fi); + AbstractMakeStep::run(fi); m_futureInterface = 0; } @@ -139,80 +104,13 @@ bool MakeStep::immutable() const void MakeStep::stdOut(const QString &line) { - if (m_buildParser) - m_buildParser->stdOutput(line); if (m_percentProgress.indexIn(line) != -1) { bool ok = false; int percent = m_percentProgress.cap(1).toInt(&ok);; if (ok) m_futureInterface->setProgressValue(percent); } - AbstractProcessStep::stdOut(line); -} - -void MakeStep::stdError(const QString &line) -{ - if (m_buildParser) - m_buildParser->stdError(line); - AbstractProcessStep::stdError(line); -} - -void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description) -{ - QString filePath = fn; - if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) { - // We have no save way to decide which file in which subfolder - // is meant. Therefore we apply following heuristics: - // 1. Search for unique file in directories currently indicated as open by GNU make - // (Enter directory xxx, Leave directory xxx...) + current directory - // 3. Check if file is unique in whole project - // 4. Otherwise give up - - filePath = filePath.trimmed(); - - QList<QFileInfo> possibleFiles; - foreach (const QString &dir, m_openDirectories) { - QFileInfo candidate(dir + QLatin1Char('/') + filePath); - if (debug) - qDebug() << "Checking path " << candidate.filePath(); - if (candidate.exists() - && !possibleFiles.contains(candidate)) { - if (debug) - qDebug() << candidate.filePath() << "exists!"; - possibleFiles << candidate; - } - } - if (possibleFiles.count() == 0) { - if (debug) - qDebug() << "No success. Trying all files in project ..."; - QString fileName = QFileInfo(filePath).fileName(); - foreach (const QString &file, project()->files(ProjectExplorer::Project::AllFiles)) { - QFileInfo candidate(file); - if (candidate.fileName() == fileName) { - if (debug) - qDebug() << "Found " << file; - possibleFiles << candidate; - } - } - } - if (possibleFiles.count() == 1) - filePath = possibleFiles.first().filePath(); - else - qWarning() << "Could not find absolute location of file " << filePath; - } - emit addToTaskWindow(filePath, type, linenumber, description); -} - -void MakeStep::addDirectory(const QString &dir) -{ - if (!m_openDirectories.contains(dir)) - m_openDirectories.insert(dir); -} - -void MakeStep::removeDirectory(const QString &dir) -{ - if (m_openDirectories.contains(dir)) - m_openDirectories.remove(dir); + AbstractMakeStep::stdOut(line); } CMakeProject *MakeStep::project() const diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h index f43977820aebc0835ecee3f28934d9921a587a16..8f99dcdb4ff75d51c585a471f30e30bf8ab27757 100644 --- a/src/plugins/cmakeprojectmanager/makestep.h +++ b/src/plugins/cmakeprojectmanager/makestep.h @@ -30,7 +30,7 @@ #ifndef MAKESTEP_H #define MAKESTEP_H -#include <projectexplorer/abstractprocessstep.h> +#include <projectexplorer/abstractmakestep.h> QT_BEGIN_NAMESPACE class QLineEdit; @@ -43,7 +43,7 @@ namespace Internal { class CMakeProject; -class MakeStep : public ProjectExplorer::AbstractProcessStep +class MakeStep : public ProjectExplorer::AbstractMakeStep { Q_OBJECT public: @@ -62,17 +62,11 @@ public: void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on); QStringList additionalArguments(const QString &buildConfiguration) const; void setAdditionalArguments(const QString &buildConfiguration, const QStringList &list); -private slots: - void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description); - void addDirectory(const QString &dir); - void removeDirectory(const QString &dir); protected: + // For parsing [ 76%] virtual void stdOut(const QString &line); - virtual void stdError(const QString &line); private: CMakeProject *m_pro; - ProjectExplorer::BuildParserInterface *m_buildParser; - QSet<QString> m_openDirectories; QRegExp m_percentProgress; QFutureInterface<bool> *m_futureInterface; }; diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp index aab4f0fbad4e3674737fe02a648c5ae3b27f3ae7..edd7b78190e2696aa347289ac6d5ab292ac8117a 100644 --- a/src/plugins/coreplugin/actionmanager/command.cpp +++ b/src/plugins/coreplugin/actionmanager/command.cpp @@ -49,12 +49,6 @@ \enum Command::CommandAttribute */ -/*! - \fn void Command::setCategory(const QString &name) - - Sets the category to \a name. -*/ - /*! \fn virtual void Command::setDefaultKeySequence(const QKeySequence &key) */ @@ -118,18 +112,6 @@ int CommandPrivate::stateFlags() const return (m_type & CS_Mask); } -void CommandPrivate::setCategory(const QString &name) -{ - m_category = name; -} - -QString CommandPrivate::category() const -{ - if (m_category.isEmpty()) - return tr("Other"); - return m_category; -} - void CommandPrivate::setDefaultKeySequence(const QKeySequence &key) { m_defaultKey = key; diff --git a/src/plugins/coreplugin/actionmanager/command.h b/src/plugins/coreplugin/actionmanager/command.h index 534b58429bcd1877b44e8708fe3dd5cefe0929f0..792d39902611d1f9d15458d4812b39ec5462e890 100644 --- a/src/plugins/coreplugin/actionmanager/command.h +++ b/src/plugins/coreplugin/actionmanager/command.h @@ -63,8 +63,6 @@ public: virtual void setDefaultText(const QString &text) = 0; virtual QString defaultText() const = 0; - virtual void setCategory(const QString &name) = 0; - virtual int id() const = 0; virtual CommandType type() const = 0; diff --git a/src/plugins/coreplugin/actionmanager/command_p.h b/src/plugins/coreplugin/actionmanager/command_p.h index 414060168785ffe9290256c14d2622f3dafd6e69..4bbf261c0732a41d69988c20155339d84e9cf558 100644 --- a/src/plugins/coreplugin/actionmanager/command_p.h +++ b/src/plugins/coreplugin/actionmanager/command_p.h @@ -60,9 +60,6 @@ public: virtual QString name() const = 0; - void setCategory(const QString &name); - QString category() const; - void setDefaultKeySequence(const QKeySequence &key); QKeySequence defaultKeySequence() const; diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui index 23ac787f49fb8f89a45ab77df6428d592ce579fd..8804fa8dbd309d632e87ef3d621208bbc72523b3 100644 --- a/src/plugins/debugger/commonoptionspage.ui +++ b/src/plugins/debugger/commonoptionspage.ui @@ -33,7 +33,7 @@ <item> <widget class="QCheckBox" name="checkBoxUseAlternatingRowColors"> <property name="text"> - <string>Use alternating row colors in debug views.</string> + <string>Use alternating row colors in debug views</string> </property> </widget> </item> diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 13b1679dc8e1a7344330759002322d131357709f..ee7c653f06efeaf33282e26a5db496a89fb3fdac 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -30,6 +30,7 @@ #include "debuggermanager.h" #include "debuggeractions.h" +#include "debuggerrunner.h" #include "debuggerconstants.h" #include "idebuggerengine.h" @@ -172,7 +173,7 @@ void DebuggerManager::init() m_busy = false; m_attachedPID = 0; - m_startMode = StartInternal; + m_runControl = 0; m_disassemblerHandler = 0; m_modulesHandler = 0; @@ -295,21 +296,6 @@ void DebuggerManager::init() connect(m_watchHandler, SIGNAL(watchModelUpdateRequested()), this, SLOT(updateWatchModel())); - m_startExternalAction = new QAction(this); - m_startExternalAction->setText(tr("Start and Debug External Application...")); - - m_attachExternalAction = new QAction(this); - m_attachExternalAction->setText(tr("Attach to Running External Application...")); - - m_attachCoreAction = new QAction(this); - m_attachCoreAction->setText(tr("Attach to Core...")); - connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore())); - - m_attachRemoteAction = new QAction(this); - m_attachRemoteAction->setText(tr("Attach to Running Remote Application...")); - connect(m_attachRemoteAction, SIGNAL(triggered()), - this, SLOT(attachRemoteApplication())); - m_continueAction = new QAction(this); m_continueAction->setText(tr("Continue")); m_continueAction->setIcon(QIcon(":/gdbdebugger/images/debugger_continue_small.png")); @@ -371,11 +357,6 @@ void DebuggerManager::init() connect(m_continueAction, SIGNAL(triggered()), this, SLOT(continueExec())); - connect(m_startExternalAction, SIGNAL(triggered()), - this, SLOT(startExternalApplication())); - connect(m_attachExternalAction, SIGNAL(triggered()), - this, SLOT(attachExternalApplication())); - connect(m_stopAction, SIGNAL(triggered()), this, SLOT(interruptDebuggingRequest())); connect(m_resetAction, SIGNAL(triggered()), @@ -798,30 +779,6 @@ void DebuggerManager::setConfigValue(const QString &name, const QVariant &value) emit setConfigValueRequested(name, value); } -void DebuggerManager::startExternalApplication() -{ - if (!startNewDebugger(StartExternal)) - emit debuggingFinished(); -} - -void DebuggerManager::attachExternalApplication() -{ - if (!startNewDebugger(AttachExternal)) - emit debuggingFinished(); -} - -void DebuggerManager::attachCore() -{ - if (!startNewDebugger(AttachCore)) - emit debuggingFinished(); -} - -void DebuggerManager::attachRemoteApplication() -{ - if (!startNewDebugger(AttachRemote)) - emit debuggingFinished(); -} - // Figure out the debugger type of an executable static bool determineDebuggerType(const QString &executable, DebuggerManager::DebuggerType *dt, @@ -869,12 +826,13 @@ static bool determineDebuggerType(int /* pid */, return true; } -bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) +void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) { + m_runControl = runControl; + if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << mode; + qDebug() << Q_FUNC_INFO << startMode(); - m_startMode = mode; // FIXME: Clean up switch (startMode()) { @@ -884,8 +842,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) configValue(_("LastExternalExecutableFile")).toString()); dlg.setExecutableArguments( configValue(_("LastExternalExecutableArguments")).toString()); - if (dlg.exec() != QDialog::Accepted) - return false; + if (dlg.exec() != QDialog::Accepted) { + runControl->debuggingFinished(); + return; + } setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile()); setConfigValue(_("LastExternalExecutableArguments"), @@ -898,8 +858,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) } case AttachExternal: { AttachExternalDialog dlg(mainWindow()); - if (dlg.exec() != QDialog::Accepted) - return false; + if (dlg.exec() != QDialog::Accepted) { + runControl->debuggingFinished(); + return; + } m_executable = QString(); m_processArgs = QStringList(); m_workingDir = QString(); @@ -907,7 +869,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) if (m_attachedPID == 0) { QMessageBox::warning(mainWindow(), tr("Warning"), tr("Cannot attach to PID 0")); - return false; + runControl->debuggingFinished(); + return; } break; } @@ -924,8 +887,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) } StartExternalDialog dlg(mainWindow()); dlg.setExecutableFile(startDirectory); - if (dlg.exec() != QDialog::Accepted) - return false; + if (dlg.exec() != QDialog::Accepted) { + runControl->debuggingFinished(); + return; + } m_executable = dlg.executableFile(); m_processArgs = dlg.executableArguments().split(' '); m_workingDir = QString(); @@ -943,8 +908,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) configValue(_("LastExternalExecutableFile")).toString()); dlg.setCoreFile( configValue(_("LastExternalCoreFile")).toString()); - if (dlg.exec() != QDialog::Accepted) - return false; + if (dlg.exec() != QDialog::Accepted) { + runControl->debuggingFinished(); + return; + } setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile()); setConfigValue(_("LastExternalCoreFile"), @@ -963,8 +930,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) dlg.setRemoteArchitectures(arches); dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString()); dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString()); - if (dlg.exec() != QDialog::Accepted) - return false; + if (dlg.exec() != QDialog::Accepted) { + runControl->debuggingFinished(); + return; + } setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel()); setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture()); m_remoteChannel = dlg.remoteChannel(); @@ -983,8 +952,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) if (!hasDebugger) { QMessageBox::warning(mainWindow(), tr("Warning"), tr("Cannot debug '%1': %2").arg(m_executable, errorMessage)); - return false; - + debuggingFinished(); + return; } if (Debugger::Constants::Internal::debug) qDebug() << m_executable << type; @@ -994,10 +963,11 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode) setStatus(DebuggerProcessStartingUp); if (!m_engine->startDebugger()) { setStatus(DebuggerProcessNotReady); - return false; + debuggingFinished(); + return; } - return true; + return; } void DebuggerManager::cleanupViews() @@ -1257,20 +1227,21 @@ void DebuggerManager::setStatus(int status) || status == DebuggerInferiorStopRequested || status == DebuggerInferiorStopped; - const bool starting = status == DebuggerProcessStartingUp; + //const bool starting = status == DebuggerProcessStartingUp; const bool running = status == DebuggerInferiorRunning; const bool ready = status == DebuggerInferiorStopped && startMode() != AttachCore; - m_startExternalAction->setEnabled(!started && !starting); - m_attachExternalAction->setEnabled(!started && !starting); -#ifdef Q_OS_WIN - m_attachCoreAction->setEnabled(false); -#else - m_attachCoreAction->setEnabled(!started && !starting); -#endif - m_attachRemoteAction->setEnabled(!started && !starting); +// FIXME +// m_startExternalAction->setEnabled(!started && !starting); +// m_attachExternalAction->setEnabled(!started && !starting); +//#ifdef Q_OS_WIN +// m_attachCoreAction->setEnabled(false); +//#else +// m_attachCoreAction->setEnabled(!started && !starting); +//#endif +// m_attachRemoteAction->setEnabled(!started && !starting); m_watchAction->setEnabled(ready); m_breakAction->setEnabled(true); @@ -1570,6 +1541,12 @@ void DebuggerManager::showQtDumperLibraryWarning(const QString &details) } } +DebuggerStartMode DebuggerManager::startMode() const +{ + return m_runControl->startMode(); +} + + ////////////////////////////////////////////////////////////////////// // // Testing @@ -1581,8 +1558,7 @@ void DebuggerManager::runTest(const QString &fileName) m_executable = fileName; m_processArgs = QStringList() << "--run-debuggee"; m_workingDir = QString(); - if (!startNewDebugger(StartInternal)) - emit debuggingFinished(); + //startNewDebugger(StartInternal); } #include "debuggermanager.moc" diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index f238b148ab7ae9d1623454d864fb0abb2c9526d0..ad92a003f3b839e3d184d33a40d09b721dd91064 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -56,6 +56,7 @@ namespace Debugger { namespace Internal { class DebuggerOutputWindow; +class DebuggerRunControl; class DebuggerPlugin; class DebugMode; @@ -204,7 +205,7 @@ public: enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger }; public slots: - bool startNewDebugger(DebuggerStartMode mode); + void startNewDebugger(DebuggerRunControl *runControl); void exitDebugger(); void setSimpleDockWidgetArrangement(); @@ -223,10 +224,6 @@ public slots: void resetLocation(); void interruptDebuggingRequest(); - void startExternalApplication(); - void attachExternalApplication(); - void attachCore(); - void attachRemoteApplication(); void jumpToLineExec(); void runToLineExec(); @@ -328,7 +325,8 @@ public: // one of the interfaces QAbstractItemModel *threadsModel(); int status() const { return m_status; } - DebuggerStartMode startMode() const { return m_startMode; } + DebuggerStartMode startMode() const; + DebuggerRunControl *runControl() const { return m_runControl; } QList<Symbol> moduleSymbols(const QString &moduleName); @@ -377,7 +375,7 @@ private: BreakpointData *findBreakpoint(const QString &fileName, int lineNumber); void setToolTipExpression(const QPoint &pos, const QString &exp0); - DebuggerStartMode m_startMode; + DebuggerRunControl *m_runControl; DebuggerType m_debuggerType; /// Views @@ -405,10 +403,6 @@ private: /// Actions friend class DebuggerPlugin; - QAction *m_startExternalAction; - QAction *m_attachExternalAction; - QAction *m_attachCoreAction; - QAction *m_attachRemoteAction; QAction *m_continueAction; QAction *m_stopAction; QAction *m_resetAction; // FIXME: Should not be needed in a stable release diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 0809df5ccafef742ba3d397d6b9872c169d85e46..cbb8a160cabc400a272a5f0d2716a72345ceac30 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -463,31 +463,48 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess //Core::ActionContainer *mcppcontext = // am->actionContainer(CppEditor::Constants::M_CONTEXT); + // External apps + m_startExternalAction = new QAction(this); + m_startExternalAction->setText(tr("Start and Debug External Application...")); + connect(m_startExternalAction, SIGNAL(triggered()), + this, SLOT(startExternalApplication())); + + m_attachExternalAction = new QAction(this); + m_attachExternalAction->setText(tr("Attach to Running External Application...")); + connect(m_attachExternalAction, SIGNAL(triggered()), + this, SLOT(attachExternalApplication())); + + m_attachCoreAction = new QAction(this); + m_attachCoreAction->setText(tr("Attach to Core...")); + connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore())); + + m_attachRemoteAction = new QAction(this); + m_attachRemoteAction->setText(tr("Attach to Running Remote Application...")); + connect(m_attachRemoteAction, SIGNAL(triggered()), + this, SLOT(attachRemoteApplication())); + + Core::ActionContainer *mdebug = am->actionContainer(ProjectExplorer::Constants::M_DEBUG); Core::Command *cmd = 0; - cmd = am->registerAction(m_manager->m_startExternalAction, + cmd = am->registerAction(m_startExternalAction, Constants::STARTEXTERNAL, globalcontext); mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - cmd = am->registerAction(m_manager->m_attachExternalAction, + cmd = am->registerAction(m_attachExternalAction, Constants::ATTACHEXTERNAL, globalcontext); mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - if (m_manager->m_attachCoreAction) { - cmd = am->registerAction(m_manager->m_attachCoreAction, - Constants::ATTACHCORE, globalcontext); - mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - } + cmd = am->registerAction(m_attachCoreAction, + Constants::ATTACHCORE, globalcontext); + mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - #if 0 + #if 1 // FIXME: not yet functional - if (m_manager->m_attachRemoteAction) { - cmd = am->registerAction(m_manager->m_attachRemoteAction, - Constants::ATTACHREMOTE, globalcontext); - mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); - } + cmd = am->registerAction(m_attachRemoteAction, + Constants::ATTACHREMOTE, globalcontext); + mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); #endif cmd = am->registerAction(m_manager->m_continueAction, @@ -642,7 +659,9 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess m_debugMode = new DebugMode(this); //addAutoReleasedObject(m_debugMode); - addAutoReleasedObject(new DebuggerRunner(m_manager)); + // register factory of DebuggerRunControl + m_debuggerRunner = new DebuggerRunner(m_manager); + addAutoReleasedObject(m_debuggerRunner); QList<int> context; context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); @@ -1036,6 +1055,48 @@ void DebuggerPlugin::showSettingsDialog() QLatin1String(Debugger::Constants::DEBUGGER_COMMON_SETTINGS_PAGE)); } +static QSharedPointer<RunConfiguration> activeRunConfiguration() +{ + ProjectExplorer::Project *project = + ProjectExplorerPlugin::instance()->currentProject(); + if (project) + return project->activeRunConfiguration(); + return QSharedPointer<RunConfiguration>(); +} + +void DebuggerPlugin::startExternalApplication() +{ + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); + if (RunControl *runControl = m_debuggerRunner + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, StartExternal)) + runControl->start(); +} + +void DebuggerPlugin::attachExternalApplication() +{ + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); + if (RunControl *runControl = m_debuggerRunner + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachExternal)) + runControl->start(); +} + +void DebuggerPlugin::attachCore() +{ + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); + if (RunControl *runControl = m_debuggerRunner + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachCore)) + runControl->start(); +} + +void DebuggerPlugin::attachRemoteApplication() +{ + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); + if (RunControl *runControl = m_debuggerRunner + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachRemote)) + runControl->start(); +} + + #include "debuggerplugin.moc" Q_EXPORT_PLUGIN(DebuggerPlugin) diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index 44a5f2e7711faea96aba22293998bf942b48859b..8990a64191738f3e1c29086604a68892ca3c37bc 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -56,6 +56,7 @@ namespace Internal { class BreakpointData; class DebuggerManager; +class DebuggerRunner; class DebugMode; class LocationMark; @@ -96,6 +97,11 @@ private slots: void focusCurrentEditor(Core::IMode *mode); void showSettingsDialog(); + void startExternalApplication(); + void attachExternalApplication(); + void attachCore(); + void attachRemoteApplication(); + private: void readSettings(); void writeSettings() const; @@ -107,12 +113,18 @@ private: DebuggerManager *m_manager; DebugMode *m_debugMode; + DebuggerRunner *m_debuggerRunner; QString m_previousMode; LocationMark *m_locationMark; int m_gdbRunningContext; QAction *m_toggleLockedAction; + + QAction *m_startExternalAction; + QAction *m_attachExternalAction; + QAction *m_attachCoreAction; + QAction *m_attachRemoteAction; }; } // namespace Internal diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 0153ef67531aa240036ace56dbe1f937e99f517f..8739091296c8c11c156652289a7ad9e46ea841f9 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -57,6 +57,7 @@ using ProjectExplorer::ApplicationRunConfiguration; // //////////////////////////////////////////////////////////////////////// +// A factory to create DebuggerRunControls DebuggerRunner::DebuggerRunner(DebuggerManager *manager) : m_manager(manager) {} @@ -72,14 +73,23 @@ QString DebuggerRunner::displayName() const return tr("Debug"); } -RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, const QString &mode) +RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, + const QString &mode, DebuggerStartMode startMode) { QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0); ApplicationRunConfigurationPtr rc = qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration); - QTC_ASSERT(rc, return 0); + //QTC_ASSERT(rc, return 0); //qDebug() << "***** Debugging" << rc->name() << rc->executable(); - return new DebuggerRunControl(m_manager, rc); + DebuggerRunControl *runControl = new DebuggerRunControl(m_manager, rc); + runControl->setStartMode(startMode); + return runControl; +} + +RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, + const QString &mode) +{ + return run(runConfiguration, mode, StartInternal); } QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguration) @@ -120,24 +130,25 @@ void DebuggerRunControl::start() m_running = true; ApplicationRunConfigurationPtr rc = qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration()); - QTC_ASSERT(rc, return); - ProjectExplorer::Project *project = rc->project(); - QTC_ASSERT(project, return); - - m_manager->m_executable = rc->executable(); - m_manager->m_environment = rc->environment().toStringList(); - m_manager->m_workingDir = rc->workingDirectory(); - m_manager->m_processArgs = rc->commandLineArguments(); - m_manager->m_dumperLib = rc->dumperLibrary(); - m_manager->m_buildDir = - project->buildDirectory(project->activeBuildConfiguration()); - m_manager->m_useTerminal = rc->runMode() == ApplicationRunConfiguration::Console; + if (rc) { + m_manager->m_executable = rc->executable(); + m_manager->m_environment = rc->environment().toStringList(); + m_manager->m_workingDir = rc->workingDirectory(); + m_manager->m_processArgs = rc->commandLineArguments(); + m_manager->m_dumperLib = rc->dumperLibrary(); + ProjectExplorer::Project *project = rc->project(); + QTC_ASSERT(project, /**/); + if (project) { + m_manager->m_buildDir = + project->buildDirectory(project->activeBuildConfiguration()); + } + m_manager->m_useTerminal = rc->runMode() == ApplicationRunConfiguration::Console; + } //emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable)); - if (m_manager->startNewDebugger(StartInternal)) - emit started(); - else - debuggingFinished(); + m_manager->startNewDebugger(this); + emit started(); + //debuggingFinished(); } void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data) diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h index 437b2c27016be0359a21c4e0d98f196c25d49c0e..619498bba6ecc374c414eea12c9d7020c7d75367 100644 --- a/src/plugins/debugger/debuggerrunner.h +++ b/src/plugins/debugger/debuggerrunner.h @@ -30,6 +30,8 @@ #ifndef DEBUGGERRUNNER_H #define DEBUGGERRUNNER_H +#include "debuggermanager.h" + #include <projectexplorer/runconfiguration.h> namespace ProjectExplorer { @@ -55,17 +57,20 @@ class DebuggerRunner : public ProjectExplorer::IRunConfigurationRunner public: explicit DebuggerRunner(DebuggerManager *manager); + // ProjectExplorer::IRunConfigurationRunner virtual bool canRun(RunConfigurationPtr runConfiguration, const QString &mode); virtual QString displayName() const; virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, const QString &mode); virtual QWidget *configurationWidget(RunConfigurationPtr runConfiguration); + virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, + const QString &mode, DebuggerStartMode startMode); private: DebuggerManager *m_manager; }; - +// This is a job description class DebuggerRunControl : public ProjectExplorer::RunControl { Q_OBJECT @@ -74,20 +79,25 @@ public: DebuggerRunControl(DebuggerManager *manager, ApplicationRunConfigurationPtr runConfiguration); + // ProjectExplorer::RunControl virtual void start(); virtual void stop(); virtual bool isRunning() const; + void setStartMode(DebuggerStartMode mode) { m_mode = mode; } + DebuggerStartMode startMode() const { return m_mode; } + Q_SLOT void debuggingFinished(); + signals: void stopRequested(); private slots: - void debuggingFinished(); void slotAddToOutputWindowInline(const QString &output); private: DebuggerManager *m_manager; bool m_running; + DebuggerStartMode m_mode; }; } // namespace Internal diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 6085b8c0dd3b415ca7649c3b68940205af964151..653a6817b62afeb6e8c7f00cdbfd0aaff141efdc 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -92,111 +92,20 @@ Q_DECLARE_METATYPE(Debugger::Internal::GdbMi); #define STRINGIFY_INTERNAL(x) #x #define STRINGIFY(x) STRINGIFY_INTERNAL(x) -struct _c -{ - inline _c(char c) : m_c(c) {} - inline operator QChar() const { return QLatin1Char(m_c); } - char m_c; -}; +#define CB(callback) &GdbEngine::callback, STRINGIFY(callback) -#define _c(c) QLatin1Char(c) -#define __(s) QLatin1String(s) -#define _(s) QString::fromLatin1(s) +typedef QLatin1Char _c; +typedef QLatin1String __; +static inline QString _(const char *s) { return QString::fromLatin1(s); } static const QString tooltipIName = _("tooltip"); -/////////////////////////////////////////////////////////////////////// -// -// GdbCommandType -// -/////////////////////////////////////////////////////////////////////// - -enum GdbCommandType -{ - GdbInvalidCommand = 0, - - GdbShowVersion = 100, - GdbFileExecAndSymbols, - //GdbQueryPwd, - GdbQuerySources, - GdbAsyncOutput2, - GdbStart, - GdbExit, - GdbAttached, - GdbStubAttached, - GdbExecRun, - GdbExecRunToFunction, - GdbExecStep, - GdbExecNext, - GdbExecStepI, - GdbExecNextI, - GdbExecContinue, - GdbExecFinish, - //GdbExecJumpToLine, - GdbExecInterrupt, - GdbInfoShared, - GdbInfoProc, - GdbInfoThreads, - GdbQueryDebuggingHelper, - GdbTemporaryContinue, - GdbTargetCore, - - BreakCondition = 200, - BreakEnablePending, - BreakSetAnnotate, - BreakDelete, - BreakEnable, - BreakDisable, - BreakList, - BreakIgnore, - BreakInfo, - BreakInsert, - BreakInsert1, - - DisassemblerList = 300, - - ModulesList = 400, - - RegisterListNames = 500, - RegisterListValues, - - StackSelectThread = 600, - StackListThreads, - StackListFrames, - StackListLocals, - StackListArguments, - - WatchVarAssign = 700, // data changed by user - WatchVarListChildren, - WatchVarCreate, - WatchEvaluateExpression, - WatchToolTip, - WatchDebuggingHelperSetup, - WatchDebuggingHelperValue1, // waiting for gdb ack - WatchDebuggingHelperValue2, // waiting for actual data - WatchDebuggingHelperValue3, // macro based - WatchDebuggingHelperEditValue, -}; - static int ¤tToken() { static int token = 0; return token; } -static bool isSkippable(int type) -{ - return type == RegisterListValues - && type == StackListThreads - && type == StackListFrames - && type == StackListLocals - && type == StackListArguments - && type == WatchVarAssign - && type == WatchVarListChildren - && type == WatchVarCreate - && type == WatchEvaluateExpression - && type == WatchToolTip; -} /////////////////////////////////////////////////////////////////////// // @@ -352,7 +261,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) static QTime lastTime; emit gdbOutputAvailable(_(" "), currentTime()); - emit gdbOutputAvailable(_("stdout:"), QString::fromLocal8Bit(buff)); + emit gdbOutputAvailable(_("stdout:"), QString::fromLocal8Bit(buff, buff.length())); #if 0 qDebug() // << "#### start response handling #### " @@ -510,8 +419,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) if (*inner < 'a' || *inner > 'z') break; - QByteArray resultClass(from, inner - from); - + QByteArray resultClass = QByteArray::fromRawData(from, inner - from); if (resultClass == "done") record.resultClass = GdbResultDone; else if (resultClass == "running") @@ -567,7 +475,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) } } -void GdbEngine::handleStubAttached() +void GdbEngine::handleStubAttached(const GdbResultRecord &, const QVariant &) { qq->notifyInferiorStopped(); m_waitingForBreakpointSynchronizationToContinue = true; @@ -578,7 +486,7 @@ void GdbEngine::stubStarted() { q->m_attachedPID = m_stubProc.applicationPID(); qq->notifyInferiorPidChanged(q->m_attachedPID); - sendCommand(_("attach ") + QString::number(q->m_attachedPID), GdbStubAttached); + execCommand(_("attach %1").arg(q->m_attachedPID), CB(handleStubAttached)); } void GdbEngine::stubError(const QString &msg) @@ -653,36 +561,38 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0) qq->notifyInferiorPidChanged(pid); } -void GdbEngine::sendSynchronizedCommand(const QString & command, - int type, const QVariant &cookie, StopNeeded needStop) +void GdbEngine::execCommand(const QString &command, GdbCommandCallback callback, + const char *callbackName, const QVariant &cookie) { - sendCommand(command, type, cookie, needStop, Synchronized); + execCommand(command, NoFlags, callback, callbackName, cookie); } -void GdbEngine::sendCommand(const QString &command, int type, - const QVariant &cookie, StopNeeded needStop, Synchronization synchronized) +void GdbEngine::execCommand(const QString &command, GdbCommandFlags flags, + GdbCommandCallback callback, const char *callbackName, + const QVariant &cookie) { if (m_gdbProc.state() == QProcess::NotRunning) { debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + command); return; } - if (synchronized) { + if (flags & RebuildModel) { ++m_pendingRequests; - PENDING_DEBUG(" TYPE " << type << " INCREMENTS PENDING TO: " + PENDING_DEBUG(" CALLBACK " << callbackName << " INCREMENTS PENDING TO: " << m_pendingRequests << command); } else { - PENDING_DEBUG(" UNKNOWN TYPE " << type << " LEAVES PENDING AT: " + PENDING_DEBUG(" UNKNOWN CALLBACK " << callbackName << " LEAVES PENDING AT: " << m_pendingRequests << command); } - GdbCookie cmd; - cmd.synchronized = synchronized; + GdbCommand cmd; cmd.command = command; - cmd.type = type; + cmd.flags = flags; + cmd.callback = callback; + cmd.callbackName = callbackName; cmd.cookie = cookie; - if (needStop && q->status() != DebuggerInferiorStopped + if ((flags & NeedsStop) && q->status() != DebuggerInferiorStopped && q->status() != DebuggerProcessStartingUp) { // queue the commands that we cannot send at once QTC_ASSERT(q->status() == DebuggerInferiorRunning, @@ -692,19 +602,24 @@ void GdbEngine::sendCommand(const QString &command, int type, m_commandsToRunOnTemporaryBreak.append(cmd); interruptInferior(); } else if (!command.isEmpty()) { - ++currentToken(); - m_cookieForToken[currentToken()] = cmd; - cmd.command = QString::number(currentToken()) + cmd.command; - if (cmd.command.contains(__("%1"))) - cmd.command = cmd.command.arg(currentToken()); - - m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); - //emit gdbInputAvailable(QString(), " " + currentTime()); - //emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command); - emit gdbInputAvailable(QString(), cmd.command); + flushCommand(cmd); } } +void GdbEngine::flushCommand(GdbCommand &cmd) +{ + ++currentToken(); + m_cookieForToken[currentToken()] = cmd; + cmd.command = QString::number(currentToken()) + cmd.command; + if (cmd.command.contains(__("%1"))) + cmd.command = cmd.command.arg(currentToken()); + + m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); + //emit gdbInputAvailable(QString(), " " + currentTime()); + //emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command); + emit gdbInputAvailable(QString(), cmd.command); +} + void GdbEngine::handleResultRecord(const GdbResultRecord &record) { //qDebug() << "TOKEN: " << record.token @@ -716,9 +631,9 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) if (token == -1) return; - GdbCookie cmd = m_cookieForToken.take(token); + GdbCommand cmd = m_cookieForToken.take(token); - if (record.token < m_oldestAcceptableToken && isSkippable(cmd.type)) { + if (record.token < m_oldestAcceptableToken && (cmd.flags & Discardable)) { //qDebug() << "### SKIPPING OLD RESULT " << record.toString(); //QMessageBox::information(m_mainWindow, tr("Skipped"), "xxx"); return; @@ -733,10 +648,10 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) // << "\n data: " << record.data.toString(true); - if (cmd.type != GdbInvalidCommand) - handleResult(record, cmd.type, cmd.cookie); + if (cmd.callback) + (this->*(cmd.callback))(record, cmd.cookie); - if (cmd.synchronized) { + if (cmd.flags & RebuildModel) { --m_pendingRequests; PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: " << m_pendingRequests << cmd.command); @@ -750,176 +665,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) } } -void GdbEngine::handleResult(const GdbResultRecord & record, int type, - const QVariant & cookie) -{ - switch (type) { - case GdbStubAttached: - handleStubAttached(); - break; - case GdbExecNext: - case GdbExecStep: - case GdbExecNextI: - case GdbExecStepI: - case GdbExecContinue: - case GdbExecFinish: - // evil code sharing - handleExecRun(record); - break; - - case GdbStart: - handleStart(record); - break; - case GdbAttached: - handleAttach(); - break; - case GdbInfoProc: - handleInfoProc(record); - break; - case GdbInfoThreads: - handleInfoThreads(record); - break; - case GdbExit: - handleExit(record); - break; - - case GdbShowVersion: - handleShowVersion(record); - break; - case GdbFileExecAndSymbols: - handleFileExecAndSymbols(record); - break; - case GdbExecRunToFunction: - // that should be "^running". We need to handle the resulting - // "Stopped" - //handleExecRunToFunction(record); - break; - case GdbExecInterrupt: - qq->notifyInferiorStopped(); - break; -#if 0 - case GdbExecJumpToLine: - handleExecJumpToLine(record); - break; -#endif -#if 0 - case GdbQueryPwd: - handleQueryPwd(record); - break; -#endif - case GdbQuerySources: - handleQuerySources(record); - break; - case GdbAsyncOutput2: - handleAsyncOutput2(cookie.value<GdbMi>()); - break; - case GdbInfoShared: - handleInfoShared(record); - break; - case GdbQueryDebuggingHelper: - handleQueryDebuggingHelper(record); - break; - case GdbTemporaryContinue: - continueInferior(); - q->showStatusMessage(tr("Continuing after temporary stop.")); - break; - case GdbTargetCore: - handleTargetCore(record); - break; - - case BreakList: - handleBreakList(record); - break; - case BreakInsert: - handleBreakInsert(record, cookie.toInt()); - break; - case BreakInsert1: - handleBreakInsert1(record, cookie.toInt()); - break; - case BreakInfo: - handleBreakInfo(record, cookie.toInt()); - break; - case BreakEnablePending: - case BreakDelete: - case BreakEnable: - case BreakDisable: - // nothing - break; - case BreakIgnore: - handleBreakIgnore(record, cookie.toInt()); - break; - case BreakCondition: - handleBreakCondition(record, cookie.toInt()); - break; - - case DisassemblerList: - handleDisassemblerList(record, cookie.toString()); - break; - - case ModulesList: - handleModulesList(record); - break; - - case RegisterListNames: - handleRegisterListNames(record); - break; - case RegisterListValues: - handleRegisterListValues(record); - break; - - case StackListFrames: - handleStackListFrames(record, cookie.toBool()); - break; - case StackListThreads: - handleStackListThreads(record, cookie.toInt()); - break; - case StackSelectThread: - handleStackSelectThread(record, cookie.toInt()); - break; - case StackListLocals: - handleStackListLocals(record); - break; - case StackListArguments: - handleStackListArguments(record); - break; - - case WatchVarListChildren: - handleVarListChildren(record, cookie.value<WatchData>()); - break; - case WatchVarCreate: - handleVarCreate(record, cookie.value<WatchData>()); - break; - case WatchVarAssign: - handleVarAssign(); - break; - case WatchEvaluateExpression: - handleEvaluateExpression(record, cookie.value<WatchData>()); - break; - case WatchToolTip: - handleToolTip(record, cookie.toByteArray()); - break; - case WatchDebuggingHelperValue1: - handleDebuggingHelperValue1(record, cookie.value<WatchData>()); - break; - case WatchDebuggingHelperValue2: - handleDebuggingHelperValue2(record, cookie.value<WatchData>()); - break; - - case WatchDebuggingHelperValue3: - handleDebuggingHelperValue3(record, cookie.value<WatchData>()); - break; - - case WatchDebuggingHelperSetup: - handleDebuggingHelperSetup(record); - break; - - default: - debugMessage(_("FIXME: GdbEngine::handleResult: " - "should not happen %1").arg(type)); - break; - } -} - void GdbEngine::executeDebuggerCommand(const QString &command) { if (m_gdbProc.state() == QProcess::NotRunning) { @@ -927,17 +672,11 @@ void GdbEngine::executeDebuggerCommand(const QString &command) return; } - GdbCookie cmd; - cmd.command = command; - cmd.type = -1; - - m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); + m_gdbProc.write(command.toLocal8Bit() + "\r\n"); } -void GdbEngine::handleTargetCore(const GdbResultRecord &record) +void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &) { - Q_UNUSED(record); - qq->notifyInferiorStopped(); q->showStatusMessage(tr("Core file loaded.")); @@ -951,7 +690,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record) reloadStack(); if (supportsThreads()) - sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, 0); + execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); // // Disassembler @@ -966,7 +705,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record) qq->reloadRegisters(); // Gdb-Macro based DebuggingHelpers - sendCommand(_( + execCommand(_( "define qdumpqstring\n" "set $i = 0\n" "set $l = $arg0->d->size\n" @@ -978,7 +717,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record) "end\n" )); - sendCommand(_( + execCommand(_( "define qdumpqstringlist\n" "set $i = $arg0->d->begin\n" "set $e = $arg0->d->end\n" @@ -1019,7 +758,7 @@ void GdbEngine::handleQueryPwd(const GdbResultRecord &record) } #endif -void GdbEngine::handleQuerySources(const GdbResultRecord &record) +void GdbEngine::handleQuerySources(const GdbResultRecord &record, const QVariant &) { if (record.resultClass == GdbResultDone) { QMap<QString, QString> oldShortToFull = m_shortToFullName; @@ -1046,7 +785,7 @@ void GdbEngine::handleQuerySources(const GdbResultRecord &record) } } -void GdbEngine::handleInfoThreads(const GdbResultRecord &record) +void GdbEngine::handleInfoThreads(const GdbResultRecord &record, const QVariant &) { if (record.resultClass == GdbResultDone) { // FIXME: use something more robust @@ -1059,12 +798,12 @@ void GdbEngine::handleInfoThreads(const GdbResultRecord &record) } } -void GdbEngine::handleInfoProc(const GdbResultRecord &record) +void GdbEngine::handleInfoProc(const GdbResultRecord &record, const QVariant &) { if (record.resultClass == GdbResultDone) { #if defined(Q_OS_MAC) //^done,process-id="85075" - maybeHandleInferiorPidChanged(QString::fromLatin1(record.data.findChild("process-id").data())); + maybeHandleInferiorPidChanged(_(record.data.findChild("process-id").data())); #endif #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) @@ -1077,11 +816,11 @@ void GdbEngine::handleInfoProc(const GdbResultRecord &record) } } -void GdbEngine::handleInfoShared(const GdbResultRecord &record) +void GdbEngine::handleInfoShared(const GdbResultRecord &record, const QVariant &cookie) { if (record.resultClass == GdbResultDone) { // let the modules handler do the parsing - handleModulesList(record); + handleModulesList(record, cookie); } } @@ -1112,7 +851,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record) } #endif -void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record) +void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record, const QVariant &) { // FIXME: remove this special case as soon as there's a real // reason given when the temporary breakpoint is hit. @@ -1156,13 +895,13 @@ static bool isStoppedReason(const QByteArray &reason) void GdbEngine::handleAqcuiredInferior() { #if defined(Q_OS_WIN) - sendCommand(_("info thread"), GdbInfoThreads); + execCommand(_("info thread"), CB(handleInfoThreads)); #endif #if defined(Q_OS_LINUX) - sendCommand(_("info proc"), GdbInfoProc); + execCommand(_("info proc"), CB(handleInfoProc)); #endif #if defined(Q_OS_MAC) - sendCommand(_("info pid"), GdbInfoProc, QVariant(), NeedsStop); + execCommand(_("info pid"), NeedsStop, CB(handleInfoProc)); #endif if (theDebuggerBoolSetting(ListSourceFiles)) reloadSourceFiles(); @@ -1172,18 +911,18 @@ void GdbEngine::handleAqcuiredInferior() // intentionally after tryLoadDebuggingHelpers(), // otherwise we'd interupt solib loading. if (theDebuggerBoolSetting(AllPluginBreakpoints)) { - sendCommand(_("set auto-solib-add on")); - sendCommand(_("set stop-on-solib-events 0")); - sendCommand(_("sharedlibrary .*")); + execCommand(_("set auto-solib-add on")); + execCommand(_("set stop-on-solib-events 0")); + execCommand(_("sharedlibrary .*")); } else if (theDebuggerBoolSetting(SelectedPluginBreakpoints)) { - sendCommand(_("set auto-solib-add on")); - sendCommand(_("set stop-on-solib-events 1")); - sendCommand(_("sharedlibrary ") + execCommand(_("set auto-solib-add on")); + execCommand(_("set stop-on-solib-events 1")); + execCommand(_("sharedlibrary ") + theDebuggerStringSetting(SelectedPluginBreakpointsPattern)); } else if (theDebuggerBoolSetting(NoPluginBreakpoints)) { // should be like that already - sendCommand(_("set auto-solib-add off")); - sendCommand(_("set stop-on-solib-events 0")); + execCommand(_("set auto-solib-add off")); + execCommand(_("set stop-on-solib-events 0")); } #endif @@ -1192,6 +931,12 @@ void GdbEngine::handleAqcuiredInferior() attemptBreakpointSynchronization(); } +void GdbEngine::handleAutoContinue(const GdbResultRecord &, const QVariant &) +{ + continueInferior(); + q->showStatusMessage(tr("Continuing after temporary stop.")); +} + void GdbEngine::handleAsyncOutput(const GdbMi &data) { const QByteArray &reason = data.findChild("reason").data(); @@ -1209,7 +954,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) msg = tr("Program exited normally"); } q->showStatusMessage(msg); - sendCommand(_("-gdb-exit"), GdbExit); + execCommand(_("-gdb-exit"), CB(handleExit)); return; } @@ -1238,13 +983,13 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) qq->notifyInferiorStopped(); q->showStatusMessage(tr("Temporarily stopped.")); // FIXME: racy - foreach (const GdbCookie &cmd, m_commandsToRunOnTemporaryBreak) { + while (!m_commandsToRunOnTemporaryBreak.isEmpty()) { + GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst(); debugMessage(_("RUNNING QUEUED COMMAND %1 %2") - .arg(cmd.command).arg(cmd.type)); - sendCommand(cmd.command, cmd.type, cmd.cookie); + .arg(cmd.command).arg(_(cmd.callbackName))); + flushCommand(cmd); } - sendCommand(_("p temporaryStop"), GdbTemporaryContinue); - m_commandsToRunOnTemporaryBreak.clear(); + execCommand(_("p temporaryStop"), CB(handleAutoContinue)); q->showStatusMessage(tr("Handling queued commands.")); return; } @@ -1256,7 +1001,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) debugMessage(_("SHARED LIBRARY EVENT: ") + dataStr); QString pat = theDebuggerStringSetting(SelectedPluginBreakpointsPattern); debugMessage(_("PATTERN: ") + pat); - sendCommand(_("sharedlibrary ") + pat); + execCommand(_("sharedlibrary ") + pat); continueInferior(); q->showStatusMessage(tr("Loading %1...").arg(dataStr)); return; @@ -1324,9 +1069,9 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) QApplication::alert(q->mainWindow(), 3000); if (theDebuggerAction(ListSourceFiles)->value().toBool()) reloadSourceFiles(); - sendCommand(_("-break-list"), BreakList); + execCommand(_("-break-list"), CB(handleBreakList)); QVariant var = QVariant::fromValue<GdbMi>(data); - sendCommand(_("p 0"), GdbAsyncOutput2, var); // dummy + execCommand(_("p 0"), CB(handleAsyncOutput2), var); // dummy } else { #ifdef Q_OS_LINUX // For some reason, attaching to a stopped process causes *two* stops @@ -1337,7 +1082,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) GdbMi frameData = data.findChild("frame"); if (frameData.findChild("func").data() == "_start" && frameData.findChild("from").data() == "/lib/ld-linux.so.2") { - sendCommand(_("-exec-continue")); + execCommand(_("-exec-continue")); return; } } @@ -1377,7 +1122,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) void GdbEngine::reloadFullStack() { QString cmd = _("-stack-list-frames"); - sendSynchronizedCommand(cmd, StackListFrames, true); + execCommand(cmd, WatchUpdate, CB(handleStackListFrames), true); } void GdbEngine::reloadStack() @@ -1385,7 +1130,12 @@ void GdbEngine::reloadStack() QString cmd = _("-stack-list-frames"); if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt()) cmd += _(" 0 ") + QString::number(stackDepth); - sendSynchronizedCommand(cmd, StackListFrames, false); + execCommand(cmd, WatchUpdate, CB(handleStackListFrames), false); +} + +void GdbEngine::handleAsyncOutput2(const GdbResultRecord &, const QVariant &cookie) +{ + handleAsyncOutput2(cookie.value<GdbMi>()); } void GdbEngine::handleAsyncOutput2(const GdbMi &data) @@ -1401,7 +1151,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data) int currentId = data.findChild("thread-id").data().toInt(); reloadStack(); if (supportsThreads()) - sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, currentId); + execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), currentId); // // Disassembler @@ -1421,7 +1171,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data) qq->reloadRegisters(); } -void GdbEngine::handleShowVersion(const GdbResultRecord &response) +void GdbEngine::handleShowVersion(const GdbResultRecord &response, const QVariant &) { //qDebug () << "VERSION 2:" << response.data.findChild("consolestreamoutput").data(); //qDebug () << "VERSION:" << response.toString(); @@ -1460,8 +1210,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response) } } -void GdbEngine::handleFileExecAndSymbols - (const GdbResultRecord &response) +void GdbEngine::handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &) { if (response.resultClass == GdbResultDone) { //m_breakHandler->clearBreakMarkers(); @@ -1474,7 +1223,7 @@ void GdbEngine::handleFileExecAndSymbols } } -void GdbEngine::handleExecRun(const GdbResultRecord &response) +void GdbEngine::handleExecRun(const GdbResultRecord &response, const QVariant &) { if (response.resultClass == GdbResultRunning) { qq->notifyInferiorRunning(); @@ -1564,11 +1313,11 @@ void GdbEngine::exitDebugger() qDebug() << "STATUS ON EXITDEBUGGER: " << q->status()); interruptInferior(); } - if (q->startMode() == AttachExternal) - sendCommand(_("detach")); + if (q->startMode() == AttachExternal || q->startMode() == AttachRemote) + execCommand(_("detach")); else - sendCommand(_("kill")); - sendCommand(_("-gdb-exit"), GdbExit); + execCommand(_("kill")); + execCommand(_("-gdb-exit"), CB(handleExit)); // 20s can easily happen when loading webkit debug information m_gdbProc.waitForFinished(20000); if (m_gdbProc.state() != QProcess::Running) { @@ -1657,25 +1406,25 @@ bool GdbEngine::startDebugger() q->showStatusMessage(tr("Gdb Running...")); - sendCommand(_("show version"), GdbShowVersion); - //sendCommand(_("-enable-timings"); - sendCommand(_("set print static-members off")); // Seemingly doesn't work. - //sendCommand(_("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend")); - //sendCommand(_("define hook-stop\nprint 4\nend")); - //sendCommand(_("define hookpost-stop\nprint 5\nend")); - //sendCommand(_("define hook-call\nprint 6\nend")); - //sendCommand(_("define hookpost-call\nprint 7\nend")); - //sendCommand(_("set print object on")); // works with CLI, but not MI - //sendCommand(_("set step-mode on")); // we can't work with that yes - //sendCommand(_("set exec-done-display on")); - //sendCommand(_("set print pretty on")); - //sendCommand(_("set confirm off")); - //sendCommand(_("set pagination off")); - sendCommand(_("set breakpoint pending on"), BreakEnablePending); - sendCommand(_("set print elements 10000")); - sendCommand(_("-data-list-register-names"), RegisterListNames); - - //sendCommand(_("set substitute-path /var/tmp/qt-x11-src-4.5.0 " + execCommand(_("show version"), CB(handleShowVersion)); + //execCommand(_("-enable-timings"); + execCommand(_("set print static-members off")); // Seemingly doesn't work. + //execCommand(_("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend")); + //execCommand(_("define hook-stop\nprint 4\nend")); + //execCommand(_("define hookpost-stop\nprint 5\nend")); + //execCommand(_("define hook-call\nprint 6\nend")); + //execCommand(_("define hookpost-call\nprint 7\nend")); + //execCommand(_("set print object on")); // works with CLI, but not MI + //execCommand(_("set step-mode on")); // we can't work with that yes + //execCommand(_("set exec-done-display on")); + //execCommand(_("set print pretty on")); + //execCommand(_("set confirm off")); + //execCommand(_("set pagination off")); + execCommand(_("set breakpoint pending on")); + execCommand(_("set print elements 10000")); + execCommand(_("-data-list-register-names"), CB(handleRegisterListNames)); + + //execCommand(_("set substitute-path /var/tmp/qt-x11-src-4.5.0 " // "/home/sandbox/qtsdk-2009.01/qt")); // one of the following is needed to prevent crashes in gdb on code like: @@ -1683,8 +1432,8 @@ bool GdbEngine::startDebugger() // int main() { return foo<int>(); } // (gdb) call 'int foo<int>'() // /build/buildd/gdb-6.8/gdb/valops.c:2069: internal-error: - sendCommand(_("set overload-resolution off")); - //sendCommand(_("set demangle-style none")); + execCommand(_("set overload-resolution off")); + //execCommand(_("set demangle-style none")); // From the docs: // Stop means reenter debugger if this signal happens (implies print). @@ -1695,19 +1444,19 @@ bool GdbEngine::startDebugger() // We need "print" as otherwise we would get no feedback whatsoever // Custom DebuggingHelper crashs which happen regularily for when accessing // uninitialized variables. - sendCommand(_("handle SIGSEGV nopass stop print")); + execCommand(_("handle SIGSEGV nopass stop print")); // This is useful to kill the inferior whenever gdb dies. - //sendCommand(_("handle SIGTERM pass nostop print")); + //execCommand(_("handle SIGTERM pass nostop print")); - sendCommand(_("set unwindonsignal on")); - //sendCommand(_("pwd", GdbQueryPwd)); - sendCommand(_("set width 0")); - sendCommand(_("set height 0")); + execCommand(_("set unwindonsignal on")); + //execCommand(_("pwd", handleQueryPwd)); + execCommand(_("set width 0")); + execCommand(_("set height 0")); #ifdef Q_OS_MAC - sendCommand(_("-gdb-set inferior-auto-start-cfm off")); - sendCommand(_("-gdb-set sharedLibrary load-rules " + execCommand(_("-gdb-set inferior-auto-start-cfm off")); + execCommand(_("-gdb-set sharedLibrary load-rules " "dyld \".*libSystem.*\" all " "dyld \".*libauto.*\" all " "dyld \".*AppKit.*\" all " @@ -1722,7 +1471,7 @@ bool GdbEngine::startDebugger() if (!scriptFileName.isEmpty()) { QFile scriptFile(scriptFileName); if (scriptFile.open(QIODevice::ReadOnly)) { - sendCommand(_("source ") + scriptFileName); + execCommand(_("source ") + scriptFileName); } else { QMessageBox::warning(q->mainWindow(), tr("Cannot find debugger initialization script"), @@ -1734,7 +1483,7 @@ bool GdbEngine::startDebugger() } if (q->startMode() == AttachExternal) { - sendCommand(_("attach ") + QString::number(q->m_attachedPID), GdbAttached); + execCommand(_("attach %1").arg(q->m_attachedPID), CB(handleAttach)); qq->breakHandler()->removeAllBreakpoints(); } else if (q->startMode() == AttachCore) { QFileInfo fi(q->m_executable); @@ -1742,37 +1491,39 @@ bool GdbEngine::startDebugger() QFileInfo fi2(q->m_coreFile); // quoting core name below fails in gdb 6.8-debian QString coreName = fi2.absoluteFilePath(); - sendCommand(_("-file-exec-and-symbols ") + fileName); - sendCommand(_("target core %1").arg(coreName), GdbTargetCore); + execCommand(_("-file-exec-and-symbols ") + fileName); + execCommand(_("target core ") + coreName, CB(handleTargetCore)); qq->breakHandler()->removeAllBreakpoints(); } else if (q->startMode() == AttachRemote) { - sendCommand(_("set architecture %1").arg(q->m_remoteArchitecture)); - sendCommand(_("target remote %1").arg(q->m_remoteChannel)); + execCommand(_("set architecture %1").arg(q->m_remoteArchitecture)); qq->breakHandler()->setAllPending(); - //sendCommand(_("info target"), GdbStart); - qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-continue"), GdbExecContinue); + //QFileInfo fi(q->m_executable); + //QString fileName = fi.absoluteFileName(); + QString fileName = q->m_executable; + execCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName)); + // works only for > 6.8 + execCommand(_("set target-async on"), CB(handleTargetAsync)); } else if (q->m_useTerminal) { qq->breakHandler()->setAllPending(); } else if (q->startMode() == StartInternal || q->startMode() == StartExternal) { QFileInfo fi(q->m_executable); QString fileName = _c('"') + fi.absoluteFilePath() + _c('"'); - sendCommand(_("-file-exec-and-symbols ") + fileName, GdbFileExecAndSymbols); - //sendCommand(_("file ") + fileName, GdbFileExecAndSymbols); + execCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols)); + //execCommand(_("file ") + fileName, handleFileExecAndSymbols); #ifdef Q_OS_MAC - sendCommand(_("sharedlibrary apply-load-rules all")); + execCommand(_("sharedlibrary apply-load-rules all")); #endif if (!q->m_processArgs.isEmpty()) - sendCommand(_("-exec-arguments ") + q->m_processArgs.join(_(" "))); + execCommand(_("-exec-arguments ") + q->m_processArgs.join(_(" "))); #ifndef Q_OS_MAC - sendCommand(_("set auto-solib-add off")); - sendCommand(_("info target"), GdbStart); + execCommand(_("set auto-solib-add off")); + execCommand(_("info target"), CB(handleStart)); #else // On MacOS, breaking in at the entry point wreaks havoc. - sendCommand(_("tbreak main")); + execCommand(_("tbreak main")); m_waitingForFirstBreakpointToBeHit = true; qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-run")); + execCommand(_("-exec-run")); #endif qq->breakHandler()->setAllPending(); } @@ -1785,10 +1536,10 @@ void GdbEngine::continueInferior() q->resetLocation(); setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-continue"), GdbExecContinue); + execCommand(_("-exec-continue"), CB(handleExecRun)); } -void GdbEngine::handleStart(const GdbResultRecord &response) +void GdbEngine::handleStart(const GdbResultRecord &response, const QVariant &) { #ifdef Q_OS_MAC Q_UNUSED(response); @@ -1801,10 +1552,10 @@ void GdbEngine::handleStart(const GdbResultRecord &response) QRegExp needle(_("\\bEntry point: (0x[0-9a-f]+)\\b")); if (needle.indexIn(msg) != -1) { //debugMessage("STREAM: " + msg + " " + needle.cap(1)); - sendCommand(_("tbreak *") + needle.cap(1)); + execCommand(_("tbreak *") + needle.cap(1)); m_waitingForFirstBreakpointToBeHit = true; qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-run")); + execCommand(_("-exec-run")); } else { debugMessage(_("PARSING START ADDRESS FAILED: ") + msg); } @@ -1814,7 +1565,7 @@ void GdbEngine::handleStart(const GdbResultRecord &response) #endif } -void GdbEngine::handleAttach() +void GdbEngine::handleAttach(const GdbResultRecord &, const QVariant &) { qq->notifyInferiorStopped(); q->showStatusMessage(tr("Attached to running process. Stopped.")); @@ -1831,7 +1582,7 @@ void GdbEngine::handleAttach() reloadStack(); if (supportsThreads()) - sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, 0); + execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); // // Disassembler @@ -1846,9 +1597,24 @@ void GdbEngine::handleAttach() qq->reloadRegisters(); } -void GdbEngine::handleExit(const GdbResultRecord &response) +void GdbEngine::handleTargetAsync(const GdbResultRecord &record, const QVariant &) +{ + if (record.resultClass == GdbResultDone) { + //execCommand(_("info target"), handleStart); + qq->notifyInferiorRunningRequested(); + execCommand(_("target remote %1").arg(q->m_remoteChannel)); + execCommand(_("-exec-continue"), CB(handleExecRun)); + } else if (record.resultClass == GdbResultError) { + // a typical response on "old" gdb is: + // &"set target-async on\n" + //&"No symbol table is loaded. Use the \"file\" command.\n" + //^error,msg="No symbol table is loaded. Use the \"file\" command." + execCommand(_("detach")); + execCommand(_("-gdb-exit"), CB(handleExit)); + } +} +void GdbEngine::handleExit(const GdbResultRecord &, const QVariant &) { - Q_UNUSED(response); q->showStatusMessage(tr("Debugger exited.")); } @@ -1856,50 +1622,53 @@ void GdbEngine::stepExec() { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-step"), GdbExecStep); + execCommand(_("-exec-step"), CB(handleExecRun)); } void GdbEngine::stepIExec() { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-step-instruction"), GdbExecStepI); + execCommand(_("-exec-step-instruction"), CB(handleExecRun)); } void GdbEngine::stepOutExec() { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-finish"), GdbExecFinish); + execCommand(_("-exec-finish"), CB(handleExecRun)); } void GdbEngine::nextExec() { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-next"), GdbExecNext); + execCommand(_("-exec-next"), CB(handleExecRun)); } void GdbEngine::nextIExec() { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-next-instruction"), GdbExecNextI); + execCommand(_("-exec-next-instruction"), CB(handleExecRun)); } void GdbEngine::runToLineExec(const QString &fileName, int lineNumber) { setTokenBarrier(); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-until ") + fileName + _c(':') + QString::number(lineNumber)); + execCommand(_("-exec-until %1:%2").arg(fileName).arg(lineNumber)); } void GdbEngine::runToFunctionExec(const QString &functionName) { setTokenBarrier(); - sendCommand(_("-break-insert -t ") + functionName); + execCommand(_("-break-insert -t ") + functionName); qq->notifyInferiorRunningRequested(); - sendCommand(_("-exec-continue"), GdbExecRunToFunction); + // that should be "^running". We need to handle the resulting + // "Stopped" + execCommand(_("-exec-continue")); + //execCommand(_("-exec-continue"), handleExecRunToFunction); } void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber) @@ -1907,8 +1676,8 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber) #if 1 // not available everywhere? //sendCliCommand(_("tbreak ") + fileName + ':' + QString::number(lineNumber)); - sendCommand(_("-break-insert -t ") + fileName + _c(':') + QString::number(lineNumber)); - sendCommand(_("jump ") + fileName + _c(':') + QString::number(lineNumber)); + execCommand(_("-break-insert -t ") + fileName + _c(':') + QString::number(lineNumber)); + execCommand(_("jump ") + fileName + _c(':') + QString::number(lineNumber)); // will produce something like // &"jump /home/apoenitz/dev/work/test1/test1.cpp:242" // ~"Continuing at 0x4058f3." @@ -1917,11 +1686,11 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber) // 23^done" q->gotoLocation(fileName, lineNumber, true); //setBreakpoint(); - //sendCommand(_("jump ") + fileName + ':' + QString::number(lineNumber)); + //execCommand(_("jump ") + fileName + ':' + QString::number(lineNumber)); #else q->gotoLocation(fileName, lineNumber, true); setBreakpoint(fileName, lineNumber); - sendCommand(_("jump ") + fileName + ':' + QString::number(lineNumber)); + execCommand(_("jump ") + fileName + ':' + QString::number(lineNumber)); #endif } @@ -1937,18 +1706,9 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber) void GdbEngine::setTokenBarrier() { - foreach (const GdbCookie &cookie, m_cookieForToken) { - QTC_ASSERT( - cookie.synchronized - || cookie.type == GdbInvalidCommand - // FIXME: use something like "command classes" for these cases: - || cookie.type == GdbInfoProc - || cookie.type == GdbStubAttached - || cookie.type == ModulesList - || cookie.type == WatchDebuggingHelperSetup - || cookie.type == GdbQueryDebuggingHelper, - qDebug() << "CMD: " << cookie.command << "TYPE: " << cookie.type - << "SYNC: " << cookie.synchronized; + foreach (const GdbCommand &cookie, m_cookieForToken) { + QTC_ASSERT(!cookie.callback || (cookie.flags & Discardable), + qDebug() << "CMD: " << cookie.command << "CALLBACK: " << cookie.callbackName; return ); } @@ -1961,12 +1721,12 @@ void GdbEngine::setDebugDebuggingHelpers(const QVariant &on) { if (on.toBool()) { debugMessage(_("SWITCHING ON DUMPER DEBUGGING")); - sendCommand(_("set unwindonsignal off")); + execCommand(_("set unwindonsignal off")); q->breakByFunction(_("qDumpObjectData440")); //updateLocals(); } else { debugMessage(_("SWITCHING OFF DUMPER DEBUGGING")); - sendCommand(_("set unwindonsignal on")); + execCommand(_("set unwindonsignal on")); } } @@ -2092,10 +1852,10 @@ void GdbEngine::sendInsertBreakpoint(int index) cmd += where; #endif debugMessage(_("Current state: %1").arg(q->status())); - sendCommand(cmd, BreakInsert, index, NeedsStop); + execCommand(cmd, NeedsStop, CB(handleBreakInsert), index); } -void GdbEngine::handleBreakList(const GdbResultRecord &record) +void GdbEngine::handleBreakList(const GdbResultRecord &record, const QVariant &) { // 45^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[ // {width="3",alignment="-1",col_name="number",colhdr="Num"}, ... @@ -2155,8 +1915,9 @@ void GdbEngine::handleBreakList(const GdbMi &table) } -void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, int index) +void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, const QVariant &cookie) { + int index = cookie.toInt(); // gdb 6.8: // ignore 2 0: // ~"Will stop next time breakpoint 2 is reached.\n" @@ -2183,8 +1944,9 @@ void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, int index) } } -void GdbEngine::handleBreakCondition(const GdbResultRecord &record, int index) +void GdbEngine::handleBreakCondition(const GdbResultRecord &record, const QVariant &cookie) { + int index = cookie.toInt(); BreakHandler *handler = qq->breakHandler(); if (record.resultClass == GdbResultDone) { // we just assume it was successful. otherwise we had to parse @@ -2208,8 +1970,9 @@ void GdbEngine::handleBreakCondition(const GdbResultRecord &record, int index) } } -void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index) +void GdbEngine::handleBreakInsert(const GdbResultRecord &record, const QVariant &cookie) { + int index = cookie.toInt(); BreakHandler *handler = qq->breakHandler(); if (record.resultClass == GdbResultDone) { //qDebug() << "HANDLE BREAK INSERT " << index; @@ -2231,21 +1994,19 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index) + data->lineNumber; // Should not happen with -break-insert -f. gdb older than 6.8? QTC_ASSERT(false, /**/); - sendCommand(_("break ") + where, BreakInsert1, index); #endif #ifdef Q_OS_MAC QFileInfo fi(data->fileName); QString where = _c('"') + fi.fileName() + _("\":") + data->lineNumber; - sendCommand(_("break ") + where, BreakInsert1, index); #endif #ifdef Q_OS_WIN QFileInfo fi(data->fileName); QString where = _c('"') + fi.fileName() + _("\":") + data->lineNumber; //QString where = m_data->fileName + _c(':') + data->lineNumber; - sendCommand(_("break ") + where, BreakInsert1, index); #endif + execCommand(_("break ") + where, CB(handleBreakInsert1), index); } } @@ -2294,8 +2055,9 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData * } } -void GdbEngine::handleBreakInfo(const GdbResultRecord &record, int bpNumber) +void GdbEngine::handleBreakInfo(const GdbResultRecord &record, const QVariant &cookie) { + int bpNumber = cookie.toInt(); BreakHandler *handler = qq->breakHandler(); if (record.resultClass == GdbResultDone) { // Old-style output for multiple breakpoints, presumably in a @@ -2310,8 +2072,9 @@ void GdbEngine::handleBreakInfo(const GdbResultRecord &record, int bpNumber) } } -void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, int index) +void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, const QVariant &cookie) { + int index = cookie.toInt(); BreakHandler *handler = qq->breakHandler(); if (record.resultClass == GdbResultDone) { // Pending breakpoints in dylibs on Mac only? @@ -2341,15 +2104,13 @@ void GdbEngine::attemptBreakpointSynchronization() foreach (BreakpointData *data, handler->takeDisabledBreakpoints()) { QString bpNumber = data->bpNumber; if (!bpNumber.trimmed().isEmpty()) - sendCommand(_("-break-disable ") + bpNumber, BreakDisable, QVariant(), - NeedsStop); + execCommand(_("-break-disable ") + bpNumber, NeedsStop); } foreach (BreakpointData *data, handler->takeEnabledBreakpoints()) { QString bpNumber = data->bpNumber; if (!bpNumber.trimmed().isEmpty()) - sendCommand(_("-break-enable ") + bpNumber, BreakEnable, QVariant(), - NeedsStop); + execCommand(_("-break-enable ") + bpNumber, NeedsStop); } foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) { @@ -2357,8 +2118,7 @@ void GdbEngine::attemptBreakpointSynchronization() debugMessage(_("DELETING BP %1 IN %2").arg(bpNumber) .arg(data->markerFileName)); if (!bpNumber.trimmed().isEmpty()) - sendCommand(_("-break-delete ") + bpNumber, BreakDelete, QVariant(), - NeedsStop); + execCommand(_("-break-delete ") + bpNumber, NeedsStop); delete data; } @@ -2368,8 +2128,8 @@ void GdbEngine::attemptBreakpointSynchronization() BreakpointData *data = handler->at(index); // multiple breakpoints? if (data->bpMultiple && data->bpFileName.isEmpty()) { - sendCommand(_("info break %1").arg(data->bpNumber), - BreakInfo, data->bpNumber.toInt()); + execCommand(_("info break %1").arg(data->bpNumber), + CB(handleBreakInfo), data->bpNumber.toInt()); updateNeeded = true; break; } @@ -2393,8 +2153,8 @@ void GdbEngine::attemptBreakpointSynchronization() // update conditions if needed if (data->bpNumber.toInt() && data->condition != data->bpCondition && !data->conditionsMatch()) { - sendCommand(_("condition %1 %2").arg(data->bpNumber) - .arg(data->condition), BreakCondition, index); + execCommand(_("condition %1 %2").arg(data->bpNumber).arg(data->condition), + CB(handleBreakCondition), index); //qDebug() << "UPDATE NEEDED BECAUSE OF CONDITION" // << data->condition << data->bpCondition; updateNeeded = true; @@ -2402,8 +2162,8 @@ void GdbEngine::attemptBreakpointSynchronization() } // update ignorecount if needed if (data->bpNumber.toInt() && data->ignoreCount != data->bpIgnoreCount) { - sendCommand(_("ignore %1 %2").arg(data->bpNumber) - .arg(data->ignoreCount), BreakIgnore, index); + execCommand(_("ignore %1 %2").arg(data->bpNumber).arg(data->ignoreCount), + CB(handleBreakIgnore), index); updateNeeded = true; break; } @@ -2437,12 +2197,13 @@ void GdbEngine::attemptBreakpointSynchronization() void GdbEngine::reloadDisassembler() { - emit sendCommand(_("disassemble"), DisassemblerList, m_address); + emit execCommand(_("disassemble"), CB(handleDisassemblerList), m_address); } void GdbEngine::handleDisassemblerList(const GdbResultRecord &record, - const QString &cookie) + const QVariant &cookie) { + QString listedLine = cookie.toString(); QList<DisassemblerLine> lines; static const QString pad = _(" "); int currentLine = -1; @@ -2474,7 +2235,7 @@ void GdbEngine::handleDisassemblerList(const GdbResultRecord &record, line.addressDisplay.replace(2, 8, QString()); line.symbolDisplay = line.symbol + pad; - if (line.address == cookie) + if (line.address == listedLine) currentLine = lines.size(); lines.append(line); @@ -2500,13 +2261,13 @@ void GdbEngine::handleDisassemblerList(const GdbResultRecord &record, void GdbEngine::loadSymbols(const QString &moduleName) { // FIXME: gdb does not understand quoted names here (tested with 6.8) - sendCommand(_("sharedlibrary ") + dotEscape(moduleName)); + execCommand(_("sharedlibrary ") + dotEscape(moduleName)); reloadModules(); } void GdbEngine::loadAllSymbols() { - sendCommand(_("sharedlibrary .*")); + execCommand(_("sharedlibrary .*")); reloadModules(); } @@ -2546,10 +2307,10 @@ QList<Symbol> GdbEngine::moduleSymbols(const QString &moduleName) void GdbEngine::reloadModules() { - sendCommand(_("info shared"), ModulesList, QVariant()); + execCommand(_("info shared"), CB(handleModulesList)); } -void GdbEngine::handleModulesList(const GdbResultRecord &record) +void GdbEngine::handleModulesList(const GdbResultRecord &record, const QVariant &) { QList<Module> modules; if (record.resultClass == GdbResultDone) { @@ -2598,7 +2359,7 @@ void GdbEngine::handleModulesList(const GdbResultRecord &record) void GdbEngine::reloadSourceFiles() { - sendCommand(_("-file-list-exec-source-files"), GdbQuerySources); + execCommand(_("-file-list-exec-source-files"), CB(handleQuerySources)); } @@ -2608,17 +2369,17 @@ void GdbEngine::reloadSourceFiles() // ////////////////////////////////////////////////////////////////////// -void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int) +void GdbEngine::handleStackSelectThread(const GdbResultRecord &, const QVariant &) { - Q_UNUSED(record); //qDebug("FIXME: StackHandler::handleOutput: SelectThread"); q->showStatusMessage(tr("Retrieving data for stack view..."), 3000); reloadStack(); } -void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull) +void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie) { + bool isFull = cookie.toBool(); QList<StackFrame> stackFrames; const GdbMi stack = record.data.findChild("stack"); @@ -2650,13 +2411,13 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull const bool isBogus = // Assume this is wrong and points to some strange stl_algobase // implementation. Happens on Karsten's XP system with Gdb 5.50 - (frame.file.endsWith(_("/bits/stl_algobase.h")) && frame.line == 150) + (frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150) // Also wrong. Happens on Vista with Gdb 5.50 - || (frame.function == _("operator new") && frame.line == 151); + || (frame.function == __("operator new") && frame.line == 151); // immediately leave bogus frames if (topFrame == -1 && isBogus) { - sendCommand(_("-exec-finish")); + execCommand(_("-exec-finish")); return; } @@ -2695,8 +2456,7 @@ void GdbEngine::selectThread(int index) QTC_ASSERT(index < threads.size(), return); int id = threads.at(index).id; q->showStatusMessage(tr("Retrieving data for stack view..."), 10000); - sendCommand(_("-thread-select ") + QString::number(id), - StackSelectThread); + execCommand(_("-thread-select %1").arg(id), CB(handleStackSelectThread)); } void GdbEngine::activateFrame(int frameIndex) @@ -2721,7 +2481,7 @@ void GdbEngine::activateFrame(int frameIndex) // Assuming this always succeeds saves a roundtrip. // Otherwise the lines below would need to get triggered // after a response to this -stack-select-frame here. - sendCommand(_("-stack-select-frame ") + QString::number(frameIndex)); + execCommand(_("-stack-select-frame ") + QString::number(frameIndex)); stackHandler->setCurrentIndex(frameIndex); updateLocals(); @@ -2735,8 +2495,9 @@ void GdbEngine::activateFrame(int frameIndex) qDebug() << "FULL NAME NOT USABLE: " << frame.file; } -void GdbEngine::handleStackListThreads(const GdbResultRecord &record, int id) +void GdbEngine::handleStackListThreads(const GdbResultRecord &record, const QVariant &cookie) { + int id = cookie.toInt(); // "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"} const QList<GdbMi> items = record.data.findChild("thread-ids").children(); QList<ThreadData> threads; @@ -2783,10 +2544,11 @@ static inline char registerFormatChar() void GdbEngine::reloadRegisters() { - sendCommand(_("-data-list-register-values ") + _c(registerFormatChar()), RegisterListValues); + execCommand(_("-data-list-register-values ") + _c(registerFormatChar()), + Discardable, CB(handleRegisterListValues)); } -void GdbEngine::handleRegisterListNames(const GdbResultRecord &record) +void GdbEngine::handleRegisterListNames(const GdbResultRecord &record, const QVariant &) { if (record.resultClass != GdbResultDone) return; @@ -2798,7 +2560,7 @@ void GdbEngine::handleRegisterListNames(const GdbResultRecord &record) qq->registerHandler()->setRegisters(registers); } -void GdbEngine::handleRegisterListValues(const GdbResultRecord &record) +void GdbEngine::handleRegisterListValues(const GdbResultRecord &record, const QVariant &) { if (record.resultClass != GdbResultDone) return; @@ -3058,7 +2820,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre QVariant var; var.setValue(data); - sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var); + execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3), var); q->showStatusMessage( tr("Retrieving data for watch view (%1 requests pending)...") @@ -3100,25 +2862,26 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) QVariant var; var.setValue(data); - sendSynchronizedCommand(cmd, WatchDebuggingHelperValue1, var); + execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue1), var); q->showStatusMessage( tr("Retrieving data for watch view (%1 requests pending)...") .arg(m_pendingRequests + 1), 10000); // retrieve response - sendSynchronizedCommand(_("p (char*)&qDumpOutBuffer"), WatchDebuggingHelperValue2, var); + execCommand(_("p (char*)&qDumpOutBuffer"), WatchUpdate, + CB(handleDebuggingHelperValue2), var); } void GdbEngine::createGdbVariable(const WatchData &data) { - sendSynchronizedCommand(_("-var-delete \"") + data.iname + _c('"')); + execCommand(_("-var-delete \"%1\"").arg(data.iname), WatchUpdate); QString exp = data.exp; if (exp.isEmpty() && data.addr.startsWith(__("0x"))) exp = _("*(") + gdbQuoteTypes(data.type) + _("*)") + data.addr; QVariant val = QVariant::fromValue<WatchData>(data); - sendSynchronizedCommand(_("-var-create \"") + data.iname + _("\" * \"") - + exp + _c('"'), WatchVarCreate, val); + execCommand(_("-var-create \"%1\" * \"%2\"").arg(data.iname).arg(exp), + WatchUpdate, CB(handleVarCreate), val); } void GdbEngine::updateSubItem(const WatchData &data0) @@ -3212,7 +2975,7 @@ void GdbEngine::updateSubItem(const WatchData &data0) qDebug() << "UPDATE SUBITEM: VALUE"; #endif QString cmd = _("-var-evaluate-expression \"") + data.iname + _c('"'); - sendSynchronizedCommand(cmd, WatchEvaluateExpression, + execCommand(cmd, WatchUpdate, CB(handleEvaluateExpression), QVariant::fromValue(data)); return; } @@ -3238,7 +3001,7 @@ void GdbEngine::updateSubItem(const WatchData &data0) if (data.isChildrenNeeded()) { QTC_ASSERT(!data.variable.isEmpty(), return); // tested above QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); - sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data)); + execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data)); return; } @@ -3263,7 +3026,7 @@ void GdbEngine::updateSubItem(const WatchData &data0) if (data.isChildCountNeeded()) { QTC_ASSERT(!data.variable.isEmpty(), return); // tested above QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); - sendCommand(cmd, WatchVarListChildren, QVariant::fromValue(data)); + execCommand(cmd, Discardable, CB(handleVarListChildren), QVariant::fromValue(data)); return; } @@ -3327,7 +3090,7 @@ void GdbEngine::updateWatchModel2() } } -void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record) +void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const QVariant &) { m_dumperHelper.clear(); //qDebug() << "DATA DUMPER TRIAL:" << record.toString(); @@ -3397,10 +3160,10 @@ void GdbEngine::sendWatchParameters(const QByteArray ¶ms0) } encoded[encoded.size() - 1] = '}'; - sendCommand(_(encoded)); + execCommand(_(encoded)); } -void GdbEngine::handleVarAssign() +void GdbEngine::handleVarAssign(const GdbResultRecord &, const QVariant &) { // everything might have changed, force re-evaluation // FIXME: Speed this up by re-using variables and only @@ -3422,9 +3185,9 @@ void GdbEngine::setWatchDataType(WatchData &data, const GdbMi &mi) } void GdbEngine::handleVarCreate(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); // happens e.g. when we already issued a var-evaluate command if (!data.isValid()) return; @@ -3463,9 +3226,9 @@ void GdbEngine::handleVarCreate(const GdbResultRecord &record, } void GdbEngine::handleEvaluateExpression(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); QTC_ASSERT(data.isValid(), qDebug() << "HUH?"); if (record.resultClass == GdbResultDone) { //if (col == 0) @@ -3480,7 +3243,7 @@ void GdbEngine::handleEvaluateExpression(const GdbResultRecord &record, //updateWatchModel2(); } -void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record) +void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record, const QVariant &) { //qDebug() << "CUSTOM SETUP RESULT: " << record.toString(); if (record.resultClass == GdbResultDone) { @@ -3492,9 +3255,9 @@ void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record) } void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); QTC_ASSERT(data.isValid(), return); if (record.resultClass == GdbResultDone) { // ignore this case, data will follow @@ -3510,7 +3273,7 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record, && msg.startsWith(__("The program being debugged stopped while")) && msg.contains(__("qDumpObjectData440"))) { // Fake full stop - sendCommand(_("p 0"), GdbAsyncOutput2); // dummy + execCommand(_("p 0"), CB(handleAsyncOutput2)); // dummy return; } #endif @@ -3524,9 +3287,9 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record, } void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); QTC_ASSERT(data.isValid(), return); //qDebug() << "CUSTOM VALUE RESULT: " << record.toString(); //qDebug() << "FOR DATA: " << data.toString() << record.resultClass; @@ -3623,9 +3386,9 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record, } void GdbEngine::handleDebuggingHelperValue3(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); QByteArray out = record.data.findChild("consolestreamoutput").data(); while (out.endsWith(' ') || out.endsWith('\n')) out.chop(1); @@ -3665,7 +3428,7 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResultRecord &record, QString cmd = _("qdumpqstring (") + data1.exp + _c(')'); QVariant var; var.setValue(data1); - sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var); + execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3), var); } } else { //: Value for variable @@ -3687,12 +3450,13 @@ void GdbEngine::updateLocals() QString level = QString::number(currentFrame()); // '2' is 'list with type and value' QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level; - sendSynchronizedCommand(cmd, StackListArguments); // stage 1/2 + execCommand(cmd, WatchUpdate, CB(handleStackListArguments)); // '2' is 'list with type and value' - sendSynchronizedCommand(_("-stack-list-locals 2"), StackListLocals); // stage 2/2 + execCommand(_("-stack-list-locals 2"), WatchUpdate, + CB(handleStackListLocals)); // stage 2/2 } -void GdbEngine::handleStackListArguments(const GdbResultRecord &record) +void GdbEngine::handleStackListArguments(const GdbResultRecord &record, const QVariant &) { // stage 1/2 @@ -3726,7 +3490,7 @@ void GdbEngine::handleStackListArguments(const GdbResultRecord &record) } } -void GdbEngine::handleStackListLocals(const GdbResultRecord &record) +void GdbEngine::handleStackListLocals(const GdbResultRecord &record, const QVariant &) { // stage 2/2 @@ -3868,7 +3632,7 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item, //qDebug() << "DATA" << data.toString(); QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); //iname += '.' + exp; - sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data)); + execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data)); } else if (item.findChild("numchild").data() == "0") { // happens for structs without data, e.g. interfaces. WatchData data; @@ -3886,7 +3650,7 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item, WatchData data; data.iname = _(name); QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); - sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data)); + execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data)); } else if (exp == "staticMetaObject") { // && item.findChild("type").data() == "const QMetaObject") // FIXME: Namespaces? @@ -3949,10 +3713,10 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item, } void GdbEngine::handleVarListChildren(const GdbResultRecord &record, - const WatchData &data0) + const QVariant &cookie) { //WatchResultCounter dummy(this, WatchVarListChildren); - WatchData data = data0; + WatchData data = cookie.value<WatchData>(); if (!data.isValid()) return; if (record.resultClass == GdbResultDone) { @@ -3989,13 +3753,15 @@ void GdbEngine::handleVarListChildren(const GdbResultRecord &record, } void GdbEngine::handleToolTip(const GdbResultRecord &record, - const QByteArray &what) + const QVariant &cookie) { + const QByteArray &what = cookie.toByteArray(); //qDebug() << "HANDLE TOOLTIP: " << what << m_toolTip.toString(); // << "record: " << record.toString(); if (record.resultClass == GdbResultError) { if (what == "create") { - sendCommand(_("ptype ") + m_toolTip.exp, WatchToolTip, QByteArray("ptype")); + execCommand(_("ptype ") + m_toolTip.exp, + Discardable, CB(handleToolTip), QByteArray("ptype")); return; } if (what == "evaluate") { @@ -4013,9 +3779,8 @@ void GdbEngine::handleToolTip(const GdbResultRecord &record, runDebuggingHelper(m_toolTip, false); else q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000); - sendCommand(_("-data-evaluate-expression ") + m_toolTip.exp, - WatchToolTip, QByteArray("evaluate")); - //sendToolTipCommand(_("-var-evaluate-expression tooltip")) + execCommand(_("-data-evaluate-expression ") + m_toolTip.exp, + Discardable, CB(handleToolTip), QByteArray("evaluate")); return; } if (what == "evaluate") { @@ -4053,9 +3818,9 @@ void GdbEngine::handleChangedItem(QStandardItem *item) void GdbEngine::assignValueInDebugger(const QString &expression, const QString &value) { - sendCommand(_("-var-delete assign")); - sendCommand(_("-var-create assign * ") + expression); - sendCommand(_("-var-assign assign ") + value, WatchVarAssign); + execCommand(_("-var-delete assign")); + execCommand(_("-var-create assign * ") + expression); + execCommand(_("-var-assign assign ") + value, Discardable, CB(handleVarAssign)); } void GdbEngine::tryLoadDebuggingHelpers() @@ -4080,41 +3845,41 @@ void GdbEngine::tryLoadDebuggingHelpers() m_debuggingHelperState = DebuggingHelperLoadTried; #if defined(Q_OS_WIN) - sendCommand(_("sharedlibrary .*")); // for LoadLibraryA - //sendCommand(_("handle SIGSEGV pass stop print")); - //sendCommand(_("set unwindonsignal off")); - sendCommand(_("call LoadLibraryA(\"") + lib + _("\")"), - WatchDebuggingHelperSetup); - sendCommand(_("sharedlibrary ") + dotEscape(lib)); + execCommand(_("sharedlibrary .*")); // for LoadLibraryA + //execCommand(_("handle SIGSEGV pass stop print")); + //execCommand(_("set unwindonsignal off")); + execCommand(_("call LoadLibraryA(\"") + lib + _("\")"), + CB(handleDebuggingHelperSetup)); + execCommand(_("sharedlibrary ") + dotEscape(lib)); #elif defined(Q_OS_MAC) - //sendCommand(_("sharedlibrary libc")); // for malloc - //sendCommand(_("sharedlibrary libdl")); // for dlopen - sendCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), - WatchDebuggingHelperSetup); - //sendCommand(_("sharedlibrary ") + dotEscape(lib)); + //execCommand(_("sharedlibrary libc")); // for malloc + //execCommand(_("sharedlibrary libdl")); // for dlopen + execCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), + CB(handleDebuggingHelperSetup)); + //execCommand(_("sharedlibrary ") + dotEscape(lib)); m_debuggingHelperState = DebuggingHelperLoadTried; #else - //sendCommand(_("p dlopen")); + //execCommand(_("p dlopen")); QString flag = QString::number(RTLD_NOW); - sendCommand(_("sharedlibrary libc")); // for malloc - sendCommand(_("sharedlibrary libdl")); // for dlopen - sendCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), - WatchDebuggingHelperSetup); + execCommand(_("sharedlibrary libc")); // for malloc + execCommand(_("sharedlibrary libdl")); // for dlopen + execCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), + CB(handleDebuggingHelperSetup)); // some older systems like CentOS 4.6 prefer this: - sendCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), - WatchDebuggingHelperSetup); - sendCommand(_("sharedlibrary ") + dotEscape(lib)); + execCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), + CB(handleDebuggingHelperSetup)); + execCommand(_("sharedlibrary ") + dotEscape(lib)); #endif // retreive list of dumpable classes - sendCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)")); - sendCommand(_("p (char*)&qDumpOutBuffer"), GdbQueryDebuggingHelper); + execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)")); + execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper)); } void GdbEngine::recheckDebuggingHelperAvailability() { // retreive list of dumpable classes - sendCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)")); - sendCommand(_("p (char*)&qDumpOutBuffer"), GdbQueryDebuggingHelper); + execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)")); + execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper)); } IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts) diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index 7b07f5bc1833a2c9c79288ec91f813a28718b436..c053bc1c0acf364cfa799fdafbf75aa60a9a6b97 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -63,16 +63,6 @@ class GdbMi; class WatchData; class BreakpointData; -struct GdbCookie -{ - GdbCookie() : type(0), synchronized(false) {} - - QString command; - int type; - bool synchronized; - QVariant cookie; -}; - enum DebuggingHelperState { DebuggingHelperUninitialized, @@ -154,19 +144,44 @@ private: void handleResult(const GdbResultRecord &, int type, const QVariant &); +public: // otherwise the Qt flag macros are unhappy + enum GdbCommandFlag { + NoFlags = 0, + NeedsStop = 1, + Discardable = 2, + RebuildModel = 4, + WatchUpdate = Discardable|RebuildModel + }; + Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag) +private: + + typedef void (GdbEngine::*GdbCommandCallback)(const GdbResultRecord &record, const QVariant &cookie); + + struct GdbCommand + { + GdbCommand() : flags(0), callback(0), callbackName(0) {} + + int flags; + GdbCommandCallback callback; + const char *callbackName; + QString command; + QVariant cookie; + }; + // type and cookie are sender-internal data, opaque for the "event // queue". resultNeeded == true increments m_pendingResults on // send and decrements on receipt, effectively preventing // watch model updates before everything is finished. - enum StopNeeded { DoesNotNeedStop, NeedsStop }; - enum Synchronization { NotSynchronized, Synchronized }; - void sendCommand(const QString &command, - int type = 0, const QVariant &cookie = QVariant(), - StopNeeded needStop = DoesNotNeedStop, - Synchronization synchronized = NotSynchronized); - void sendSynchronizedCommand(const QString & command, - int type = 0, const QVariant &cookie = QVariant(), - StopNeeded needStop = DoesNotNeedStop); + void flushCommand(GdbCommand &cmd); + void execCommand(const QString &command, + GdbCommandFlags flags, + GdbCommandCallback callback = 0, + const char *callbackName = 0, + const QVariant &cookie = QVariant()); + void execCommand(const QString &command, + GdbCommandCallback callback = 0, + const char *callbackName = 0, + const QVariant &cookie = QVariant()); void setTokenBarrier(); @@ -183,25 +198,28 @@ private slots: private: int terminationIndex(const QByteArray &buffer, int &length); void handleResponse(const QByteArray &buff); - void handleStart(const GdbResultRecord &response); - void handleAttach(); - void handleStubAttached(); + void handleStart(const GdbResultRecord &response, const QVariant &); + void handleAttach(const GdbResultRecord &, const QVariant &); + void handleStubAttached(const GdbResultRecord &, const QVariant &); void handleAqcuiredInferior(); + void handleAsyncOutput2(const GdbResultRecord &, const QVariant &cookie); void handleAsyncOutput2(const GdbMi &data); void handleAsyncOutput(const GdbMi &data); void handleResultRecord(const GdbResultRecord &response); - void handleFileExecAndSymbols(const GdbResultRecord &response); - void handleExecRun(const GdbResultRecord &response); - void handleExecJumpToLine(const GdbResultRecord &response); - void handleExecRunToFunction(const GdbResultRecord &response); - void handleInfoShared(const GdbResultRecord &response); - void handleInfoProc(const GdbResultRecord &response); - void handleInfoThreads(const GdbResultRecord &response); - void handleShowVersion(const GdbResultRecord &response); - void handleQueryPwd(const GdbResultRecord &response); - void handleQuerySources(const GdbResultRecord &response); - void handleTargetCore(const GdbResultRecord &response); - void handleExit(const GdbResultRecord &response); + void handleAutoContinue(const GdbResultRecord &, const QVariant &); + void handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &); + void handleExecRun(const GdbResultRecord &response, const QVariant &); + void handleExecJumpToLine(const GdbResultRecord &response, const QVariant &); + void handleExecRunToFunction(const GdbResultRecord &response, const QVariant &); + void handleInfoShared(const GdbResultRecord &response, const QVariant &); + void handleInfoProc(const GdbResultRecord &response, const QVariant &); + void handleInfoThreads(const GdbResultRecord &response, const QVariant &); + void handleShowVersion(const GdbResultRecord &response, const QVariant &); + void handleQueryPwd(const GdbResultRecord &response, const QVariant &); + void handleQuerySources(const GdbResultRecord &response, const QVariant &); + void handleTargetCore(const GdbResultRecord &, const QVariant &); + void handleExit(const GdbResultRecord &, const QVariant &); + void handleTargetAsync(const GdbResultRecord &, const QVariant &); void debugMessage(const QString &msg); OutputCollector m_outputCollector; @@ -214,7 +232,7 @@ private: Core::Utils::ConsoleProcess m_stubProc; - QHash<int, GdbCookie> m_cookieForToken; + QHash<int, GdbCommand> m_cookieForToken; QHash<int, QByteArray> m_customOutputForToken; QByteArray m_pendingConsoleStreamOutput; @@ -237,13 +255,13 @@ private: // // Breakpoint specific stuff // - void handleBreakList(const GdbResultRecord &record); + void handleBreakList(const GdbResultRecord &record, const QVariant &); void handleBreakList(const GdbMi &table); - void handleBreakIgnore(const GdbResultRecord &record, int index); - void handleBreakInsert(const GdbResultRecord &record, int index); - void handleBreakInsert1(const GdbResultRecord &record, int index); - void handleBreakCondition(const GdbResultRecord &record, int index); - void handleBreakInfo(const GdbResultRecord &record, int index); + void handleBreakIgnore(const GdbResultRecord &record, const QVariant &cookie); + void handleBreakInsert(const GdbResultRecord &record, const QVariant &cookie); + void handleBreakInsert1(const GdbResultRecord &record, const QVariant &cookie); + void handleBreakCondition(const GdbResultRecord &record, const QVariant &cookie); + void handleBreakInfo(const GdbResultRecord &record, const QVariant &cookie); void extractDataFromInfoBreak(const QString &output, BreakpointData *data); void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt); void sendInsertBreakpoint(int index); @@ -253,7 +271,7 @@ private: // Disassembler specific stuff // void handleDisassemblerList(const GdbResultRecord &record, - const QString &cookie); + const QVariant &cookie); void reloadDisassembler(); QString m_address; @@ -262,15 +280,15 @@ private: // Modules specific stuff // void reloadModules(); - void handleModulesList(const GdbResultRecord &record); + void handleModulesList(const GdbResultRecord &record, const QVariant &); // // Register specific stuff // Q_SLOT void reloadRegisters(); - void handleRegisterListNames(const GdbResultRecord &record); - void handleRegisterListValues(const GdbResultRecord &record); + void handleRegisterListNames(const GdbResultRecord &record, const QVariant &); + void handleRegisterListValues(const GdbResultRecord &record, const QVariant &); // // Source file specific stuff @@ -280,9 +298,9 @@ private: // // Stack specific stuff // - void handleStackListFrames(const GdbResultRecord &record, bool isFull); - void handleStackSelectThread(const GdbResultRecord &record, int cookie); - void handleStackListThreads(const GdbResultRecord &record, int cookie); + void handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie); + void handleStackSelectThread(const GdbResultRecord &, const QVariant &); + void handleStackListThreads(const GdbResultRecord &record, const QVariant &cookie); Q_SLOT void reloadStack(); Q_SLOT void reloadFullStack(); @@ -316,25 +334,25 @@ private: bool hasDebuggingHelperForType(const QString &type) const; void handleVarListChildren(const GdbResultRecord &record, - const WatchData &cookie); + const QVariant &cookie); void handleVarCreate(const GdbResultRecord &record, - const WatchData &cookie); - void handleVarAssign(); + const QVariant &cookie); + void handleVarAssign(const GdbResultRecord &, const QVariant &); void handleEvaluateExpression(const GdbResultRecord &record, - const WatchData &cookie); + const QVariant &cookie); void handleToolTip(const GdbResultRecord &record, - const QByteArray &cookie); - void handleQueryDebuggingHelper(const GdbResultRecord &record); + const QVariant &cookie); + void handleQueryDebuggingHelper(const GdbResultRecord &record, const QVariant &); void handleDebuggingHelperValue1(const GdbResultRecord &record, - const WatchData &cookie); + const QVariant &cookie); void handleDebuggingHelperValue2(const GdbResultRecord &record, - const WatchData &cookie); + const QVariant &cookie); void handleDebuggingHelperValue3(const GdbResultRecord &record, - const WatchData &cookie); + const QVariant &cookie); void handleDebuggingHelperEditValue(const GdbResultRecord &record); - void handleDebuggingHelperSetup(const GdbResultRecord &record); - void handleStackListLocals(const GdbResultRecord &record); - void handleStackListArguments(const GdbResultRecord &record); + void handleDebuggingHelperSetup(const GdbResultRecord &record, const QVariant &); + void handleStackListLocals(const GdbResultRecord &record, const QVariant &); + void handleStackListArguments(const GdbResultRecord &record, const QVariant &); void handleVarListChildrenHelper(const GdbMi &child, const WatchData &parent); void setWatchDataType(WatchData &data, const GdbMi &mi); @@ -354,7 +372,7 @@ private: bool m_waitingForFirstBreakpointToBeHit; bool m_modulesListOutdated; - QList<GdbCookie> m_commandsToRunOnTemporaryBreak; + QList<GdbCommand> m_commandsToRunOnTemporaryBreak; DebuggerManager *q; IDebuggerManagerAccessForEngines *qq; @@ -363,4 +381,6 @@ private: } // namespace Internal } // namespace Debugger +Q_DECLARE_OPERATORS_FOR_FLAGS(Debugger::Internal::GdbEngine::GdbCommandFlags) + #endif // DEBUGGER_GDBENGINE_H diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp index e7d0434d8fd8381244b3ec3ca5caef240ae63761..4cbd53ab1fed4bd2e6476d5bba5151314ad8af8a 100644 --- a/src/plugins/debugger/gdbmi.cpp +++ b/src/plugins/debugger/gdbmi.cpp @@ -42,16 +42,8 @@ QTextStream &operator<<(QTextStream &os, const GdbMi &mi) return os << mi.toString(); } -//static void skipSpaces(const char *&from, const char *to) -//{ -// while (from != to && QChar(*from).isSpace()) -// ++from; -//} - - void GdbMi::parseResultOrValue(const char *&from, const char *to) { - //skipSpaces(from, to); while (from != to && QChar(*from).isSpace()) ++from; diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp index 40ffcee7fb62db8fd433fc21be0a9a006893f692..a67b8dd0d75742e10702a67762d2c482d88ebac1 100644 --- a/src/plugins/debugger/moduleswindow.cpp +++ b/src/plugins/debugger/moduleswindow.cpp @@ -209,5 +209,5 @@ void ModulesWindow::showSymbols(const QString &name) emit newDockRequested(w); } -} -} +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 3a5b891533b11caa9cac07ddd9083244ff183bab..5693c2c2159adfa034117f184ca3df28b498b724 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -367,7 +367,9 @@ QString decodeData(const QByteArray &ba, int encoding) // --------------- QtDumperResult QtDumperResult::Child::Child() : - valueEncoded(0) + valueEncoded(0), + childCount(0), + valuedisabled(false) { } @@ -385,6 +387,7 @@ void QtDumperResult::clear() value.clear(); address.clear(); type.clear(); + displayedType.clear(); valueEncoded = 0; valuedisabled = false; childCount = 0; @@ -403,7 +406,7 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const const int lastDotIndex = root.iname.lastIndexOf(dot); root.exp = root.name = lastDotIndex == -1 ? iname : iname.mid(lastDotIndex + 1); root.setValue(decodeData(value, valueEncoded)); - root.setType(type); + root.setType(displayedType.isEmpty() ? type : displayedType); root.valuedisabled = valuedisabled; root.setAddress(address); root.source = source; @@ -419,8 +422,10 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const wchild.iname = iname; wchild.iname += dot; wchild.iname += dchild.name; - wchild.exp = wchild.name = dchild.name; - wchild.setType(childType); + wchild.name = dchild.name; + wchild.exp = dchild.exp; + wchild.valuedisabled = dchild.valuedisabled; + wchild.setType(dchild.type.isEmpty() ? childType : dchild.type); wchild.setAddress(dchild.address); wchild.setValue(decodeData(dchild.value, dchild.valueEncoded)); wchild.setChildCount(0); @@ -436,19 +441,23 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const QDebug operator<<(QDebug in, const QtDumperResult &d) { QDebug nospace = in.nospace(); - nospace << " iname=" << d.iname << " type=" << d.type << " address=" << d.address + nospace << " iname=" << d.iname << " type=" << d.type << " displayed=" << d.displayedType + << " address=" << d.address << " value=" << d.value << " disabled=" << d.valuedisabled << " encoded=" << d.valueEncoded << " internal=" << d.internal; - if (d.childCount) { - nospace << " childCount=" << d.childCount + const int realChildCount = d.children.size(); + if (d.childCount || realChildCount) { + nospace << " childCount=" << d.childCount << '/' << realChildCount << " childType=" << d.childType << '\n'; - const int childCount = d.children.size(); - for (int i = 0; i < childCount; i++) { + for (int i = 0; i < realChildCount; i++) { const QtDumperResult::Child &c = d.children.at(i); nospace << " #" << i << " addr=" << c.address + << " disabled=" << c.valuedisabled + << " type=" << c.type << " name=" << c.name << " encoded=" << c.valueEncoded - << " value=" << c.value << '\n'; + << " value=" << c.value + << "childcount=" << c.childCount << '\n'; } } return in; @@ -602,8 +611,6 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s) bool QtDumperHelper::needsExpressionSyntax(Type t) { switch (t) { - case QObjectType: - case QWidgetType: case QObjectSlotType: case QObjectSignalType: case QMapType: @@ -1064,12 +1071,14 @@ void QtDumperHelper::evaluationParameters(const WatchData &data, switch (td.type) { case QObjectType: case QWidgetType: - extraArgs[0] = QLatin1String("(char*)&((('"); - extraArgs[0] += m_qtNamespace; - extraArgs[0] += QLatin1String("QObjectPrivate'*)&"); - extraArgs[0] += data.exp; - extraArgs[0] += QLatin1String(")->children)-(char*)&"); - extraArgs[0] += data.exp; + if (debugger == GdbDebugger) { + extraArgs[0] = QLatin1String("(char*)&((('"); + extraArgs[0] += m_qtNamespace; + extraArgs[0] += QLatin1String("QObjectPrivate'*)&"); + extraArgs[0] += data.exp; + extraArgs[0] += QLatin1String(")->children)-(char*)&"); + extraArgs[0] += data.exp; + } break; case QVectorType: extraArgs[1] = QLatin1String("(char*)&(("); @@ -1201,13 +1210,16 @@ protected: private: enum Mode { None, ExpectingIName, ExpectingAddress, ExpectingValue, - ExpectingType, ExpectingInternal, + ExpectingType, ExpectingDisplayedType, ExpectingInternal, ExpectingValueDisabled, ExpectingValueEncoded, - ExpectingChildType, ExpectingChildCount, + ExpectingCommonChildType, ExpectingChildCount, IgnoreNext, ChildModeStart, ExpectingChildren,ExpectingChildName, ExpectingChildAddress, - ExpectingChildValue, ExpectingChildValueEncoded }; + ExpectingChildExpression, ExpectingChildType, + ExpectingChildValue, ExpectingChildValueEncoded, + ExpectingChildValueDisabled, ExpectingChildChildCount + }; static inline Mode nextMode(Mode in, const char *keyword, int size); @@ -1226,11 +1238,15 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword { // Careful with same prefix switch (size) { + case 3: + if (!qstrncmp(keyword, "exp", size)) + return ExpectingChildExpression; + break; case 4: if (!qstrncmp(keyword, "addr", size)) return in > ChildModeStart ? ExpectingChildAddress : ExpectingAddress; if (!qstrncmp(keyword, "type", size)) - return ExpectingType; + return in > ChildModeStart ? ExpectingChildType : ExpectingType; if (!qstrncmp(keyword, "name", size)) return ExpectingChildName; break; @@ -1244,13 +1260,13 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword if (!qstrncmp(keyword, "children", size)) return ExpectingChildren; if (!qstrncmp(keyword, "numchild", size)) - return ExpectingChildCount; + return in > ChildModeStart ? ExpectingChildChildCount : ExpectingChildCount; if (!qstrncmp(keyword, "internal", size)) return ExpectingInternal; break; case 9: if (!qstrncmp(keyword, "childtype", size)) - return ExpectingChildType; + return ExpectingCommonChildType; break; case 12: if (!qstrncmp(keyword, "valueencoded", size)) @@ -1258,7 +1274,9 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword break; case 13: if (!qstrncmp(keyword, "valuedisabled", size)) - return ExpectingValueDisabled; + return in > ChildModeStart ? ExpectingChildValueDisabled : ExpectingValueDisabled; + if (!qstrncmp(keyword, "displayedtype", size)) + return ExpectingDisplayedType; if (!qstrncmp(keyword, "childnumchild", size)) return IgnoreNext; break; @@ -1306,10 +1324,13 @@ bool ValueDumperParser::handleValue(const char *k, int size) case ExpectingType: m_result.type = QString::fromLatin1(valueBA); break; + case ExpectingDisplayedType: + m_result.displayedType = QString::fromLatin1(valueBA); + break; case ExpectingInternal: m_result.internal = valueBA == "true"; break; - case ExpectingChildType: + case ExpectingCommonChildType: m_result.childType = QString::fromLatin1(valueBA); break; case ExpectingChildCount: @@ -1327,9 +1348,21 @@ bool ValueDumperParser::handleValue(const char *k, int size) case ExpectingChildValue: m_result.children.back().value = valueBA; break; + case ExpectingChildExpression: + m_result.children.back().exp = QString::fromLatin1(valueBA); + break; case ExpectingChildValueEncoded: m_result.children.back().valueEncoded = QString::fromLatin1(valueBA).toInt(); break; + case ExpectingChildValueDisabled: + m_result.children.back().valuedisabled = valueBA == "true"; + break; + case ExpectingChildType: + m_result.children.back().type = QString::fromLatin1(valueBA); + break; + case ExpectingChildChildCount: + m_result.children.back().childCount = QString::fromLatin1(valueBA).toInt(); + break; } return true; } @@ -1340,6 +1373,9 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r) if (!parser.run()) return false; *r = parser.result(); + // Sanity + if (r->childCount < r->children.size()) + r->childCount = r->children.size(); return true; } @@ -1352,5 +1388,5 @@ QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d) return in; } -} -} +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index 47f73a8bb79cf8e1fbf418887c961d1d782bb0bf..af0a20c3b7c66299f5eba4112996b6fa883517c7 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -76,8 +76,12 @@ struct QtDumperResult Child(); int valueEncoded; + int childCount; + bool valuedisabled; QString name; QString address; + QString exp; + QString type; QByteArray value; }; @@ -88,6 +92,7 @@ struct QtDumperResult QString iname; QString address; QString type; + QString displayedType; QByteArray value; int valueEncoded; bool valuedisabled; diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp index 65ae59f8358c34e1c1dbe0dba17d22a60c704ae2..586f10f3c5d3864fe810aedb264aae631d565e29 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.cpp +++ b/src/plugins/genericprojectmanager/genericmakestep.cpp @@ -42,61 +42,24 @@ #include <QtGui/QLineEdit> #include <QtGui/QListWidget> -namespace { -bool debug = false; -} - using namespace GenericProjectManager; using namespace GenericProjectManager::Internal; GenericMakeStep::GenericMakeStep(GenericProject *pro) - : AbstractProcessStep(pro), m_pro(pro), m_buildParser(0) + : AbstractMakeStep(pro), m_pro(pro) { } GenericMakeStep::~GenericMakeStep() { - delete m_buildParser; - m_buildParser = 0; } bool GenericMakeStep::init(const QString &buildConfiguration) { - // TODO figure out the correct build parser - delete m_buildParser; - m_buildParser = 0; - const QString buildParser = m_pro->buildParser(buildConfiguration); + setBuildParser(buildParser); qDebug() << "*** build parser:" << buildParser; - QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories = - ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); - - foreach (ProjectExplorer::IBuildParserFactory *factory, buildParserFactories) { - if (factory->canCreate(buildParser)) { - m_buildParser = factory->create(buildParser); - break; - } - } - - if (m_buildParser) { - connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)), - this, SIGNAL(addToOutputWindow(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), - this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(enterDirectory(const QString &)), - this, SLOT(addDirectory(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)), - this, SLOT(removeDirectory(const QString &)), - Qt::DirectConnection); - } - - m_openDirectories.clear(); - addDirectory(m_pro->buildDirectory(buildConfiguration)); - setEnabled(buildConfiguration, true); setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); @@ -115,7 +78,7 @@ bool GenericMakeStep::init(const QString &buildConfiguration) setArguments(buildConfiguration, arguments); setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration)); - return AbstractProcessStep::init(buildConfiguration); + return AbstractMakeStep::init(buildConfiguration); } void GenericMakeStep::run(QFutureInterface<bool> &fi) @@ -143,79 +106,6 @@ bool GenericMakeStep::immutable() const return true; } -void GenericMakeStep::stdOut(const QString &line) -{ - if (m_buildParser) - m_buildParser->stdOutput(line); - AbstractProcessStep::stdOut(line); -} - -void GenericMakeStep::stdError(const QString &line) -{ - if (m_buildParser) - m_buildParser->stdError(line); - AbstractProcessStep::stdError(line); -} - -void GenericMakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description) -{ - QString filePath = fn; - if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) { - // We have no save way to decide which file in which subfolder - // is meant. Therefore we apply following heuristics: - // 1. Search for unique file in directories currently indicated as open by GNU make - // (Enter directory xxx, Leave directory xxx...) + current directory - // 3. Check if file is unique in whole project - // 4. Otherwise give up - - filePath = filePath.trimmed(); - - QList<QFileInfo> possibleFiles; - foreach (const QString &dir, m_openDirectories) { - QFileInfo candidate(dir + QLatin1Char('/') + filePath); - if (debug) - qDebug() << "Checking path " << candidate.filePath(); - if (candidate.exists() - && !possibleFiles.contains(candidate)) { - if (debug) - qDebug() << candidate.filePath() << "exists!"; - possibleFiles << candidate; - } - } - if (possibleFiles.count() == 0) { - if (debug) - qDebug() << "No success. Trying all files in project ..."; - QString fileName = QFileInfo(filePath).fileName(); - foreach (const QString &file, project()->files(ProjectExplorer::Project::AllFiles)) { - QFileInfo candidate(file); - if (candidate.fileName() == fileName) { - if (debug) - qDebug() << "Found " << file; - possibleFiles << candidate; - } - } - } - if (possibleFiles.count() == 1) - filePath = possibleFiles.first().filePath(); - else - qWarning() << "Could not find absolute location of file " << filePath; - } - emit addToTaskWindow(filePath, type, linenumber, description); -} - -void GenericMakeStep::addDirectory(const QString &dir) -{ - if (!m_openDirectories.contains(dir)) - m_openDirectories.insert(dir); -} - -void GenericMakeStep::removeDirectory(const QString &dir) -{ - if (m_openDirectories.contains(dir)) - m_openDirectories.remove(dir); -} - - GenericProject *GenericMakeStep::project() const { return m_pro; diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h index c103fa1ba9343bc394a48a1e0349e1661e694cff..96e71c8589140f1fc8ad843b0a870cf46426b62e 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.h +++ b/src/plugins/genericprojectmanager/genericmakestep.h @@ -30,7 +30,7 @@ #ifndef GENERICMAKESTEP_H #define GENERICMAKESTEP_H -#include <projectexplorer/abstractprocessstep.h> +#include <projectexplorer/abstractmakestep.h> QT_BEGIN_NAMESPACE class QListWidgetItem; @@ -45,7 +45,7 @@ namespace Internal { class GenericProject; -class GenericMakeStep : public ProjectExplorer::AbstractProcessStep +class GenericMakeStep : public ProjectExplorer::AbstractMakeStep { Q_OBJECT public: @@ -62,17 +62,8 @@ public: GenericProject *project() const; bool buildsTarget(const QString &buildConfiguration, const QString &target) const; void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on); -private slots: - void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description); - void addDirectory(const QString &dir); - void removeDirectory(const QString &dir); -protected: - virtual void stdOut(const QString &line); - virtual void stdError(const QString &line); private: GenericProject *m_pro; - ProjectExplorer::BuildParserInterface *m_buildParser; - QSet<QString> m_openDirectories; }; class GenericMakeStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index cc6d06d9b53a402d12a7ddfd8728a68be77d774d..7765dee3304e0c1f473d20d0c1599bca1faf077c 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -97,16 +97,13 @@ QString SettingsPage::trCategory() const QWidget *SettingsPage::createPage(QWidget *parent) { - if (!m_widget) - m_widget = new SettingsPageWidget(parent); + m_widget = new SettingsPageWidget(parent); m_widget->setSettings(GitPlugin::instance()->settings()); return m_widget; } void SettingsPage::apply() { - if (!m_widget) - return; const GitSettings newSettings = m_widget->settings(); // Warn if git cannot be found in path if the widget is on top if (m_widget->isVisible()) { diff --git a/src/plugins/git/settingspage.h b/src/plugins/git/settingspage.h index ec247d8a8967d5398f50e5693d064cb612d954ec..2bb9c0a8d300dbdd4f1688349a3ee86a6d9befaf 100644 --- a/src/plugins/git/settingspage.h +++ b/src/plugins/git/settingspage.h @@ -78,7 +78,7 @@ public: void finish() { } private: - QPointer<SettingsPageWidget> m_widget; + SettingsPageWidget* m_widget; }; } // namespace Internal diff --git a/src/plugins/perforce/settingspage.cpp b/src/plugins/perforce/settingspage.cpp index 1672186e9b7fbf210cb2794bd9ee17c90c32f0e3..024c2ac01fab2385c6e0d3b7bb886a4bb0af2fb9 100644 --- a/src/plugins/perforce/settingspage.cpp +++ b/src/plugins/perforce/settingspage.cpp @@ -108,16 +108,12 @@ QString SettingsPage::trCategory() const QWidget *SettingsPage::createPage(QWidget *parent) { - if (!m_widget) - m_widget = new SettingsPageWidget(parent); + m_widget = new SettingsPageWidget(parent); m_widget->setSettings(PerforcePlugin::perforcePluginInstance()->settings()); return m_widget; } void SettingsPage::apply() { - if (!m_widget) - return; - PerforcePlugin::perforcePluginInstance()->setSettings(m_widget->p4Command(), m_widget->p4Port(), m_widget->p4Client(), m_widget->p4User(), m_widget->defaultEnv()); } diff --git a/src/plugins/perforce/settingspage.h b/src/plugins/perforce/settingspage.h index 5f54c5c53812c07d90dca4cd40e15b50aaa6c2f0..f4c6d028af36b4be1062b818ca64d22775ccaf72 100644 --- a/src/plugins/perforce/settingspage.h +++ b/src/plugins/perforce/settingspage.h @@ -76,7 +76,7 @@ public: void finish() { } private: - QPointer<SettingsPageWidget> m_widget; + SettingsPageWidget* m_widget; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/abstractmakestep.cpp b/src/plugins/projectexplorer/abstractmakestep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19b9aa1db742629f02b6eda4b2ac2a02d48a90ef --- /dev/null +++ b/src/plugins/projectexplorer/abstractmakestep.cpp @@ -0,0 +1,189 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "abstractmakestep.h" + +#include "projectexplorerconstants.h" + +#include <extensionsystem/pluginmanager.h> +#include <utils/qtcassert.h> + +#include <QtCore/QDir> +#include <QtCore/QFileInfo> + +using ExtensionSystem::PluginManager; + +using namespace ProjectExplorer; + +namespace { +bool debug = false; +} + +AbstractMakeStep::AbstractMakeStep(Project *project) + : AbstractProcessStep(project), + m_project(project), + m_buildParser(0) +{ +} + +AbstractMakeStep::~AbstractMakeStep() +{ + delete m_buildParser; + m_buildParser = 0; +} + +bool AbstractMakeStep::init(const QString &buildConfiguration) +{ + m_buildConfiguration = buildConfiguration; + + m_openDirectories.clear(); + addDirectory(workingDirectory(buildConfiguration)); + + return AbstractProcessStep::init(buildConfiguration); +} + +QString AbstractMakeStep::buildParser() const +{ + return m_buildParserName; +} + +void AbstractMakeStep::setBuildParser(const QString &parser) +{ + // Nothing to do? + if (m_buildParserName == parser) + return; + + // Clean up + delete m_buildParser; + m_buildParser = 0; + m_buildParserName = QString::null; + + // Now look for new parser + QList<IBuildParserFactory *> buildParserFactories = + ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); + + foreach (IBuildParserFactory * factory, buildParserFactories) + if (factory->canCreate(parser)) { + m_buildParser = factory->create(parser); + break; + } + + if (m_buildParser) { + m_buildParserName = parser; + connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)), + this, SIGNAL(addToOutputWindow(const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), + this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(enterDirectory(const QString &)), + this, SLOT(addDirectory(const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)), + this, SLOT(removeDirectory(const QString &)), + Qt::DirectConnection); + } +} + +void AbstractMakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description) +{ + QString filePath = fn; + if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) { + // We have no save way to decide which file in which subfolder + // is meant. Therefore we apply following heuristics: + // 1. Search for unique file in directories currently indicated as open by GNU make + // (Enter directory xxx, Leave directory xxx...) + current directory + // 3. Check if file is unique in whole project + // 4. Otherwise give up + + filePath = filePath.trimmed(); + + QList<QFileInfo> possibleFiles; + foreach (const QString &dir, m_openDirectories) { + QFileInfo candidate(dir + QLatin1Char('/') + filePath); + if (debug) + qDebug() << "Checking path " << candidate.filePath(); + if (candidate.exists() + && !possibleFiles.contains(candidate)) { + if (debug) + qDebug() << candidate.filePath() << "exists!"; + possibleFiles << candidate; + } + } + if (possibleFiles.count() == 0) { + if (debug) + qDebug() << "No success. Trying all files in project ..."; + QString fileName = QFileInfo(filePath).fileName(); + foreach (const QString &file, m_project->files(ProjectExplorer::Project::AllFiles)) { + QFileInfo candidate(file); + if (candidate.fileName() == fileName) { + if (debug) + qDebug() << "Found " << file; + possibleFiles << candidate; + } + } + } + if (possibleFiles.count() == 1) + filePath = possibleFiles.first().filePath(); + else + qWarning() << "Could not find absolute location of file " << filePath; + } + emit addToTaskWindow(filePath, type, linenumber, description); +} + +void AbstractMakeStep::addDirectory(const QString &dir) +{ + if (!m_openDirectories.contains(dir)) + m_openDirectories.insert(dir); +} + +void AbstractMakeStep::removeDirectory(const QString &dir) +{ + if (m_openDirectories.contains(dir)) + m_openDirectories.remove(dir); +} + +void AbstractMakeStep::run(QFutureInterface<bool> & fi) +{ + AbstractProcessStep::run(fi); +} + +void AbstractMakeStep::stdOut(const QString &line) +{ + if (m_buildParser) + m_buildParser->stdOutput(line); + AbstractProcessStep::stdOut(line); +} + +void AbstractMakeStep::stdError(const QString &line) +{ + if (m_buildParser) + m_buildParser->stdError(line); + AbstractProcessStep::stdError(line); +} diff --git a/src/plugins/projectexplorer/abstractmakestep.h b/src/plugins/projectexplorer/abstractmakestep.h new file mode 100644 index 0000000000000000000000000000000000000000..3f60c3217c816131c2c1d3b41f226617394f667f --- /dev/null +++ b/src/plugins/projectexplorer/abstractmakestep.h @@ -0,0 +1,76 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef ABSTRACTMAKESTEP_H +#define ABSTRACTMAKESTEP_H + +#include "abstractprocessstep.h" +#include "projectexplorer.h" +#include "projectexplorer_export.h" + +namespace ProjectExplorer { +class BuildStep; +class IBuildStepFactory; +class Project; +} + +namespace ProjectExplorer { + +class PROJECTEXPLORER_EXPORT AbstractMakeStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT +public: + AbstractMakeStep(Project * project); + ~AbstractMakeStep(); + virtual bool init(const QString & name); + virtual void run(QFutureInterface<bool> &); + +protected: + // derived classes needs to call these functions + virtual void stdOut(const QString &line); + virtual void stdError(const QString &line); + + // derived classes needs to call this function + void setBuildParser(const QString &parser); + QString buildParser() const; +private slots: + void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description); + void addDirectory(const QString &dir); + void removeDirectory(const QString &dir); +private: + Project *m_project; + QString m_buildParserName; + ProjectExplorer::BuildParserInterface *m_buildParser; + QString m_buildConfiguration; + QSet<QString> m_openDirectories; +}; + +} // ProjectExplorer + +#endif // ABSTRACTMAKESTEP_H diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index ac021e8976efb37f0c47957478b02c32cd3d7156..e6a04cf83d9c551f11a90e19512a8fb8886ffe25 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -59,7 +59,8 @@ HEADERS += projectexplorer.h \ gccparser.h \ msvcparser.h \ filewatcher.h \ - debugginghelper.h + debugginghelper.h\ + abstractmakestep.h SOURCES += projectexplorer.cpp \ projectwindow.cpp \ buildmanager.cpp \ @@ -107,7 +108,8 @@ SOURCES += projectexplorer.cpp \ gccparser.cpp \ msvcparser.cpp \ filewatcher.cpp \ - debugginghelper.cpp + debugginghelper.cpp \ + abstractmakestep.cpp FORMS += dependenciespanel.ui \ buildsettingspropertiespage.ui \ processstep.ui \ diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp index b972142925bd954ac4587bf59b136471150a8ac9..c12c880b42a2f3d9656aee399c0713938838f267 100644 --- a/src/plugins/qt4projectmanager/makestep.cpp +++ b/src/plugins/qt4projectmanager/makestep.cpp @@ -34,9 +34,6 @@ #include <projectexplorer/projectexplorerconstants.h> -#include <extensionsystem/pluginmanager.h> -#include <utils/qtcassert.h> - #include <QtCore/QDir> #include <QtCore/QFileInfo> @@ -47,39 +44,15 @@ using ExtensionSystem::PluginManager; using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; -namespace { -bool debug = false; -} - MakeStep::MakeStep(Qt4Project * project) - : AbstractProcessStep(project), - m_project(project), - m_buildParser(0) + : AbstractMakeStep(project) { -} -MakeStep::~MakeStep() -{ - delete m_buildParser; - m_buildParser = 0; } -ProjectExplorer::BuildParserInterface *MakeStep::buildParser(const QtVersion *const version) +MakeStep::~MakeStep() { - QString buildParser; - ProjectExplorer::ToolChain::ToolChainType type = version->toolchainType(); - if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE) - buildParser = ProjectExplorer::Constants::BUILD_PARSER_MSVC; - else - buildParser = ProjectExplorer::Constants::BUILD_PARSER_GCC; - - QList<IBuildParserFactory *> buildParserFactories = - ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); - foreach (IBuildParserFactory * factory, buildParserFactories) - if (factory->canCreate(buildParser)) - return factory->create(buildParser); - return 0; } bool MakeStep::init(const QString &name) @@ -135,87 +108,13 @@ bool MakeStep::init(const QString &name) setEnabled(name, !skipMakeClean); setArguments(name, args); - m_openDirectories.clear(); - addDirectory(workingDirectory); - - delete m_buildParser; - m_buildParser = 0; - - m_buildParser = buildParser(qobject_cast<Qt4Project *>(project())->qtVersion(name)); - if (m_buildParser) { - connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)), - this, SIGNAL(addToOutputWindow(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), - this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(enterDirectory(const QString &)), - this, SLOT(addDirectory(const QString &)), - Qt::DirectConnection); - connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)), - this, SLOT(removeDirectory(const QString &)), - Qt::DirectConnection); - } - - return AbstractProcessStep::init(name); -} - -void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description) -{ - QString filePath = fn; - if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) { - // We have no save way to decide which file in which subfolder - // is meant. Therefore we apply following heuristics: - // 1. Search for unique file in directories currently indicated as open by GNU make - // (Enter directory xxx, Leave directory xxx...) + current directory - // 3. Check if file is unique in whole project - // 4. Otherwise give up - - filePath = filePath.trimmed(); - - QList<QFileInfo> possibleFiles; - foreach (const QString &dir, m_openDirectories) { - QFileInfo candidate(dir + QLatin1Char('/') + filePath); - if (debug) - qDebug() << "Checking path " << candidate.filePath(); - if (candidate.exists() - && !possibleFiles.contains(candidate)) { - if (debug) - qDebug() << candidate.filePath() << "exists!"; - possibleFiles << candidate; - } - } - if (possibleFiles.count() == 0) { - if (debug) - qDebug() << "No success. Trying all files in project ..."; - QString fileName = QFileInfo(filePath).fileName(); - foreach (const QString &file, m_project->files(ProjectExplorer::Project::AllFiles)) { - QFileInfo candidate(file); - if (candidate.fileName() == fileName) { - if (debug) - qDebug() << "Found " << file; - possibleFiles << candidate; - } - } - } - if (possibleFiles.count() == 1) - filePath = possibleFiles.first().filePath(); - else - qWarning() << "Could not find absolute location of file " << filePath; - } - emit addToTaskWindow(filePath, type, linenumber, description); -} + ProjectExplorer::ToolChain::ToolChainType type = qobject_cast<Qt4Project *>(project())->qtVersion(name)->toolchainType(); + if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE) + setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_MSVC); + else + setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_GCC); -void MakeStep::addDirectory(const QString &dir) -{ - if (!m_openDirectories.contains(dir)) - m_openDirectories.insert(dir); -} - -void MakeStep::removeDirectory(const QString &dir) -{ - if (m_openDirectories.contains(dir)) - m_openDirectories.remove(dir); + return AbstractMakeStep::init(name); } void MakeStep::run(QFutureInterface<bool> & fi) @@ -231,21 +130,7 @@ void MakeStep::run(QFutureInterface<bool> & fi) return; } - AbstractProcessStep::run(fi); -} - -void MakeStep::stdOut(const QString &line) -{ - if (m_buildParser) - m_buildParser->stdOutput(line); - AbstractProcessStep::stdOut(line); -} - -void MakeStep::stdError(const QString &line) -{ - if (m_buildParser) - m_buildParser->stdError(line); - AbstractProcessStep::stdError(line); + AbstractMakeStep::run(fi); } QString MakeStep::name() diff --git a/src/plugins/qt4projectmanager/makestep.h b/src/plugins/qt4projectmanager/makestep.h index 4276ea770980636c62a839d0a16bd4cd3e59903a..36e1f703dd67ac0d88f1f068266f9b3cca306a5e 100644 --- a/src/plugins/qt4projectmanager/makestep.h +++ b/src/plugins/qt4projectmanager/makestep.h @@ -33,7 +33,7 @@ #include "ui_makestep.h" #include "qtversionmanager.h" -#include <projectexplorer/abstractprocessstep.h> +#include <projectexplorer/abstractmakestep.h> #include <projectexplorer/projectexplorer.h> namespace ProjectExplorer { @@ -60,8 +60,7 @@ public: class Qt4Project; -// NBS move this class to an own plugin? So that there can be a make project at a future time -class MakeStep : public ProjectExplorer::AbstractProcessStep +class MakeStep : public ProjectExplorer::AbstractMakeStep { Q_OBJECT public: @@ -73,20 +72,8 @@ public: virtual QString displayName(); virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); virtual bool immutable() const; -protected: - virtual void stdOut(const QString &line); - virtual void stdError(const QString &line); -private slots: - void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description); - void addDirectory(const QString &dir); - void removeDirectory(const QString &dir); private: - ProjectExplorer::BuildParserInterface *buildParser(const QtVersion *const version); - Qt4Project *m_project; - ProjectExplorer::BuildParserInterface *m_buildParser; - bool m_skipMakeClean; QString m_buildConfiguration; - QSet<QString> m_openDirectories; }; class MakeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget diff --git a/src/plugins/quickopen/settingspage.cpp b/src/plugins/quickopen/settingspage.cpp index bd900e6bba0debb82f0656d23215b03993c6f384..dbb69b44273fbd72a20357e47720918c64b30652 100644 --- a/src/plugins/quickopen/settingspage.cpp +++ b/src/plugins/quickopen/settingspage.cpp @@ -71,20 +71,20 @@ QString SettingsPage::trCategory() const QWidget *SettingsPage::createPage(QWidget *parent) { - if (!m_page) { - m_page = new QWidget(parent); - m_ui.setupUi(m_page); - connect(m_ui.filterList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(updateButtonStates())); - connect(m_ui.filterList, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(configureFilter(QListWidgetItem *))); - connect(m_ui.editButton, SIGNAL(clicked()), - this, SLOT(configureFilter())); - connect(m_ui.addButton, SIGNAL(clicked()), - this, SLOT(addCustomFilter())); - connect(m_ui.removeButton, SIGNAL(clicked()), - this, SLOT(removeCustomFilter())); - } + + m_page = new QWidget(parent); + m_ui.setupUi(m_page); + connect(m_ui.filterList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(updateButtonStates())); + connect(m_ui.filterList, SIGNAL(itemActivated(QListWidgetItem *)), + this, SLOT(configureFilter(QListWidgetItem *))); + connect(m_ui.editButton, SIGNAL(clicked()), + this, SLOT(configureFilter())); + connect(m_ui.addButton, SIGNAL(clicked()), + this, SLOT(addCustomFilter())); + connect(m_ui.removeButton, SIGNAL(clicked()), + this, SLOT(removeCustomFilter())); + m_ui.refreshInterval->setValue(m_plugin->refreshInterval()); m_filters = m_plugin->filters(); m_customFilters = m_plugin->customFilters(); diff --git a/src/plugins/quickopen/settingspage.h b/src/plugins/quickopen/settingspage.h index 6bb3a2984abaea393380a5c340d9db04306da0e9..936ecd082b2a09eae1300e5f5243358e064b48eb 100644 --- a/src/plugins/quickopen/settingspage.h +++ b/src/plugins/quickopen/settingspage.h @@ -78,7 +78,7 @@ private: Ui::SettingsWidget m_ui; QuickOpenPlugin *m_plugin; - QPointer<QWidget> m_page; + QWidget* m_page; QList<IQuickOpenFilter *> m_filters; QList<IQuickOpenFilter *> m_addedFilters; QList<IQuickOpenFilter *> m_removedFilters; diff --git a/src/plugins/subversion/settingspage.cpp b/src/plugins/subversion/settingspage.cpp index e06560feddc260704f2f2fdb52a729d124aae346..b099b8715ce0caed79c6d9bc107faf5a9ac73e4a 100644 --- a/src/plugins/subversion/settingspage.cpp +++ b/src/plugins/subversion/settingspage.cpp @@ -96,15 +96,12 @@ QString SettingsPage::trCategory() const QWidget *SettingsPage::createPage(QWidget *parent) { - if (!m_widget) - m_widget = new SettingsPageWidget(parent); + m_widget = new SettingsPageWidget(parent); m_widget->setSettings(SubversionPlugin::subversionPluginInstance()->settings()); return m_widget; } void SettingsPage::apply() { - if (!m_widget) - return; SubversionPlugin::subversionPluginInstance()->setSettings(m_widget->settings()); } diff --git a/src/plugins/subversion/settingspage.h b/src/plugins/subversion/settingspage.h index 7808920e04e046bb5f773c6cc262e14e4e51e6b1..1fc5e8e3350c588567b303a78c99ba98d61122e4 100644 --- a/src/plugins/subversion/settingspage.h +++ b/src/plugins/subversion/settingspage.h @@ -77,7 +77,7 @@ public: void finish() { } private: - QPointer<SettingsPageWidget> m_widget; + SettingsPageWidget* m_widget; }; } // namespace Subversion diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index cd683f7990b625ab95b1c14a3f38a6359cf04907..d01cc3f1d6ec67665b92584d41bc13cd759be413 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -2348,10 +2348,10 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e) bool active = blockNumber == extraAreaHighlightCollapseBlockNumber; bool drawStart = drawBox && active; bool drawEnd = blockNumber == extraAreaHighlightCollapseEndBlockNumber || (drawStart && !endIsVisible); + bool hovered = blockNumber >= extraAreaHighlightCollapseBlockNumber + && blockNumber <= extraAreaHighlightCollapseEndBlockNumber; - if ( blockNumber >= extraAreaHighlightCollapseBlockNumber - && blockNumber <= extraAreaHighlightCollapseEndBlockNumber) { - + if (hovered) { QRect box = QRect(extraAreaWidth + 1, top, collapseBoxWidth - 2, collapseBoxWidth); drawRectBox(&painter, box, drawStart, drawEnd, pal); } @@ -2360,7 +2360,7 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e) bool expanded = nextBlock.isVisible(); QRect box(extraAreaWidth + collapseBoxWidth/4, top + collapseBoxWidth/4, 2 * (collapseBoxWidth/4) + 1, 2 * (collapseBoxWidth/4) + 1); - drawFoldingMarker(&painter, box, expanded, active); + drawFoldingMarker(&painter, pal, box, expanded, active, hovered); } } @@ -2404,8 +2404,11 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e) } } -void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QRect &rect, - bool expanded, bool hovered) const +void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QPalette &pal, + const QRect &rect, + bool expanded, + bool active, + bool hovered) const { QStyleOptionViewItemV2 opt; opt.rect = rect; @@ -2414,9 +2417,12 @@ void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QRect &rect, if (expanded) opt.state |= QStyle::State_Open; - if (hovered) + if (active) opt.state |= QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Selected; + if (hovered) + opt.palette.setBrush(QPalette::Window, pal.highlight()); + style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this); } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index bc4e8c208759c925d3fa2e30ae12662cd695f86a..c93cd86123b81ae671973ef135f510793c37e20b 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -511,8 +511,11 @@ private: void moveLineUpDown(bool up); void saveCurrentCursorPositionForNavigation(); - void drawFoldingMarker(QPainter *painter, const QRect &rect, - bool expanded, bool hovered) const; + void drawFoldingMarker(QPainter *painter, const QPalette &pal, + const QRect &rect, + bool expanded, + bool active, + bool hovered) const; void toggleBlockVisible(const QTextBlock &block); QRect collapseBox(); diff --git a/src/plugins/vcsbase/vcsbasesettingspage.h b/src/plugins/vcsbase/vcsbasesettingspage.h index 9c271c561e9dcb710eb0fddc472e8c0143e1695a..a81daf5f35211d3f3ba006fbd6469d0e5a0e5d44 100644 --- a/src/plugins/vcsbase/vcsbasesettingspage.h +++ b/src/plugins/vcsbase/vcsbasesettingspage.h @@ -80,7 +80,7 @@ signals: private: void updateNickNames(); - QPointer<VCSBaseSettingsWidget> m_widget; + VCSBaseSettingsWidget* m_widget; VCSBaseSettings m_settings; };