aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Hunger <[email protected]>2012-09-18 15:58:07 +0200
committerTim Jenssen <[email protected]>2012-09-21 17:07:10 +0200
commit4f36ad63ce7d04cf2cba561ace7600efedcdf3ca (patch)
tree385a5460f2bc1a2d846358086123030e11ff2d14
parent9c2afc4f29345c625363cfc6b474bd41e586a3fd (diff)
Add sdktool
Add a tool to ease configuration of Qt versions, tool chains and kits with Qt Creator for the SDK and similar systems. Change-Id: I9727dd25ea359a935ea494b035a59411eb3529b8 Reviewed-by: Tim Jenssen <[email protected]>
-rw-r--r--qtcreator.qbp3
-rw-r--r--src/tools/sdktool/README.txt135
-rw-r--r--src/tools/sdktool/addkeysoperation.cpp264
-rw-r--r--src/tools/sdktool/addkeysoperation.h59
-rw-r--r--src/tools/sdktool/addkitoperation.cpp382
-rw-r--r--src/tools/sdktool/addkitoperation.h76
-rw-r--r--src/tools/sdktool/addqtoperation.cpp280
-rw-r--r--src/tools/sdktool/addqtoperation.h67
-rw-r--r--src/tools/sdktool/addtoolchainoperation.cpp280
-rw-r--r--src/tools/sdktool/addtoolchainoperation.h70
-rw-r--r--src/tools/sdktool/findkeyoperation.cpp130
-rw-r--r--src/tools/sdktool/findkeyoperation.h58
-rw-r--r--src/tools/sdktool/findvalueoperation.cpp135
-rw-r--r--src/tools/sdktool/findvalueoperation.h58
-rw-r--r--src/tools/sdktool/getoperation.cpp126
-rw-r--r--src/tools/sdktool/getoperation.h58
-rw-r--r--src/tools/sdktool/main.cpp185
-rw-r--r--src/tools/sdktool/operation.cpp131
-rw-r--r--src/tools/sdktool/operation.h75
-rw-r--r--src/tools/sdktool/rmkeysoperation.cpp211
-rw-r--r--src/tools/sdktool/rmkeysoperation.h58
-rw-r--r--src/tools/sdktool/rmkitoperation.cpp209
-rw-r--r--src/tools/sdktool/rmkitoperation.h59
-rw-r--r--src/tools/sdktool/rmqtoperation.cpp152
-rw-r--r--src/tools/sdktool/rmqtoperation.h59
-rw-r--r--src/tools/sdktool/rmtoolchainoperation.cpp162
-rw-r--r--src/tools/sdktool/rmtoolchainoperation.h59
-rw-r--r--src/tools/sdktool/sdktool.pro44
-rw-r--r--src/tools/sdktool/sdktool.qbs40
-rw-r--r--src/tools/sdktool/settings.cpp100
-rw-r--r--src/tools/sdktool/settings.h56
-rw-r--r--src/tools/tools.pro3
32 files changed, 3782 insertions, 2 deletions
diff --git a/qtcreator.qbp b/qtcreator.qbp
index 6fa81f2a343..7e73414f74e 100644
--- a/qtcreator.qbp
+++ b/qtcreator.qbp
@@ -80,7 +80,8 @@ Project {
"src/plugins/welcome/welcome.qbs",
"src/share/share.qbs",
"src/tools/qtcdebugger/qtcdebugger.qbs",
- "src/tools/qtpromaker/qtpromaker.qbs"
+ "src/tools/qtpromaker/qtpromaker.qbs",
+ "src/tools/sdktool/sdktool.qbs"
]
Product {
diff --git a/src/tools/sdktool/README.txt b/src/tools/sdktool/README.txt
new file mode 100644
index 00000000000..be6f2225ff3
--- /dev/null
+++ b/src/tools/sdktool/README.txt
@@ -0,0 +1,135 @@
+The SDK tool can be used to set up Qt versions, tool chains and kits
+in Qt Creator.
+
+There still is a lot of knowledge about Qt Creator internals required
+to use this tool!
+
+Note that some tool chains/Qt versions/kits may require settings not
+available via command line switches. All operations will add any parameter
+followed by another parameter in the form "<TYPE>:<VALUE>" to the
+configuration that they create.
+
+Currently supported types are int, bool, QString, QByteArray and QVariantList.
+
+Dependencies:
+The SDK tool depends on the Utils library of Qt Creator and Qt itself.
+Please make sure both libraries are found by setting PATH/LD_LIBRARY_PATH.
+
+Usage:
+Qt Creator SDK setup tool.
+ Usage:./sdktool <ARGS> <OPERATION> <OPERATION_ARGS>
+
+ARGS:
+ --help|-h Print this help text
+ --sdkpath=PATH|-s PATH Set the path to the SDK files
+
+OPERATION:
+ One of:
+ addKeys add settings to Qt Creator configuration
+ addKit add a Kit to Qt Creator
+ addQt add a Qt version to Qt Creator
+ addTC add a tool chain to Qt Creator
+ findKey find a key in the settings of Qt Creator
+ find find a value in the settings of Qt Creator
+ get get settings from Qt Creator configuration
+ rmKeys remove settings from Qt Creator configuration
+ rmKit remove a Kit from Qt Creator
+ rmQt remove a Qt version from Qt Creator
+ rmTC remove a tool chain from Qt Creator
+
+OPERATION_ARGS:
+ use "--help <OPERATION>" to get help on the arguments required for an operation.
+
+
+Help for individual operations can be retrieved using
+
+ ./sdktool --help addKit
+
+Examples:
+
+Add a tool chain:
+./sdktool addTC \
+ --id "ProjectExplorer.ToolChain.Gcc:my_test_TC" \
+ --name "Test TC" \
+ --path /usr/bin/g++ \
+ --abi x86-linux-generic-elf-64bit \
+ --supportedAbis x86-linux-generic-elf-64bit,x86-linux-generic-elf-32bit \
+ ADDITIONAL_INTEGER_PARAMETER int:42 \
+ ADDITIONAL_STRING_PARAMETER "QString:some string" \
+
+Tricky parts:
+ - The id has to be in the form "ToolChainType:some_unique_part", where the
+ tool chain type must be one of (as of Qt Creator 2.6):
+ * ProjectExplorer.ToolChain.Msvc for Microsoft MSVC compilers
+ (Note: This one will be autodetected anyway, so there is little
+ need to add it from the sdktool)
+ * ProjectExplorer.ToolChain.WinCE for Windows CE tool chain by
+ Microsoft (Note: This one will be autodetected anyway, so there
+ is little need to add it from the sdktool)
+ * ProjectExplorer.ToolChain.Gcc for a normal GCC (linux/mac)
+ * Qt4ProjectManager.ToolChain.Android for the Android tool chain
+ * ProjectExplorer.ToolChain.Clang for the Clang compiler
+ * ProjectExplorer.ToolChain.LinuxIcc for the LinuxICC compiler
+ * ProjectExplorer.ToolChain.Mingw for the Mingw compiler
+
+ Check the classes derived from ProjectExplorer::ToolChain for their
+ Ids.
+
+ The some_unique_part can be anything. Creator uses GUIDs by default,
+ but any string is fine for the SDK to use.
+
+ - The ABI needs to be in a format that ProjectExplorer::Abi::fromString(...)
+ can parse.
+
+Add a Qt version:
+./sdktool addQt \
+ --id "my_test_Qt" \
+ --name "Test Qt" \
+ --qmake /home/code/build/qt4-4/bin/qmake \
+ --type Qt4ProjectManager.QtVersion.Desktop \
+
+Tricky parts:
+ - The id can be any unique string. In creator this is set as the autodetection
+ source of the Qt version.
+
+ - type must be the string returned by BaseQtVersion::type().
+
+ Currently these are (Qt Creator 2.6):
+ * Qt4ProjectManager.QtVersion.Android for Android
+ * Qt4ProjectManager.QtVersion.Desktop for a desktop Qt
+ * RemoteLinux.EmbeddedLinuxQt for an embedded linux Qt
+ * Qt4ProjectManager.QtVersion.Maemo for an Maemo Qt
+ * Qt4ProjectManager.QtVersion.QNX.BlackBerry for Qt on BlackBerry
+ * Qt4ProjectManager.QtVersion.QNX.QNX for Qt on QNX
+ * Qt4ProjectManager.QtVersion.Simulator for Qt running in the Qt simulator
+ * Qt4ProjectManager.QtVersion.WinCE for Qt on WinCE
+
+Add a Kit using the newly set up tool chain and Qt version:
+./sdktool addKit \
+ --id "my_test_kit" \
+ --name "Test Kit" \
+ --debuggerengine 1 \
+ --debugger /tmp/gdb-test \
+ --devicetype Desktop \
+ --sysroot /tmp/sysroot \
+ --toolchain "ProjectExplorer.ToolChain.Gcc:my_test_TC" \
+ --qt "my_test_Qt" \
+ --mkspec "testspec" \
+
+Tricky parts:
+ - debuggerengine is the integer used in the enum Debugger::DebuggerEngineType
+ The most important type is 1 for GDB.
+
+ - devicetype is the string returned IDevice::type()
+
+ Currently these are (Qt Creator 2.6):
+ * Android.Device.Type for Android devices
+ * Desktop for code running on the local desktop
+ * BBOsType for BlackBerry devices
+ * HarmattanOsType for N9/N950 devices based on Harmattan
+ * Maemo5OsType for N900 devices based on Maemo
+
+ - toolchain is one of the ids used when setting up toolchains with sdktool addTC.
+
+ - qt is one of the ids used when setting up Qt versions with sdktool addQt.
+
diff --git a/src/tools/sdktool/addkeysoperation.cpp b/src/tools/sdktool/addkeysoperation.cpp
new file mode 100644
index 00000000000..4cc898088a1
--- /dev/null
+++ b/src/tools/sdktool/addkeysoperation.cpp
@@ -0,0 +1,264 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "addkeysoperation.h"
+
+#include <iostream>
+
+QString AddKeysOperation::name() const
+{
+ return QLatin1String("addKeys");
+}
+
+QString AddKeysOperation::helpText() const
+{
+ return QLatin1String("add settings to Qt Creator configuration");
+}
+
+QString AddKeysOperation::argumentsHelpText() const
+{
+ return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more Tuples\n"
+ "<KEY> <TYPE>:<VALUE> are required. KEY needs to start with\n"
+ "the name of the file to insert data into (minus the .xml extension).");
+}
+
+bool AddKeysOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (m_file.isNull()) {
+ m_file = current;
+ continue;
+ }
+
+ if (next.isNull())
+ return false;
+
+ ++i;
+ KeyValuePair pair(current, next);
+ if (pair.key.isEmpty() || !pair.value.isValid())
+ return false;
+ m_data << pair;
+ }
+
+ return !m_file.isEmpty();
+}
+
+int AddKeysOperation::execute() const
+{
+ if (m_data.isEmpty())
+ return 0;
+
+ QVariantMap map = load(m_file);
+
+ map = addKeys(map, m_data);
+ if (map.isEmpty())
+ return 1;
+
+ // Write data again:
+ return save(map, m_file) ? 0 : 2;
+}
+
+#ifdef WITH_TESTS
+bool AddKeysOperation::test() const
+{
+ QVariantMap testMap;
+ QVariantMap subKeys;
+ subKeys.insert(QLatin1String("subsubkeys"), QVariantMap());
+ subKeys.insert(QLatin1String("testbool"), true);
+ testMap.insert(QLatin1String("subkeys"), subKeys);
+ subKeys.clear();
+ testMap.insert(QLatin1String("subkeys2"), subKeys);
+ testMap.insert(QLatin1String("testint"), 23);
+
+ KeyValuePairList data;
+ data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
+ data.append(KeyValuePair(QLatin1String("bool-false"), QString::fromLatin1("bool:false")));
+ data.append(KeyValuePair(QLatin1String("int"), QString::fromLatin1("int:42")));
+ data.append(KeyValuePair(QLatin1String("qstring"), QString::fromLatin1("QString:test string.")));
+ data.append(KeyValuePair(QLatin1String("qbytearray"), QString::fromLatin1("QByteArray:test array.")));
+
+ data.append(KeyValuePair(QLatin1String("subkeys/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
+ data.append(KeyValuePair(QLatin1String("subkeys/newsubkeys/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
+ data.append(KeyValuePair(QLatin1String("newsub/1/2/3/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
+ data.append(KeyValuePair(QLatin1String("newsub/1/2.1/3/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
+
+ QVariantMap result = addKeys(testMap, data);
+ if (!result.count() == 8)
+ return false;
+
+ // subkeys:
+ QVariantMap cur = result.value(QLatin1String("subkeys")).toMap();
+ if (cur.count() != 4
+ || !cur.contains(QLatin1String("qbytearray"))
+ || !cur.contains(QLatin1String("testbool"))
+ || !cur.contains(QLatin1String("subsubkeys"))
+ || !cur.contains(QLatin1String("newsubkeys")))
+ return false;
+
+ // subkeys/newsubkeys:
+ QVariantMap tmp = cur;
+ cur = cur.value(QLatin1String("newsubkeys")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("qbytearray")))
+ return false;
+
+ // subkeys/subsubkeys:
+ cur = tmp.value(QLatin1String("subsubkeys")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ // newsub:
+ cur = result.value(QLatin1String("newsub")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("1")))
+ return false;
+
+ // newsub/1:
+ cur = cur.value(QLatin1String("1")).toMap();
+ if (cur.count() != 2
+ || !cur.contains(QLatin1String("2"))
+ || !cur.contains(QLatin1String("2.1")))
+ return false;
+
+ // newsub/1/2:
+ tmp = cur;
+ cur = cur.value(QLatin1String("2")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("3")))
+ return false;
+
+ // newsub/1/2/3:
+ cur = cur.value(QLatin1String("3")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("qbytearray")))
+ return false;
+
+ // newsub/1/2.1:
+ cur = tmp.value(QLatin1String("2.1")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("3")))
+ return false;
+
+ // newsub/1/2.1/3:
+ cur = cur.value(QLatin1String("3")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("qbytearray")))
+ return false;
+
+ // subkeys2:
+ cur = result.value(QLatin1String("subkeys2")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ // values:
+ if (!result.contains(QLatin1String("bool-true")) || !result.value(QLatin1String("bool-true")).toBool())
+ return false;
+ if (!result.contains(QLatin1String("bool-false")) || result.value(QLatin1String("bool-false")).toBool())
+ return false;
+ if (!result.contains(QLatin1String("int")) || result.value(QLatin1String("int")).toInt() != 42)
+ return false;
+ if (!result.contains(QLatin1String("qstring"))
+ || result.value(QLatin1String("qstring")).toString() != QLatin1String("test string."))
+ return false;
+ if (!result.contains(QLatin1String("qbytearray"))
+ || result.value(QLatin1String("qbytearray")).toByteArray() != "test array.")
+ return false;
+
+ // Make sure we do not overwrite data:
+ // preexisting:
+ data.clear();
+ data.append(KeyValuePair(QLatin1String("testint"), QString::fromLatin1("int:4")));
+ result = addKeys(testMap, data);
+ if (!result.isEmpty())
+ return false;
+
+ data.clear();
+ data.append(KeyValuePair(QLatin1String("subkeys/testbool"), QString::fromLatin1("int:24")));
+ result = addKeys(testMap, data);
+ if (!result.isEmpty())
+ return false;
+
+ // data inserted before:
+ data.clear();
+ data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
+ data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
+ result = addKeys(testMap, data);
+ if (!result.isEmpty())
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap AddKeysOperation::addKeys(const QVariantMap &map, const KeyValuePairList &additions)
+{
+ // Insert data:
+ QVariantMap result = map;
+
+ foreach (const KeyValuePair &p, additions) {
+ QList<QVariantMap> stack;
+
+ // Set up a stack of QVariantMaps along the path we take:
+ stack.append(result);
+ for (int i = 0; i < p.key.count() - 1; ++i) {
+ QVariantMap subMap;
+ if (stack.last().contains(p.key.at(i)))
+ subMap = stack.last().value(p.key.at(i)).toMap();
+ stack.append(subMap);
+ }
+
+ // insert
+ Q_ASSERT(stack.count() == p.key.count());
+ if (stack.last().contains(p.key.last())) {
+ std::cerr << "DEBUG: Adding key " << qPrintable(p.key.join(QLatin1String("/"))) << " which already exists." << std::endl;
+ return QVariantMap();
+ }
+ stack.last().insert(p.key.last(), p.value);
+
+ // Generate new resultset by folding maps back in:
+ QVariantMap foldBack = stack.takeLast();
+ for (int i = p.key.count() - 2; i >= 0; --i) { // skip last key, that is already taken care of
+ const QString k = p.key.at(i);
+ QVariantMap current = stack.takeLast();
+ current.insert(k, foldBack);
+ foldBack = current;
+ }
+
+ Q_ASSERT(stack.count() == 0);
+ Q_ASSERT(foldBack != map);
+
+ result = foldBack;
+ }
+
+ return result;
+}
diff --git a/src/tools/sdktool/addkeysoperation.h b/src/tools/sdktool/addkeysoperation.h
new file mode 100644
index 00000000000..4a6a7f85e69
--- /dev/null
+++ b/src/tools/sdktool/addkeysoperation.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef ADDKEYSOPERATION_H
+#define ADDKEYSOPERATION_H
+
+#include "operation.h"
+
+class AddKeysOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap addKeys(const QVariantMap &map, const KeyValuePairList &additions);
+
+private:
+ QString m_file;
+
+ QList<KeyValuePair> m_data;
+};
+
+#endif // ADDKEYSOPERATION_H
diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp
new file mode 100644
index 00000000000..ba5a05d46fe
--- /dev/null
+++ b/src/tools/sdktool/addkitoperation.cpp
@@ -0,0 +1,382 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "addkitoperation.h"
+
+#include "addkeysoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include "settings.h"
+
+#include <iostream>
+
+// Qt version file stuff:
+static char PREFIX[] = "Profile.";
+static char VERSION[] = "Version";
+static char COUNT[] = "Profile.Count";
+static char DEFAULT[] = "Profile.Default";
+
+// Kit:
+static char ID[] = "PE.Profile.Id";
+static char DISPLAYNAME[] = "PE.Profile.Name";
+static char ICON[] = "PE.Profile.Icon";
+static char AUTODETECTED[] = "PE.Profile.Autodetected";
+static char DATA[] = "PE.Profile.Data";
+
+// Standard KitInformation:
+static char DEBUGGER[] = "Debugger.Information";
+static char DEBUGGER_ENGINE[] = "EngineType";
+static char DEBUGGER_BINARY[] = "Binary";
+static char DEVICE_TYPE[] = "PE.Profile.DeviceType";
+static char SYSROOT[] = "PE.Profile.SysRoot";
+static char TOOLCHAIN[] = "PE.Profile.ToolChain";
+static char MKSPEC[] = "QtPM4.mkSpecInformation";
+static char QT[] = "QtSupport.QtInformation";
+
+QString AddKitOperation::name() const
+{
+ return QLatin1String("addKit");
+}
+
+QString AddKitOperation::helpText() const
+{
+ return QLatin1String("add a Kit to Qt Creator");
+}
+
+QString AddKitOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> id of the new kit.\n"
+ " --name <NAME> display name of the new kit.\n"
+ " --icon <PATH> icon of the new kit.\n"
+ " --debuggerengine <ENGINE> debuggerengine of the new kit.\n"
+ " --debugger <PATH> debugger of the new kit.\n"
+ " --devicetype <TYPE> device type of the new kit.\n"
+ " --sysroot <PATH> sysroot of the new kit.\n"
+ " --toolchain <ID> tool chain of the new kit.\n"
+ " --qt <ID> Qt of the new kit.\n"
+ " --mkspec <PATH> mkspec of the new kit.\n"
+ " <KEY> <TYPE:VALUE> extra key value pairs\n");
+}
+
+bool AddKitOperation::setArguments(const QStringList &args)
+{
+ m_debuggerEngine = 0;
+
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (current == QLatin1String("--id")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_id = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--name")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_displayName = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--icon")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_icon = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--debuggerengine")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ bool ok;
+ m_debuggerEngine = next.toInt(&ok);
+ if (!ok) {
+ std::cerr << "Debugger type is not an integer!" << std::endl;
+ return false;
+ }
+ continue;
+ }
+
+ if (current == QLatin1String("--debugger")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_debugger = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--devicetype")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_deviceType = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--sysroot")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_sysRoot = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--toolchain")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_tc = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--qt")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_qt = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--mkspec")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_mkspec = next;
+ continue;
+ }
+
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ KeyValuePair pair(current, next);
+ if (!pair.value.isValid())
+ return false;
+ m_extra << pair;
+ }
+
+ if (m_icon.isEmpty())
+ m_icon = QLatin1String(":///DESKTOP///");
+
+ return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_deviceType.isEmpty();
+}
+
+int AddKitOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("profiles"));
+ if (map.isEmpty())
+ map = initializeKits();
+
+ map = addKit(map, m_id, m_displayName, m_icon, m_debuggerEngine, m_debugger,
+ m_deviceType, m_sysRoot, m_tc, m_qt, m_mkspec, m_extra);
+
+ if (map.isEmpty())
+ return -2;
+
+ return save(map, QLatin1String("profiles")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool AddKitOperation::test() const
+{
+ QVariantMap map = initializeKits();
+
+ if (!map.count() == 3
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1
+ || !map.contains(QLatin1String(COUNT))
+ || map.value(QLatin1String(COUNT)).toInt() != 0
+ || !map.contains(QLatin1String(DEFAULT))
+ || map.value(QLatin1String(DEFAULT)).toInt() != -1)
+ return false;
+
+ map = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon.png"),
+ 1, QLatin1String("/usr/bin/gdb-test"),
+ QLatin1String("Desktop"), QString(),
+ QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"), QLatin1String("unsupported/mkspec"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue"))));
+
+ if (!map.count() == 4
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1
+ || !map.contains(QLatin1String(COUNT))
+ || map.value(QLatin1String(COUNT)).toInt() != 1
+ || !map.contains(QLatin1String(DEFAULT))
+ || map.value(QLatin1String(DEFAULT)).toInt() != 0
+ || !map.contains(QLatin1String("Profile.0")))
+ return false;
+
+ QVariantMap profile0 = map.value(QLatin1String("Profile.0")).toMap();
+ if (!profile0.count() == 6
+ || !profile0.contains(QLatin1String(ID))
+ || profile0.value(QLatin1String(ID)).toString() != QLatin1String("testId")
+ || !profile0.contains(QLatin1String(DISPLAYNAME))
+ || profile0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version")
+ || !profile0.contains(QLatin1String(AUTODETECTED))
+ || profile0.value(QLatin1String(AUTODETECTED)).toBool() != true)
+ return false;
+
+ // Ignore existing ids:
+ QVariantMap result = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version X"), QLatin1String("/tmp/icon3.png"),
+ 1, QLatin1String("/usr/bin/gdb-test3"),
+ QLatin1String("Desktop"), QString(),
+ QLatin1String("{some-tc-id3}"), QLatin1String("{some-qt-id3}"), QLatin1String("unsupported/mkspec3"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue3"))));
+ if (!result.isEmpty())
+ return false;
+
+ // Make sure name is unique:
+ map = addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon2.png"),
+ 1, QLatin1String("/usr/bin/gdb-test2"),
+ QLatin1String("Desktop"), QString(),
+ QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"), QLatin1String("unsupported/mkspec2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2"))));
+ if (!map.count() == 5
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1
+ || !map.contains(QLatin1String(COUNT))
+ || map.value(QLatin1String(COUNT)).toInt() != 2
+ || !map.contains(QLatin1String(DEFAULT))
+ || map.value(QLatin1String(DEFAULT)).toInt() != 0
+ || !map.contains(QLatin1String("Profile.0"))
+ || !map.contains(QLatin1String("Profile.1")))
+
+ if (map.value(QLatin1String("Profile.0")) != profile0)
+ return false;
+
+ QVariantMap profile1 = map.value(QLatin1String("Profile.1")).toMap();
+ if (!profile1.count() == 6
+ || !profile1.contains(QLatin1String(ID))
+ || profile1.value(QLatin1String(ID)).toString() != QLatin1String("testId2")
+ || !profile1.contains(QLatin1String(DISPLAYNAME))
+ || profile1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version2")
+ || !profile1.contains(QLatin1String(AUTODETECTED))
+ || profile1.value(QLatin1String(AUTODETECTED)).toBool() != true)
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap AddKitOperation::addKit(const QVariantMap &map,
+ const QString &id, const QString &displayName, const QString &icon,
+ const quint32 &debuggerType, const QString &debugger,
+ const QString &deviceType, const QString &sysRoot,
+ const QString &tc, const QString &qt, const QString &mkspec,
+ const KeyValuePairList &extra)
+{
+ // Sanity check: Make sure autodetection source is not in use already:
+ QStringList valueKeys = FindValueOperation::findValues(map, QVariant(id));
+ bool hasId = false;
+ foreach (const QString &k, valueKeys) {
+ if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(ID))) {
+ hasId = true;
+ break;
+ }
+ }
+ if (hasId) {
+ std::cerr << "Error: Id " << qPrintable(id) << " already defined as kit." << std::endl;
+ return QVariantMap();
+ }
+
+ // Find position to insert:
+ bool ok;
+ int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
+ if (!ok || count < 0) {
+ std::cerr << "Error: Count found in kits file seems wrong." << std::endl;
+ return QVariantMap();
+ }
+ const QString kit = QString::fromLatin1(PREFIX) + QString::number(count);
+
+ int defaultKit = GetOperation::get(map, QLatin1String(DEFAULT)).toInt(&ok);
+ if (!ok) {
+ std::cerr << "Error: Default kit seems wrong." << std::endl;
+ return QVariantMap();
+ }
+
+ if (defaultKit < 0)
+ defaultKit = 0;
+
+ // remove data:
+ QStringList toRemove;
+ toRemove << QLatin1String(COUNT) << QLatin1String(DEFAULT);
+ QVariantMap cleaned = RmKeysOperation::rmKeys(map, toRemove);
+
+ // Sanity check: Make sure displayName is unique.
+ QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
+ QStringList nameList;
+ foreach (const QString nameKey, nameKeys)
+ nameList << GetOperation::get(map, nameKey).toString();
+ const QString uniqueName = makeUnique(displayName, nameList);
+
+ // insert data:
+ KeyValuePairList data;
+ data << KeyValuePair(QStringList() << kit << QLatin1String(ID), QVariant(id));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(ICON), QVariant(icon));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(AUTODETECTED), QVariant(true));
+
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA)
+ << QLatin1String(DEBUGGER) << QLatin1String(DEBUGGER_ENGINE), QVariant(debuggerType));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA)
+ << QLatin1String(DEBUGGER) << QLatin1String(DEBUGGER_BINARY), QVariant(debugger));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << DEVICE_TYPE, QVariant(deviceType));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << SYSROOT, QVariant(sysRoot));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << TOOLCHAIN, QVariant(tc));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << QT, QVariant(qt));
+ data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << MKSPEC, QVariant(mkspec));
+
+ data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit));
+ data << KeyValuePair(QStringList() << QLatin1String(COUNT), QVariant(count + 1));
+
+ KeyValuePairList qtExtraList;
+ foreach (const KeyValuePair &pair, extra)
+ qtExtraList << KeyValuePair(QStringList() << kit << pair.key, pair.value);
+ data.append(qtExtraList);
+
+ return AddKeysOperation::addKeys(cleaned, data);
+}
+
+QVariantMap AddKitOperation::initializeKits()
+{
+ QVariantMap map;
+ map.insert(QLatin1String(VERSION), 1);
+ map.insert(QLatin1String(DEFAULT), -1);
+ map.insert(QLatin1String(COUNT), 0);
+ return map;
+}
diff --git a/src/tools/sdktool/addkitoperation.h b/src/tools/sdktool/addkitoperation.h
new file mode 100644
index 00000000000..e526bcb6044
--- /dev/null
+++ b/src/tools/sdktool/addkitoperation.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef ADDKITOPERATION_H
+#define ADDKITOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class AddKitOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap addKit(const QVariantMap &map,
+ const QString &id, const QString &displayName, const QString &icon,
+ const quint32 &debuggerType, const QString &debugger,
+ const QString &deviceType, const QString &sysRoot,
+ const QString &tc, const QString &qt, const QString &mkspec,
+ const KeyValuePairList &extra);
+
+ static QVariantMap initializeKits();
+
+private:
+ QString m_id;
+ QString m_displayName;
+ QString m_icon;
+ quint32 m_debuggerEngine;
+ QString m_debugger;
+ QString m_deviceType;
+ QString m_sysRoot;
+ QString m_tc;
+ QString m_qt;
+ QString m_mkspec;
+ KeyValuePairList m_extra;
+};
+
+#endif // ADDKITOPERATION_H
diff --git a/src/tools/sdktool/addqtoperation.cpp b/src/tools/sdktool/addqtoperation.cpp
new file mode 100644
index 00000000000..4f29501b672
--- /dev/null
+++ b/src/tools/sdktool/addqtoperation.cpp
@@ -0,0 +1,280 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "addqtoperation.h"
+
+#include "addkeysoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include "settings.h"
+
+#include <iostream>
+
+// Qt version file stuff:
+static char PREFIX[] = "QtVersion.";
+static char VERSION[] = "Version";
+
+// BaseQtVersion:
+static char ID[] = "Id";
+static char DISPLAYNAME[] = "Name";
+static char AUTODETECTED[] = "isAutodetected";
+static char AUTODETECTION_SOURCE[] = "autodetectionSource";
+static char QMAKE[] = "QMakePath";
+static char TYPE[] = "QtVersion.Type";
+
+QString AddQtOperation::name() const
+{
+ return QLatin1String("addQt");
+}
+
+QString AddQtOperation::helpText() const
+{
+ return QLatin1String("add a Qt version to Qt Creator");
+}
+
+QString AddQtOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> id of the new Qt version. (required)\n"
+ " --name <NAME> display name of the new Qt version. (required)\n"
+ " --qmake <PATH> path to qmake. (required)\n"
+ " --type <TYPE> type of Qt version to add. (required)\n"
+ " --noauto do not mark tool chain as autodetected.\n"
+ " <KEY> <TYPE:VALUE> extra key value pairs\n");
+}
+
+bool AddQtOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (current == QLatin1String("--id")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_id = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--name")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_displayName = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--qmake")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_qmake = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--type")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_type = next;
+ continue;
+ }
+
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ KeyValuePair pair(current, next);
+ if (!pair.value.isValid())
+ return false;
+ m_extra << pair;
+ }
+
+ return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_qmake.isEmpty() && !m_type.isEmpty();
+}
+
+int AddQtOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("qtversions"));
+ if (map.isEmpty())
+ map = initializeQtVersions();
+
+ map = addQt(map, m_id, m_displayName, m_type, m_qmake, m_extra);
+
+ if (map.isEmpty())
+ return -2;
+
+ return save(map, QLatin1String("qtversions")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool AddQtOperation::test() const
+{
+ QVariantMap map = initializeQtVersions();
+
+ if (!map.count() == 1
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1)
+ return false;
+
+ map = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("testType"),
+ QLatin1String("/tmp/test/qmake"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
+
+ if (!map.count() == 2
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1
+ || !map.contains(QLatin1String("QtVersion.0")))
+ return false;
+
+ QVariantMap version0 = map.value(QLatin1String("QtVersion.0")).toMap();
+ if (!version0.count() == 6
+ || !version0.contains(QLatin1String(ID))
+ || version0.value(QLatin1String(ID)).toInt() != -1
+ || !version0.contains(QLatin1String(DISPLAYNAME))
+ || version0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version")
+ || !version0.contains(QLatin1String(AUTODETECTED))
+ || version0.value(QLatin1String(AUTODETECTED)).toBool() != true
+ || !version0.contains(QLatin1String(AUTODETECTION_SOURCE))
+ || version0.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != QLatin1String("testId")
+ || !version0.contains(QLatin1String(TYPE))
+ || version0.value(QLatin1String(TYPE)).toString() != QLatin1String("testType")
+ || !version0.contains(QLatin1String(QMAKE))
+ || version0.value(QLatin1String(QMAKE)).toString() != QLatin1String("/tmp/test/qmake")
+ || !version0.contains(QLatin1String("extraData"))
+ || version0.value(QLatin1String("extraData")).toString() != QLatin1String("extraValue"))
+ return false;
+
+ // Ignore existing ids:
+ QVariantMap result = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version2"), QLatin1String("testType2"),
+ QLatin1String("/tmp/test/qmake2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
+ if (!result.isEmpty())
+ return false;
+
+ // Make sure name is unique:
+ map = addQt(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("testType3"),
+ QLatin1String("/tmp/test/qmake2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
+ if (!map.count() == 3
+ || !map.contains(QLatin1String(VERSION))
+ || map.value(QLatin1String(VERSION)).toInt() != 1
+ || !map.contains(QLatin1String("QtVersion.0"))
+ || !map.contains(QLatin1String("QtVersion.1")))
+ return false;
+
+ if (map.value(QLatin1String("QtVersion.0")) != version0)
+ return false;
+
+ QVariantMap version1 = map.value(QLatin1String("QtVersion.1")).toMap();
+ if (!version1.count() == 6
+ || !version1.contains(QLatin1String(ID))
+ || version1.value(QLatin1String(ID)).toInt() != -1
+ || !version1.contains(QLatin1String(DISPLAYNAME))
+ || version1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version2")
+ || !version1.contains(QLatin1String(AUTODETECTED))
+ || version1.value(QLatin1String(AUTODETECTED)).toBool() != true
+ || !version1.contains(QLatin1String(AUTODETECTION_SOURCE))
+ || version1.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != QLatin1String("testId2")
+ || !version1.contains(QLatin1String(TYPE))
+ || version1.value(QLatin1String(TYPE)).toString() != QLatin1String("testType3")
+ || !version1.contains(QLatin1String(QMAKE))
+ || version1.value(QLatin1String(QMAKE)).toString() != QLatin1String("/tmp/test/qmake2")
+ || !version1.contains(QLatin1String("extraData"))
+ || version1.value(QLatin1String("extraData")).toString() != QLatin1String("extraValue"))
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap AddQtOperation::addQt(const QVariantMap &map,
+ const QString &id, const QString &displayName, const QString &type,
+ const QString &qmake, const KeyValuePairList &extra)
+{
+ // Sanity check: Make sure autodetection source is not in use already:
+ QStringList valueKeys = FindValueOperation::findValues(map, id);
+ bool hasId = false;
+ foreach (const QString &k, valueKeys) {
+ if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(AUTODETECTION_SOURCE))) {
+ hasId = true;
+ break;
+ }
+ }
+ if (hasId) {
+ std::cerr << "Error: Id " << qPrintable(id) << " already defined as Qt versions." << std::endl;
+ return QVariantMap();
+ }
+
+ // Find position to insert:
+ int versionCount = 0;
+ for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
+ if (!i.key().startsWith(QLatin1String(PREFIX)))
+ continue;
+ QString number = i.key().mid(QString::fromLatin1(PREFIX).count());
+ bool ok;
+ int count = number.toInt(&ok);
+ if (ok && count >= versionCount)
+ versionCount = count + 1;
+ }
+ const QString qt = QString::fromLatin1(PREFIX) + QString::number(versionCount);
+
+ // Sanity check: Make sure displayName is unique.
+ QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
+ QStringList nameList;
+ foreach (const QString nameKey, nameKeys)
+ nameList << GetOperation::get(map, nameKey).toString();
+ const QString uniqueName = makeUnique(displayName, nameList);
+
+ // insert data:
+ KeyValuePairList data;
+ data << KeyValuePair(QStringList() << qt << QLatin1String(ID), QVariant(-1));
+ data << KeyValuePair(QStringList() << qt << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
+ data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTED), QVariant(true));
+ data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTION_SOURCE), QVariant(id));
+ data << KeyValuePair(QStringList() << qt << QLatin1String(QMAKE), QVariant(qmake));
+ data << KeyValuePair(QStringList() << qt << QLatin1String(TYPE), QVariant(type));
+
+ KeyValuePairList qtExtraList;
+ foreach (const KeyValuePair &pair, extra)
+ qtExtraList << KeyValuePair(QStringList() << qt << pair.key, pair.value);
+ data.append(qtExtraList);
+
+ return AddKeysOperation::addKeys(map, data);
+}
+
+QVariantMap AddQtOperation::initializeQtVersions()
+{
+ QVariantMap map;
+ map.insert(QLatin1String(VERSION), 1);
+ return map;
+}
diff --git a/src/tools/sdktool/addqtoperation.h b/src/tools/sdktool/addqtoperation.h
new file mode 100644
index 00000000000..0e202375f71
--- /dev/null
+++ b/src/tools/sdktool/addqtoperation.h
@@ -0,0 +1,67 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef ADDQTOPERATION_H
+#define ADDQTOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class AddQtOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap addQt(const QVariantMap &map,
+ const QString &id, const QString &displayName, const QString &type,
+ const QString &qmake, const KeyValuePairList &extra);
+
+ static QVariantMap initializeQtVersions();
+
+private:
+ QString m_id; // actually this is the autodetectionSource
+ QString m_displayName;
+ QString m_type;
+ QString m_qmake;
+ KeyValuePairList m_extra;
+};
+
+#endif // ADDQTOPERATION_H
diff --git a/src/tools/sdktool/addtoolchainoperation.cpp b/src/tools/sdktool/addtoolchainoperation.cpp
new file mode 100644
index 00000000000..01317d7b9a0
--- /dev/null
+++ b/src/tools/sdktool/addtoolchainoperation.cpp
@@ -0,0 +1,280 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "addtoolchainoperation.h"
+
+#include "addkeysoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include "settings.h"
+
+#include <iostream>
+
+// ToolChain file stuff:
+static char COUNT[] = "ToolChain.Count";
+static char PREFIX[] = "ToolChain.";
+static char VERSION[] = "Version";
+
+// ToolChain:
+static char ID[] = "ProjectExplorer.ToolChain.Id";
+static char DISPLAYNAME[] = "ProjectExplorer.ToolChain.DisplayName";
+static char AUTODETECTED[] = "ProjectExplorer.ToolChain.Autodetect";
+
+// GCC ToolChain:
+static char PATH[] = "ProjectExplorer.GccToolChain.Path";
+static char TARGET_ABI[] = "ProjectExplorer.GccToolChain.TargetAbi";
+static char SUPPORTED_ABIS[] = "ProjectExplorer.GccToolChain.SupportedAbis";
+
+QString AddToolChainOperation::name() const
+{
+ return QLatin1String("addTC");
+}
+
+QString AddToolChainOperation::helpText() const
+{
+ return QLatin1String("add a tool chain to Qt Creator");
+}
+
+QString AddToolChainOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> id of the new tool chain.\n"
+ " --name <NAME> display name of the new tool chain.\n"
+ " --path <PATH> path to the compiler.\n"
+ " --abi <ABI STRING> ABI of the compiler.\n"
+ " --supportedAbis <ABI STRING>,<ABI STRING> list of ABIs supported by the compiler.\n"
+ " <KEY> <TYPE:VALUE> extra key value pairs\n");
+}
+
+bool AddToolChainOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (current == QLatin1String("--id")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_id = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--name")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_displayName = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--path")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_path = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--abi")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_targetAbi = next;
+ continue;
+ }
+
+ if (current == QLatin1String("--supportedAbis")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_supportedAbis = next;
+ continue;
+ }
+
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ KeyValuePair pair(current, next);
+ if (!pair.value.isValid())
+ return false;
+ m_extra << pair;
+ }
+
+ if (m_supportedAbis.isEmpty())
+ m_supportedAbis = m_targetAbi;
+
+ return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_path.isEmpty() && !m_targetAbi.isEmpty();
+}
+
+int AddToolChainOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("toolchains"));
+ if (map.isEmpty())
+ map = initializeToolChains();
+
+ map = addToolChain(map, m_id, m_displayName, m_path, m_targetAbi, m_supportedAbis, m_extra);
+ if (map.isEmpty())
+ return -2;
+
+ return save(map, QLatin1String("toolchains")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool AddToolChainOperation::test() const
+{
+ QVariantMap map = initializeToolChains();
+
+ // Add toolchain:
+ map = addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
+ QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
+ if (!map.value(QLatin1String(COUNT)).toInt() == 1
+ || !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0')))
+ return false;
+ QVariantMap tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('0')).toMap();
+ if (tcData.count() != 7
+ || tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
+ || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
+ || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
+ || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+ || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
+ || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
+ || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
+ return false;
+
+ // Ignore same Id:
+ QVariantMap unchanged = addToolChain(map, QLatin1String("testId"), QLatin1String("name2"), QLatin1String("/tmp/test2"),
+ QLatin1String("test-abi2"), QLatin1String("test-abi2,test-abi3"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue2"))));
+ if (!unchanged.isEmpty())
+ return false;
+
+ // Make sure name stays unique:
+ map = addToolChain(map, QLatin1String("testId2"), QLatin1String("name"), QLatin1String("/tmp/test"),
+ QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
+ if (!map.value(QLatin1String(COUNT)).toInt() == 2
+ || !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0'))
+ || !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('1')))
+ return false;
+ tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('0')).toMap();
+ if (tcData.count() != 7
+ || tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
+ || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
+ || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
+ || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+ || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
+ || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
+ || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
+ return false;
+ tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('1')).toMap();
+ if (tcData.count() != 7
+ || tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId2")
+ || tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name2")
+ || tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
+ || tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
+ || tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
+ || tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
+ || tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map,
+ const QString &id, const QString &displayName,
+ const QString &path, const QString &abi,
+ const QString &supportedAbis, const KeyValuePairList &extra)
+{
+ // Sanity check: Does the Id already exist?
+ QStringList valueKeys = FindValueOperation::findValues(map, id);
+ bool hasId = false;
+ foreach (const QString &k, valueKeys) {
+ if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(ID))) {
+ hasId = true;
+ break;
+ }
+ }
+ if (hasId) {
+ std::cerr << "Error: Id " << qPrintable(id) << " already defined for tool chains." << std::endl;
+ return QVariantMap();
+ }
+
+ // Find position to insert Tool Chain at:
+ bool ok;
+ int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
+ if (!ok || count < 0) {
+ std::cerr << "Error: Count found in toolchains file seems wrong." << std::endl;
+ return QVariantMap();
+ }
+
+ // Sanity check: Make sure displayName is unique.
+ QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
+ QStringList nameList;
+ foreach (const QString nameKey, nameKeys)
+ nameList << GetOperation::get(map, nameKey).toString();
+ const QString uniqueName = makeUnique(displayName, nameList);
+
+ QVariantMap result = RmKeysOperation::rmKeys(map, QStringList() << QLatin1String(COUNT));
+
+ std::cout << "Registering ToolChain " << count << std::endl;
+ const QString tc = QString::fromLatin1(PREFIX) + QString::number(count);
+
+ KeyValuePairList data;
+ data << KeyValuePair(QStringList() << tc << QLatin1String(ID), QVariant(id.toUtf8()));
+ data << KeyValuePair(QStringList() << tc << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
+ data << KeyValuePair(QStringList() << tc << QLatin1String(AUTODETECTED), QVariant(true));
+ data << KeyValuePair(QStringList() << tc << QLatin1String(PATH), QVariant(path));
+ data << KeyValuePair(QStringList() << tc << QLatin1String(TARGET_ABI), QVariant(abi));
+ QVariantList abis;
+ QStringList abiStrings = supportedAbis.split(QLatin1Char(','));
+ foreach (const QString &s, abiStrings)
+ abis << QVariant(s);
+ data << KeyValuePair(QStringList() << tc << QLatin1String(SUPPORTED_ABIS), QVariant(abis));
+ KeyValuePairList tcExtraList;
+ foreach (const KeyValuePair &pair, extra)
+ tcExtraList << KeyValuePair(QStringList() << tc << pair.key, pair.value);
+ data.append(tcExtraList);
+ data << KeyValuePair(QLatin1String(COUNT), QVariant(count + 1));
+
+ return AddKeysOperation::addKeys(result, data);
+}
+
+QVariantMap AddToolChainOperation::initializeToolChains()
+{
+ QVariantMap map;
+ map.insert(QLatin1String(COUNT), 0);
+ map.insert(QLatin1String(VERSION), 1);
+ return map;
+}
diff --git a/src/tools/sdktool/addtoolchainoperation.h b/src/tools/sdktool/addtoolchainoperation.h
new file mode 100644
index 00000000000..327791d5cd7
--- /dev/null
+++ b/src/tools/sdktool/addtoolchainoperation.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef ADDTOOLCHAINOPERATION_H
+#define ADDTOOLCHAINOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class AddToolChainOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap addToolChain(const QVariantMap &map,
+ const QString &id, const QString &displayName,
+ const QString &path, const QString &abi,
+ const QString &supportedAbis,
+ const KeyValuePairList &extra);
+
+ static QVariantMap initializeToolChains();
+
+private:
+ QString m_id;
+ QString m_displayName;
+ QString m_path;
+ QString m_targetAbi;
+ QString m_supportedAbis;
+ KeyValuePairList m_extra;
+};
+
+#endif // ADDTOOLCHAINOPERATION_H
diff --git a/src/tools/sdktool/findkeyoperation.cpp b/src/tools/sdktool/findkeyoperation.cpp
new file mode 100644
index 00000000000..2c6b20d3c6c
--- /dev/null
+++ b/src/tools/sdktool/findkeyoperation.cpp
@@ -0,0 +1,130 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "findkeyoperation.h"
+
+#include <iostream>
+
+QString FindKeyOperation::name() const
+{
+ return QLatin1String("findKey");
+}
+
+QString FindKeyOperation::helpText() const
+{
+ return QLatin1String("find a key in the settings of Qt Creator");
+}
+
+QString FindKeyOperation::argumentsHelpText() const
+{
+ return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to search for.\n");
+}
+
+bool FindKeyOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+
+ if (m_file.isNull()) {
+ m_file = current;
+ continue;
+ }
+
+ m_keys.append(current);
+ }
+
+ return (!m_file.isEmpty() && !m_keys.isEmpty());
+}
+
+int FindKeyOperation::execute() const
+{
+ Q_ASSERT(!m_keys.isEmpty());
+ QVariantMap map = load(m_file);
+
+ foreach (const QString &k, m_keys) {
+ const QStringList result = findKey(map, k);
+ foreach (const QString r, result)
+ std::cout << qPrintable(r) << std::endl;
+ }
+
+ return 0;
+}
+
+#ifdef WITH_TESTS
+bool FindKeyOperation::test() const
+{
+ QVariantMap testMap;
+ QVariantMap subKeys;
+ QVariantMap cur;
+ cur.insert(QLatin1String("testint"), 53);
+ subKeys.insert(QLatin1String("subsubkeys"), cur);
+ subKeys.insert(QLatin1String("testbool"), true);
+ testMap.insert(QLatin1String("subkeys"), subKeys);
+ subKeys.clear();
+ testMap.insert(QLatin1String("subkeys2"), subKeys);
+ testMap.insert(QLatin1String("testint"), 23);
+ testMap.insert(QLatin1String("testbool"), true);
+
+ QStringList result;
+ result = findKey(testMap, QLatin1String("missing"));
+ if (!result.isEmpty())
+ return false;
+
+ result = findKey(testMap, QLatin1String("testint"));
+ if (result.count() != 2
+ || !result.contains(QLatin1String("testint"))
+ || !result.contains(QLatin1String("subkeys/subsubkeys/testint")))
+ return false;
+
+ result = findKey(testMap, QLatin1String("testbool"));
+ if (result.count() != 2
+ || !result.contains(QLatin1String("testbool")))
+ return false;
+
+ return true;
+}
+#endif
+
+QStringList FindKeyOperation::findKey(const QVariantMap &map, const QString &key)
+{
+ QStringList result;
+ for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
+ if (i.key() == key) {
+ result << key;
+ continue;
+ }
+ if (i.value().type() == QVariant::Map) {
+ QStringList subKeyList = findKey(i.value().toMap(), key);
+ foreach (const QString &subKey, subKeyList)
+ result << i.key() + QLatin1Char('/') + subKey;
+ }
+ }
+ return result;
+}
diff --git a/src/tools/sdktool/findkeyoperation.h b/src/tools/sdktool/findkeyoperation.h
new file mode 100644
index 00000000000..8552f6d1fdf
--- /dev/null
+++ b/src/tools/sdktool/findkeyoperation.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef FINDKEYOPERATION_H
+#define FINDKEYOPERATION_H
+
+#include "operation.h"
+
+class FindKeyOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QStringList findKey(const QVariantMap &map, const QString &key);
+
+private:
+ QString m_file;
+ QStringList m_keys;
+};
+
+#endif // FINDKEYOPERATION_H
diff --git a/src/tools/sdktool/findvalueoperation.cpp b/src/tools/sdktool/findvalueoperation.cpp
new file mode 100644
index 00000000000..ba56e64c452
--- /dev/null
+++ b/src/tools/sdktool/findvalueoperation.cpp
@@ -0,0 +1,135 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "findvalueoperation.h"
+
+#include <iostream>
+
+QString FindValueOperation::name() const
+{
+ return QLatin1String("find");
+}
+
+QString FindValueOperation::helpText() const
+{
+ return QLatin1String("find a value in the settings of Qt Creator");
+}
+
+QString FindValueOperation::argumentsHelpText() const
+{
+ return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more type:value tupels to search for.\n");
+}
+
+bool FindValueOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+
+ if (m_file.isNull()) {
+ m_file = current;
+ continue;
+ }
+
+ QVariant v = Operation::valueFromString(current);
+ if (!v.isValid())
+ return false;
+ m_values << v;
+ }
+
+ return (!m_file.isEmpty() && !m_values.isEmpty());
+}
+
+int FindValueOperation::execute() const
+{
+ Q_ASSERT(!m_values.isEmpty());
+ QVariantMap map = load(m_file);
+
+ foreach (const QVariant &v, m_values) {
+ const QStringList result = findValues(map, v);
+ foreach (const QString &r, result)
+ std::cout << qPrintable(r) << std::endl;
+ }
+
+ return 0;
+}
+
+#ifdef WITH_TESTS
+bool FindValueOperation::test() const
+{
+ QVariantMap testMap;
+ QVariantMap subKeys;
+ QVariantMap cur;
+ cur.insert(QLatin1String("testint2"), 53);
+ subKeys.insert(QLatin1String("subsubkeys"), cur);
+ subKeys.insert(QLatin1String("testbool"), true);
+ subKeys.insert(QLatin1String("otherint"), 53);
+ testMap.insert(QLatin1String("subkeys"), subKeys);
+ subKeys.clear();
+ testMap.insert(QLatin1String("subkeys2"), subKeys);
+ testMap.insert(QLatin1String("testint"), 23);
+
+ QStringList result;
+ result = findValues(testMap, QVariant(23));
+ if (result.count() != 1
+ || !result.contains(QLatin1String("testint")))
+ return false;
+
+ result = findValues(testMap, QVariant(53));
+ if (result.count() != 2
+ || !result.contains(QLatin1String("subkeys/subsubkeys/testint2"))
+ || !result.contains(QLatin1String("subkeys/otherint")))
+ return false;
+
+ result = findValues(testMap, QVariant(23456));
+ if (!result.isEmpty())
+ return false;
+
+ return true;
+}
+#endif
+
+QStringList FindValueOperation::findValues(const QVariantMap &map, const QVariant &value)
+{
+ QStringList result;
+ if (!value.isValid())
+ return result;
+
+ for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
+ if (i.value() == value)
+ result << i.key();
+ if (i.value().type() == QVariant::Map) {
+ const QStringList subKeys = findValues(i.value().toMap(), value);
+ foreach (const QString &subKey, subKeys)
+ result << i.key() + QLatin1Char('/') + subKey;
+ }
+ }
+
+ return result;
+}
diff --git a/src/tools/sdktool/findvalueoperation.h b/src/tools/sdktool/findvalueoperation.h
new file mode 100644
index 00000000000..9bc56268678
--- /dev/null
+++ b/src/tools/sdktool/findvalueoperation.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef FINDVALUEOPERATION_H
+#define FINDVALUEOPERATION_H
+
+#include "operation.h"
+
+class FindValueOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QStringList findValues(const QVariantMap &map, const QVariant &value);
+
+private:
+ QString m_file;
+ QVariantList m_values;
+};
+
+#endif // FINDVALUEOPERATION_H
diff --git a/src/tools/sdktool/getoperation.cpp b/src/tools/sdktool/getoperation.cpp
new file mode 100644
index 00000000000..717365e1b38
--- /dev/null
+++ b/src/tools/sdktool/getoperation.cpp
@@ -0,0 +1,126 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "getoperation.h"
+
+#include <iostream>
+
+QString GetOperation::name() const
+{
+ return QLatin1String("get");
+}
+
+QString GetOperation::helpText() const
+{
+ return QLatin1String("get settings from Qt Creator configuration");
+}
+
+QString GetOperation::argumentsHelpText() const
+{
+ return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to list.\n");
+}
+
+bool GetOperation::setArguments(const QStringList &args)
+{
+ if (args.count() < 2)
+ return false;
+
+ m_keys = args;
+ m_file = m_keys.takeFirst();
+ return true;
+}
+
+int GetOperation::execute() const
+{
+ Q_ASSERT(!m_keys.isEmpty());
+ QVariantMap map = load(m_file);
+
+ foreach (const QString &key, m_keys) {
+ const QVariant result = get(map, key);
+ if (result.isValid())
+ return -2;
+ std::cout << qPrintable(result.toString()) << std::endl;
+ }
+
+ return 0;
+}
+
+#ifdef WITH_TESTS
+bool GetOperation::test() const
+{
+ QVariantMap testMap;
+ QVariantMap subKeys;
+ QVariantMap cur;
+ cur.insert(QLatin1String("testint2"), 53);
+ subKeys.insert(QLatin1String("subsubkeys"), cur);
+ subKeys.insert(QLatin1String("testbool"), true);
+ testMap.insert(QLatin1String("subkeys"), subKeys);
+ subKeys.clear();
+ testMap.insert(QLatin1String("subkeys2"), subKeys);
+ testMap.insert(QLatin1String("testint"), 23);
+
+ QVariant result;
+ result = get(testMap, QLatin1String("testint"));
+ if (result.toString() != QLatin1String("23"))
+ return false;
+
+ result = get(testMap, QLatin1String("subkeys/testbool"));
+ if (result.toString() != QLatin1String("true"))
+ return false;
+
+ result = get(testMap, QLatin1String("subkeys/subsubkeys"));
+ if (result.type() != QVariant::Map)
+ return false;
+
+ result = get(testMap, QLatin1String("nonexistant"));
+ if (result.isValid())
+ return false;
+
+ return true;
+}
+#endif
+
+QVariant GetOperation::get(const QVariantMap &map, const QString &key)
+{
+ if (key.isEmpty())
+ return QString();
+
+ const QStringList keys = key.split(QLatin1Char('/'));
+
+ QVariantMap subMap = map;
+ for (int i = 0; i < keys.count() - 1; ++i) {
+ const QString k = keys.at(i);
+ if (!subMap.contains(k))
+ return QString();
+ subMap = subMap.value(k).toMap();
+ }
+
+ return subMap.value(keys.last());
+}
diff --git a/src/tools/sdktool/getoperation.h b/src/tools/sdktool/getoperation.h
new file mode 100644
index 00000000000..26bbc0de9a5
--- /dev/null
+++ b/src/tools/sdktool/getoperation.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef GETOPERATION_H
+#define GETOPERATION_H
+
+#include "operation.h"
+
+class GetOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariant get(const QVariantMap &map, const QString &key);
+
+private:
+ QStringList m_keys;
+ QString m_file;
+};
+
+#endif // GETOPERATION_H
diff --git a/src/tools/sdktool/main.cpp b/src/tools/sdktool/main.cpp
new file mode 100644
index 00000000000..53c24c1b8db
--- /dev/null
+++ b/src/tools/sdktool/main.cpp
@@ -0,0 +1,185 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "settings.h"
+
+#include "operation.h"
+
+#include "addkeysoperation.h"
+#include "addkitoperation.h"
+#include "addqtoperation.h"
+#include "addtoolchainoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+#include "rmkitoperation.h"
+#include "rmqtoperation.h"
+#include "rmtoolchainoperation.h"
+
+#include <iostream>
+
+#include <QCoreApplication>
+#include <QStringList>
+
+void printHelp(const Operation *op)
+{
+ std::cout << "Qt Creator SDK setup tool." << std::endl;
+
+ std::cout << "Help for operation " << qPrintable(op->name()) << std::endl;
+ std::cout << std::endl;
+ std::cout << qPrintable(op->argumentsHelpText());
+ std::cout << std::endl;
+}
+
+void printHelp(const QList<Operation *> &operations)
+{
+ std::cout << "Qt Creator SDK setup tool." << std::endl;
+ std::cout << " Usage:" << qPrintable(qApp->arguments().at(0))
+ << " <ARGS> <OPERATION> <OPERATION_ARGS>" << std::endl << std::endl;
+ std::cout << "ARGS:" << std::endl;
+ std::cout << " --help|-h Print this help text" << std::endl;
+ std::cout << " --sdkpath=PATH|-s PATH Set the path to the SDK files" << std::endl << std::endl;
+
+ std::cout << "OPERATION:" << std::endl;
+ std::cout << " One of:" << std::endl;
+ foreach (const Operation *o, operations)
+ std::cout << " " << qPrintable(o->name()) << "\t\t" << qPrintable(o->helpText()) << std::endl;
+ std::cout << std::endl;
+ std::cout << "OPERATION_ARGS:" << std::endl;
+ std::cout << " use \"--help <OPERATION>\" to get help on the arguments required for an operation." << std::endl;
+
+ std::cout << std::endl;
+}
+
+int parseArguments(const QStringList &args, Settings *s, const QList<Operation *> &operations)
+{
+ QStringList opArgs;
+ int argCount = args.count();
+
+ for (int i = 1; i < argCount; ++i) {
+ const QString current = args[i];
+ const QString next = (i + 1 < argCount) ? args[i + 1] : QString();
+
+ if (!s->operation) {
+ // help
+ if (current == QLatin1String("-h") || current == QLatin1String("--help")) {
+ if (!next.isEmpty()) {
+ foreach (Operation *o, operations) {
+ if (o->name() == next) {
+ printHelp(o);
+ return 0;
+ }
+ }
+ }
+ printHelp(operations);
+ return 0;
+ }
+
+ // sdkpath
+ if (current.startsWith(QLatin1String("--sdkpath="))) {
+ s->sdkPath = Utils::FileName::fromString(current.mid(10));
+ continue;
+ }
+ if (current == QLatin1String("-s")) {
+ s->sdkPath = Utils::FileName::fromString(next);
+ ++i; // skip next;
+ continue;
+ }
+
+ // operation
+ foreach (Operation *o, operations) {
+ if (o->name() == current) {
+ s->operation = o;
+ break;
+ }
+ }
+
+ if (s->operation)
+ continue;
+ } else {
+ opArgs << current;
+ continue;
+ }
+
+ std::cerr << "Unknown parameter given." << std::endl << std::endl;
+ printHelp(operations);
+ return -1;
+ }
+
+ if (!s->operation) {
+ std::cerr << "No operation requested." << std::endl << std::endl;
+ printHelp(operations);
+ return -1;
+ }
+ if (!s->operation->setArguments(opArgs)) {
+ printHelp(s->operation);
+ return -1;
+ }
+
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ Settings settings;
+
+ QList<Operation *> operations;
+ operations << new AddKeysOperation
+ << new AddKitOperation
+ << new AddQtOperation
+ << new AddToolChainOperation
+ << new FindKeyOperation
+ << new FindValueOperation
+ << new GetOperation
+ << new RmKeysOperation
+ << new RmKitOperation
+ << new RmQtOperation
+ << new RmToolChainOperation;
+
+#ifdef WITH_TESTS
+ std::cerr << std::endl << std::endl << "Starting tests..." << std::endl;
+ foreach (Operation *o, operations)
+ if (!o->test())
+ std::cerr << "!!!! Test failed for: " << qPrintable(o->name()) << " !!!!" << std::endl;
+ std::cerr << "Tests done." << std::endl << std::endl;
+#endif
+
+ int result = parseArguments(a.arguments(), &settings, operations);
+ if (result <= 0)
+ return result;
+
+ Q_ASSERT(settings.operation);
+ settings.operation->execute();
+
+ return result;
+}
diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp
new file mode 100644
index 00000000000..636d76ffd9b
--- /dev/null
+++ b/src/tools/sdktool/operation.cpp
@@ -0,0 +1,131 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "operation.h"
+
+#include "settings.h"
+
+#include "utils/persistentsettings.h"
+
+#include <QDir>
+
+#include <iostream>
+
+QVariant Operation::valueFromString(const QString &v)
+{
+ int pos = v.indexOf(QLatin1Char(':'));
+ if (pos <= 0)
+ return QVariant();
+ const QString type = v.left(pos);
+ const QString value = v.mid(pos + 1);
+
+ if (type == QLatin1String("int")) {
+ return QVariant(value.toInt());
+ } else if (type == QLatin1String("bool")) {
+ const QString tmp = value.toLower();
+ return QVariant(tmp == QLatin1String("true") || tmp == QLatin1String("yes")
+ || tmp == QLatin1String("1") || tmp == QLatin1String("on"));
+ } else if (type == QLatin1String("QByteArray")) {
+ return QVariant(value.toLocal8Bit());
+ } else if (type == QLatin1String("QString")) {
+ return QVariant(value);
+ } else if (type == QLatin1String("QVariantList")) {
+ QVariantList list;
+ const QStringList elements = value.split(QLatin1Char(','));
+ foreach (const QString &e, elements)
+ list << QVariant(e);
+ return QVariant(list);
+ }
+ return QVariant();
+}
+
+QString Operation::makeUnique(const QString &name, const QStringList &inUse)
+{
+ QString unique = name;
+ int i = 1;
+ while (inUse.contains(unique))
+ unique = name + QString::number(++i);
+ return unique;
+}
+
+Operation::KeyValuePair::KeyValuePair(const QString &k, const QString &v) :
+ value(valueFromString(v))
+{
+ key = k.split(QLatin1Char('/'));
+}
+
+Operation::KeyValuePair::KeyValuePair(const QString &k, const QVariant &v) :
+ value(v)
+{
+ key = k.split(QLatin1Char('/'));
+}
+
+Operation::KeyValuePair::KeyValuePair(const QStringList &k, const QString &v) :
+ key(k), value(valueFromString(v))
+{ }
+
+Operation::KeyValuePair::KeyValuePair(const QStringList &k, const QVariant &v) :
+ key(k), value(v)
+{ }
+
+QVariantMap Operation::load(const QString &file) const
+{
+ QVariantMap map;
+
+ // Read values from original file:
+ Utils::FileName path = Settings::instance()->getPath(file);
+ if (path.toFileInfo().exists()) {
+ Utils::PersistentSettingsReader reader;
+ if (!reader.load(path))
+ return QVariantMap();
+ map = reader.restoreValues();
+ } else {
+ std::cout << "No such file: " << qPrintable(path.toUserOutput()) << std::endl;
+ }
+
+ return map;
+}
+
+bool Operation::save(const QVariantMap &map, const QString &file) const
+{
+ Utils::FileName path = Settings::instance()->getPath(file);
+
+ if (path.isEmpty()) {
+ std::cerr << "Error: No path found for " << qPrintable(file) << "." << std::endl;
+ return false;
+ }
+
+ Utils::FileName dir = path.parentDir();
+ if (!dir.toFileInfo().exists())
+ QDir(dir.toString()).mkpath(dir.toString());
+
+ Utils::PersistentSettingsWriter writer(path, QLatin1String("unknown"));
+ return writer.save(map, 0);
+}
diff --git a/src/tools/sdktool/operation.h b/src/tools/sdktool/operation.h
new file mode 100644
index 00000000000..6b5c441a71e
--- /dev/null
+++ b/src/tools/sdktool/operation.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef OPERATION_H
+#define OPERATION_H
+
+#include <utils/fileutils.h>
+
+#include <QStringList>
+#include <QVariant>
+
+class Operation
+{
+public:
+ class KeyValuePair {
+ public:
+ KeyValuePair(const QString &k, const QString &v);
+ KeyValuePair(const QString &k, const QVariant &v);
+ KeyValuePair(const QStringList &k, const QString &v);
+ KeyValuePair(const QStringList &k, const QVariant &v);
+
+ QStringList key;
+ QVariant value;
+ };
+ typedef QList<KeyValuePair> KeyValuePairList;
+
+ virtual ~Operation() { }
+
+ virtual QString name() const = 0;
+ virtual QString helpText() const = 0;
+ virtual QString argumentsHelpText() const = 0;
+
+ virtual bool setArguments(const QStringList &args) = 0;
+
+ virtual int execute() const = 0;
+
+#ifdef WITH_TESTS
+ virtual bool test() const = 0;
+#endif
+
+ QVariantMap load(const QString &file) const;
+ bool save(const QVariantMap &map, const QString &file) const;
+
+ static QVariant valueFromString(const QString &v);
+ static QString makeUnique(const QString &name, const QStringList &inUse);
+};
+
+#endif // OPERATION_H
diff --git a/src/tools/sdktool/rmkeysoperation.cpp b/src/tools/sdktool/rmkeysoperation.cpp
new file mode 100644
index 00000000000..f6b98b04af2
--- /dev/null
+++ b/src/tools/sdktool/rmkeysoperation.cpp
@@ -0,0 +1,211 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "rmkeysoperation.h"
+
+#include <iostream>
+
+QString RmKeysOperation::name() const
+{
+ return QLatin1String("rmKeys");
+}
+
+QString RmKeysOperation::helpText() const
+{
+ return QLatin1String("remove settings from Qt Creator configuration");
+}
+
+QString RmKeysOperation::argumentsHelpText() const
+{
+ return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to remove.\n");
+}
+
+bool RmKeysOperation::setArguments(const QStringList &args)
+{
+ if (args.count() < 2)
+ return false;
+
+ m_keys = args;
+ m_file = m_keys.takeFirst();
+ return true;
+}
+
+int RmKeysOperation::execute() const
+{
+ Q_ASSERT(!m_keys.isEmpty());
+ QVariantMap map = load(m_file);
+
+ QVariantMap result = rmKeys(map, m_keys);
+ if (map == result)
+ return 1;
+
+ // Write data again:
+ return save(map, m_file) ? 0 : 2;
+}
+
+#ifdef WITH_TESTS
+bool RmKeysOperation::test() const
+{
+ QVariantMap testMap;
+ QVariantMap subKeys;
+ QVariantMap cur;
+ cur.insert(QLatin1String("testint2"), 53);
+ subKeys.insert(QLatin1String("subsubkeys"), cur);
+ subKeys.insert(QLatin1String("testbool"), true);
+ testMap.insert(QLatin1String("subkeys"), subKeys);
+ subKeys.clear();
+ testMap.insert(QLatin1String("subkeys2"), subKeys);
+ testMap.insert(QLatin1String("testint"), 23);
+
+ QStringList data;
+
+ QVariantMap result = rmKeys(testMap, data);
+
+ if (result != testMap)
+ return false;
+
+ data.append(QLatin1String("testint"));
+ result = rmKeys(testMap, data);
+
+ if (result.count() != 2
+ || !result.contains(QLatin1String("subkeys"))
+ || !result.contains(QLatin1String("subkeys2")))
+ return false;
+ cur = result.value(QLatin1String("subkeys")).toMap();
+ if (cur.count() != 2
+ || !cur.contains(QLatin1String("subsubkeys"))
+ || !cur.contains(QLatin1String("testbool")))
+ return false;
+
+ cur = cur.value(QLatin1String("subsubkeys")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("testint2")))
+ return false;
+
+ cur = result.value(QLatin1String("subkeys2")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ data.clear();
+ data.append("subkeys/subsubkeys");
+ result = rmKeys(testMap, data);
+
+ if (result.count() != 3
+ || !result.contains(QLatin1String("subkeys"))
+ || !result.contains(QLatin1String("subkeys2"))
+ || !result.contains(QLatin1String("testint")))
+ return false;
+ cur = result.value(QLatin1String("subkeys")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("testbool")))
+ return false;
+
+ cur = result.value(QLatin1String("subkeys2")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ data.clear();
+ data.append("subkeys/testbool");
+ result = rmKeys(testMap, data);
+
+ if (result.count() != 3
+ || !result.contains(QLatin1String("subkeys"))
+ || !result.contains(QLatin1String("subkeys2"))
+ || !result.contains(QLatin1String("testint")))
+ return false;
+ cur = result.value(QLatin1String("subkeys")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("subsubkeys")))
+ return false;
+
+ cur = cur.value(QLatin1String("subsubkeys")).toMap();
+ if (cur.count() != 1
+ || !cur.contains(QLatin1String("testint2")))
+ return false;
+
+ cur = result.value(QLatin1String("subkeys2")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ cur = result.value(QLatin1String("subkeys2")).toMap();
+ if (cur.count() != 0)
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap RmKeysOperation::rmKeys(const QVariantMap &map, const QStringList &removals)
+{
+ QVariantMap result = map;
+
+ foreach (const QString &r, removals) {
+ QList<QVariantMap> stack;
+
+ const QStringList keys = r.split(QLatin1Char('/'));
+
+ // Set up a stack of QVariantMaps along the path we take:
+ stack.append(result);
+ for (int i = 0; i < keys.count() - 1; ++i) {
+ QVariantMap subMap;
+ if (stack.last().contains(keys.at(i))) {
+ subMap = stack.last().value(keys.at(i)).toMap();
+ } else {
+ std::cerr << "Warning: Key " << qPrintable(r) << " not found." << std::endl;
+ continue;
+ }
+ stack.append(subMap);
+ }
+
+ // remove
+ Q_ASSERT(stack.count() == keys.count());
+ if (!stack.last().contains(keys.last())) {
+ std::cerr << "Warning: Key " << qPrintable(r) << " not found." << std::endl;
+ continue;
+ }
+ stack.last().remove(keys.last());
+
+ // Generate new resultset by folding maps back in:
+ QVariantMap foldBack = stack.takeLast();
+ for (int i = keys.count() - 2; i >= 0; --i) { // skip last key, that is already taken care of
+ const QString k = keys.at(i);
+ QVariantMap current = stack.takeLast();
+ current.insert(k, foldBack);
+ foldBack = current;
+ }
+
+ Q_ASSERT(stack.count() == 0);
+ Q_ASSERT(foldBack != map);
+
+ result = foldBack;
+ }
+
+ return result;
+}
diff --git a/src/tools/sdktool/rmkeysoperation.h b/src/tools/sdktool/rmkeysoperation.h
new file mode 100644
index 00000000000..1a2201a7057
--- /dev/null
+++ b/src/tools/sdktool/rmkeysoperation.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef RMKEYSOPERATION_H
+#define RMKEYSOPERATION_H
+
+#include "operation.h"
+
+class RmKeysOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap rmKeys(const QVariantMap &map, const QStringList &removals);
+
+private:
+ QStringList m_keys;
+ QString m_file;
+};
+
+#endif // RMKEYSOPERATION_H
diff --git a/src/tools/sdktool/rmkitoperation.cpp b/src/tools/sdktool/rmkitoperation.cpp
new file mode 100644
index 00000000000..7c31a554d61
--- /dev/null
+++ b/src/tools/sdktool/rmkitoperation.cpp
@@ -0,0 +1,209 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "rmkitoperation.h"
+
+#include "addkeysoperation.h"
+#include "addkitoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include "settings.h"
+
+#include <iostream>
+
+// Qt version file stuff:
+static char PREFIX[] = "Profile.";
+static char COUNT[] = "Profile.Count";
+static char DEFAULT[] = "Profile.Default";
+#ifdef WITH_TESTS
+static char VERSION[] = "Version";
+#endif
+
+// Kit:
+static char ID[] = "PE.Profile.Id";
+
+QString RmKitOperation::name() const
+{
+ return QLatin1String("rmKit");
+}
+
+QString RmKitOperation::helpText() const
+{
+ return QLatin1String("remove a Kit from Qt Creator");
+}
+
+QString RmKitOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> id of the new kit.\n");
+}
+
+bool RmKitOperation::setArguments(const QStringList &args)
+{
+ if (args.count() != 2)
+ return false;
+ if (args.at(0) != QLatin1String("--id"))
+ return false;
+
+ m_id = args.at(1);
+
+ return !m_id.isEmpty();
+}
+
+int RmKitOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("profiles"));
+ if (map.isEmpty())
+ map = AddKitOperation::initializeKits();
+
+ map = rmKit(map, m_id);
+
+ if (map.isEmpty())
+ return -2;
+
+ return save(map, QLatin1String("profiles")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool RmKitOperation::test() const
+{
+ QVariantMap map =
+ AddKitOperation::addKit(AddKitOperation::initializeKits(),
+ QLatin1String("testId"), QLatin1String("Test Qt Version"),
+ QLatin1String("/tmp/icon.png"),
+ 1, QLatin1String("/usr/bin/gdb-test"),
+ QLatin1String("Desktop"), QString(),
+ QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"),
+ QLatin1String("unsupported/mkspec"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue"))));
+ map =
+ AddKitOperation::addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"),
+ QLatin1String("/tmp/icon2.png"),
+ 1, QLatin1String("/usr/bin/gdb-test2"),
+ QLatin1String("Desktop"), QString(),
+ QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"),
+ QLatin1String("unsupported/mkspec2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2"))));
+
+ QVariantMap result = rmKit(map, QLatin1String("testId"));
+ if (result.count() != 4
+ || !result.contains("Profile.0")
+ || !result.contains(QLatin1String(COUNT))
+ || result.value(QLatin1String(COUNT)).toInt() != 1
+ || !result.contains(QLatin1String(DEFAULT))
+ || result.value(QLatin1String(DEFAULT)).toInt() != 0
+ || !result.contains(QLatin1String(VERSION))
+ || result.value(QLatin1String(VERSION)).toInt() != 1)
+ return false;
+
+ result = rmKit(map, QLatin1String("unknown"));
+ if (result != map)
+ return false;
+
+ result = rmKit(map, QLatin1String("testId2"));
+ if (result.count() != 4
+ || !result.contains("Profile.0")
+ || !result.contains(QLatin1String(COUNT))
+ || result.value(QLatin1String(COUNT)).toInt() != 1
+ || !result.contains(QLatin1String(DEFAULT))
+ || result.value(QLatin1String(DEFAULT)).toInt() != 0
+ || !result.contains(QLatin1String(VERSION))
+ || result.value(QLatin1String(VERSION)).toInt() != 1)
+ return false;
+
+ result = rmKit(result, QLatin1String("testId"));
+ if (result.count() != 3
+ || !result.contains(QLatin1String(COUNT))
+ || result.value(QLatin1String(COUNT)).toInt() != 0
+ || !result.contains(QLatin1String(DEFAULT))
+ || result.value(QLatin1String(DEFAULT)).toInt() != -1
+ || !result.contains(QLatin1String(VERSION))
+ || result.value(QLatin1String(VERSION)).toInt() != 1)
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap RmKitOperation::rmKit(const QVariantMap &map, const QString &id)
+{
+ QVariantMap result = AddKitOperation::initializeKits();
+
+ QVariantList profileList;
+ bool ok;
+ int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
+ if (!ok) {
+ std::cerr << "Error: The count found in map is not an integer.";
+ return map;
+ }
+
+ int kitPos = -1;
+ for (int i = 0; i < count; ++i) {
+ const QString key = QString::fromLatin1(PREFIX) + QString::number(i);
+ QVariantMap profile = map.value(key).toMap();
+ if (profile.value(QLatin1String(ID)).toString() == id) {
+ kitPos = i;
+ continue;
+ }
+ profileList << profile;
+ }
+ if (profileList.count() == map.count() - 3) {
+ std::cerr << "Error: Id was not found.";
+ return map;
+ }
+
+ int defaultKit = GetOperation::get(map, QLatin1String(DEFAULT)).toInt(&ok);
+ if (!ok) {
+ std::cerr << "Error: Could not find the default kit.";
+ defaultKit = -1;
+ }
+
+ if (defaultKit == kitPos || defaultKit < 0)
+ defaultKit = (count > 1) ? 0 : -1;
+
+ // remove data:
+ QStringList toRemove;
+ toRemove << QLatin1String(COUNT) << QLatin1String(DEFAULT);
+ result = RmKeysOperation::rmKeys(result, toRemove);
+
+ // insert data:
+ KeyValuePairList data;
+ data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit));
+ data << KeyValuePair(QStringList() << QLatin1String(COUNT), QVariant(count - 1));
+
+ for (int i = 0; i < profileList.count(); ++i)
+ data << KeyValuePair(QStringList() << QString::fromLatin1(PREFIX) + QString::number(i),
+ profileList.at(i));
+
+ return AddKeysOperation::addKeys(result, data);
+}
+
diff --git a/src/tools/sdktool/rmkitoperation.h b/src/tools/sdktool/rmkitoperation.h
new file mode 100644
index 00000000000..35832265c94
--- /dev/null
+++ b/src/tools/sdktool/rmkitoperation.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef RMKITOPERATION_H
+#define RMKITOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class RmKitOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap rmKit(const QVariantMap &map, const QString &id);
+
+private:
+ QString m_id;
+};
+
+#endif // RMKITOPERATION_H
diff --git a/src/tools/sdktool/rmqtoperation.cpp b/src/tools/sdktool/rmqtoperation.cpp
new file mode 100644
index 00000000000..ac4a8962f6a
--- /dev/null
+++ b/src/tools/sdktool/rmqtoperation.cpp
@@ -0,0 +1,152 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "rmqtoperation.h"
+
+#include "addkeysoperation.h"
+#include "addqtoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include <iostream>
+
+// ToolChain file stuff:
+static char PREFIX[] = "QtVersion.";
+
+// ToolChain:
+static char AUTODETECTION_SOURCE[] = "autodetectionSource";
+
+QString RmQtOperation::name() const
+{
+ return QLatin1String("rmQt");
+}
+
+QString RmQtOperation::helpText() const
+{
+ return QLatin1String("remove a Qt version from Qt Creator");
+}
+
+QString RmQtOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> The id of the qt version to remove.\n");
+}
+
+bool RmQtOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (current == QLatin1String("--id")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_id = next;
+ continue;
+ }
+ }
+
+ return !m_id.isEmpty();
+}
+
+int RmQtOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("qtversion"));
+ if (map.isEmpty())
+ return 0;
+
+ QVariantMap result = rmQt(map, m_id);
+ if (result == map)
+ return -2;
+
+ return save(map, QLatin1String("qtversion")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool RmQtOperation::test() const
+{
+ // Add toolchain:
+ QVariantMap map = AddQtOperation::initializeQtVersions();
+
+ QVariantMap result = rmQt(QVariantMap(), QLatin1String("nonexistant"));
+ if (result != map)
+ return false;
+
+ map = AddQtOperation::addQt(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("type"),
+ QLatin1String("/tmp/test"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
+ map = AddQtOperation::addQt(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("type"),
+ QLatin1String("/tmp/test2"),
+ KeyValuePairList());
+
+ result = rmQt(map, QLatin1String("nonexistant"));
+ if (result != map)
+ return false;
+
+ result = rmQt(map, QLatin1String("testId2"));
+ if (result == map
+ || !result.contains(QLatin1String("QtVersion.0"))
+ || result.value(QLatin1String("QtVersion.0")) != map.value(QLatin1String("QtVersion.0")))
+ return false;
+
+ result = rmQt(map, QLatin1String("testId"));
+ if (result == map
+ || !result.contains(QLatin1String("QtVersion.0"))
+ || result.value(QLatin1String("QtVersion.0")) != map.value(QLatin1String("QtVersion.1")))
+ return false;
+
+ result = rmQt(result, QLatin1String("testId2"));
+ if (result == map)
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap RmQtOperation::rmQt(const QVariantMap &map, const QString &id)
+{
+ QVariantList qtList;
+ for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
+ if (!i.key().startsWith(QLatin1String(PREFIX)))
+ continue;
+ QVariantMap qtData = i.value().toMap();
+ if (qtData.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != id)
+ qtList.append(qtData);
+ }
+
+ QVariantMap newMap = AddQtOperation::initializeQtVersions();
+ for (int i = 0; i < qtList.count(); ++i)
+ newMap.insert(QString::fromLatin1(PREFIX) + QString::number(i), qtList.at(i));
+
+ return newMap;
+}
+
diff --git a/src/tools/sdktool/rmqtoperation.h b/src/tools/sdktool/rmqtoperation.h
new file mode 100644
index 00000000000..750e885700e
--- /dev/null
+++ b/src/tools/sdktool/rmqtoperation.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef RMQTOPERATION_H
+#define RMQTOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class RmQtOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap rmQt(const QVariantMap &map, const QString &id);
+
+private:
+ QString m_id;
+};
+
+#endif // RMQTOPERATION_H
diff --git a/src/tools/sdktool/rmtoolchainoperation.cpp b/src/tools/sdktool/rmtoolchainoperation.cpp
new file mode 100644
index 00000000000..7aa56599694
--- /dev/null
+++ b/src/tools/sdktool/rmtoolchainoperation.cpp
@@ -0,0 +1,162 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "rmtoolchainoperation.h"
+
+#include "addkeysoperation.h"
+#include "addtoolchainoperation.h"
+#include "findkeyoperation.h"
+#include "findvalueoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include <iostream>
+
+// ToolChain file stuff:
+static char COUNT[] = "ToolChain.Count";
+static char PREFIX[] = "ToolChain.";
+
+// ToolChain:
+static char ID[] = "ProjectExplorer.ToolChain.Id";
+
+QString RmToolChainOperation::name() const
+{
+ return QLatin1String("rmTC");
+}
+
+QString RmToolChainOperation::helpText() const
+{
+ return QLatin1String("remove a tool chain from Qt Creator");
+}
+
+QString RmToolChainOperation::argumentsHelpText() const
+{
+ return QLatin1String(" --id <ID> The id of the tool chain to remove.\n");
+}
+
+bool RmToolChainOperation::setArguments(const QStringList &args)
+{
+ for (int i = 0; i < args.count(); ++i) {
+ const QString current = args.at(i);
+ const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
+
+ if (current == QLatin1String("--id")) {
+ if (next.isNull())
+ return false;
+ ++i; // skip next;
+ m_id = next;
+ continue;
+ }
+ }
+
+ return !m_id.isEmpty();
+}
+
+int RmToolChainOperation::execute() const
+{
+ QVariantMap map = load(QLatin1String("toolchains"));
+ if (map.isEmpty())
+ return 0;
+
+ QVariantMap result = rmToolChain(map, m_id);
+ if (result == map)
+ return -2;
+
+ return save(map, QLatin1String("toolchains")) ? 0 : -3;
+}
+
+#ifdef WITH_TESTS
+bool RmToolChainOperation::test() const
+{
+ // Add toolchain:
+ QVariantMap map = AddToolChainOperation::initializeToolChains();
+ map = AddToolChainOperation::addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
+ QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+ KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
+ map = AddToolChainOperation::addToolChain(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("/tmp/test2"),
+ QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
+ KeyValuePairList());
+
+ QVariantMap result = rmToolChain(QVariantMap(), QLatin1String("nonexistant"));
+ if (!result.isEmpty())
+ return false;
+
+ result = rmToolChain(map, QLatin1String("nonexistant"));
+ if (result != map)
+ return false;
+
+ result = rmToolChain(map, QLatin1String("testId2"));
+ if (result == map
+ || result.value(QLatin1String(COUNT), 0).toInt() != 1
+ || !result.contains(QLatin1String("ToolChain.0"))
+ || result.value(QLatin1String("ToolChain.0")) != map.value(QLatin1String("ToolChain.0")))
+ return false;
+
+ result = rmToolChain(map, QLatin1String("testId"));
+ if (result == map
+ || result.value(QLatin1String(COUNT), 0).toInt() != 1
+ || !result.contains(QLatin1String("ToolChain.0"))
+ || result.value(QLatin1String("ToolChain.0")) != map.value(QLatin1String("ToolChain.1")))
+ return false;
+
+ result = rmToolChain(result, QLatin1String("testId2"));
+ if (result == map
+ || result.value(QLatin1String(COUNT), 0).toInt() != 0)
+ return false;
+
+ return true;
+}
+#endif
+
+QVariantMap RmToolChainOperation::rmToolChain(const QVariantMap &map, const QString &id)
+{
+ // Find count of tool chains:
+ bool ok;
+ int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
+ if (!ok || count < 0) {
+ std::cerr << "Error: Count found in toolchains file seems wrong." << std::endl;
+ return map;
+ }
+
+ QVariantList tcList;
+ for (int i = 0; i < count; ++i) {
+ QVariantMap tcData = GetOperation::get(map, QString::fromLatin1(PREFIX) + QString::number(i)).toMap();
+ if (tcData.value(QLatin1String(ID)).toString() != id)
+ tcList.append(tcData);
+ }
+
+ QVariantMap newMap = AddToolChainOperation::initializeToolChains();
+ for (int i = 0; i < tcList.count(); ++i)
+ newMap.insert(QString::fromLatin1(PREFIX) + QString::number(i), tcList.at(i));
+ newMap.insert(QLatin1String(COUNT), tcList.count());
+
+ return newMap;
+}
+
diff --git a/src/tools/sdktool/rmtoolchainoperation.h b/src/tools/sdktool/rmtoolchainoperation.h
new file mode 100644
index 00000000000..0789d904be4
--- /dev/null
+++ b/src/tools/sdktool/rmtoolchainoperation.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef RMTOOLCHAINOPERATION_H
+#define RMTOOLCHAINOPERATION_H
+
+#include "operation.h"
+
+#include <QString>
+
+class RmToolChainOperation : public Operation
+{
+public:
+ QString name() const;
+ QString helpText() const;
+ QString argumentsHelpText() const;
+
+ bool setArguments(const QStringList &args);
+
+ int execute() const;
+
+#ifdef WITH_TESTS
+ bool test() const;
+#endif
+
+ static QVariantMap rmToolChain(const QVariantMap &map, const QString &id);
+
+private:
+ QString m_id;
+};
+
+#endif // RMTOOLCHAINOPERATION_H
diff --git a/src/tools/sdktool/sdktool.pro b/src/tools/sdktool/sdktool.pro
new file mode 100644
index 00000000000..28bbd4f271c
--- /dev/null
+++ b/src/tools/sdktool/sdktool.pro
@@ -0,0 +1,44 @@
+include(../../../qtcreator.pri)
+include(../../libs/utils/utils.pri)
+
+CONFIG += console
+
+QT -= gui test
+
+SOURCES += \
+ main.cpp \
+ addkeysoperation.cpp \
+ addkitoperation.cpp \
+ addqtoperation.cpp \
+ addtoolchainoperation.cpp \
+ findkeyoperation.cpp \
+ findvalueoperation.cpp \
+ getoperation.cpp \
+ operation.cpp \
+ rmkeysoperation.cpp \
+ rmkitoperation.cpp \
+ rmqtoperation.cpp \
+ rmtoolchainoperation.cpp \
+ settings.cpp \
+
+HEADERS += \
+ addkeysoperation.h \
+ addkitoperation.h \
+ addqtoperation.h \
+ addtoolchainoperation.h \
+ findkeyoperation.h \
+ findvalueoperation.h \
+ getoperation.h \
+ operation.h \
+ rmkeysoperation.h \
+ rmkitoperation.h \
+ rmqtoperation.h \
+ rmtoolchainoperation.h \
+ settings.h \
+
+INCLUDEPATH += \
+ $$PWD/../../plugins \
+ $$PWD/../../libs
+
+DESTDIR=$$IDE_APP_PATH
+
diff --git a/src/tools/sdktool/sdktool.qbs b/src/tools/sdktool/sdktool.qbs
new file mode 100644
index 00000000000..9886fd5f963
--- /dev/null
+++ b/src/tools/sdktool/sdktool.qbs
@@ -0,0 +1,40 @@
+import qbs.base 1.0
+import "../QtcTool.qbs" as QtcTool
+
+QtcTool {
+ name: "sdktool"
+
+ Depends { name: "cpp" }
+ Depends { name: "Qt.core" }
+ Depends { name: "Utils" }
+
+ files: [
+ "main.cpp",
+ "addkeysoperation.cpp",
+ "addkeysoperation.h",
+ "addkitoperation.cpp",
+ "addkitoperation.h",
+ "addqtoperation.cpp",
+ "addqtoperation.h",
+ "addtoolchainoperation.cpp",
+ "addtoolchainoperation.h",
+ "findkeyoperation.cpp",
+ "findkeyoperation.h",
+ "findvalueoperation.cpp",
+ "findvalueoperation.h",
+ "getoperation.cpp",
+ "getoperation.h",
+ "operation.h",
+ "operation.cpp",
+ "rmkeysoperation.cpp",
+ "rmkeysoperation.h",
+ "rmkitoperation.cpp",
+ "rmkitoperation.h",
+ "rmqtoperation.cpp",
+ "rmqtoperation.h",
+ "rmtoolchainoperation.cpp",
+ "rmtoolchainoperation.h",
+ "settings.cpp",
+ "settings.h"
+ ]
+}
diff --git a/src/tools/sdktool/settings.cpp b/src/tools/sdktool/settings.cpp
new file mode 100644
index 00000000000..3ccad8f8f6a
--- /dev/null
+++ b/src/tools/sdktool/settings.cpp
@@ -0,0 +1,100 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#include "settings.h"
+#include "operation.h"
+
+#include <iostream>
+
+#include <QCoreApplication>
+#include <QFileInfo>
+
+Settings *Settings::m_instance = 0;
+
+Settings *Settings::instance()
+{
+ return m_instance;
+}
+
+Settings::Settings() :
+ operation(0)
+{
+ Q_ASSERT(!m_instance);
+ m_instance = this;
+
+ // autodetect sdk dir:
+ Utils::FileName sdk = Utils::FileName::fromString(QCoreApplication::applicationDirPath());
+ Utils::FileName qtc = sdk;
+ qtc.appendPath(QLatin1String("qtcreator"));
+#ifdef Q_OS_WIN
+ qtc.append(".exe");
+#endif
+
+ QFileInfo qtcFi = qtc.toFileInfo();
+ if (!qtcFi.exists() || !qtcFi.isFile() || !qtcFi.isExecutable()) {
+ // we are in src/tools/sdktool (or lib/qtcreator/bin):
+ qtc = sdk;
+ qtc.appendPath(QLatin1String("../../../bin/qtcreator"));
+#ifdef Q_OS_WIN
+ qtc.append(".exe");
+#endif
+ qtcFi = qtc.toFileInfo();
+ if (!qtcFi.exists() || !qtcFi.isFile() || !qtcFi.isExecutable())
+ qtc.clear();
+ }
+
+ if (!qtc.isEmpty()) {
+ sdk = qtc.parentDir();
+ sdk = sdk.parentDir();
+ sdk.appendPath(QLatin1String("share/qtcreator/Nokia/qtcreator"));
+ sdkPath = sdk;
+ }
+}
+
+Utils::FileName Settings::getPath(const QString &file)
+{
+ Utils::FileName result = sdkPath;
+ if (file == QLatin1String("profiles") || file == QLatin1String("kits"))
+ result.appendPath(QLatin1String("profiles"));
+ else if (file == QLatin1String("qtversions") || file == QLatin1String("qtversion"))
+ result.appendPath(QLatin1String("qtversion"));
+ else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains"))
+ result.appendPath(QLatin1String("toolchains"));
+ else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains"))
+ result.appendPath(QLatin1String("toolchains"));
+ else if (file == QLatin1String("devices"))
+ result.appendPath(QLatin1String("devices"));
+ else if (file == QLatin1String("android"))
+ result.appendPath(QLatin1String("android"));
+ else
+ return Utils::FileName();
+ result.append(QLatin1String(".xml"));
+ return result;
+}
diff --git a/src/tools/sdktool/settings.h b/src/tools/sdktool/settings.h
new file mode 100644
index 00000000000..c60eec279c5
--- /dev/null
+++ b/src/tools/sdktool/settings.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <utils/fileutils.h>
+
+#include <QStringList>
+
+class Operation;
+
+class Settings
+{
+public:
+ Settings();
+ static Settings *instance();
+
+ Utils::FileName sdkPath;
+
+ Operation *operation;
+
+ Utils::FileName getPath(const QString &file);
+
+private:
+ static Settings *m_instance;
+};
+
+#endif // SETTINGS_H
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index 321d6a8e57b..1f499584d5e 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -1,7 +1,8 @@
TEMPLATE = subdirs
SUBDIRS = qtpromaker \
- qmlpuppet
+ qmlpuppet \
+ sdktool
win32 {
SUBDIRS += qtcdebugger