From ede779e3c7f9224f427ba2410a75ed6bb2c94e2d Mon Sep 17 00:00:00 2001 From: Christian Kandeler <christian.kandeler@nokia.com> Date: Tue, 30 Nov 2010 13:45:15 +0100 Subject: [PATCH] Maemo: Support new "mad info" schema. Reviewed-by: kh1 --- .../qt-maemo/maemoqemumanager.cpp | 200 +++++++++++++++--- .../qt-maemo/maemoqemumanager.h | 18 +- 2 files changed, 192 insertions(+), 26 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp index cee546f2067..dffe4bc06dc 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.cpp @@ -157,14 +157,10 @@ void MaemoQemuManager::qtVersionsChanged(const QList<int> &uniqueIds) if (manager->isValidId(uniqueId)) { QtVersion *version = manager->version(uniqueId); if (version->supportsTargetId(Constants::MAEMO_DEVICE_TARGET_ID)) { - const QString &qmake = version->qmakeCommand(); - const QString &runtimeRoot = runtimeForQtVersion(qmake); - if (!runtimeRoot.isEmpty()) { - Runtime runtime(runtimeRoot); - if (QFile::exists(runtimeRoot)) - fillRuntimeInformation(&runtime); + Runtime runtime = createRuntime(version); + if (runtime.isValid()) { runtime.m_watchPath = - runtimeRoot.left(runtimeRoot.lastIndexOf(QLatin1Char('/'))); + 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); @@ -609,7 +605,7 @@ QString MaemoQemuManager::targetRoot(const QString &qmake) const return target.mid(target.lastIndexOf(QLatin1Char('/')) + 1); } -bool MaemoQemuManager::fillRuntimeInformation(Runtime *runtime) const +bool MaemoQemuManager::fillRuntimeInformationForOldMadInfo(Runtime *runtime) const { const QStringList files = QDir(runtime->m_root).entryList(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot); @@ -676,31 +672,79 @@ void MaemoQemuManager::setEnvironment(Runtime *runTime, } } -QString MaemoQemuManager::runtimeForQtVersion(const QString &qmakeCommand) const +Runtime MaemoQemuManager::createRuntime(const QtVersion *qtVersion) const { - const QString &target = targetRoot(qmakeCommand); - const QString &madRoot = maddeRoot(qmakeCommand); - - const QString madCommand = madRoot + QLatin1String("/bin/mad"); + Runtime runtime; + const QString maddeRootPath = maddeRoot(qtVersion->qmakeCommand()); + const QString madCommand = maddeRootPath + QLatin1String("/bin/mad"); if (!QFileInfo(madCommand).exists()) - return QString(); - + return runtime; QProcess madProc; - const QStringList arguments(QLatin1String("info")); - - MaemoGlobal::callMaddeShellScript(madProc, madRoot, madCommand, arguments); + MaemoGlobal::callMaddeShellScript(madProc, maddeRootPath, madCommand, + QStringList() << QLatin1String("info")); if (!madProc.waitForStarted() || !madProc.waitForFinished()) - return QString(); + 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); + } +} + +Runtime MaemoQemuManager::parseRuntimeFromMadInfo(const QByteArray &output, + const QString &targetName) const +{ + QXmlStreamReader infoReader(output); + QString runtimeName; + QList<Runtime> 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 Runtime &rt = handleMadInfoRuntimeTag(infoReader); + if (!rt.m_name.isEmpty() && !rt.m_bin.isEmpty() + && !rt.m_args.isEmpty()) { + runtimes << rt; + } + } + } else { + infoReader.skipCurrentElement(); + } + } + } + } + foreach (const Runtime &rt, runtimes) { + if (rt.m_name == runtimeName) + return rt; + } + return Runtime(); +} +Runtime MaemoQemuManager::parseRuntimeFromOldMadInfo(const QString &output, + const QString &maddeRootPath, const QString &targetName) const +{ + QXmlStreamReader infoReader(output); QStringList installedRuntimes; QString targetRuntime; - QXmlStreamReader infoReader(madProc.readAllStandardOutput()); 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")) == target) + if (attrs.value(QLatin1String("target_id")) == targetName) targetRuntime = attrs.value("runtime_id").toString(); } else if (infoReader.name() == QLatin1String("runtime")) { const QXmlStreamAttributes attrs = infoReader.attributes(); @@ -725,9 +769,117 @@ QString MaemoQemuManager::runtimeForQtVersion(const QString &qmakeCommand) const } } } - if (installedRuntimes.contains(targetRuntime)) - return madRoot + QLatin1String("/runtimes/") + targetRuntime; - return QString(); + + Runtime 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(); + } +} + +Runtime MaemoQemuManager::handleMadInfoRuntimeTag(QXmlStreamReader &infoReader) const +{ + Runtime 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) diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h b/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h index 6222ea972c1..605af072fe3 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoqemumanager.h @@ -43,6 +43,7 @@ QT_FORWARD_DECLARE_CLASS(QAction); QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher) QT_FORWARD_DECLARE_CLASS(QStringList); +QT_FORWARD_DECLARE_CLASS(QXmlStreamReader); namespace ProjectExplorer { class BuildConfiguration; @@ -56,6 +57,7 @@ namespace Qt4ProjectManager { namespace Internal { class MaemoRunConfiguration; +// TODO: Rename to something more unique struct Runtime { Runtime() {} @@ -65,6 +67,7 @@ struct Runtime return !m_bin.isEmpty(); } + QString m_name; QString m_bin; QString m_root; QString m_args; @@ -133,9 +136,20 @@ private: QString maddeRoot(const QString &qmake) const; QString targetRoot(const QString &qmake) const; - bool fillRuntimeInformation(Runtime *runtime) const; + bool fillRuntimeInformationForOldMadInfo(Runtime *runtime) const; void setEnvironment(Runtime *runTime, const QString &envSpec) const; - QString runtimeForQtVersion(const QString &qmakeCommand) const; + Runtime createRuntime(const QtVersion *qtVersion) const; + Runtime parseRuntimeFromMadInfo(const QByteArray &output, + const QString &targetName) const; + Runtime parseRuntimeFromOldMadInfo(const QString &output, + const QString &maddeRootPath, const QString &targetName) const; + void handleMadInfoTargetTag(QXmlStreamReader &infoReader, + QString &runtimeName, const QString &targetName) const; + Runtime 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); -- GitLab