forked from qt-creator/qt-creator
debugger: more robust version string parsing
Fix for QTCREATORBUG-1490 Reviewed-By: Friedemann Kleint
This commit is contained in:
@@ -1470,70 +1470,22 @@ void GdbEngine::handleInfoProc(const GdbResponse &response)
|
||||
|
||||
void GdbEngine::handleShowVersion(const GdbResponse &response)
|
||||
{
|
||||
//qDebug () << "VERSION 2:" << response.data.findChild("consolestreamoutput").data();
|
||||
//qDebug () << "VERSION:" << response.toString();
|
||||
debugMessage(_("VERSION: " + response.toString()));
|
||||
debugMessage(_("PARSING VERSION: " + response.toString()));
|
||||
if (response.resultClass == GdbResultDone) {
|
||||
m_gdbVersion = 100;
|
||||
m_gdbBuildVersion = -1;
|
||||
m_isMacGdb = false;
|
||||
GdbMi version = response.data.findChild("consolestreamoutput");
|
||||
QString msg = QString::fromLocal8Bit(version.data());
|
||||
|
||||
bool foundIt = false;
|
||||
|
||||
QRegExp supported(_("GNU gdb(.*) (\\d+)\\.(\\d+)(\\.(\\d+))?(-(\\d+))?"));
|
||||
if (supported.indexIn(msg) >= 0) {
|
||||
extractGdbVersion(msg,
|
||||
&m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb);
|
||||
if (m_gdbVersion > 60500 && m_gdbVersion < 200000)
|
||||
debugMessage(_("SUPPORTED GDB VERSION ") + msg);
|
||||
m_gdbVersion = 10000 * supported.cap(2).toInt()
|
||||
+ 100 * supported.cap(3).toInt()
|
||||
+ 1 * supported.cap(5).toInt();
|
||||
m_gdbBuildVersion = supported.cap(7).toInt();
|
||||
m_isMacGdb = msg.contains(__("Apple version"));
|
||||
foundIt = true;
|
||||
}
|
||||
|
||||
// OpenSUSE managed to ship "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4).
|
||||
if (!foundIt && msg.startsWith(_("GNU gdb (GDB) SUSE "))) {
|
||||
supported.setPattern(_("[^\\d]*(\\d+).(\\d+).(\\d+).*"));
|
||||
if (supported.indexIn(msg) >= 0) {
|
||||
debugMessage(_("SUSE PATCHED GDB VERSION ") + msg);
|
||||
m_gdbVersion = 10000 * supported.cap(1).toInt()
|
||||
+ 100 * supported.cap(2).toInt()
|
||||
+ 1 * supported.cap(3).toInt();
|
||||
m_gdbBuildVersion = -1;
|
||||
m_isMacGdb = false;
|
||||
foundIt = true;
|
||||
} else {
|
||||
debugMessage(_("UNPARSABLE SUSE PATCHED GDB VERSION ") + msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundIt) {
|
||||
else
|
||||
debugMessage(_("UNSUPPORTED GDB VERSION ") + msg);
|
||||
#if 0
|
||||
QStringList list = msg.split(_c('\n'));
|
||||
while (list.size() > 2)
|
||||
list.removeLast();
|
||||
msg = tr("The debugger you are using identifies itself as:")
|
||||
+ _("<p><p>") + list.join(_("<br>")) + _("<p><p>")
|
||||
+ tr("This version is not officially supported by Qt Creator.\n"
|
||||
"Debugging will most likely not work well.\n"
|
||||
"Using gdb 7.1 or later is strongly recommended.");
|
||||
#if 0
|
||||
// ugly, but 'Show again' check box...
|
||||
static QErrorMessage *err = new QErrorMessage(mainWindow());
|
||||
err->setMinimumSize(400, 300);
|
||||
err->showMessage(msg);
|
||||
#else
|
||||
//showMessageBox(QMessageBox::Information, tr("Warning"), msg);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
debugMessage(_("USING GDB VERSION: %1, BUILD: %2%3").arg(m_gdbVersion)
|
||||
.arg(m_gdbBuildVersion).arg(_(m_isMacGdb ? " (APPLE)" : "")));
|
||||
//qDebug () << "VERSION 3:" << m_gdbVersion << m_gdbBuildVersion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -400,5 +401,50 @@ QByteArray GdbResponse::toString() const
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GdbResponse
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void extractGdbVersion(const QString &msg,
|
||||
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb)
|
||||
{
|
||||
const QChar dot(QLatin1Char('.'));
|
||||
|
||||
QString cleaned;
|
||||
QString build;
|
||||
bool inClean = true;
|
||||
foreach (QChar c, msg) {
|
||||
if (inClean && !cleaned.isEmpty() && c != dot && (c.isPunct() || c.isSpace()))
|
||||
inClean = false;
|
||||
if (inClean) {
|
||||
if (c.isDigit())
|
||||
cleaned.append(c);
|
||||
else if (!cleaned.isEmpty() && !cleaned.endsWith(dot))
|
||||
cleaned.append(dot);
|
||||
} else {
|
||||
if (c.isDigit())
|
||||
build.append(c);
|
||||
else if (!build.isEmpty() && !build.endsWith(dot))
|
||||
build.append(dot);
|
||||
}
|
||||
}
|
||||
|
||||
*isMacGdb = msg.contains(QLatin1String("Apple version"));
|
||||
|
||||
*gdbVersion = 10000 * cleaned.section(dot, 0, 0).toInt()
|
||||
+ 100 * cleaned.section(dot, 1, 1).toInt()
|
||||
+ 1 * cleaned.section(dot, 2, 2).toInt();
|
||||
if (cleaned.count(dot) >= 3)
|
||||
*gdbBuildVersion = cleaned.section(dot, 3, 3).toInt();
|
||||
else
|
||||
*gdbBuildVersion = build.section(dot, 0, 0).toInt();
|
||||
|
||||
if (*isMacGdb)
|
||||
*gdbBuildVersion = build.section(dot, 1, 1).toInt();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
@@ -168,6 +168,9 @@ public:
|
||||
QVariant cookie;
|
||||
};
|
||||
|
||||
void extractGdbVersion(const QString &msg,
|
||||
int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = dumpers.pro plugin.pro gdb.pro
|
||||
SUBDIRS = dumpers.pro plugin.pro gdb.pro version.pro
|
||||
|
||||
|
||||
82
tests/auto/debugger/tst_version.cpp
Normal file
82
tests/auto/debugger/tst_version.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
#include "gdb/gdbmi.h"
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
|
||||
class tst_Version : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_Version() {}
|
||||
|
||||
private slots:
|
||||
void version();
|
||||
void version_data();
|
||||
};
|
||||
|
||||
void tst_Version::version()
|
||||
{
|
||||
QFETCH(QString, msg);
|
||||
QFETCH(int, gdbVersion);
|
||||
QFETCH(int, gdbBuildVersion);
|
||||
QFETCH(bool, isMacGdb);
|
||||
int v = 0, bv = 0;
|
||||
bool mac = true;
|
||||
Debugger::Internal::extractGdbVersion(msg, &v, &bv, &mac);
|
||||
qDebug() << msg << " -> " << v << bv << mac;
|
||||
QCOMPARE(v, gdbVersion);
|
||||
QCOMPARE(bv, gdbBuildVersion);
|
||||
QCOMPARE(mac, isMacGdb);
|
||||
}
|
||||
|
||||
void tst_Version::version_data()
|
||||
{
|
||||
QTest::addColumn<QString>("msg");
|
||||
QTest::addColumn<int>("gdbVersion");
|
||||
QTest::addColumn<int>("gdbBuildVersion");
|
||||
QTest::addColumn<bool>("isMacGdb");
|
||||
|
||||
QTest::newRow("Debian")
|
||||
<< "GNU gdb (GDB) 7.0.1-debian"
|
||||
<< 70001 << 0 << false;
|
||||
|
||||
QTest::newRow("CVS 7.0.90")
|
||||
<< "GNU gdb (GDB) 7.0.90.20100226-cvs"
|
||||
<< 70090 << 20100226 << false;
|
||||
|
||||
QTest::newRow("Ubuntu Lucid")
|
||||
<< "GNU gdb (GDB) 7.1-ubuntu"
|
||||
<< 70100 << 0 << false;
|
||||
|
||||
QTest::newRow("Fedora 13")
|
||||
<< "GNU gdb (GDB) Fedora (7.1-22.fc13)"
|
||||
<< 70100 << 22 << false;
|
||||
|
||||
QTest::newRow("Gentoo")
|
||||
<< "GNU gdb (Gentoo 7.1 p1) 7.1"
|
||||
<< 70100 << 1 << false;
|
||||
|
||||
QTest::newRow("Fedora EL5")
|
||||
<< "GNU gdb Fedora (6.8-37.el5)"
|
||||
<< 60800 << 37 << false;
|
||||
|
||||
QTest::newRow("SUSE")
|
||||
<< "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)"
|
||||
<< 60891 << 20090930 << false;
|
||||
|
||||
QTest::newRow("Apple")
|
||||
<< "GNU gdb 6.3.50-20050815 (Apple version gdb-1461.2)"
|
||||
<< 60350 << 1461 << true;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
tst_Version test;
|
||||
return QTest::qExec(&test, argc, argv);
|
||||
}
|
||||
|
||||
#include "tst_version.moc"
|
||||
|
||||
15
tests/auto/debugger/version.pro
Normal file
15
tests/auto/debugger/version.pro
Normal file
@@ -0,0 +1,15 @@
|
||||
QT += testlib
|
||||
QT -= gui
|
||||
|
||||
UTILSDIR = ../../../src/libs
|
||||
|
||||
DEBUGGERDIR = ../../../src/plugins/debugger
|
||||
|
||||
INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
|
||||
|
||||
SOURCES += \
|
||||
tst_version.cpp \
|
||||
$$DEBUGGERDIR/gdb/gdbmi.cpp \
|
||||
|
||||
TARGET = tst_$$TARGET
|
||||
|
||||
Reference in New Issue
Block a user