OSDN Git Service

debugger: more robust version string parsing
authorhjk <qtc-committer@nokia.com>
Thu, 27 May 2010 13:41:52 +0000 (15:41 +0200)
committerhjk <qtc-committer@nokia.com>
Thu, 27 May 2010 13:55:01 +0000 (15:55 +0200)
Fix for QTCREATORBUG-1490

Reviewed-By: Friedemann Kleint
src/plugins/debugger/gdb/gdbengine.cpp
src/plugins/debugger/gdb/gdbmi.cpp
src/plugins/debugger/gdb/gdbmi.h
tests/auto/debugger/debugger.pro
tests/auto/debugger/tst_version.cpp [new file with mode: 0644]
tests/auto/debugger/version.pro [new file with mode: 0644]

index 166e5de..12f9d8c 100644 (file)
@@ -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;
     }
 }
 
index c34d811..158a1fc 100644 (file)
@@ -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
index ce484c8..7803d71 100644 (file)
@@ -168,6 +168,9 @@ public:
     QVariant       cookie;
 };
 
+void extractGdbVersion(const QString &msg,
+    int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb);
+
 } // namespace Internal
 } // namespace Debugger
 
index ef1547f..84ad799 100644 (file)
@@ -1,5 +1,5 @@
 
 TEMPLATE = subdirs
 
-SUBDIRS = dumpers.pro plugin.pro gdb.pro
+SUBDIRS = dumpers.pro plugin.pro gdb.pro version.pro
 
diff --git a/tests/auto/debugger/tst_version.cpp b/tests/auto/debugger/tst_version.cpp
new file mode 100644 (file)
index 0000000..cfac4f1
--- /dev/null
@@ -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"
+
diff --git a/tests/auto/debugger/version.pro b/tests/auto/debugger/version.pro
new file mode 100644 (file)
index 0000000..78d3f0f
--- /dev/null
@@ -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
+