OSDN Git Service

Maemo: Move "mad info" parsing for Qemu specs into dedicated classes.
authorChristian Kandeler <christian.kandeler@nokia.com>
Tue, 30 Nov 2010 14:31:15 +0000 (15:31 +0100)
committerChristian Kandeler <christian.kandeler@nokia.com>
Tue, 30 Nov 2010 14:32:02 +0000 (15:32 +0100)
src/plugins/qt4projectmanager/qt-maemo/maemoglobal.cpp
src/plugins/qt4projectmanager/qt-maemo/maemoglobal.h
src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp
src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h
src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.cpp [new file with mode: 0644]
src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.h [new file with mode: 0644]
src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri

index 318f5e1..8111293 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "maemoglobal.h"
 
+#include "maemoconstants.h"
 #include "maemodeviceconfigurations.h"
 
 #include <coreplugin/ssh/sshconnection.h>
@@ -44,6 +45,9 @@
 
 namespace Qt4ProjectManager {
 namespace Internal {
+namespace {
+static const QLatin1String binQmake("/bin/qmake" EXEC_SUFFIX);
+}
 
 QString MaemoGlobal::homeDirOnDevice(const QString &uname)
 {
@@ -99,6 +103,19 @@ QString MaemoGlobal::failedToConnectToServerMessage(const Core::SshConnection::P
     return errorMsg;
 }
 
+QString MaemoGlobal::maddeRoot(const QString &qmakePath)
+{
+    QDir dir(QDir::cleanPath(qmakePath).remove(binQmake));
+    dir.cdUp(); dir.cdUp();
+    return dir.absolutePath();
+}
+
+QString MaemoGlobal::targetName(const QString &qmakePath)
+{
+    const QString target = QDir::cleanPath(qmakePath).remove(binQmake);
+    return target.mid(target.lastIndexOf(QLatin1Char('/')) + 1);
+}
+
 bool MaemoGlobal::removeRecursively(const QString &filePath, QString &error)
 {
     QFileInfo fileInfo(filePath);
index d86ff74..ca2ac5b 100644 (file)
@@ -63,6 +63,8 @@ public:
     static QString remoteSourceProfilesCommand();
     static QString failedToConnectToServerMessage(const QSharedPointer<Core::SshConnection> &connection,
         const MaemoDeviceConfig &deviceConfig);
+    static QString maddeRoot(const QString &qmakePath);
+    static QString targetName(const QString &qmakePath);
 
     static bool removeRecursively(const QString &filePath, QString &error);
     static void callMaddeShellScript(QProcess &proc, const QString &maddeRoot,
index acedb44..36e1c17 100644 (file)
@@ -30,6 +30,7 @@
 #include "maemoqemumanager.h"
 
 #include "maemoglobal.h"
+#include "maemoqemuruntimeparser.h"
 #include "maemorunconfiguration.h"
 #include "maemotoolchain.h"
 #include "qtversionmanager.h"
 #include <QtCore/QList>
 #include <QtCore/QSet>
 #include <QtCore/QStringBuilder>
-#include <QtCore/QTextStream>
 
 #include <QtGui/QAction>
 #include <QtGui/QDesktopServices>
 #include <QtGui/QMessageBox>
 
-#include <QtXml/QXmlStreamReader>
-
 #include <limits.h>
 
 using namespace ProjectExplorer;
@@ -69,7 +67,6 @@ using namespace Qt4ProjectManager::Internal;
 MaemoQemuManager *MaemoQemuManager::m_instance = 0;
 
 const QSize iconSize = QSize(24, 20);
-const QLatin1String binQmake("/bin/qmake" EXEC_SUFFIX);
 
 MaemoQemuManager::MaemoQemuManager(QObject *parent)
     : QObject(parent)
@@ -157,10 +154,9 @@ void MaemoQemuManager::qtVersionsChanged(const QList<int> &uniqueIds)
         if (manager->isValidId(uniqueId)) {
             QtVersion *version = manager->version(uniqueId);
             if (version->supportsTargetId(Constants::MAEMO_DEVICE_TARGET_ID)) {
-                MaemoQemuRuntime runtime = createRuntime(version);
+                MaemoQemuRuntime runtime
+                    = MaemoQemuRuntimeParser::parseRuntime(version);
                 if (runtime.isValid()) {
-                    runtime.m_watchPath =
-                        runtime.m_root.left(runtime.m_root.lastIndexOf(QLatin1Char('/')));
                     m_runtimes.insert(uniqueId, runtime);
                     if (!m_runtimeRootWatcher->directories().contains(runtime.m_watchPath))
                         m_runtimeRootWatcher->addPath(runtime.m_watchPath);
@@ -357,7 +353,7 @@ void MaemoQemuManager::startRuntime()
 
     m_runningQtId = version->uniqueId();
     const QString root
-        = QDir::toNativeSeparators(maddeRoot(version->qmakeCommand())
+        = QDir::toNativeSeparators(MaemoGlobal::maddeRoot(version->qmakeCommand())
             + QLatin1Char('/'));
     const MaemoQemuRuntime rt = m_runtimes.value(version->uniqueId());
     QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -592,296 +588,6 @@ bool MaemoQemuManager::targetUsesMatchingRuntimeConfig(Target *target,
     return config.isValid() && config.type == MaemoDeviceConfig::Simulator;
 }
 
-QString MaemoQemuManager::maddeRoot(const QString &qmake) const
-{
-    QDir dir(QDir::cleanPath(qmake).remove(binQmake));
-    dir.cdUp(); dir.cdUp();
-    return dir.absolutePath();
-}
-
-QString MaemoQemuManager::targetRoot(const QString &qmake) const
-{
-    const QString target = QDir::cleanPath(qmake).remove(binQmake);
-    return target.mid(target.lastIndexOf(QLatin1Char('/')) + 1);
-}
-
-bool MaemoQemuManager::fillRuntimeInformationForOldMadInfo(MaemoQemuRuntime *runtime) const
-{
-    const QStringList files = QDir(runtime->m_root).entryList(QDir::Files
-        | QDir::NoSymLinks | QDir::NoDotAndDotDot);
-
-    // we need at least the information file
-    const QLatin1String infoFile("information");
-    if (files.contains(infoFile)) {
-        QFile file(runtime->m_root + QLatin1Char('/') + infoFile);
-        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-            QMap<QString, QString> map;
-            QTextStream stream(&file);
-            while (!stream.atEnd()) {
-                const QString &line = stream.readLine().trimmed();
-                const int index = line.indexOf(QLatin1Char('='));
-                map.insert(line.mid(0, index).remove(QLatin1Char('\'')),
-                    line.mid(index + 1).remove(QLatin1Char('\'')));
-            }
-
-            runtime->m_bin = map.value(QLatin1String("qemu"));
-            runtime->m_args = map.value(QLatin1String("qemu_args"));
-            setEnvironment(runtime, map.value(QLatin1String("libpath")));
-            runtime->m_sshPort = map.value(QLatin1String("sshport"));
-            runtime->m_freePorts = MaemoPortList();
-            int i = 2;
-            while (true) {
-                const QString port = map.value(QLatin1String("redirport")
-                    + QString::number(i++));
-                if (port.isEmpty())
-                    break;
-                runtime->m_freePorts.addPort(port.toInt());
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-void MaemoQemuManager::setEnvironment(MaemoQemuRuntime *runTime,
-    const QString &envSpec) const
-{
-    QString remainingEnvSpec = envSpec;
-    QString currentKey;
-    while (true) {
-        const int nextEqualsSignPos
-            = remainingEnvSpec.indexOf(QLatin1Char('='));
-        if (nextEqualsSignPos == -1) {
-            if (!currentKey.isEmpty())
-                runTime->m_environment.insert(currentKey, remainingEnvSpec);
-            break;
-        }
-        const int keyStartPos
-            = remainingEnvSpec.lastIndexOf(QRegExp(QLatin1String("\\s")),
-                nextEqualsSignPos) + 1;
-        if (!currentKey.isEmpty()) {
-            const int valueEndPos
-                = remainingEnvSpec.lastIndexOf(QRegExp(QLatin1String("\\S")),
-                    qMax(0, keyStartPos - 1)) + 1;
-            runTime->m_environment.insert(currentKey,
-                remainingEnvSpec.left(valueEndPos));
-        }
-        currentKey = remainingEnvSpec.mid(keyStartPos,
-            nextEqualsSignPos - keyStartPos);
-        remainingEnvSpec.remove(0, nextEqualsSignPos + 1);
-    }
-}
-
-MaemoQemuRuntime MaemoQemuManager::createRuntime(const QtVersion *qtVersion) const
-{
-    MaemoQemuRuntime runtime;
-    const QString maddeRootPath = maddeRoot(qtVersion->qmakeCommand());
-    const QString madCommand = maddeRootPath + QLatin1String("/bin/mad");
-    if (!QFileInfo(madCommand).exists())
-        return runtime;
-    QProcess madProc;
-    MaemoGlobal::callMaddeShellScript(madProc, maddeRootPath, madCommand,
-        QStringList() << QLatin1String("info"));
-    if (!madProc.waitForStarted() || !madProc.waitForFinished())
-        return runtime;
-    const QByteArray &madInfoOutput = madProc.readAllStandardOutput();
-    const QString &targetName = targetRoot(qtVersion->qmakeCommand());
-    runtime = parseRuntimeFromMadInfo(madInfoOutput, targetName);
-    if (!runtime.m_name.isEmpty()) {
-        runtime.m_root = maddeRootPath + QLatin1String("/runtimes/")
-            + runtime.m_name;
-
-        // TODO: Workaround for missing ssh tag. Fix once MADDE is ready.
-        runtime.m_sshPort = QLatin1String("6666");
-
-        return runtime;
-    } else {
-        return parseRuntimeFromOldMadInfo(madInfoOutput, maddeRootPath, targetName);
-    }
-}
-
-MaemoQemuRuntime MaemoQemuManager::parseRuntimeFromMadInfo(const QByteArray &output,
-    const QString &targetName) const
-{
-    QXmlStreamReader infoReader(output);
-    QString runtimeName;
-    QList<MaemoQemuRuntime> runtimes;
-    while (infoReader.readNextStartElement()) {
-        if (infoReader.name() == QLatin1String("madde")) {
-            while (infoReader.readNextStartElement()) {
-                if (infoReader.name() == QLatin1String("targets")) {
-                    while (infoReader.readNextStartElement())
-                        handleMadInfoTargetTag(infoReader, runtimeName, targetName);
-                } else if (infoReader.name() == QLatin1String("runtimes")) {
-                    while (infoReader.readNextStartElement()) {
-                        const MaemoQemuRuntime &rt = handleMadInfoRuntimeTag(infoReader);
-                        if (!rt.m_name.isEmpty() && !rt.m_bin.isEmpty()
-                                && !rt.m_args.isEmpty()) {
-                            runtimes << rt;
-                        }
-                    }
-                } else {
-                    infoReader.skipCurrentElement();
-                }
-            }
-        }
-    }
-    foreach (const MaemoQemuRuntime &rt, runtimes) {
-        if (rt.m_name == runtimeName)
-            return rt;
-    }
-    return MaemoQemuRuntime();
-}
-
-MaemoQemuRuntime MaemoQemuManager::parseRuntimeFromOldMadInfo(const QString &output,
-    const QString &maddeRootPath, const QString &targetName) const
-{
-    QXmlStreamReader infoReader(output);
-    QStringList installedRuntimes;
-    QString targetRuntime;
-    while (!infoReader.atEnd() && !installedRuntimes.contains(targetRuntime)) {
-        if (infoReader.readNext() == QXmlStreamReader::StartElement) {
-            if (targetRuntime.isEmpty()
-                && infoReader.name() == QLatin1String("target")) {
-                const QXmlStreamAttributes &attrs = infoReader.attributes();
-                if (attrs.value(QLatin1String("target_id")) == targetName)
-                    targetRuntime = attrs.value("runtime_id").toString();
-            } else if (infoReader.name() == QLatin1String("runtime")) {
-                const QXmlStreamAttributes attrs = infoReader.attributes();
-                while (!infoReader.atEnd()) {
-                    if (infoReader.readNext() == QXmlStreamReader::EndElement
-                         && infoReader.name() == QLatin1String("runtime"))
-                        break;
-                    if (infoReader.tokenType() == QXmlStreamReader::StartElement
-                        && infoReader.name() == QLatin1String("installed")) {
-                        if (infoReader.readNext() == QXmlStreamReader::Characters
-                            && infoReader.text() == QLatin1String("true")) {
-                            if (attrs.hasAttribute(QLatin1String("runtime_id")))
-                                installedRuntimes << attrs.value(QLatin1String("runtime_id")).toString();
-                            else if (attrs.hasAttribute(QLatin1String("id"))) {
-                                // older MADDE seems to use only id
-                                installedRuntimes << attrs.value(QLatin1String("id")).toString();
-                            }
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    MaemoQemuRuntime runtime;
-    if (installedRuntimes.contains(targetRuntime)) {
-        runtime.m_name = targetRuntime;
-        runtime.m_root = maddeRootPath + QLatin1String("/runtimes/")
-            + targetRuntime;
-        fillRuntimeInformationForOldMadInfo(&runtime);
-    }
-    return runtime;
-}
-
-
-void MaemoQemuManager::handleMadInfoTargetTag(QXmlStreamReader &infoReader,
-    QString &runtimeName, const QString &targetName) const
-{
-    const QXmlStreamAttributes &attrs = infoReader.attributes();
-    if (infoReader.name() == QLatin1String("target") && runtimeName.isEmpty()
-            && attrs.value(QLatin1String("name")) == targetName
-            && attrs.value(QLatin1String("installed")) == QLatin1String("true")) {
-        while (infoReader.readNextStartElement()) {
-            if (infoReader.name() == QLatin1String("runtime"))
-                runtimeName = infoReader.readElementText();
-            else
-                infoReader.skipCurrentElement();
-        }
-    } else {
-        infoReader.skipCurrentElement();
-    }
-}
-
-MaemoQemuRuntime MaemoQemuManager::handleMadInfoRuntimeTag(QXmlStreamReader &infoReader) const
-{
-    MaemoQemuRuntime runtime;
-    const QXmlStreamAttributes &attrs = infoReader.attributes();
-    if (infoReader.name() != QLatin1String("runtime")
-            || attrs.value(QLatin1String("installed")) != QLatin1String("true")) {
-        infoReader.skipCurrentElement();
-        return runtime;
-    }
-    runtime.m_name = attrs.value(QLatin1String("name")).toString();
-    while (infoReader.readNextStartElement()) {
-        if (infoReader.name() == QLatin1String("exec-path")) {
-            runtime.m_bin = infoReader.readElementText();
-        } else if (infoReader.name() == QLatin1String("args")) {
-            runtime.m_args = infoReader.readElementText();
-        } else if (infoReader.name() == QLatin1String("environment")) {
-            runtime.m_environment = handleMadInfoEnvironmentTag(infoReader);
-        } else if (infoReader.name() == QLatin1String("tcpportmap")) {
-            runtime.m_freePorts = handleMadInfoTcpPortListTag(infoReader);
-        } else {
-            infoReader.skipCurrentElement();
-        }
-    }
-    return runtime;
-}
-
-QHash<QString, QString> MaemoQemuManager::handleMadInfoEnvironmentTag(QXmlStreamReader &infoReader) const
-{
-    QHash<QString, QString> env;
-    while (infoReader.readNextStartElement()) {
-        const QPair<QString, QString> &var
-            = handleMadInfoVariableTag(infoReader);
-        if (!var.first.isEmpty())
-            env.insert(var.first, var.second);
-    }
-    return env;
-}
-
-QPair<QString, QString> MaemoQemuManager::handleMadInfoVariableTag(QXmlStreamReader &infoReader) const
-{
-    QPair<QString, QString> var;
-    if (infoReader.name() != QLatin1String("variable")) {
-        infoReader.skipCurrentElement();
-        return var;
-    }
-
-    // TODO: Check for "purpose" attribute and handle "glbackend" in a special way
-    while (infoReader.readNextStartElement()) {
-        if (infoReader.name() == QLatin1String("name"))
-            var.first = infoReader.readElementText();
-        else if (infoReader.name() == QLatin1String("value"))
-            var.second = infoReader.readElementText();
-        else
-            infoReader.skipCurrentElement();
-    }
-    return var;
-}
-
-MaemoPortList MaemoQemuManager::handleMadInfoTcpPortListTag(QXmlStreamReader &infoReader) const
-{
-    MaemoPortList ports;
-    while (infoReader.readNextStartElement()) {
-        const int port = handleMadInfoPortTag(infoReader);
-        if (port != -1 && port != 6666) // TODO: Remove second condition once MADDE has ssh tag
-            ports.addPort(port);
-    }
-    return ports;
-}
-
-int MaemoQemuManager::handleMadInfoPortTag(QXmlStreamReader &infoReader) const
-{
-    int port = -1;
-    if (infoReader.name() == QLatin1String("port")) {
-        while (infoReader.readNextStartElement()) {
-            if (infoReader.name() == QLatin1String("host"))
-                port = infoReader.readElementText().toInt();
-            else
-                infoReader.skipCurrentElement();
-        }
-    }
-    return port;
-}
-
 void MaemoQemuManager::notify(const QList<int> uniqueIds)
 {
     qtVersionsChanged(uniqueIds);
index 5ffa242..c280818 100644 (file)
@@ -42,7 +42,6 @@
 QT_FORWARD_DECLARE_CLASS(QAction);
 QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)
 QT_FORWARD_DECLARE_CLASS(QStringList);
-QT_FORWARD_DECLARE_CLASS(QXmlStreamReader);
 
 namespace ProjectExplorer {
     class BuildConfiguration;
@@ -113,24 +112,6 @@ private:
     bool targetUsesMatchingRuntimeConfig(ProjectExplorer::Target *target,
         QtVersion **qtVersion = 0);
 
-    QString maddeRoot(const QString &qmake) const;
-    QString targetRoot(const QString &qmake) const;
-
-    bool fillRuntimeInformationForOldMadInfo(MaemoQemuRuntime *runtime) const;
-    void setEnvironment(MaemoQemuRuntime *runTime, const QString &envSpec) const;
-    MaemoQemuRuntime createRuntime(const QtVersion *qtVersion) const;
-    MaemoQemuRuntime parseRuntimeFromMadInfo(const QByteArray &output,
-        const QString &targetName) const;
-    MaemoQemuRuntime parseRuntimeFromOldMadInfo(const QString &output,
-        const QString &maddeRootPath, const QString &targetName) const;
-    void handleMadInfoTargetTag(QXmlStreamReader &infoReader,
-        QString &runtimeName, const QString &targetName) const;
-    MaemoQemuRuntime handleMadInfoRuntimeTag(QXmlStreamReader &infoReader) const;
-    QHash<QString, QString> handleMadInfoEnvironmentTag(QXmlStreamReader &infoReader) const;
-    QPair<QString, QString> handleMadInfoVariableTag(QXmlStreamReader &infoReader) const;
-    MaemoPortList handleMadInfoTcpPortListTag(QXmlStreamReader &infoReader) const;
-    int handleMadInfoPortTag(QXmlStreamReader &infoReader) const;
-
     void notify(const QList<int> uniqueIds);
     void toggleDeviceConnections(MaemoRunConfiguration *mrc, bool connect);
 
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.cpp
new file mode 100644 (file)
index 0000000..b64370a
--- /dev/null
@@ -0,0 +1,367 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 "maemoqemuruntimeparser.h"
+
+#include "maemoglobal.h"
+
+#include <qt4projectmanager/qtversionmanager.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QProcess>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class MaemoQemuRuntimeParserV1 : public MaemoQemuRuntimeParser
+{
+public:
+    MaemoQemuRuntimeParserV1(const QString &madInfoOutput,
+        const QString &targetName, const QString &maddeRoot);
+    MaemoQemuRuntime parseRuntime();
+
+private:
+    void fillRuntimeInformation(MaemoQemuRuntime *runtime) const;
+    void setEnvironment(MaemoQemuRuntime *runTime, const QString &envSpec) const;
+
+    const QString m_maddeRoot;
+};
+
+class MaemoQemuRuntimeParserV2 : public MaemoQemuRuntimeParser
+{
+public:
+    MaemoQemuRuntimeParserV2(const QString &madInfoOutput,
+        const QString &targetName);
+    MaemoQemuRuntime parseRuntime();
+
+private:
+    void handleTargetTag(QString &runtimeName);
+    MaemoQemuRuntime handleRuntimeTag();
+    QHash<QString, QString> handleEnvironmentTag();
+    QPair<QString, QString> handleVariableTag();
+    MaemoPortList handleTcpPortListTag();
+    int handlePortTag();
+};
+
+MaemoQemuRuntimeParser::MaemoQemuRuntimeParser(const QString &madInfoOutput,
+    const QString &targetName)
+    : m_madInfoReader(madInfoOutput), m_targetName(targetName)
+{
+}
+
+MaemoQemuRuntime MaemoQemuRuntimeParser::parseRuntime(const QtVersion *qtVersion)
+{
+    MaemoQemuRuntime runtime;
+    const QString maddeRootPath
+        = MaemoGlobal::maddeRoot(qtVersion->qmakeCommand());
+    const QString madCommand = maddeRootPath + QLatin1String("/bin/mad");
+    if (!QFileInfo(madCommand).exists())
+        return runtime;
+    QProcess madProc;
+    MaemoGlobal::callMaddeShellScript(madProc, maddeRootPath, madCommand,
+        QStringList() << QLatin1String("info"));
+    if (!madProc.waitForStarted() || !madProc.waitForFinished())
+        return runtime;
+    const QByteArray &madInfoOutput = madProc.readAllStandardOutput();
+    const QString &targetName
+        = MaemoGlobal::targetName(qtVersion->qmakeCommand());
+    runtime = MaemoQemuRuntimeParserV2(madInfoOutput, targetName).parseRuntime();
+    if (!runtime.m_name.isEmpty()) {
+        runtime.m_root = maddeRootPath + QLatin1String("/runtimes/")
+            + runtime.m_name;
+
+        // TODO: Workaround for missing ssh tag. Fix once MADDE is ready.
+        runtime.m_sshPort = QLatin1String("6666");
+    } else {
+        runtime = MaemoQemuRuntimeParserV1(madInfoOutput, targetName,
+            maddeRootPath).parseRuntime();
+    }
+    runtime.m_watchPath = runtime.m_root
+        .left(runtime.m_root.lastIndexOf(QLatin1Char('/')));
+
+    return runtime;
+}
+
+MaemoQemuRuntimeParserV1::MaemoQemuRuntimeParserV1(const QString &madInfoOutput,
+    const QString &targetName, const QString &maddeRoot)
+    : MaemoQemuRuntimeParser(madInfoOutput, targetName), m_maddeRoot(maddeRoot)
+{
+}
+
+MaemoQemuRuntime MaemoQemuRuntimeParserV1::parseRuntime()
+{
+    QStringList installedRuntimes;
+    QString targetRuntime;
+    while (!m_madInfoReader.atEnd() && !installedRuntimes.contains(targetRuntime)) {
+        if (m_madInfoReader.readNext() == QXmlStreamReader::StartElement) {
+            if (targetRuntime.isEmpty()
+                && m_madInfoReader.name() == QLatin1String("target")) {
+                const QXmlStreamAttributes &attrs = m_madInfoReader.attributes();
+                if (attrs.value(QLatin1String("target_id")) == targetName())
+                    targetRuntime = attrs.value("runtime_id").toString();
+            } else if (m_madInfoReader.name() == QLatin1String("runtime")) {
+                const QXmlStreamAttributes attrs = m_madInfoReader.attributes();
+                while (!m_madInfoReader.atEnd()) {
+                    if (m_madInfoReader.readNext() == QXmlStreamReader::EndElement
+                         && m_madInfoReader.name() == QLatin1String("runtime"))
+                        break;
+                    if (m_madInfoReader.tokenType() == QXmlStreamReader::StartElement
+                        && m_madInfoReader.name() == QLatin1String("installed")) {
+                        if (m_madInfoReader.readNext() == QXmlStreamReader::Characters
+                            && m_madInfoReader.text() == QLatin1String("true")) {
+                            if (attrs.hasAttribute(QLatin1String("runtime_id")))
+                                installedRuntimes << attrs.value(QLatin1String("runtime_id")).toString();
+                            else if (attrs.hasAttribute(QLatin1String("id"))) {
+                                // older MADDE seems to use only id
+                                installedRuntimes << attrs.value(QLatin1String("id")).toString();
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    MaemoQemuRuntime runtime;
+    if (installedRuntimes.contains(targetRuntime)) {
+        runtime.m_name = targetRuntime;
+        runtime.m_root = m_maddeRoot + QLatin1String("/runtimes/")
+            + targetRuntime;
+        fillRuntimeInformation(&runtime);
+    }
+    return runtime;
+
+}
+
+void MaemoQemuRuntimeParserV1::fillRuntimeInformation(MaemoQemuRuntime *runtime) const
+{
+    const QStringList files = QDir(runtime->m_root).entryList(QDir::Files
+        | QDir::NoSymLinks | QDir::NoDotAndDotDot);
+
+    const QLatin1String infoFile("information");
+    if (files.contains(infoFile)) {
+        QFile file(runtime->m_root + QLatin1Char('/') + infoFile);
+        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+            QMap<QString, QString> map;
+            QTextStream stream(&file);
+            while (!stream.atEnd()) {
+                const QString &line = stream.readLine().trimmed();
+                const int index = line.indexOf(QLatin1Char('='));
+                map.insert(line.mid(0, index).remove(QLatin1Char('\'')),
+                    line.mid(index + 1).remove(QLatin1Char('\'')));
+            }
+
+            runtime->m_bin = map.value(QLatin1String("qemu"));
+            runtime->m_args = map.value(QLatin1String("qemu_args"));
+            setEnvironment(runtime, map.value(QLatin1String("libpath")));
+            runtime->m_sshPort = map.value(QLatin1String("sshport"));
+            runtime->m_freePorts = MaemoPortList();
+            int i = 2;
+            while (true) {
+                const QString port = map.value(QLatin1String("redirport")
+                    + QString::number(i++));
+                if (port.isEmpty())
+                    break;
+                runtime->m_freePorts.addPort(port.toInt());
+            }
+            return;
+        }
+    }
+}
+
+void MaemoQemuRuntimeParserV1::setEnvironment(MaemoQemuRuntime *runTime,
+    const QString &envSpec) const
+{
+    QString remainingEnvSpec = envSpec;
+    QString currentKey;
+    while (true) {
+        const int nextEqualsSignPos
+            = remainingEnvSpec.indexOf(QLatin1Char('='));
+        if (nextEqualsSignPos == -1) {
+            if (!currentKey.isEmpty())
+                runTime->m_environment.insert(currentKey, remainingEnvSpec);
+            break;
+        }
+        const int keyStartPos
+            = remainingEnvSpec.lastIndexOf(QRegExp(QLatin1String("\\s")),
+                nextEqualsSignPos) + 1;
+        if (!currentKey.isEmpty()) {
+            const int valueEndPos
+                = remainingEnvSpec.lastIndexOf(QRegExp(QLatin1String("\\S")),
+                    qMax(0, keyStartPos - 1)) + 1;
+            runTime->m_environment.insert(currentKey,
+                remainingEnvSpec.left(valueEndPos));
+        }
+        currentKey = remainingEnvSpec.mid(keyStartPos,
+            nextEqualsSignPos - keyStartPos);
+        remainingEnvSpec.remove(0, nextEqualsSignPos + 1);
+    }
+}
+
+
+MaemoQemuRuntimeParserV2::MaemoQemuRuntimeParserV2(const QString &madInfoOutput,
+    const QString &targetName)
+    : MaemoQemuRuntimeParser(madInfoOutput, targetName)
+{
+}
+
+MaemoQemuRuntime MaemoQemuRuntimeParserV2::parseRuntime()
+{
+    QString runtimeName;
+    QList<MaemoQemuRuntime> runtimes;
+    while (m_madInfoReader.readNextStartElement()) {
+        if (m_madInfoReader.name() == QLatin1String("madde")) {
+            while (m_madInfoReader.readNextStartElement()) {
+                if (m_madInfoReader.name() == QLatin1String("targets")) {
+                    while (m_madInfoReader.readNextStartElement())
+                        handleTargetTag(runtimeName);
+                } else if (m_madInfoReader.name() == QLatin1String("runtimes")) {
+                    while (m_madInfoReader.readNextStartElement()) {
+                        const MaemoQemuRuntime &rt = handleRuntimeTag();
+                        if (!rt.m_name.isEmpty() && !rt.m_bin.isEmpty()
+                                && !rt.m_args.isEmpty()) {
+                            runtimes << rt;
+                        }
+                    }
+                } else {
+                    m_madInfoReader.skipCurrentElement();
+                }
+            }
+        }
+    }
+    foreach (const MaemoQemuRuntime &rt, runtimes) {
+        if (rt.m_name == runtimeName)
+            return rt;
+    }
+    return MaemoQemuRuntime();
+}
+
+void MaemoQemuRuntimeParserV2::handleTargetTag(QString &runtimeName)
+{
+    const QXmlStreamAttributes &attrs = m_madInfoReader.attributes();
+    if (m_madInfoReader.name() == QLatin1String("target") && runtimeName.isEmpty()
+            && attrs.value(QLatin1String("name")) == targetName()
+            && attrs.value(QLatin1String("installed")) == QLatin1String("true")) {
+        while (m_madInfoReader.readNextStartElement()) {
+            if (m_madInfoReader.name() == QLatin1String("runtime"))
+                runtimeName = m_madInfoReader.readElementText();
+            else
+                m_madInfoReader.skipCurrentElement();
+        }
+    } else {
+        m_madInfoReader.skipCurrentElement();
+    }
+}
+
+MaemoQemuRuntime MaemoQemuRuntimeParserV2::handleRuntimeTag()
+{
+    MaemoQemuRuntime runtime;
+    const QXmlStreamAttributes &attrs = m_madInfoReader.attributes();
+    if (m_madInfoReader.name() != QLatin1String("runtime")
+            || attrs.value(QLatin1String("installed")) != QLatin1String("true")) {
+        m_madInfoReader.skipCurrentElement();
+        return runtime;
+    }
+    runtime.m_name = attrs.value(QLatin1String("name")).toString();
+    while (m_madInfoReader.readNextStartElement()) {
+        if (m_madInfoReader.name() == QLatin1String("exec-path")) {
+            runtime.m_bin = m_madInfoReader.readElementText();
+        } else if (m_madInfoReader.name() == QLatin1String("args")) {
+            runtime.m_args = m_madInfoReader.readElementText();
+        } else if (m_madInfoReader.name() == QLatin1String("environment")) {
+            runtime.m_environment = handleEnvironmentTag();
+        } else if (m_madInfoReader.name() == QLatin1String("tcpportmap")) {
+            runtime.m_freePorts = handleTcpPortListTag();
+        } else {
+            m_madInfoReader.skipCurrentElement();
+        }
+    }
+    return runtime;
+}
+
+QHash<QString, QString> MaemoQemuRuntimeParserV2::handleEnvironmentTag()
+{
+    QHash<QString, QString> env;
+    while (m_madInfoReader.readNextStartElement()) {
+        const QPair<QString, QString> &var = handleVariableTag();
+        if (!var.first.isEmpty())
+            env.insert(var.first, var.second);
+    }
+    return env;
+}
+
+QPair<QString, QString> MaemoQemuRuntimeParserV2::handleVariableTag()
+{
+    QPair<QString, QString> var;
+    if (m_madInfoReader.name() != QLatin1String("variable")) {
+        m_madInfoReader.skipCurrentElement();
+        return var;
+    }
+
+    // TODO: Check for "purpose" attribute and handle "glbackend" in a special way
+    while (m_madInfoReader.readNextStartElement()) {
+        if (m_madInfoReader.name() == QLatin1String("name"))
+            var.first = m_madInfoReader.readElementText();
+        else if (m_madInfoReader.name() == QLatin1String("value"))
+            var.second = m_madInfoReader.readElementText();
+        else
+            m_madInfoReader.skipCurrentElement();
+    }
+    return var;
+}
+
+MaemoPortList MaemoQemuRuntimeParserV2::handleTcpPortListTag()
+{
+    MaemoPortList ports;
+    while (m_madInfoReader.readNextStartElement()) {
+        const int port = handlePortTag();
+        if (port != -1 && port != 6666) // TODO: Remove second condition once MADDE has ssh tag
+            ports.addPort(port);
+    }
+    return ports;
+}
+
+int MaemoQemuRuntimeParserV2::handlePortTag()
+{
+    int port = -1;
+    if (m_madInfoReader.name() == QLatin1String("port")) {
+        while (m_madInfoReader.readNextStartElement()) {
+            if (m_madInfoReader.name() == QLatin1String("host"))
+                port = m_madInfoReader.readElementText().toInt();
+            else
+                m_madInfoReader.skipCurrentElement();
+        }
+    }
+    return port;
+}
+
+}   // namespace Internal
+}   // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.h b/src/plugins/qt4projectmanager/qt-maemo/maemoqemuruntimeparser.h
new file mode 100644 (file)
index 0000000..4592093
--- /dev/null
@@ -0,0 +1,60 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 MAEMOQEMURUNTIMEPARSER_H
+#define MAEMOQEMURUNTIMEPARSER_H
+
+#include "maemoqemuruntime.h"
+
+#include <QtCore/QString>
+#include <QtXml/QXmlStreamReader>
+
+namespace Qt4ProjectManager {
+class QtVersion;
+namespace Internal {
+
+class MaemoQemuRuntimeParser
+{
+public:
+    static MaemoQemuRuntime parseRuntime(const QtVersion *qtVersion);
+
+protected:
+    MaemoQemuRuntimeParser(const QString &madInfoOutput,
+        const QString &targetName);
+    const QString &targetName() const { return m_targetName; }
+
+    QXmlStreamReader m_madInfoReader;
+
+private:
+    const QString m_targetName;
+};
+
+}   // namespace Internal
+}   // namespace Qt4ProjectManager
+
+#endif // MAEMOQEMURUNTIMEPARSER_H
index e8051fa..2b5852b 100644 (file)
@@ -42,7 +42,8 @@ HEADERS += \
     $$PWD/maemopublishingwizardfremantlefree.h \
     $$PWD/maemopublishingresultpagefremantlefree.h \
     $$PWD/maemopublisherfremantlefree.h \
-    $$PWD/maemoqemuruntime.h
+    $$PWD/maemoqemuruntime.h \
+    qt-maemo/maemoqemuruntimeparser.h
 
 SOURCES += \
     $$PWD/maemoconfigtestdialog.cpp \
@@ -85,7 +86,8 @@ SOURCES += \
     $$PWD/maemopublishinguploadsettingspagefremantlefree.cpp \
     $$PWD/maemopublishingwizardfremantlefree.cpp \
     $$PWD/maemopublishingresultpagefremantlefree.cpp \
-    $$PWD/maemopublisherfremantlefree.cpp
+    $$PWD/maemopublisherfremantlefree.cpp \
+    qt-maemo/maemoqemuruntimeparser.cpp
 
 FORMS += \
     $$PWD/maemoconfigtestdialog.ui \