diff options
39 files changed, 639 insertions, 173 deletions
diff --git a/doc/api/first-plugin.qdoc b/doc/api/first-plugin.qdoc index 6f1e67b0db..d81cee4a13 100644 --- a/doc/api/first-plugin.qdoc +++ b/doc/api/first-plugin.qdoc @@ -35,6 +35,12 @@ build and use one for actually developing, and the other for testing your plugin with. + You need to make sure that you use the same \QC version that you want + to develop for to create the plugin. Because of the + \l{Binary and Source Compatibility} rules of \QC, the \QC plugin wizard + creates a plugin that might only compile and run with the same \QC + version that it was created with. + \list 1 \li Select \gui{File > New File or Project > Libraries > Qt Creator Plugin > Choose}. diff --git a/doc/config/style/qt5-sidebar.html b/doc/config/style/qt5-sidebar.html new file mode 100644 index 0000000000..531262ab5b --- /dev/null +++ b/doc/config/style/qt5-sidebar.html @@ -0,0 +1,17 @@ +<div class="sectionlist normallist"> + <div class="heading"> + <a name="reference"></a> + <h2 id="reference">Qt Creator Manual</h2> + </div> + <div class="indexboxcont indexboxbar"> + <ul> + <li><a href="creator-getting-started.html">Getting Started</a></li> + <li><a href="creator-project-managing.html">Managing Projects</a></li> + <li><a href="creator-design-mode.html">Designing User Interfaces</a></li> + <li><a href="creator-coding.html">Coding</a></li> + <li><a href="creator-building-running.html">Building and Running</a></li> + <li><a href="creator-testing.html">Debugging and Analyzing</a></li> + <li><a href="creator-advanced.html">Advanced Use</a></li> + <li><a href="creator-help-overview.html">Getting Help</a></li> + </ul> + </div> diff --git a/doc/qtcreator-online.qdocconf b/doc/qtcreator-online.qdocconf index e1ef0e1f08..8aeb9f61a9 100644 --- a/doc/qtcreator-online.qdocconf +++ b/doc/qtcreator-online.qdocconf @@ -1,3 +1,20 @@ # Run qdoc from the directory that contains this file. include(config/qtcreator-project.qdocconf) + +HTML.footer = \ + " </div>\n" \ + " <p class=\"copy-notice\">\n" \ + " <acronym title=\"Copyright\">©</acronym> 2014 Digia Plc and/or its\n" \ + " subsidiaries. Documentation contributions included herein are the copyrights of\n" \ + " their respective owners. " \ + " The documentation provided herein is licensed under the terms of the" \ + " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation" \ + " License version 1.3</a> as published by the Free Software Foundation. " \ + " Digia, Qt and their respective logos are trademarks of Digia Plc " \ + " in Finland and/or other countries worldwide. All other trademarks are property\n" \ + " of their respective owners. </p>\n" + include($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf) + +# Add an .html file with sidebar content, used in the online style +HTML.stylesheets += config/style/qt5-sidebar.html diff --git a/doc/src/overview/creator-overview.qdoc b/doc/src/overview/creator-overview.qdoc index 792c54bd3d..fdae1cc685 100644 --- a/doc/src/overview/creator-overview.qdoc +++ b/doc/src/overview/creator-overview.qdoc @@ -80,7 +80,8 @@ \li \b {\l{Building and Running}} \QC is integrated with cross-platform systems for build - automation: qmake and CMake. In addition, you can import + automation: qmake, Qbs, CMake, and Autotools. In addition, you + can import projects as \e {generic projects} and fully control the steps and commands used to build the project. diff --git a/doc/src/projects/creator-projects-other.qdoc b/doc/src/projects/creator-projects-other.qdoc index 85aab3d67f..b363458c97 100644 --- a/doc/src/projects/creator-projects-other.qdoc +++ b/doc/src/projects/creator-projects-other.qdoc @@ -31,7 +31,9 @@ \title Using Other Build Systems \QC project wizards create projects that are configured to use qmake. Most - of the instructions in this manual apply to using qmake. + of the instructions in this manual apply to using qmake. However, \QC is + also integrated to other build systems, as described in the the following + sections: \list diff --git a/doc/src/projects/creator-projects-targets.qdoc b/doc/src/projects/creator-projects-targets.qdoc index 4efed7de9f..ea9e9c605f 100644 --- a/doc/src/projects/creator-projects-targets.qdoc +++ b/doc/src/projects/creator-projects-targets.qdoc @@ -107,8 +107,9 @@ it is referred to as \b{Qt in PATH} and selected as the Qt version to use for the \gui Desktop kit that is created by default. - \li In the \gui {Qt mkspec} field, specify build instructions for qmake. - If you leave this field empty, the default value is used. + \li In the \gui {Qt mkspec} field, specify the name of the mkspec + configuration that should be used by qmake. If you leave this field + empty, the default mkspec of the selected Qt version is used. \endlist diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 8eb1b3eda4..8adac2c801 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -487,8 +487,10 @@ bool LinkPrivate::importLibrary(Document::Ptr doc, } else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError || libraryInfo.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileError) { // Only underline import if package isn't described in .qmltypes anyway + // and is not a private package QString packageName = importInfo.name(); - if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName))) { + if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName)) + && !packageName.endsWith(QLatin1String("private"), Qt::CaseInsensitive)) { error(doc, errorLoc, libraryInfo.pluginTypeInfoError()); import->valid = false; } diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index 9ddaa4dc8f..8895796ddc 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -876,6 +876,8 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths, language = mainLanguage; if (language == Dialect::Qml && mainLanguage == Dialect::QmlQtQuick2Ui) language = Dialect::QmlQtQuick2; + if (language == Dialect::QmlTypeInfo || language == Dialect::QmlProject) + continue; QString contents; int documentRevision = 0; @@ -1321,6 +1323,8 @@ LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const ProjectInfo info = projectInfoForPath(doc->path()); if (!info.isValid()) return LibraryInfo(); + if (!info.qtQmlPath.isEmpty()) + return m_validSnapshot.libraryInfo(info.qtQmlPath); return m_validSnapshot.libraryInfo(info.qtImportsPath); } diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index 14539410bd..63ad5f40ff 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -93,34 +93,35 @@ void PluginDumper::scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterfac void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, bool force) { - if (info.qmlDumpPath.isEmpty() || info.qtImportsPath.isEmpty()) + if (info.qmlDumpPath.isEmpty() || (info.qtImportsPath.isEmpty() && info.qtQmlPath.isEmpty())) return; - const QString importsPath = QDir::cleanPath(info.qtImportsPath); + const QString baseImportsPath = info.qtQmlPath.isEmpty() ? info.qtImportsPath : info.qtQmlPath; + const QString importsPath = QDir::cleanPath(baseImportsPath); if (m_runningQmldumps.values().contains(importsPath)) return; LibraryInfo builtinInfo; if (!force) { const Snapshot snapshot = m_modelManager->snapshot(); - builtinInfo = snapshot.libraryInfo(info.qtImportsPath); + builtinInfo = snapshot.libraryInfo(baseImportsPath); if (builtinInfo.isValid()) return; } builtinInfo = LibraryInfo(LibraryInfo::Found); m_modelManager->updateLibraryInfo(info.qtImportsPath, builtinInfo); - // prefer QTDIR/imports/builtins.qmltypes if available - const QString builtinQmltypesPath = info.qtImportsPath + QLatin1String("/builtins.qmltypes"); + // prefer QTDIR/qml/builtins.qmltypes if available + const QString builtinQmltypesPath = baseImportsPath + QLatin1String("/builtins.qmltypes"); if (QFile::exists(builtinQmltypesPath)) { - loadQmltypesFile(QStringList(builtinQmltypesPath), info.qtImportsPath, builtinInfo); + loadQmltypesFile(QStringList(builtinQmltypesPath), baseImportsPath, builtinInfo); return; } // QTDIR/imports/QtQuick1/builtins.qmltypes was used in developer builds of 5.0.0, 5.0.1 const QString builtinQmltypesPath2 = info.qtImportsPath + QLatin1String("/QtQuick1/builtins.qmltypes"); if (QFile::exists(builtinQmltypesPath2)) { - loadQmltypesFile(QStringList(builtinQmltypesPath2), info.qtImportsPath, builtinInfo); + loadQmltypesFile(QStringList(builtinQmltypesPath2), baseImportsPath, builtinInfo); return; } @@ -131,8 +132,8 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError))); QStringList args(QLatin1String("--builtins")); process->start(info.qmlDumpPath, args); - m_runningQmldumps.insert(process, info.qtImportsPath); - m_qtToInfo.insert(info.qtImportsPath, info); + m_runningQmldumps.insert(process, baseImportsPath); + m_qtToInfo.insert(baseImportsPath, info); } static QString makeAbsolute(const QString &path, const QString &base) @@ -306,10 +307,12 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode) return; const Snapshot snapshot = m_modelManager->snapshot(); LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); + bool privatePlugin = libraryPath.endsWith(QLatin1String("private")); if (exitCode != 0) { const QString errorMessages = qmlPluginDumpErrorMessage(process); - ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); + if (!privatePlugin) + ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); } @@ -324,7 +327,8 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode) if (!error.isEmpty()) { libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpErrorMessage(libraryPath, error)); - printParseWarnings(libraryPath, libraryInfo.pluginTypeInfoError()); + if (!privatePlugin) + printParseWarnings(libraryPath, libraryInfo.pluginTypeInfoError()); } else { libraryInfo.setMetaObjects(objectsList.values()); libraryInfo.setModuleApis(moduleApis); @@ -349,16 +353,14 @@ void PluginDumper::qmlPluginTypeDumpError(QProcess::ProcessError) const QString libraryPath = m_runningQmldumps.take(process); if (libraryPath.isEmpty()) return; - const QString errorMessages = qmlPluginDumpErrorMessage(process); - ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); - if (!libraryPath.isEmpty()) { - const Snapshot snapshot = m_modelManager->snapshot(); - LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); - libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); - libraryInfo.updateFingerprint(); - m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); - } + const Snapshot snapshot = m_modelManager->snapshot(); + LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); + if (!libraryPath.endsWith(QLatin1String("private"), Qt::CaseInsensitive)) + ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages)); + libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages)); + libraryInfo.updateFingerprint(); + m_modelManager->updateLibraryInfo(libraryPath, libraryInfo); } void PluginDumper::pluginChanged(const QString &pluginLibrary) @@ -421,10 +423,12 @@ void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths, void PluginDumper::dump(const Plugin &plugin) { + ModelManagerInterface::ProjectInfo info = m_modelManager->defaultProjectInfo(); + const Snapshot snapshot = m_modelManager->snapshot(); + LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); + // if there are type infos, don't dump! if (!plugin.typeInfoPaths.isEmpty()) { - const Snapshot snapshot = m_modelManager->snapshot(); - LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); if (!libraryInfo.isValid()) return; @@ -432,11 +436,10 @@ void PluginDumper::dump(const Plugin &plugin) return; } - ModelManagerInterface::ProjectInfo info = m_modelManager->defaultProjectInfo(); + if (plugin.importUri.isEmpty()) + return; // initial scan without uri, ignore if (!info.tryQmlDump || info.qmlDumpPath.isEmpty()) { - const Snapshot snapshot = m_modelManager->snapshot(); - LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath); if (!libraryInfo.isValid()) return; @@ -460,10 +463,8 @@ void PluginDumper::dump(const Plugin &plugin) connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int))); connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError))); QStringList args; - if (plugin.importUri.isEmpty()) - return; // dumping with --path always fails if (info.qmlDumpHasRelocatableFlag) - args << QLatin1String("-relocatable"); + args << QLatin1String("-nonrelocatable"); args << plugin.importUri; args << plugin.importVersion; args << plugin.importPath; diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp index 478cbb1642..269cee765b 100644 --- a/src/libs/ssh/sshchannel.cpp +++ b/src/libs/ssh/sshchannel.cpp @@ -137,10 +137,16 @@ void AbstractSshChannel::flushSendBuffer() void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, quint32 remoteWindowSize, quint32 remoteMaxPacketSize) { - if (m_state != SessionRequested) { - throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, - "Invalid SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet."); - } + switch (m_state) { + case SessionRequested: + break; // Ok, continue. + case CloseRequested: + return; // Late server reply; we requested a channel close in the meantime. + default: + throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, + "Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet."); + } + m_timeoutTimer->stop(); if (remoteMaxPacketSize < MinMaxPacketSize) { @@ -162,10 +168,16 @@ void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, void AbstractSshChannel::handleOpenFailure(const QString &reason) { - if (m_state != SessionRequested) { - throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, - "Invalid SSH_MSG_CHANNEL_OPEN_FAILURE packet."); - } + switch (m_state) { + case SessionRequested: + break; // Ok, continue. + case CloseRequested: + return; // Late server reply; we requested a channel close in the meantime. + default: + throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, + "Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet."); + } + m_timeoutTimer->stop(); #ifdef CREATOR_SSH_DEBUG diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index 6698dfce8b..bd8bd6dc9f 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -85,9 +85,7 @@ SshRemoteProcess::SshRemoteProcess(quint32 channelId, Internal::SshSendFacility SshRemoteProcess::~SshRemoteProcess() { - Q_ASSERT(d->channelState() == Internal::SshRemoteProcessPrivate::Inactive - || d->channelState() == Internal::SshRemoteProcessPrivate::CloseRequested - || d->channelState() == Internal::SshRemoteProcessPrivate::Closed); + close(); delete d; } diff --git a/src/libs/utils/elfreader.cpp b/src/libs/utils/elfreader.cpp index bb98013649..0199fbd7aa 100644 --- a/src/libs/utils/elfreader.cpp +++ b/src/libs/utils/elfreader.cpp @@ -34,6 +34,8 @@ #include <QDir> #include <QDebug> +#include <new> // std::bad_alloc + namespace Utils { quint16 getHalfWord(const unsigned char *&s, const ElfData &context) @@ -113,7 +115,11 @@ bool ElfMapper::map() ustart = file.map(0, fdlen); if (ustart == 0) { // Try reading the data into memory instead. - raw = file.readAll(); + try { + raw = file.readAll(); + } catch (std::bad_alloc &) { + return false; + } start = raw.constData(); fdlen = raw.size(); } diff --git a/src/libs/utils/json.cpp b/src/libs/utils/json.cpp index 203d4b4f4f..75259520bd 100644 --- a/src/libs/utils/json.cpp +++ b/src/libs/utils/json.cpp @@ -42,8 +42,10 @@ using namespace Utils; JsonMemoryPool::~JsonMemoryPool() { - foreach (char *obj, _objs) + foreach (char *obj, _objs) { + reinterpret_cast<JsonValue *>(obj)->~JsonValue(); delete[] obj; + } } JsonValue::JsonValue(Kind kind) diff --git a/src/plugins/analyzerbase/detailederrorview.cpp b/src/plugins/analyzerbase/detailederrorview.cpp index 6b2eba80e0..f6a6f3fbc2 100644 --- a/src/plugins/analyzerbase/detailederrorview.cpp +++ b/src/plugins/analyzerbase/detailederrorview.cpp @@ -51,6 +51,9 @@ DetailedErrorDelegate::DetailedErrorDelegate(QListView *parent) QSize DetailedErrorDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const { + if (!index.isValid()) + return QStyledItemDelegate::sizeHint(opt, index); + const QListView *view = qobject_cast<const QListView *>(parent()); const int viewportWidth = view->viewport()->width(); const bool isSelected = view->selectionModel()->currentIndex() == index; diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 8a4b8563c2..00770fa296 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -308,6 +308,7 @@ QString AndroidManager::androidNameForApiLevel(int x) case 19: return QLatin1String("Android 4.4"); case 20: + return QLatin1String("Android 4.4W"); case 21: return QLatin1String("Android 5.0"); default: diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 54053240c5..3826c382f7 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -149,7 +149,6 @@ void CppEditorWidget::finalizeInitialization() d->m_cppEditorDocument = qobject_cast<CppEditorDocument *>(textDocument()); setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID); - setRevisionsVisible(true); // function combo box sorting connect(CppEditorPlugin::instance(), &CppEditorPlugin::outlineSortingChanged, diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 2fb94adea9..5540a2f2da 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -693,8 +693,8 @@ void CppModelManager::updateVisibleEditorDocuments() const foreach (Core::IEditor *editor, Core::EditorManager::visibleEditors()) { if (const Core::IDocument *document = editor->document()) { const QString filePath = document->filePath(); - QTC_ASSERT(!filePath.isEmpty(), continue); - visibleDocumentsInEditMode.insert(filePath); + if (!filePath.isEmpty()) + visibleDocumentsInEditMode.insert(filePath); } } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 7cf5b79d70..4e9b867016 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1576,8 +1576,8 @@ void DebuggerPluginPrivate::continueOnAttach(Debugger::DebuggerState state) if (state != InferiorStopOk) return; // disconnect and continue - disconnect(currentEngine(), SIGNAL(stateChanged(Debugger::DebuggerState)), - this, SLOT(continueOnAttach(Debugger::DebuggerState))); + disconnect(currentEngine(), &DebuggerEngine::stateChanged, + this, &DebuggerPluginPrivate::continueOnAttach); handleExecContinue(); } diff --git a/src/plugins/debugger/unstartedappwatcherdialog.cpp b/src/plugins/debugger/unstartedappwatcherdialog.cpp index 4de800a6ab..fe22bc2fc4 100644 --- a/src/plugins/debugger/unstartedappwatcherdialog.cpp +++ b/src/plugins/debugger/unstartedappwatcherdialog.cpp @@ -31,6 +31,7 @@ #include "unstartedappwatcherdialog.h" #include "debuggerdialogs.h" +#include "debuggerkitinformation.h" #include <utils/pathchooser.h> @@ -151,6 +152,9 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent) connect(m_pathChooser, SIGNAL(pathChanged(QString)), this, SLOT(stopAndCheckExecutable())); connect(m_closePushButton, SIGNAL(clicked()), this, SLOT(reject())); connect(&m_timer, SIGNAL(timeout()), this, SLOT(findProcess())); + connect(m_kitChooser, &ProjectExplorer::KitChooser::currentIndexChanged, + this, &UnstartedAppWatcherDialog::kitChanged); + kitChanged(); setWaitingState(checkExecutableString() ? NotWatchingState : InvalidWacherState); } @@ -224,10 +228,10 @@ void UnstartedAppWatcherDialog::startStopTimer(bool start) void UnstartedAppWatcherDialog::findProcess() { - QString appName = m_pathChooser->path(); + const QString &appName = Utils::FileUtils::normalizePathName(m_pathChooser->path()); DeviceProcessItem fallback; foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) { - if (p.exe == appName) { + if (Utils::FileUtils::normalizePathName(p.exe) == appName) { pidFound(p); return; } @@ -244,6 +248,19 @@ void UnstartedAppWatcherDialog::stopAndCheckExecutable() setWaitingState(checkExecutableString() ? NotWatchingState : InvalidWacherState); } +void UnstartedAppWatcherDialog::kitChanged() +{ + const DebuggerItem *debugger = DebuggerKitInformation::debugger(m_kitChooser->currentKit()); + if (!debugger) + return; + if (debugger->engineType() == Debugger::CdbEngineType) { + m_continueOnAttachCheckBox->setEnabled(false); + m_continueOnAttachCheckBox->setChecked(true); + } else { + m_continueOnAttachCheckBox->setEnabled(true); + } +} + bool UnstartedAppWatcherDialog::checkExecutableString() const { if (!m_pathChooser->path().isEmpty()) { @@ -270,7 +287,7 @@ bool UnstartedAppWatcherDialog::hideOnAttach() const bool UnstartedAppWatcherDialog::continueOnAttach() const { - return m_continueOnAttachCheckBox->isChecked(); + return m_continueOnAttachCheckBox->isEnabled() && m_continueOnAttachCheckBox->isChecked(); } void UnstartedAppWatcherDialog::setWaitingState(UnstartedAppWacherState state) diff --git a/src/plugins/debugger/unstartedappwatcherdialog.h b/src/plugins/debugger/unstartedappwatcherdialog.h index 2144683bcd..4da10c05cf 100644 --- a/src/plugins/debugger/unstartedappwatcherdialog.h +++ b/src/plugins/debugger/unstartedappwatcherdialog.h @@ -70,6 +70,7 @@ public slots: void startStopWatching(bool start); void findProcess(); void stopAndCheckExecutable(); + void kitChanged(); signals: void processFound(); diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 7bfab38189..8530a41832 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -420,10 +420,11 @@ void IosConfigurations::updateSimulators() DeviceManager *devManager = DeviceManager::instance(); Core::Id devId = Constants::IOS_SIMULATOR_DEVICE_ID; IDevice::ConstPtr dev = devManager->find(devId); - if (!dev.isNull()) - return; - IosSimulator *newDev = new IosSimulator(devId); - devManager->addDevice(IDevice::ConstPtr(newDev)); + if (dev.isNull()) { + dev = IDevice::ConstPtr(new IosSimulator(devId)); + devManager->addDevice(dev); + } + IosSimulator::updateAvailableDevices(); } void IosConfigurations::setDeveloperPath(const FileName &devPath) diff --git a/src/plugins/ios/iosconstants.h b/src/plugins/ios/iosconstants.h index 8fc42bf98c..8fc8f8a8fd 100644 --- a/src/plugins/ios/iosconstants.h +++ b/src/plugins/ios/iosconstants.h @@ -38,17 +38,6 @@ namespace Internal { Q_DECLARE_LOGGING_CATEGORY(iosLog) } // namespace Internal -namespace IosDeviceType { -enum Enum { - IosDevice, - SimulatedIphone, - SimulatedIpad, - SimulatedIphoneRetina4Inch, - SimulatedIphoneRetina3_5Inch, - SimulatedIpadRetina -}; -} - namespace Constants { const char IOS_SETTINGS_ID[] = "ZZ.Ios Configurations"; const char IOS_SETTINGS_CATEGORY[] = "XA.Ios"; diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp index 78861b0862..d0a24cd10d 100644 --- a/src/plugins/ios/iosdeploystep.cpp +++ b/src/plugins/ios/iosdeploystep.cpp @@ -134,7 +134,7 @@ void IosDeployStep::run(QFutureInterface<bool> &fi) } m_transferStatus = TransferInProgress; QTC_CHECK(m_toolHandler == 0); - m_toolHandler = new IosToolHandler(IosDeviceType::IosDevice, this); + m_toolHandler = new IosToolHandler(IosDeviceType(), this); m_futureInterface.setProgressRange(0, 200); m_futureInterface.setProgressValueAndText(0, QLatin1String("Transferring application")); m_futureInterface.reportStarted(); diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp index 01d71788b2..59667f2d3b 100644 --- a/src/plugins/ios/iosdevice.cpp +++ b/src/plugins/ios/iosdevice.cpp @@ -29,6 +29,7 @@ ****************************************************************************/ #include "iosdevice.h" +#include "iossimulator.h" #include "iosconstants.h" #include "iosconfigurations.h" #include "iostoolhandler.h" @@ -291,7 +292,7 @@ void IosDeviceManager::deviceDisconnected(const QString &uid) void IosDeviceManager::updateInfo(const QString &devId) { - IosToolHandler *requester = new IosToolHandler(IosDeviceType::IosDevice, this); + IosToolHandler *requester = new IosToolHandler(IosDeviceType(), this); connect(requester, SIGNAL(deviceInfo(Ios::IosToolHandler*,QString,Ios::IosToolHandler::Dict)), SLOT(deviceInfo(Ios::IosToolHandler*,QString,Ios::IosToolHandler::Dict)), Qt::QueuedConnection); connect(requester, SIGNAL(finished(Ios::IosToolHandler*)), diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp index f102824ade..22231a529b 100644 --- a/src/plugins/ios/iosrunconfiguration.cpp +++ b/src/plugins/ios/iosrunconfiguration.cpp @@ -47,6 +47,7 @@ #include <qtsupport/qtkitinformation.h> #include <QList> +#include <QStandardItemModel> #include <utils/qtcprocess.h> #include <utils/qtcassert.h> @@ -79,6 +80,7 @@ private slots: private: Ui::IosRunConfiguration *m_ui; IosRunConfiguration *m_runConfiguration; + QStandardItemModel m_deviceTypeModel; }; IosRunConfiguration::IosRunConfiguration(Target *parent, Core::Id id, const QString &path) @@ -103,7 +105,6 @@ void IosRunConfiguration::init() m_parseInProgress = project->parseInProgress(m_profilePath); m_lastIsEnabled = isEnabled(); m_lastDisabledReason = disabledReason(); - m_deviceType = IosDeviceType::IosDevice; updateDisplayNames(); connect(DeviceManager::instance(), SIGNAL(updated()), SLOT(deviceChanges())); @@ -161,9 +162,9 @@ QStringList IosRunConfiguration::commandLineArguments() void IosRunConfiguration::updateDisplayNames() { if (DeviceTypeKitInformation::deviceTypeId(target()->kit()) == Constants::IOS_DEVICE_TYPE) - m_deviceType = IosDeviceType::IosDevice; - else if (m_deviceType == IosDeviceType::IosDevice) - m_deviceType = IosDeviceType::SimulatedIphoneRetina4Inch; + m_deviceType = IosDeviceType(); + else if (m_deviceType.type == IosDeviceType::IosDevice) + m_deviceType = IosDeviceType(IosDeviceType::SimulatedDevice); IDevice::ConstPtr dev = DeviceKitInformation::device(target()->kit()); const QString devName = dev.isNull() ? IosDevice::name() : dev->displayName(); setDefaultDisplayName(tr("Run on %1").arg(devName)); @@ -264,19 +265,14 @@ Utils::FileName IosRunConfiguration::localExecutable() const bool IosRunConfiguration::fromMap(const QVariantMap &map) { m_arguments = map.value(runConfigurationKey).toStringList(); - IosDeviceType::Enum deviceType = static_cast<IosDeviceType::Enum>(map.value(deviceTypeKey) - .toInt()); - bool valid = false; - for (int i = 0 ; i < nSimulatedDevices; ++i) - if (simulatedDevices[i] == m_deviceType) - valid = true; - if (valid) - m_deviceType = deviceType; - else if (DeviceTypeKitInformation::deviceTypeId(target()->kit()) == Constants::IOS_DEVICE_TYPE) - m_deviceType = IosDeviceType::IosDevice; - else - m_deviceType = IosDeviceType::SimulatedIphoneRetina4Inch; - + bool deviceTypeIsInt; + map.value(deviceTypeKey).toInt(&deviceTypeIsInt); + if (deviceTypeIsInt || !m_deviceType.fromMap(map.value(deviceTypeKey).toMap())) { + if (DeviceTypeKitInformation::deviceTypeId(target()->kit()) == Constants::IOS_DEVICE_TYPE) + m_deviceType = IosDeviceType(IosDeviceType::IosDevice); + else + m_deviceType = IosDeviceType(IosDeviceType::SimulatedDevice); + } return RunConfiguration::fromMap(map); } @@ -284,7 +280,7 @@ QVariantMap IosRunConfiguration::toMap() const { QVariantMap res = RunConfiguration::toMap(); res[runConfigurationKey] = m_arguments; - res[deviceTypeKey] = m_deviceType; + res[deviceTypeKey] = deviceType().toMap(); return res; } @@ -358,12 +354,29 @@ QString IosRunConfiguration::disabledReason() const return RunConfiguration::disabledReason(); } -IosDeviceType::Enum IosRunConfiguration::deviceType() const +IosDeviceType IosRunConfiguration::deviceType() const { + QList<IosDeviceType> availableSimulators; + if (m_deviceType.type == IosDeviceType::SimulatedDevice) + availableSimulators = IosSimulator::availableDevices(); + if (!availableSimulators.isEmpty()) { + QList<IosDeviceType> elegibleDevices; + QString devname = m_deviceType.identifier.split(QLatin1Char(',')).value(0); + foreach (const IosDeviceType &dType, availableSimulators) { + if (dType == m_deviceType) + return m_deviceType; + if (!devname.isEmpty() && dType.identifier.startsWith(devname) + && dType.identifier.split(QLatin1Char(',')).value(0) == devname) + elegibleDevices << dType; + } + if (!elegibleDevices.isEmpty()) + return elegibleDevices.last(); + return availableSimulators.last(); + } return m_deviceType; } -void IosRunConfiguration::setDeviceType(IosDeviceType::Enum deviceType) +void IosRunConfiguration::setDeviceType(const IosDeviceType &deviceType) { m_deviceType = deviceType; } @@ -372,6 +385,7 @@ IosRunConfigurationWidget::IosRunConfigurationWidget(IosRunConfiguration *runCon m_ui(new Ui::IosRunConfiguration), m_runConfiguration(runConfiguration) { m_ui->setupUi(this); + m_ui->deviceTypeComboBox->setModel(&m_deviceTypeModel); updateValues(); connect(m_ui->deviceTypeComboBox, SIGNAL(currentIndexChanged(int)), @@ -436,25 +450,46 @@ void IosRunConfigurationWidget::argumentsLineEditTextEdited() void IosRunConfigurationWidget::setDeviceTypeIndex(int devIndex) { - if (devIndex >= 0 && devIndex < nSimulatedDevices) - m_runConfiguration->setDeviceType(simulatedDevices[devIndex]); - else - m_runConfiguration->setDeviceType(IosDeviceType::SimulatedIphoneRetina4Inch); + QVariant selectedDev = m_deviceTypeModel.data(m_deviceTypeModel.index(devIndex, 0), Qt::UserRole + 1); + if (selectedDev.isValid()) + m_runConfiguration->setDeviceType(selectedDev.value<IosDeviceType>()); } void IosRunConfigurationWidget::updateValues() { - bool showDeviceSelector = m_runConfiguration->deviceType() != IosDeviceType::IosDevice; + bool showDeviceSelector = m_runConfiguration->deviceType().type != IosDeviceType::IosDevice; m_ui->deviceTypeLabel->setVisible(showDeviceSelector); m_ui->deviceTypeComboBox->setVisible(showDeviceSelector); + if (showDeviceSelector && m_deviceTypeModel.rowCount() == 0) { + foreach (const IosDeviceType &dType, IosSimulator::availableDevices()) { + QStandardItem *item = new QStandardItem(dType.displayName); + QVariant v; + v.setValue(dType); + item->setData(v); + m_deviceTypeModel.appendRow(item); + } + } QStringList args = m_runConfiguration->commandLineArguments(); QString argsString = argListToString(args); - if (m_runConfiguration->deviceType() == IosDeviceType::IosDevice) - for (int i = 0; i < nSimulatedDevices; ++i) - if (simulatedDevices[i] == m_runConfiguration->deviceType()) + IosDeviceType currentDType = m_runConfiguration->deviceType(); + if (!m_ui->deviceTypeComboBox->currentData().isValid() + || currentDType != m_ui->deviceTypeComboBox->currentData().value<IosDeviceType>()) { + bool didSet = false; + for (int i = 0; m_deviceTypeModel.hasIndex(i, 0); ++i) { + QVariant vData = m_deviceTypeModel.data(m_deviceTypeModel.index(i, 0), Qt::UserRole + 1); + IosDeviceType dType = vData.value<IosDeviceType>(); + if (dType == currentDType) { m_ui->deviceTypeComboBox->setCurrentIndex(i); + didSet = true; + break; + } + } + if (!didSet) { + qCWarning(iosLog) << "could not set " << currentDType << " as it is not in model"; + } + } m_ui->argumentsLineEdit->setText(argsString); m_ui->executableLineEdit->setText(m_runConfiguration->localExecutable().toUserOutput()); } diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h index 23f63b0e6d..2790dd6c55 100644 --- a/src/plugins/ios/iosrunconfiguration.h +++ b/src/plugins/ios/iosrunconfiguration.h @@ -32,6 +32,7 @@ #include "iosconstants.h" #include "iosconfigurations.h" +#include "iossimulator.h" #include <projectexplorer/runconfiguration.h> #include <utils/fileutils.h> @@ -43,16 +44,6 @@ class QmakeProFileNode; namespace Ios { namespace Internal { -enum { nSimulatedDevices = 4 }; -static const IosDeviceType::Enum simulatedDevices[nSimulatedDevices] = { - // skip iPhone as it does not support iOS7 - // TODO: clean solution would be to check also sdk version or make it configurable - IosDeviceType::SimulatedIphoneRetina3_5Inch, - IosDeviceType::SimulatedIphoneRetina4Inch, - IosDeviceType::SimulatedIpad, - IosDeviceType::SimulatedIpadRetina -}; - class IosDeployStep; class IosRunConfigurationFactory; class IosRunConfigurationWidget; @@ -76,8 +67,8 @@ public: Utils::FileName localExecutable() const; bool isEnabled() const; QString disabledReason() const; - IosDeviceType::Enum deviceType() const; - void setDeviceType(IosDeviceType::Enum deviceType); + IosDeviceType deviceType() const; + void setDeviceType(const IosDeviceType &deviceType); bool fromMap(const QVariantMap &map) Q_DECL_OVERRIDE; QVariantMap toMap() const Q_DECL_OVERRIDE; @@ -102,7 +93,7 @@ private: bool m_lastIsEnabled; bool m_parseInProgress; bool m_parseSuccess; - IosDeviceType::Enum m_deviceType; + IosDeviceType m_deviceType; }; } // namespace Internal diff --git a/src/plugins/ios/iosrunner.h b/src/plugins/ios/iosrunner.h index 3db5255f7e..a77b512b53 100644 --- a/src/plugins/ios/iosrunner.h +++ b/src/plugins/ios/iosrunner.h @@ -32,7 +32,7 @@ #include "iosconfigurations.h" #include "iostoolhandler.h" -#include "iosconstants.h" +#include "iossimulator.h" #include <projectexplorer/devicesupport/idevice.h> @@ -90,7 +90,7 @@ private: QString m_bundleDir; QStringList m_arguments; ProjectExplorer::IDevice::ConstPtr m_device; - IosDeviceType::Enum m_deviceType; + IosDeviceType m_deviceType; bool m_cppDebug; bool m_qmlDebug; bool m_cleanExit; diff --git a/src/plugins/ios/iossimulator.cpp b/src/plugins/ios/iossimulator.cpp index a428fc2fa5..8beb1b7da1 100644 --- a/src/plugins/ios/iossimulator.cpp +++ b/src/plugins/ios/iossimulator.cpp @@ -30,10 +30,13 @@ #include "iossimulator.h" #include "iosconstants.h" +#include "iostoolhandler.h" #include <projectexplorer/kitinformation.h> #include <QCoreApplication> +#include <QMapIterator> +#include <QMutexLocker> #include <QProcess> using namespace ProjectExplorer; @@ -41,6 +44,13 @@ using namespace ProjectExplorer; namespace Ios { namespace Internal { +static const QLatin1String iosDeviceTypeDisplayNameKey = QLatin1String("displayName"); +static const QLatin1String iosDeviceTypeTypeKey = QLatin1String("type"); +static const QLatin1String iosDeviceTypeIdentifierKey = QLatin1String("identifier"); + +QMutex IosSimulator::_mutex; +QList<IosDeviceType> IosSimulator::_availableDevices; + IosSimulator::IosSimulator(Core::Id id) : IDevice(Core::Id(Constants::IOS_SIMULATOR_TYPE), IDevice::AutoDetected, @@ -113,6 +123,48 @@ IDevice::Ptr IosSimulator::clone() const return IDevice::Ptr(new IosSimulator(*this)); } +QList<IosDeviceType> IosSimulator::availableDevices() +{ + QMutexLocker l(&_mutex); + return _availableDevices; +} + +void IosSimulator::setAvailableDevices(QList<IosDeviceType> value) +{ + QMutexLocker l(&_mutex); + _availableDevices = value; +} + +namespace { +void handleDeviceInfo(Ios::IosToolHandler *handler, const QString &deviceId, + const Ios::IosToolHandler::Dict &info) +{ + Q_UNUSED(deviceId); + QList<IosDeviceType> res; + QMapIterator<QString, QString> i(info); + while (i.hasNext()) { + i.next(); + IosDeviceType simulatorType(IosDeviceType::SimulatedDevice); + simulatorType.displayName = i.value(); + simulatorType.identifier = i.key(); + QStringList ids = i.key().split(QLatin1Char(',')); + if (ids.length() > 1) + simulatorType.displayName += QLatin1String(", iOS ") + ids.last().trimmed(); + res.append(simulatorType); + } + handler->deleteLater(); + std::stable_sort(res.begin(), res.end()); + IosSimulator::setAvailableDevices(res); +} +} + +void IosSimulator::updateAvailableDevices() +{ + IosToolHandler *toolHandler = new IosToolHandler(IosDeviceType(IosDeviceType::SimulatedDevice)); + QObject::connect(toolHandler, &IosToolHandler::deviceInfo, &handleDeviceInfo); + toolHandler->requestDeviceInfo(QString()); +} + void IosSimulator::fromMap(const QVariantMap &map) { IDevice::fromMap(map); @@ -162,5 +214,137 @@ IosSimulator::ConstPtr IosKitInformation::simulator(Kit *kit) return res; } +IosDeviceType::IosDeviceType(IosDeviceType::Type type, const QString &identifier, const QString &displayName) : + type(type), identifier(identifier), displayName(displayName) +{ } + +bool IosDeviceType::fromMap(const QVariantMap &map) +{ + bool validType; + displayName = map.value(iosDeviceTypeDisplayNameKey, QVariant()).toString(); + type = IosDeviceType::Type(map.value(iosDeviceTypeTypeKey, QVariant()).toInt(&validType)); + identifier = map.value(iosDeviceTypeIdentifierKey, QVariant()).toString(); + return validType && !displayName.isEmpty() + && (type != IosDeviceType::SimulatedDevice || !identifier.isEmpty()); +} + +QVariantMap IosDeviceType::toMap() const +{ + QVariantMap res; + res[iosDeviceTypeDisplayNameKey] = displayName; + res[iosDeviceTypeTypeKey] = type; + res[iosDeviceTypeIdentifierKey] = identifier; + return res; +} + +bool IosDeviceType::operator ==(const IosDeviceType &o) const +{ + return o.type == type && o.identifier == identifier && o.displayName == displayName; +} + +// compare strings comparing embedded numbers as numeric values. +// the result is negative if x<y, zero if x==y, positive if x>y +// Prefixed 0 are used to resolve ties, so that this ordering is still a total ordering (equality +// only for identical strings) +// "20" > "3" , "03-4" < "3-10", "3-5" < "03-5" +static int numberCompare(const QString &s1, const QString &s2) +{ + int i1 = 0; + int i2 = 0; + int solveTie = 0; + while (i1 < s1.size() && i2 < s2.size()) { + QChar c1 = s1.at(i1); + QChar c2 = s2.at(i2); + if (c1.isDigit() && c2.isDigit()) { + // we found a number on both sides, find where the number ends + int j1 = i1 + 1; + int j2 = i2 + 1; + while (j1 < s1.size() && s1.at(j1).isDigit()) + ++j1; + while (j2 < s2.size() && s2.at(j2).isDigit()) + ++j2; + // and compare it from the right side, first units, then decimals,.... + int cmp = 0; + int newI1 = j1; + int newI2 = j2; + while (j1 > i1 && j2 > i2) { + --j1; + --j2; + QChar cc1 = s1.at(j1); + QChar cc2 = s2.at(j2); + if (cc1 < cc2) + cmp = -1; + else if (cc1 > cc2) + cmp = 1; + } + int tie = 0; + // if the left number has more digits, if they are all 0, use this info only to break + // ties, otherwise the left number is larger + while (j1-- > i1) { + tie = 1; + if (s1.at(j1) != QLatin1Char('0')) + cmp = 1; + } + // same for the right number + while (j2-- > i2) { + tie = -1; + if (s2.at(j2) != QLatin1Char('0')) + cmp = -1; + } + // if not equal return + if (cmp != 0) + return cmp; + // otherwise possibly store info to break ties (first nomber with more leading zeros is + // larger) + if (solveTie == 0) + solveTie = tie; + // continue comparing after the numbers + i1 = newI1; + i2 = newI2; + } else { + // compare plain characters (non numbers) + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + ++i1; ++i2; + } + } + // if one side has more characters it is the larger one + if (i1 < s1.size()) + return 1; + if (i2 < s2.size()) + return -1; + // if we had differences in prefixed 0, use that choose the largest string, otherwise they are + // equal + return solveTie; +} + +bool IosDeviceType::operator <(const IosDeviceType &o) const +{ + if (type < o.type) + return true; + if (type > o.type) + return false; + int cmp = numberCompare(displayName, o.displayName); + if (cmp < 0) + return true; + if (cmp > 0) + return false; + cmp = numberCompare(identifier, o.identifier); + if (cmp < 0) + return true; + return false; +} + +QDebug operator <<(QDebug debug, const IosDeviceType &deviceType) +{ + if (deviceType.type == IosDeviceType::IosDevice) + debug << "iOS Device " << deviceType.displayName << deviceType.identifier; + else + debug << deviceType.displayName << " (" << deviceType.identifier << ")"; + return debug; +} + } // namespace Internal } // namespace Ios diff --git a/src/plugins/ios/iossimulator.h b/src/plugins/ios/iossimulator.h index 9b92d551a8..dae3f6a5ac 100644 --- a/src/plugins/ios/iossimulator.h +++ b/src/plugins/ios/iossimulator.h @@ -33,6 +33,8 @@ #include <projectexplorer/devicesupport/idevice.h> #include <utils/fileutils.h> +#include <QMutex> +#include <QDebug> #include <QSharedPointer> namespace ProjectExplorer { class Kit; } @@ -41,6 +43,28 @@ namespace Internal { class IosConfigurations; class IosSimulatorFactory; +class IosDeviceType { +public: + enum Type { + IosDevice, + SimulatedDevice + }; + IosDeviceType(Type type = IosDevice, const QString &identifier = QString(), + const QString &displayName = QString()); + + bool fromMap(const QVariantMap &map); + QVariantMap toMap() const; + + bool operator ==(const IosDeviceType &o) const; + bool operator !=(const IosDeviceType &o) const { return !(*this == o); } + bool operator <(const IosDeviceType &o) const; + + Type type; + QString identifier; + QString displayName; +}; +QDebug operator <<(QDebug debug, const IosDeviceType &deviceType); + class IosSimulator : public ProjectExplorer::IDevice { public: @@ -48,6 +72,10 @@ public: typedef QSharedPointer<IosSimulator> Ptr; ProjectExplorer::IDevice::DeviceInfo deviceInformation() const Q_DECL_OVERRIDE; + static QList<IosDeviceType> availableDevices(); + static void setAvailableDevices(QList<IosDeviceType> value); + static void updateAvailableDevices(); + QString displayType() const Q_DECL_OVERRIDE; ProjectExplorer::IDeviceWidget *createWidget() Q_DECL_OVERRIDE; QList<Core::Id> actionIds() const Q_DECL_OVERRIDE; @@ -60,7 +88,6 @@ public: bool canAutoDetectPorts() const Q_DECL_OVERRIDE; ProjectExplorer::IDevice::Ptr clone() const Q_DECL_OVERRIDE; - protected: friend class IosSimulatorFactory; friend class IosConfigurations; @@ -69,6 +96,8 @@ protected: IosSimulator(const IosSimulator &other); private: mutable quint16 m_lastPort; + static QMutex _mutex; + static QList<IosDeviceType> _availableDevices; }; namespace IosKitInformation { @@ -77,4 +106,6 @@ IosSimulator::ConstPtr simulator(ProjectExplorer::Kit *kit); } // namespace Internal } // namespace Ios +Q_DECLARE_METATYPE(Ios::Internal::IosDeviceType) + #endif // IOSSIMULATOR_H diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp index 61617bc5a8..cd640edc99 100644 --- a/src/plugins/ios/iostoolhandler.cpp +++ b/src/plugins/ios/iostoolhandler.cpp @@ -31,6 +31,7 @@ #include "iostoolhandler.h" #include "iosconfigurations.h" #include "iosconstants.h" +#include "iossimulator.h" #include <coreplugin/icore.h> #include <utils/qtcassert.h> @@ -126,7 +127,7 @@ public: OpAppRun }; - explicit IosToolHandlerPrivate(IosDeviceType::Enum devType, IosToolHandler *q); + explicit IosToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q); virtual ~IosToolHandlerPrivate() {} virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId, int timeout = 1000) = 0; @@ -170,7 +171,7 @@ protected: IosToolHandler::RunKind runKind; State state; Op op; - IosDeviceType::Enum devType; + IosDeviceType devType; static const int lookaheadSize = 67; int iBegin, iEnd, gdbSocket; QList<ParserState> stack; @@ -179,7 +180,7 @@ protected: class IosDeviceToolHandlerPrivate : public IosToolHandlerPrivate { public: - explicit IosDeviceToolHandlerPrivate(IosDeviceType::Enum devType, IosToolHandler *q); + explicit IosDeviceToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q); virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId, int timeout = 1000); virtual void requestRunApp(const QString &bundlePath, const QStringList &extraArgs, @@ -192,7 +193,7 @@ public: class IosSimulatorToolHandlerPrivate : public IosToolHandlerPrivate { public: - explicit IosSimulatorToolHandlerPrivate(IosDeviceType::Enum devType, IosToolHandler *q); + explicit IosSimulatorToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q); virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId, int timeout = 1000); virtual void requestRunApp(const QString &bundlePath, const QStringList &extraArgs, @@ -204,7 +205,7 @@ private: void addDeviceArguments(QStringList &args) const; }; -IosToolHandlerPrivate::IosToolHandlerPrivate(IosDeviceType::Enum devType, +IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType, Ios::IosToolHandler *q) : q(q), state(NonStarted), devType(devType), iBegin(0), iEnd(0), gdbSocket(-1) @@ -578,7 +579,7 @@ void IosToolHandlerPrivate::subprocessHasData() // IosDeviceToolHandlerPrivate -IosDeviceToolHandlerPrivate::IosDeviceToolHandlerPrivate(IosDeviceType::Enum devType, +IosDeviceToolHandlerPrivate::IosDeviceToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q) : IosToolHandlerPrivate(devType, q) { } @@ -637,7 +638,7 @@ bool IosDeviceToolHandlerPrivate::expectsFileDescriptor() // IosSimulatorToolHandlerPrivate -IosSimulatorToolHandlerPrivate::IosSimulatorToolHandlerPrivate(IosDeviceType::Enum devType, +IosSimulatorToolHandlerPrivate::IosSimulatorToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q) : IosToolHandlerPrivate(devType, q) { } @@ -684,7 +685,7 @@ void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, Q_UNUSED(timeout); this->deviceId = deviceId; QStringList args; - args << QLatin1String("showsdks"); + args << QLatin1String("showdevicetypes"); op = OpDeviceInfo; start(IosToolHandler::iosSimulatorToolPath(), args); } @@ -696,27 +697,11 @@ bool IosSimulatorToolHandlerPrivate::expectsFileDescriptor() void IosSimulatorToolHandlerPrivate::addDeviceArguments(QStringList &args) const { - switch (devType) { - case IosDeviceType::IosDevice: - qCWarning(toolHandlerLog) << "IosSimulatorToolHandlerPrivate has device type IosDeviceType"; - break; - case IosDeviceType::SimulatedIphone: - args << QLatin1String("--family") << QLatin1String("iphone"); - break; - case IosDeviceType::SimulatedIpad: - args << QLatin1String("--family") << QLatin1String("ipad"); - break; - case IosDeviceType::SimulatedIphoneRetina4Inch: - args << QLatin1String("--family") << QLatin1String("iphone") - << QLatin1String("--retina") << QLatin1String("--tall"); - break; - case IosDeviceType::SimulatedIphoneRetina3_5Inch: - args << QLatin1String("--family") << QLatin1String("iphone") << QLatin1String("--retina"); - break; - case IosDeviceType::SimulatedIpadRetina: - args << QLatin1String("--family") << QLatin1String("ipad") << QLatin1String("--retina"); - break; + if (devType.type != IosDeviceType::SimulatedDevice) { + qCWarning(toolHandlerLog) << "IosSimulatorToolHandlerPrivate device type is not SimulatedDevice"; + return; } + args << QLatin1String("--devicetypeid") << devType.identifier; } void IosToolHandlerPrivate::killProcess() @@ -745,10 +730,10 @@ QString IosToolHandler::iosSimulatorToolPath() return res; } -IosToolHandler::IosToolHandler(IosDeviceType::Enum devType, QObject *parent) : +IosToolHandler::IosToolHandler(const Internal::IosDeviceType &devType, QObject *parent) : QObject(parent) { - if (devType == IosDeviceType::IosDevice) + if (devType.type == Internal::IosDeviceType::IosDevice) d = new Internal::IosDeviceToolHandlerPrivate(devType, this); else d = new Internal::IosSimulatorToolHandlerPrivate(devType, this); diff --git a/src/plugins/ios/iostoolhandler.h b/src/plugins/ios/iostoolhandler.h index 3329488753..59f0cbba1d 100644 --- a/src/plugins/ios/iostoolhandler.h +++ b/src/plugins/ios/iostoolhandler.h @@ -31,8 +31,6 @@ #ifndef IOSTOOLHANDLER_H #define IOSTOOLHANDLER_H -#include "iosconstants.h" - #include <QObject> #include <QMap> #include <QString> @@ -41,7 +39,10 @@ namespace Ios { -namespace Internal { class IosToolHandlerPrivate; } +namespace Internal { +class IosToolHandlerPrivate; +class IosDeviceType; +} class IosToolHandler : public QObject { @@ -61,7 +62,7 @@ public: static QString iosDeviceToolPath(); static QString iosSimulatorToolPath(); - explicit IosToolHandler(IosDeviceType::Enum = IosDeviceType::IosDevice, QObject *parent = 0); + explicit IosToolHandler(const Internal::IosDeviceType &type, QObject *parent = 0); ~IosToolHandler(); void requestTransferApp(const QString &bundlePath, const QString &deviceId, int timeout = 1000); void requestRunApp(const QString &bundlePath, const QStringList &extraArgs, RunKind runType, diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 5525e95db3..5976ed476e 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -1184,7 +1184,15 @@ IEditor *PerforcePlugin::showOutputInEditor(const QString &title, qDebug() << "PerforcePlugin::showOutputInEditor" << title << id.name() << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); QString s = title; - IEditor *editor = EditorManager::openEditorWithContents(id, &s, output.toUtf8()); + QString content = output; + const int maxSize = EditorManager::maxTextFileSize() - 1000; + if (content.size() >= maxSize) { + content = tr("[Only %1 MB of output shown]").arg(maxSize / 1024 / 1024) + QLatin1Char('\n') + + content.right(maxSize); + + } + IEditor *editor = EditorManager::openEditorWithContents(id, &s, content.toUtf8()); + QTC_ASSERT(editor, return 0); connect(editor, SIGNAL(annotateRevisionRequested(QString,QString,QString,int)), this, SLOT(vcsAnnotate(QString,QString,QString,int))); PerforceEditorWidget *e = qobject_cast<PerforceEditorWidget*>(editor->widget()); diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index 544f3ac67c..3135a78134 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -265,7 +265,8 @@ void ModelManager::updateDefaultProjectInfo() { // needs to be performed in the ui therad ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectExplorerPlugin::currentProject(); - ProjectInfo newDefaultProjectInfo = defaultProjectInfoForProject(currentProject); + ProjectInfo newDefaultProjectInfo = projectInfo(currentProject, + defaultProjectInfoForProject(currentProject)); setDefaultProject(projectInfo(currentProject,newDefaultProjectInfo), currentProject); } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 3c39c7d760..4062b9d366 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7211,7 +7211,6 @@ bool TextEditorWidget::isMissingSyntaxDefinition() const // The remnants of PlainTextEditor. void TextEditorWidget::setupAsPlainEditor() { - setRevisionsVisible(true); setMarksVisible(true); setLineSeparatorsAllowed(true); diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp index b29025e008..c3365105d4 100644 --- a/src/plugins/valgrind/memcheckerrorview.cpp +++ b/src/plugins/valgrind/memcheckerrorview.cpp @@ -154,9 +154,13 @@ static QString errorLocation(const QModelIndex &index, const Error &error, link, linkAttr)); } -QWidget *MemcheckErrorDelegate::createDetailsWidget(const QFont & font, const QModelIndex &errorIndex, QWidget *parent) const +QWidget *MemcheckErrorDelegate::createDetailsWidget(const QFont & font, + const QModelIndex &errorIndex, + QWidget *parent) const { QWidget *widget = new QWidget(parent); + QTC_ASSERT(errorIndex.isValid(), return widget); + QVBoxLayout *layout = new QVBoxLayout; // code + white-space:pre so the padding (see below) works properly // don't include frameName here as it should wrap if required and pre-line is not supported diff --git a/src/plugins/valgrind/valgrindconfigwidget.cpp b/src/plugins/valgrind/valgrindconfigwidget.cpp index 137c9022b9..a9e30a9fd3 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.cpp +++ b/src/plugins/valgrind/valgrindconfigwidget.cpp @@ -159,9 +159,12 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings, if (!global) { // In project settings we want a flat vertical list. QVBoxLayout *l = new QVBoxLayout; - while (layout()->count()) - if (QWidget *w = layout()->takeAt(0)->widget()) + while (layout()->count()) { + QLayoutItem *item = layout()->takeAt(0); + if (QWidget *w = item->widget()) l->addWidget(w); + delete item; + } delete layout(); setLayout(l); } diff --git a/src/tools/3rdparty/iossim/iphonesimulator.mm b/src/tools/3rdparty/iossim/iphonesimulator.mm index d573808f10..b120fab64e 100644 --- a/src/tools/3rdparty/iossim/iphonesimulator.mm +++ b/src/tools/3rdparty/iossim/iphonesimulator.mm @@ -284,13 +284,24 @@ NSString* FindDeveloperDir() { - (int) showDeviceTypes { Class simDeviceSet = NSClassFromString(@"SimDeviceSet"); + nsprintf(@"<device_info>"); + bool hasDevices = false; if (simDeviceSet) { SimDeviceSet* deviceSet = [simDeviceSet defaultSet]; NSArray* devices = [deviceSet availableDevices]; for (SimDevice* device in devices) { - nsfprintf(stderr, @"%@, %@", device.deviceType.identifier, device.runtime.versionString); + hasDevices = true; + nsfprintf(stdout, @"<item><key>%@, %@</key><value>%@</value></item>",device.deviceType.identifier, device.runtime.versionString, device.deviceType.name); } } + if (!hasDevices) { + // fallback devices for Xcode 5.x + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-4s</key><value>iPhone 3.5-inch Retina Display</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-5s</key><value>iPhone 4-inch Retina Display</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-2</key><value>iPad</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-Retina</key><value>iPad Retina Display</value></item>"); + } + nsprintf(@"</device_info>"); return EXIT_SUCCESS; } @@ -620,7 +631,21 @@ static void ChildSignal(int /*arg*/) { - (NSString*) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice is64Bit:(BOOL)is64Bit { NSString *devicePropertyValue; - if (retina) { + if (self->deviceTypeId) { + if ([deviceTypeIdIphone4s isEqual: deviceTypeId]) + devicePropertyValue = deviceIphoneRetina3_5Inch; + else if ([deviceTypeIdIphone5s isEqual: deviceTypeId]) + devicePropertyValue = deviceIphoneRetina4_0Inch; + else if ([deviceTypeIdIpad2 isEqual: deviceTypeId]) + devicePropertyValue = deviceIpad; + else if ([deviceTypeIdIpadRetina isEqual: deviceTypeId]) + devicePropertyValue = deviceIpadRetina; + else { + nsprintf(@"<msg>Unknown or unsupported device type: %@</msg>\n", deviceTypeId); + [self doExit:EXIT_FAILURE]; + return nil; + } + } else if (retina) { if (verbose) { msgprintf(@"using retina"); } @@ -690,8 +715,8 @@ static void ChildSignal(int /*arg*/) { } NSString* developerDir = FindDeveloperDir(); if (!developerDir) { - nsprintf(@"Unable to find developer directory."); - exit(EXIT_FAILURE); + nsprintf(@"<msg>Unable to find developer directory.</msg>"); + [self doExit:EXIT_FAILURE]; } NSString *xcodePlistPath = [developerDir stringByAppendingPathComponent:@"../Info.plist"]; NSAssert([[NSFileManager defaultManager] fileExistsAtPath:xcodePlistPath isDirectory:NULL], @@ -717,15 +742,15 @@ static void ChildSignal(int /*arg*/) { } if (strcmp(argv[1], "showsdks") == 0) { [self LoadSimulatorFramework:developerDir]; - exit([self showSDKs]); + [self doExit:[self showSDKs]]; } else if (strcmp(argv[1], "showdevicetypes") == 0) { [self LoadSimulatorFramework:developerDir]; - exit([self showDeviceTypes]); + [self doExit:[self showDeviceTypes]]; } else if (strcmp(argv[1], "launch") == 0 || startOnly) { if (strcmp(argv[1], "launch") == 0 && argc < 3) { msgprintf(@"Missing application path argument"); [self printUsage]; - exit(EXIT_FAILURE); + [self doExit:EXIT_FAILURE]; } NSString *appPath = nil; @@ -767,6 +792,11 @@ static void ChildSignal(int /*arg*/) { useGDB = YES; } else if (strcmp(argv[i], "--developer-path") == 0) { ++i; + if (i == argc) { + nsprintf(@"<msg>missing arg after --developer-path</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } } else if (strcmp(argv[i], "--timeout") == 0) { if (i + 1 < argc) { timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue]; @@ -776,7 +806,12 @@ static void ChildSignal(int /*arg*/) { else if (strcmp(argv[i], "--sdk") == 0) { [self printDeprecation:argv[i]]; i++; - [self LoadSimulatorFramework:developerDir]; + if (i == argc) { + nsprintf(@"<msg>missing arg after --sdk</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } + [self LoadSimulatorFramework:developerDir]; NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]; Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"]; NSArray *roots = [systemRootClass knownRoots]; @@ -795,19 +830,44 @@ static void ChildSignal(int /*arg*/) { } else if (strcmp(argv[i], "--family") == 0) { [self printDeprecation:argv[i]]; i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --sdkfamilymsg>"); + [self doExit:EXIT_FAILURE]; + return; + } family = [NSString stringWithUTF8String:argv[i]]; } else if (strcmp(argv[i], "--uuid") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --uuid</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } uuid = [NSString stringWithUTF8String:argv[i]]; } else if (strcmp(argv[i], "--devicetypeid") == 0) { - i++; - deviceTypeId = [NSString stringWithUTF8String:argv[i]]; + i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --devicetypeid</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } + deviceTypeId = [NSString stringWithUTF8String:argv[i]]; } else if (strcmp(argv[i], "--setenv") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --setenv</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="]; [environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]]; } else if (strcmp(argv[i], "--env") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --env</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath]; [environment setValuesForKeysWithDictionary:[NSDictionary dictionaryWithContentsOfFile:envFilePath]]; if (!environment) { @@ -817,14 +877,29 @@ static void ChildSignal(int /*arg*/) { } } else if (strcmp(argv[i], "--stdout") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --stdout</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; NSLog(@"stdoutPath: %@", stdoutPath); } else if (strcmp(argv[i], "--stderr") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --stderr</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; NSLog(@"stderrPath: %@", stderrPath); } else if (strcmp(argv[i], "--xctest") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --xctest</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } xctest = [[NSString stringWithUTF8String:argv[i]] expandPath]; NSLog(@"xctest: %@", xctest); } else if (strcmp(argv[i], "--retina") == 0) { diff --git a/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm b/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm index a7ab822cdd..737a694786 100644 --- a/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm +++ b/src/tools/3rdparty/iossim_1_8_2/iphonesimulator.mm @@ -400,7 +400,16 @@ NSString *deviceIpadRetina = @"iPad (Retina)"; startOnly = strcmp(argv[1], "start") == 0; nsprintf(@"<query_result>"); - if (strcmp(argv[1], "showsdks") == 0) { + if (strcmp(argv[1], "showdevicetypes") == 0) { + nsprintf(@"<deviceinfo>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-4s</key><value>iPhone 3.5-inch Retina Display</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPhone-5s</key><value>iPhone 4-inch Retina Display</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-2</key><value>iPad</value></item>"); + nsprintf(@"<item><key>com.apple.CoreSimulator.SimDeviceType.iPad-Retina</key><value>iPad Retina Display</value></item>"); + nsprintf(@"</deviceinfo>"); + [self doExit:0]; + return; + } else if (strcmp(argv[1], "showsdks") == 0) { [self doExit:[self showSDKs]]; return; } else if (strcmp(argv[1], "launch") == 0 || startOnly) { @@ -449,14 +458,24 @@ NSString *deviceIpadRetina = @"iPad (Retina)"; useGDB = YES; } else if (strcmp(argv[i], "--developer-path") == 0) { ++i; + if (i == argc) { + nsprintf(@"<msg>missing arg after --developer-path</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } } else if (strcmp(argv[i], "--timeout") == 0) { if (i + 1 < argc) { timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue]; - NSLog(@"<msg>Timeout: %f second(s)</msg>", timeout); + nsprintf(@"<msg>Timeout: %f second(s)</msg>", timeout); } } else if (strcmp(argv[i], "--sdk") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --sdk</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]; id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot"); NSArray *roots; @@ -480,16 +499,55 @@ NSString *deviceIpadRetina = @"iPad (Retina)"; } } else if (strcmp(argv[i], "--family") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --family</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } family = [NSString stringWithUTF8String:argv[i]]; } else if (strcmp(argv[i], "--uuid") == 0) { i++; uuid = [NSString stringWithUTF8String:argv[i]]; + } else if (strcmp(argv[i], "--devicetypeid") == 0) { + i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --devicetypeid</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } + if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPhone-4s") == 0) { + family = [NSString stringWithUTF8String:"iphone"]; + retinaDevice = YES; + } else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPad-2") == 0) { + family = [NSString stringWithUTF8String:"ipad"]; + } else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPhone-5s") == 0) { + family = [NSString stringWithUTF8String:"iphone"]; + retinaDevice = YES; + tallDevice = YES; + } else if (strcmp(argv[i], "com.apple.CoreSimulator.SimDeviceType.iPad-Retina") == 0) { + family = [NSString stringWithUTF8String:"ipad"]; + retinaDevice = YES; + } else { + fprintf(stdout,"<msg>Unknown or unsupported device type: %s</msg>\n",argv[i]); + [self doExit:EXIT_FAILURE]; + return; + } } else if (strcmp(argv[i], "--setenv") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --setenv</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="]; [environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]]; } else if (strcmp(argv[i], "--env") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --env</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath]; environment = [NSMutableDictionary dictionaryWithContentsOfFile:envFilePath]; if (!environment) { @@ -499,12 +557,22 @@ NSString *deviceIpadRetina = @"iPad (Retina)"; } } else if (strcmp(argv[i], "--stdout") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --stdout</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; - NSLog(@"stdoutPath: %@", stdoutPath); + nsprintf(@"<msg>stdoutPath: %@</msg>", stdoutPath); } else if (strcmp(argv[i], "--stderr") == 0) { i++; + if (i == argc) { + nsprintf(@"<msg>missing arg after --stderr</msg>"); + [self doExit:EXIT_FAILURE]; + return; + } stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; - NSLog(@"stderrPath: %@", stderrPath); + nsprintf(@"<msg>stderrPath: %@</msg>", stderrPath); } else if (strcmp(argv[i], "--retina") == 0) { retinaDevice = YES; } else if (strcmp(argv[i], "--tall") == 0) { diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 2e405e6c09..c7b2ca7773 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -4274,11 +4274,11 @@ void tst_Dumpers::dumper_data() // Known issue: Clang produces "std::vector<std::allocator<bool>> + Check("b0", "<0 items>", "std::vector<bool>") % GdbEngine + Check("b0", "<0 items>", "std::vector<bool>") % ClangVersion(600) - + Check("b0", "<0 items>", "std::vector<std::allocator<bool>>") % ClangVersion(0, 599) + + Check("b0", "<0 items>", "std::vector<std::allocator<bool>>") % ClangVersion(1, 599) + Check("b1", "<5 items>", "std::vector<bool>") % GdbEngine + Check("b1", "<5 items>", "std::vector<bool>") % ClangVersion(600) - + Check("b1", "<5 items>", "std::vector<std::allocator<bool>>") % ClangVersion(0, 599) + + Check("b1", "<5 items>", "std::vector<std::allocator<bool>>") % ClangVersion(1, 599) + Check("b1.0", "[0]", "1", "bool") + Check("b1.1", "[1]", "0", "bool") + Check("b1.2", "[2]", "0", "bool") @@ -4287,13 +4287,13 @@ void tst_Dumpers::dumper_data() + Check("b2", "<65 items>", "std::vector<bool>") % GdbEngine + Check("b2", "<65 items>", "std::vector<bool>") % ClangVersion(600) - + Check("b2", "<65 items>", "std::vector<std::allocator<bool>>") % ClangVersion(0, 599) + + Check("b2", "<65 items>", "std::vector<std::allocator<bool>>") % ClangVersion(1, 599) + Check("b2.0", "[0]", "1", "bool") + Check("b2.64", "[64]", "1", "bool") + Check("b3", "<300 items>", "std::vector<bool>") % GdbEngine + Check("b3", "<300 items>", "std::vector<bool>") % ClangVersion(600) - + Check("b3", "<300 items>", "std::vector<std::allocator<bool>>") % ClangVersion(0, 599) + + Check("b3", "<300 items>", "std::vector<std::allocator<bool>>") % ClangVersion(1, 599) + Check("b3.0", "[0]", "0", "bool") + Check("b3.299", "[299]", "0", "bool"); |