forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.6'
Change-Id: I68512c775ed25b51c8b0abe1818c9c7c5955874c
This commit is contained in:
104
dist/changes-3.5.0.md
vendored
104
dist/changes-3.5.0.md
vendored
@@ -193,55 +193,55 @@ BareMetal
|
|||||||
|
|
||||||
* Fixed processing of additional OpenOCD arguments
|
* Fixed processing of additional OpenOCD arguments
|
||||||
|
|
||||||
Credits for these changes go to:
|
Credits for these changes go to:
|
||||||
Alessandro Portale
|
Alessandro Portale
|
||||||
André Pönitz
|
André Pönitz
|
||||||
Alexander Drozdov
|
Alexander Drozdov
|
||||||
Alexander Izmailov
|
Alexander Izmailov
|
||||||
Arnold Dumas
|
Arnold Dumas
|
||||||
Benjamin Zeller
|
Benjamin Zeller
|
||||||
BogDan Vatra
|
BogDan Vatra
|
||||||
Christian Kandeler
|
Christian Kandeler
|
||||||
Christian Stenger
|
Christian Stenger
|
||||||
Cristian Adam
|
Cristian Adam
|
||||||
Daniel Teske
|
Daniel Teske
|
||||||
David Schulz
|
David Schulz
|
||||||
Denis Kormalev
|
Denis Kormalev
|
||||||
Eike Ziller
|
Eike Ziller
|
||||||
Erik Verbruggen
|
Erik Verbruggen
|
||||||
Finn Brudal
|
Finn Brudal
|
||||||
Friedemann Kleint
|
Friedemann Kleint
|
||||||
Hugues Delorme
|
Hugues Delorme
|
||||||
Jack Andersen
|
Jack Andersen
|
||||||
Jarek Kobus
|
Jarek Kobus
|
||||||
Jochen Becher
|
Jochen Becher
|
||||||
Jörg Bornemann
|
Jörg Bornemann
|
||||||
Johannes Lorenz
|
Johannes Lorenz
|
||||||
Kai Köhne
|
Kai Köhne
|
||||||
Knut Petter Svendsen
|
Knut Petter Svendsen
|
||||||
Kudryavtsev Alexander
|
Kudryavtsev Alexander
|
||||||
Leena Miettinen
|
Leena Miettinen
|
||||||
Libor Tomsik
|
Libor Tomsik
|
||||||
Lorenz Haas
|
Lorenz Haas
|
||||||
Lukas Holecek
|
Lukas Holecek
|
||||||
Marcel Krems
|
Marcel Krems
|
||||||
Marco Benelli
|
Marco Benelli
|
||||||
Marco Bubke
|
Marco Bubke
|
||||||
Montel Laurent
|
Montel Laurent
|
||||||
Nikita Baryshnikov
|
Nikita Baryshnikov
|
||||||
Nikita Kniazev
|
Nikita Kniazev
|
||||||
Nikolai Kosjar
|
Nikolai Kosjar
|
||||||
Olivier Goffart
|
Olivier Goffart
|
||||||
Orgad Shaneh
|
Orgad Shaneh
|
||||||
Ray Donnelly
|
Ray Donnelly
|
||||||
Robert Löhning
|
Robert Löhning
|
||||||
Stanislav Ionascu
|
Stanislav Ionascu
|
||||||
Sune Vuorela
|
Sune Vuorela
|
||||||
Takumi ASAKI
|
Takumi ASAKI
|
||||||
Tasuku Suzuki
|
Tasuku Suzuki
|
||||||
Thiago Macieira
|
Thiago Macieira
|
||||||
Thomas Hartmann
|
Thomas Hartmann
|
||||||
Thorben Kroeger
|
Thorben Kroeger
|
||||||
Tim Jenssen
|
Tim Jenssen
|
||||||
Tobias Hunger
|
Tobias Hunger
|
||||||
Ulf Hermann
|
Ulf Hermann
|
||||||
|
45
dist/changes-3.6.0.md
vendored
45
dist/changes-3.6.0.md
vendored
@@ -51,7 +51,7 @@ C++ Support
|
|||||||
|
|
||||||
* Added support for `noexcept`
|
* Added support for `noexcept`
|
||||||
* Clang code model
|
* Clang code model
|
||||||
* Added diagnostic messages to editors
|
* Added more diagnostic messages to editors
|
||||||
* Added Clang's Fix-its to refactoring actions (QTCREATORBUG-14868)
|
* Added Clang's Fix-its to refactoring actions (QTCREATORBUG-14868)
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
@@ -125,3 +125,46 @@ Remote Linux
|
|||||||
ECDSA user keys, and ECDSA key creation
|
ECDSA user keys, and ECDSA key creation
|
||||||
* Fixed environment and working directory for Valgrind analyzer
|
* Fixed environment and working directory for Valgrind analyzer
|
||||||
|
|
||||||
|
Credits for these changes go to:
|
||||||
|
Aleix Pol
|
||||||
|
Alessandro Portale
|
||||||
|
Alexander Drozdov
|
||||||
|
Andre Hartmann
|
||||||
|
André Pönitz
|
||||||
|
Benjamin Zeller
|
||||||
|
BogDan Vatra
|
||||||
|
Christian Kandeler
|
||||||
|
Christian Stenger
|
||||||
|
Christian Strømme
|
||||||
|
Claus Steuer
|
||||||
|
Cristian Adam
|
||||||
|
Daniel Teske
|
||||||
|
David Schulz
|
||||||
|
Eike Ziller
|
||||||
|
Jake Petroules
|
||||||
|
Jakub Golebiewski
|
||||||
|
Jan Dalheimer
|
||||||
|
Jarek Kobus
|
||||||
|
Jean Gressmann
|
||||||
|
Jochen Becher
|
||||||
|
Leena Miettinen
|
||||||
|
Lorenz Haas
|
||||||
|
Marco Bubke
|
||||||
|
Maurice Kalinowski
|
||||||
|
Mitch Curtis
|
||||||
|
Montel Laurent
|
||||||
|
Niels Weber
|
||||||
|
Nikita Baryshnikov
|
||||||
|
Nikolai Kosjar
|
||||||
|
Oliver Wolff
|
||||||
|
Orgad Shaneh
|
||||||
|
Oswald Buddenhagen
|
||||||
|
Robert Loehning
|
||||||
|
Sze Howe Koh
|
||||||
|
Thiago Macieira
|
||||||
|
Thomas Hartmann
|
||||||
|
Thorbjørn Lindeijer
|
||||||
|
Tim Jenssen
|
||||||
|
Tobias Hunger
|
||||||
|
Ulf Hermann
|
||||||
|
Vladyslav Gapchych
|
||||||
|
@@ -23,6 +23,7 @@ indexes += $QDOC_INDEX_DIR/qtwidgets/qtwidgets.index \
|
|||||||
$QDOC_INDEX_DIR/qtgui/qtgui.index \
|
$QDOC_INDEX_DIR/qtgui/qtgui.index \
|
||||||
$QDOC_INDEX_DIR/qthelp/qthelp.index \
|
$QDOC_INDEX_DIR/qthelp/qthelp.index \
|
||||||
$QDOC_INDEX_DIR/qtquickcontrols/qtquickcontrols.index \
|
$QDOC_INDEX_DIR/qtquickcontrols/qtquickcontrols.index \
|
||||||
|
$QDOC_INDEX_DIR/qtquickextras/qtquickextras.index \
|
||||||
$QDOC_INDEX_DIR/qtquicklayouts/qtquicklayouts.index \
|
$QDOC_INDEX_DIR/qtquicklayouts/qtquicklayouts.index \
|
||||||
$QDOC_INDEX_DIR/qtlinguist/qtlinguist.index \
|
$QDOC_INDEX_DIR/qtlinguist/qtlinguist.index \
|
||||||
$QDOC_INDEX_DIR/qtscript/qtscript.index \
|
$QDOC_INDEX_DIR/qtscript/qtscript.index \
|
||||||
|
BIN
doc/images/qtcreator-iso-icon-browser.png
Normal file
BIN
doc/images/qtcreator-iso-icon-browser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
@@ -1699,6 +1699,13 @@
|
|||||||
You can also press \key {Alt+Enter} to open a context menu that contains
|
You can also press \key {Alt+Enter} to open a context menu that contains
|
||||||
refactoring actions available in the current cursor position.
|
refactoring actions available in the current cursor position.
|
||||||
|
|
||||||
|
If you use the \l{Parsing C++ Files}{Clang code model} to parse the C++
|
||||||
|
files, the \l{http://clang.llvm.org/diagnostics.html}{Clang fix-it hints}
|
||||||
|
that have been integrated into \QC are also available to you. In addition to
|
||||||
|
the standard ways of activating refactoring actions, you can select the
|
||||||
|
actions that are applicable on a line in the context menu in the left margin
|
||||||
|
of the code editor.
|
||||||
|
|
||||||
\section2 Refactoring C++ Code
|
\section2 Refactoring C++ Code
|
||||||
|
|
||||||
You can apply the following types of refactoring actions to C++ code:
|
You can apply the following types of refactoring actions to C++ code:
|
||||||
@@ -2312,6 +2319,8 @@
|
|||||||
\li QObject::connect() (Qt 4 style)
|
\li QObject::connect() (Qt 4 style)
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\section2 Refactoring QML Code
|
\section2 Refactoring QML Code
|
||||||
|
|
||||||
You can apply the following types of refactoring actions to QML code:
|
You can apply the following types of refactoring actions to QML code:
|
||||||
|
@@ -185,6 +185,7 @@
|
|||||||
\li \l {Creating Buttons}
|
\li \l {Creating Buttons}
|
||||||
\li \l {Creating Scalable Buttons and Borders}
|
\li \l {Creating Scalable Buttons and Borders}
|
||||||
\li \l {Creating Screens}
|
\li \l {Creating Screens}
|
||||||
|
\li \l {Browsing ISO 7000 Icons}
|
||||||
\li \l {Exporting Designs from Graphics Software}
|
\li \l {Exporting Designs from Graphics Software}
|
||||||
\li \l {Using QML Modules with Plugins}
|
\li \l {Using QML Modules with Plugins}
|
||||||
\endlist
|
\endlist
|
||||||
|
@@ -69,6 +69,11 @@
|
|||||||
Dialogs, and Layouts (available since Qt 5.1) to create screens. You
|
Dialogs, and Layouts (available since Qt 5.1) to create screens. You
|
||||||
can use states and transitions to navigate between screens.
|
can use states and transitions to navigate between screens.
|
||||||
|
|
||||||
|
\li \l {Browsing ISO 7000 Icons}
|
||||||
|
|
||||||
|
You can add ISO 7000 icons from a library delivered with \QC to Qt
|
||||||
|
Quick applications and change their color (commercial only).
|
||||||
|
|
||||||
\li \l {Exporting Designs from Graphics Software}
|
\li \l {Exporting Designs from Graphics Software}
|
||||||
|
|
||||||
You can export designs from graphics software, such as Adobe
|
You can export designs from graphics software, such as Adobe
|
||||||
|
@@ -77,6 +77,9 @@
|
|||||||
creating classic desktop-style user interfaces using Qt Quick 2.1. You can
|
creating classic desktop-style user interfaces using Qt Quick 2.1. You can
|
||||||
use the Qt Quick Controls Styles to customize Qt Quick Controls.
|
use the Qt Quick Controls Styles to customize Qt Quick Controls.
|
||||||
|
|
||||||
|
Some ready-made controls, such as a gauge, dial, status indicator, and
|
||||||
|
tumbler, are provided by the \l {Qt Quick Extras} module.
|
||||||
|
|
||||||
The \QC project wizards create Qt Quick applications that use Qt Quick
|
The \QC project wizards create Qt Quick applications that use Qt Quick
|
||||||
Components or Controls.
|
Components or Controls.
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
/*!
|
/*!
|
||||||
|
|
||||||
\contentspage {Qt Creator Manual}
|
\contentspage {Qt Creator Manual}
|
||||||
\previouspage qmldesigner-connections.html
|
\previouspage qtquick-iso-icon-browser.html
|
||||||
\page quick-export-to-qml.html
|
\page quick-export-to-qml.html
|
||||||
\nextpage creator-qml-modules-with-plugins.html
|
\nextpage creator-qml-modules-with-plugins.html
|
||||||
|
|
||||||
|
82
doc/src/qtquick/qtquick-iso-icon-browser.qdoc
Normal file
82
doc/src/qtquick/qtquick-iso-icon-browser.qdoc
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Contact: http://www.qt.io/licensing
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms and
|
||||||
|
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||||
|
** use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||||
|
** rights. These rights are described in The Qt Company LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\contentspage {Qt Creator Manual}
|
||||||
|
\previouspage quick-screens.html
|
||||||
|
\page qtquick-iso-icon-browser.html
|
||||||
|
\nextpage quick-export-to-qml.html
|
||||||
|
|
||||||
|
\title Browsing ISO 7000 Icons
|
||||||
|
|
||||||
|
\commercial
|
||||||
|
|
||||||
|
You can add icons from an ISO 7000 icon library that is installed with \QC
|
||||||
|
to Qt Quick applications (commercial only). You can use the
|
||||||
|
\uicontrol {ISO Icon Browser} to add a \l {Picture} type and select the
|
||||||
|
icon to use for the type. You can change the default color of the icon.
|
||||||
|
|
||||||
|
\image qtcreator-iso-icon-browser.png
|
||||||
|
|
||||||
|
\section1 Using ISO Icons in Applications
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
|
||||||
|
\li Create a new Qt Quick Application or open an application in \QC.
|
||||||
|
|
||||||
|
\li Open the Qt Quick UI form in the \uicontrol Design mode.
|
||||||
|
|
||||||
|
\li In the \uicontrol Library, select \uicontrol Imports >
|
||||||
|
\uicontrol {Add Import} > \uicontrol {QtQuick.Extras} to import the
|
||||||
|
\l {Qt Quick Extras} module.
|
||||||
|
|
||||||
|
\li Drag and drop a \uicontrol Picture element from the library to the
|
||||||
|
canvas.
|
||||||
|
|
||||||
|
\li Right-click the picture element and select \uicontrol {Choose Icon}
|
||||||
|
to open the \uicontrol {ISO Icon Browser}.
|
||||||
|
|
||||||
|
\li To find icons, select a criterion for filtering icons and enter a
|
||||||
|
search string.
|
||||||
|
|
||||||
|
\li Select an icon in the list, and then select \uicontrol OK to add
|
||||||
|
the icon.
|
||||||
|
|
||||||
|
\li To view the icon you added, press \key {Ctrl+R} (or \key {Cmd+R})
|
||||||
|
to run the application.
|
||||||
|
|
||||||
|
\li To adjust the icon color, select the icon on the canvas, and then
|
||||||
|
select \uicontrol {Edit Color} in the context menu.
|
||||||
|
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\QC generates a Qt resource file called \c iso-icons.qrc that adds the
|
||||||
|
icons as a part of your project for delivery with your application.
|
||||||
|
|
||||||
|
*/
|
@@ -27,7 +27,7 @@
|
|||||||
\contentspage {Qt Creator Manual}
|
\contentspage {Qt Creator Manual}
|
||||||
\previouspage quick-scalable-image.html
|
\previouspage quick-scalable-image.html
|
||||||
\page quick-screens.html
|
\page quick-screens.html
|
||||||
\nextpage creator-qtquick-designer-extensions.html
|
\nextpage qtquick-iso-icon-browser.html
|
||||||
|
|
||||||
\title Creating Screens
|
\title Creating Screens
|
||||||
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
|
!isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included")
|
||||||
QTCREATOR_PRI_INCLUDED = 1
|
QTCREATOR_PRI_INCLUDED = 1
|
||||||
|
|
||||||
QTCREATOR_VERSION = 3.5.81
|
QTCREATOR_VERSION = 3.5.82
|
||||||
QTCREATOR_COMPAT_VERSION = 3.5.81
|
QTCREATOR_COMPAT_VERSION = 3.5.82
|
||||||
BINARY_ARTIFACTS_BRANCH = master
|
BINARY_ARTIFACTS_BRANCH = 3.6
|
||||||
|
|
||||||
# enable c++11
|
# enable c++11
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
@@ -6,11 +6,11 @@ Project {
|
|||||||
property bool withAutotests: qbs.buildVariant === "debug"
|
property bool withAutotests: qbs.buildVariant === "debug"
|
||||||
property string ide_version_major: '3'
|
property string ide_version_major: '3'
|
||||||
property string ide_version_minor: '5'
|
property string ide_version_minor: '5'
|
||||||
property string ide_version_release: '81'
|
property string ide_version_release: '82'
|
||||||
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release
|
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release
|
||||||
property string ide_compat_version_major: '3'
|
property string ide_compat_version_major: '3'
|
||||||
property string ide_compat_version_minor: '5'
|
property string ide_compat_version_minor: '5'
|
||||||
property string ide_compat_version_release: '81'
|
property string ide_compat_version_release: '82'
|
||||||
property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release
|
property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release
|
||||||
property path ide_source_tree: path
|
property path ide_source_tree: path
|
||||||
property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin"
|
property string ide_app_path: qbs.targetOS.contains("osx") ? "" : "bin"
|
||||||
|
@@ -1269,7 +1269,7 @@ def _qdump__QObject(d, value):
|
|||||||
d.putField("keyencoded", Hex2EncodedLatin1)
|
d.putField("keyencoded", Hex2EncodedLatin1)
|
||||||
qq = q.cast(valuesType.pointer().pointer())
|
qq = q.cast(valuesType.pointer().pointer())
|
||||||
qq = qq.dereference();
|
qq = qq.dereference();
|
||||||
d.putField("addr", d.cleanAddress(qq))
|
d.putField("address", d.cleanAddress(qq))
|
||||||
d.putField("exp", "*(%s*)%s"
|
d.putField("exp", "*(%s*)%s"
|
||||||
% (variant, d.cleanAddress(qq)))
|
% (variant, d.cleanAddress(qq)))
|
||||||
t = qdump__QVariant(d, qq)
|
t = qdump__QVariant(d, qq)
|
||||||
|
@@ -98,12 +98,12 @@
|
|||||||
"openAsProject": true
|
"openAsProject": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "../../qmake/qtquickapplication/main.qml",
|
"source": "../../qmake/qtquickapplication/main.qml.tpl",
|
||||||
"target": "%{ProjectDirectory}/%{MainQmlFileName}",
|
"target": "%{ProjectDirectory}/%{MainQmlFileName}",
|
||||||
"openInEditor": true
|
"openInEditor": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "../../qmake/qtquickapplication/MainForm.ui.qml",
|
"source": "../../qmake/qtquickapplication/MainForm.ui.qml.tpl",
|
||||||
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
||||||
"condition": "%{IsUiFileInUse}"
|
"condition": "%{IsUiFileInUse}"
|
||||||
},
|
},
|
||||||
|
@@ -106,12 +106,12 @@
|
|||||||
"openAsProject": true
|
"openAsProject": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "../../qmake/qtquickcontrolsapplication/main.qml",
|
"source": "../../qmake/qtquickcontrolsapplication/main.qml.tpl",
|
||||||
"target": "%{ProjectDirectory}/%{MainQmlFileName}",
|
"target": "%{ProjectDirectory}/%{MainQmlFileName}",
|
||||||
"openInEditor": true
|
"openInEditor": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "../../qmake/qtquickcontrolsapplication/MainForm.ui.qml",
|
"source": "../../qmake/qtquickcontrolsapplication/MainForm.ui.qml.tpl",
|
||||||
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
||||||
"condition": "%{IsUiFileInUse}"
|
"condition": "%{IsUiFileInUse}"
|
||||||
},
|
},
|
||||||
|
@@ -13,8 +13,9 @@ defineReplace(findToTranslate) {
|
|||||||
SUBKEY = $${ROOTKEY}.$${KEY}
|
SUBKEY = $${ROOTKEY}.$${KEY}
|
||||||
MATCHED = $$find(KEY, ^tr[A-Z])
|
MATCHED = $$find(KEY, ^tr[A-Z])
|
||||||
!isEmpty(MATCHED) {
|
!isEmpty(MATCHED) {
|
||||||
VALUE = $$eval($${SUBKEY})
|
VALUE = $$replace($${SUBKEY}, "\\n", "\\n")
|
||||||
OUTPUT += "QCoreApplication(\"ProjectExplorer::JsonWizard\", \"$${VALUE}\");"
|
VALUE ~= s,\",\\\",
|
||||||
|
OUTPUT += "QT_TRANSLATE_NOOP(\"ProjectExplorer::JsonWizard\", \"$${VALUE}\");"
|
||||||
}
|
}
|
||||||
OUTPUT += $$findToTranslate($${SUBKEY})
|
OUTPUT += $$findToTranslate($${SUBKEY})
|
||||||
}
|
}
|
||||||
@@ -22,8 +23,7 @@ defineReplace(findToTranslate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WIZ_TRANS_FILE_CONT= \
|
WIZ_TRANS_FILE_CONT= \
|
||||||
"// This file is autogenerated by qmake." \
|
"// This file is autogenerated by qmake."
|
||||||
"$${LITERAL_HASH}include <QCoreApplication>"
|
|
||||||
|
|
||||||
for (FILE, JSONWIZARD_FILES) {
|
for (FILE, JSONWIZARD_FILES) {
|
||||||
exists($$FILE) {
|
exists($$FILE) {
|
||||||
|
@@ -79,7 +79,7 @@ for(file, files) {
|
|||||||
$$v = extract
|
$$v = extract
|
||||||
QMAKE_EXTRA_TARGETS += ts-$$lang
|
QMAKE_EXTRA_TARGETS += ts-$$lang
|
||||||
}
|
}
|
||||||
ts-all.commands = cd $$wd && $$LUPDATE $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H -ts $$files
|
ts-all.commands = cd $$wd && $$LUPDATE $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H -ts $$files
|
||||||
ts-all.depends = extract
|
ts-all.depends = extract
|
||||||
QMAKE_EXTRA_TARGETS += ts-all
|
QMAKE_EXTRA_TARGETS += ts-all
|
||||||
|
|
||||||
|
@@ -13,11 +13,11 @@
|
|||||||
<description><![CDATA[Developing Qt applications using C++ and the Qt Widgets module.]]></description>
|
<description><![CDATA[Developing Qt applications using C++ and the Qt Widgets module.]]></description>
|
||||||
<tags>qt,qt creator,qt designer,widgets,c++</tags>
|
<tags>qt,qt creator,qt designer,widgets,c++</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/qtquick.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-qml-application.html" projectPath="" name="Creating a Qt Quick Application">
|
<tutorial imageUrl="images/icons/qtquick.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-transitions-example.html" projectPath="" name="Creating a Qt Quick Application">
|
||||||
<description><![CDATA[Using basic QML elements and learning about basic concepts of Qt Quick.]]></description>
|
<description><![CDATA[Using basic QML elements and learning about basic concepts of Qt Quick.]]></description>
|
||||||
<tags>qt creator,qt quick designer,qt quick,qml,states,transitions</tags>
|
<tags>qt creator,qt quick designer,qt quick,qml,states,transitions</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/androidapp.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-mobile-app-tutorial.html" projectPath="" name="Creating a Mobile Application">
|
<tutorial imageUrl="images/icons/androidapp.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-accelbubble-example.html" projectPath="" name="Creating a Mobile Application">
|
||||||
<description><![CDATA[Developing Qt Quick applications for Android and iOS devices using Qt Quick Controls.]]></description>
|
<description><![CDATA[Developing Qt Quick applications for Android and iOS devices using Qt Quick Controls.]]></description>
|
||||||
<tags>qt creator,qt quick designer,qml,android</tags>
|
<tags>qt creator,qt quick designer,qml,android</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
@@ -25,10 +25,14 @@
|
|||||||
<description><![CDATA[Developing Qt Quick applications using QML and C++.]]></description>
|
<description><![CDATA[Developing Qt Quick applications using QML and C++.]]></description>
|
||||||
<tags>qt quick,qml,c++</tags>
|
<tags>qt quick,qml,c++</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Introduction to Qt Creator" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TEpJLwzdQGs" videoLength="56:22">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Introduction to Qt Creator" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nGFmjOiT22Y" videoLength="50:36">
|
||||||
<description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description>
|
<description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description>
|
||||||
<tags>qt creator</tags>
|
<tags>qt creator</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Custom Qt Creator Wizards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3DuCgFamo" videoLength="27:21">
|
||||||
|
<description><![CDATA[Adding custom file and project creation wizards to Qt Creator.]]></description>
|
||||||
|
<tags>qt creator,wizard</tags>
|
||||||
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Extending Qt Creator Without Writing Code" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49">
|
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Extending Qt Creator Without Writing Code" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49">
|
||||||
<description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description>
|
<description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description>
|
||||||
<tags>qt creator,configuration</tags>
|
<tags>qt creator,configuration</tags>
|
||||||
@@ -37,89 +41,85 @@
|
|||||||
<description><![CDATA[Adding plugins to Qt Creator.]]></description>
|
<description><![CDATA[Adding plugins to Qt Creator.]]></description>
|
||||||
<tags>qt creator,plugins</tags>
|
<tags>qt creator,plugins</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Using the QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12">
|
||||||
|
<description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description>
|
||||||
|
<tags>qt quick,qt creator,qml profiler</tags>
|
||||||
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="CPU Usage Analyzer for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=G0AbgVHGdXI" videoLength="22:30">
|
||||||
|
<description><![CDATA[Using the Linux perf tool to generate data for code analysis.]]></description>
|
||||||
|
<tags>qt creator,cpu usage analyzer,perf</tags>
|
||||||
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Targeting Multiple Mobile Platforms with Qt Creator" isVideo="true" videoUrl="http://www.youtube.com/watch?v=jDRup5z2qz0" videoLength="52:38">
|
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Targeting Multiple Mobile Platforms with Qt Creator" isVideo="true" videoUrl="http://www.youtube.com/watch?v=jDRup5z2qz0" videoLength="52:38">
|
||||||
<description><![CDATA[Using Qt Creator to develop a cross-platform application for mobile devices and other small devices.]]></description>
|
<description><![CDATA[Using Qt Creator to develop a cross-platform application for mobile devices and other small devices.]]></description>
|
||||||
<tags>qt creator,qt quick,qml,c++,android,sailfishos</tags>
|
<tags>qt creator,qt quick,qml,c++,android,sailfishos</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Step by Step Qt on Android Tutorial" isVideo="true" videoUrl="http://www.youtube.com/watch?v=yhdi6JONtQo" videoLength="1:02:30">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Effective Multi-Platform Development with Qt Creator, Qbs, and QEMU" isVideo="true" videoUrl="https://www.youtube.com/watch?v=v4glCQt2jE0" videoLength="19:08">
|
||||||
|
<description><![CDATA[Using Qt Creator, Qbs, and QEMU for application development.]]></description>
|
||||||
|
<tags>qt creator,qbs,qemu</tags>
|
||||||
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Getting Started with Qt on Android" isVideo="true" videoUrl="https://www.youtube.com/watch?v=FWGUA9RS_ak" videoLength="41:30">
|
||||||
<description><![CDATA[Using Qt Creator to develop a Qt Quick application for Android devices.]]></description>
|
<description><![CDATA[Using Qt Creator to develop a Qt Quick application for Android devices.]]></description>
|
||||||
<tags>qt creator,qt quick,qml,android</tags>
|
<tags>qt creator,android</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Qt for iOS" isVideo="true" videoUrl="http://www.youtube.com/watch?v=HNQpJG2F6ow" videoLength="1:00:48">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Mastering Qt on Android" isVideo="true" videoUrl="https://www.youtube.com/watch?v=xqtoUCjG6GM" videoLength="43:54">
|
||||||
<description><![CDATA[Using Qt Creator to develop a Qt Quick application for iOS that uses sensors and the native camera on the device.]]></description>
|
<description><![CDATA[Using the Qt Android Extras module.]]></description>
|
||||||
<tags>qt creator,qt quick,ios,sensors,camera</tags>
|
<tags>qt,android</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Qt Creator for BareMetal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt on iOS A to Z" isVideo="true" videoUrl="https://www.youtube.com/watch?v=8A7DPUwIcDg" videoLength="1:05:32">
|
||||||
<description><![CDATA[Using Qt Creator to develop for BareMetal devices.]]></description>
|
<description><![CDATA[Using Qt Creator to develop an application for iOS.]]></description>
|
||||||
|
<tags>qt creator,ios</tags>
|
||||||
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Qt Creator for Bare Metal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35">
|
||||||
|
<description><![CDATA[Using Qt Creator to develop for Bare Metal devices.]]></description>
|
||||||
<tags>qt creator,baremetal</tags>
|
<tags>qt creator,baremetal</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Qt on WinRT" isVideo="true" videoUrl="http://www.youtube.com/watch?v=NubVGd_LcxQ" videoLength="50:01">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt and Windows 10" isVideo="true" videoUrl="https://www.youtube.com/watch?v=J9QrPvr-Sg0" videoLength="21:19">
|
||||||
<description><![CDATA[Learning about the experimental Qt on Windows Runtime port.]]></description>
|
<description><![CDATA[Qt support for Windows 10 on desktop, mobile, and embedded devices.]]></description>
|
||||||
<tags>qt,winrt</tags>
|
<tags>qt,Windows 10</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Device Creation with Qt" isVideo="true" videoUrl="https://www.youtube.com/watch?v=RXFnCmlsq3s" videoLength="55:11">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Developing for Windows 10 with Qt" isVideo="true" videoUrl="https://www.youtube.com/watch?v=o5Xdt-j3hkA" videoLength="38:53">
|
||||||
<description><![CDATA[Prototyping and creating your own embedded devices that run Qt applications.]]></description>
|
<description><![CDATA[Using Qt Creator to develop applications for Windows 10.]]></description>
|
||||||
<tags>qt, embedded, device creation,prototype</tags>
|
<tags>qt creator,Windows 10,demo</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Deep Dive into Qt Quick and Qt Quick Controls" isVideo="true" videoUrl="https://www.youtube.com/watch?v=WLoirPcKgg0" videoLength="57:34">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nRf1e-AYk0o" videoLength="57:45">
|
||||||
<description><![CDATA[Using Qt Quick Controls to create user interfaces and C++ for the application logic.]]></description>
|
<description><![CDATA[Creating your own embedded devices that run Qt applications.]]></description>
|
||||||
|
<tags>qt, embedded, device creation</tags>
|
||||||
|
</tutorial>
|
||||||
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt Quick Controls Re-Engineered" isVideo="true" videoUrl="https://www.youtube.com/watch?v=FqjabvHSiZk" videoLength="45:34">
|
||||||
|
<description><![CDATA[Overview of changes planned to Qt Quick Controls.]]></description>
|
||||||
<tags>qt quick,controls</tags>
|
<tags>qt quick,controls</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Adaptable UIs with Qt Quick" isVideo="true" videoUrl="http://www.youtube.com/watch?v=7zlvbHow9Gw" videoLength="46:16">
|
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Adaptable UIs with Qt Quick" isVideo="true" videoUrl="http://www.youtube.com/watch?v=7zlvbHow9Gw" videoLength="46:16">
|
||||||
<description><![CDATA[Implementing adaptable Qt Quick UIs using layouts, bindings, file selectors, and loaders.]]></description>
|
<description><![CDATA[Implementing adaptable Qt Quick UIs using layouts, bindings, file selectors, and loaders.]]></description>
|
||||||
<tags>qt quick,layouts,bindings</tags>
|
<tags>qt quick,layouts,bindings</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Qt Quick and Input Events (Touch, Mouse, Keyboard)" isVideo="true" videoUrl="http://www.youtube.com/watch?v=yTsCkfTAl1s" videoLength="1:07:05">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt 3D CAD Demo" isVideo="true" videoUrl="https://www.youtube.com/watch?v=pDgo3EQxtaE" videoLength="10:10">
|
||||||
<description><![CDATA[Handling user input with Qt Quick.]]></description>
|
<description><![CDATA[Creating a CAD application using Qt 3D.]]></description>
|
||||||
<tags>qt quick,qml,input</tags>
|
<tags>qt 3d,demo</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="Building 3D OpenGL Scenes with Qt 5 and QML" isVideo="true" videoUrl="http://www.youtube.com/watch?v=29wCpA0DBZI" videoLength="52:38">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Effective QML" isVideo="true" videoUrl="https://www.youtube.com/watch?v=vzs5VPTf4QQ" videoLength="55:25">
|
||||||
<description><![CDATA[Using QQuickWindow's OpenGL context to render 3D objects.]]></description>
|
<description><![CDATA[Improving your QML code by using tools and by understanding the QML system.]]></description>
|
||||||
<tags>qt quick,qml,3d,opengl</tags>
|
<tags>qml,qml profiler</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Enabling Direct WebGL in Qt Quick 2" isVideo="true" videoUrl="https://www.youtube.com/watch?v=I379HnymiAw" videoLength="51:12">
|
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Qt Widgets and Qt Quick Controls - A Comparison" isVideo="true" videoUrl="https://www.youtube.com/watch?v=-S9ki14ZtIk" videoLength="57:00">
|
||||||
<description><![CDATA[Using Qt Canvas 3D.]]></description>
|
|
||||||
<tags>qt quick, qt canvas 3d,webgl</tags>
|
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="QML Engine in Depth" isVideo="true" videoUrl="https://www.youtube.com/watch?v=odx7-A9c5Ak" videoLength="1:00:04">
|
|
||||||
<description><![CDATA[Changes in the QML Engine in Qt 5.4.]]></description>
|
|
||||||
<tags>qt,qml engine</tags>
|
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays13.png" difficulty="" projectPath="" name="QML Tricks and Treats" isVideo="true" videoUrl="http://www.youtube.com/watch?v=JNDFUHOoPSM" videoLength="56:20">
|
|
||||||
<description><![CDATA[Structuring an application that combines QML and C++ code, looking up QML language scope and names, creating custom views, handling user input, and styling applications.]]></description>
|
|
||||||
<tags>qt quick,qml,c++,build,compile,input,styling</tags>
|
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="QtWidgets and QtQuick Controls - A Comparison" isVideo="true" videoUrl="https://www.youtube.com/watch?v=-S9ki14ZtIk" videoLength="57:00">
|
|
||||||
<description><![CDATA[Comparison of Qt Widgets and Qt Quick Controls.]]></description>
|
<description><![CDATA[Comparison of Qt Widgets and Qt Quick Controls.]]></description>
|
||||||
<tags>qt quick,widgets</tags>
|
<tags>qt quick,widgets</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="QtWebEngine - Learning to Walk" isVideo="true" videoUrl="https://www.youtube.com/watch?v=q_UumdWw1iI" videoLength="51:04">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt's Web Offering - An Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=XW-oTBCj1JQ" videoLength="23:32">
|
||||||
<description><![CDATA[Introduces the Qt Web Engine technology for desktop and embedded platforms.]]></description>
|
<description><![CDATA[Overview of the Qt modules that provide functions for embedding web content into applications.]]></description>
|
||||||
<tags>qt web engine</tags>
|
<tags>qt webengine</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="QmlWeb - Running Qt Quick Applications on the Web" isVideo="true" videoUrl="https://www.youtube.com/watch?v=q_UumdWw1iI" videoLength="57:05">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt WebEngine – Taming the Beast" isVideo="true" videoUrl="https://www.youtube.com/watch?v=3CTFxhBc_1I" videoLength="58:23">
|
||||||
<description><![CDATA[Taking QML to the web.]]></description>
|
<description><![CDATA[Using the Qt WebEngine module.]]></description>
|
||||||
<tags>qml,qt quick,web</tags>
|
<tags>qt webengine</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Using the QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Building Desktop and Embedded UIs with Qt 3D" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QCdti6xmug0" videoLength="47:40">
|
||||||
<description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description>
|
<description><![CDATA[Adding 3D content to Qt applications.]]></description>
|
||||||
<tags>qt quick,qt creator,qml profiler</tags>
|
<tags>qt,qt creator,3d</tags>
|
||||||
</tutorial>
|
</tutorial>
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Introducing Qt 3D 2.0 (3D Rendering & Visualization)" isVideo="true" videoUrl="https://www.youtube.com/watch?v=WbLBgpancME" videoLength="1:01:24">
|
<tutorial imageUrl="images/icons/worldsummit15.png" difficulty="" projectPath="" name="Developing for Multiple Screen Resolutions" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nNyhsdX6BsI" videoLength="40:09">
|
||||||
<description><![CDATA[Rendering and visualization in Qt 3D.]]></description>
|
<description><![CDATA[Developing for multiple screen resolutions.]]></description>
|
||||||
<tags>qt,3d</tags>
|
<tags>qt,qt quick,screen resolution</tags>
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Rapid UI Prototyping - Better, Faster, Awesome" isVideo="true" videoUrl="https://www.youtube.com/watch?v=j3r_2aaQQIc" videoLength="45:46">
|
|
||||||
<description><![CDATA[Prototyping with QML and QML Demo.]]></description>
|
|
||||||
<tags>qt,qml,prototype</tags>
|
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="Analyzing Performance of Qt Quick Applications" isVideo="true" videoUrl="https://www.youtube.com/watch?v=FUMNqX5Q7tw" videoLength="52:01">
|
|
||||||
<description><![CDATA[Measuring startup time and rendering (in frames per second).]]></description>
|
|
||||||
<tags>qt quick,qml,qt creator,qml profiler,embedded</tags>
|
|
||||||
</tutorial>
|
|
||||||
<tutorial imageUrl="images/icons/ddays14.png" difficulty="" projectPath="" name="A Framework for the Multiscreen World" isVideo="true" videoUrl="https://www.youtube.com/watch?v=qJpuG7fWh98" videoLength="52:36">
|
|
||||||
<description><![CDATA[Supporting desktop and embedded platforms from the same source.]]></description>
|
|
||||||
<tags>qt,qml,c++,embedded</tags>
|
|
||||||
</tutorial>
|
</tutorial>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
</instructionals>
|
</instructionals>
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
@@ -696,8 +696,8 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
|||||||
_end_a_cardinality->setEnabled(is_single_selection);
|
_end_a_cardinality->setEnabled(is_single_selection);
|
||||||
}
|
}
|
||||||
if (_end_a_navigable == 0) {
|
if (_end_a_navigable == 0) {
|
||||||
_end_a_navigable = new QCheckBox(_top_widget);
|
_end_a_navigable = new QCheckBox(tr("Navigable"), _top_widget);
|
||||||
_top_layout->addRow(tr("Navigable"), _end_a_navigable);
|
_top_layout->addRow(QString(), _end_a_navigable);
|
||||||
connect(_end_a_navigable, SIGNAL(clicked(bool)), this, SLOT(onAssociationEndANavigableChanged(bool)));
|
connect(_end_a_navigable, SIGNAL(clicked(bool)), this, SLOT(onAssociationEndANavigableChanged(bool)));
|
||||||
}
|
}
|
||||||
if (is_single_selection) {
|
if (is_single_selection) {
|
||||||
@@ -763,8 +763,8 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
|
|||||||
_end_b_cardinality->setEnabled(is_single_selection);
|
_end_b_cardinality->setEnabled(is_single_selection);
|
||||||
}
|
}
|
||||||
if (_end_b_navigable == 0) {
|
if (_end_b_navigable == 0) {
|
||||||
_end_b_navigable = new QCheckBox(_top_widget);
|
_end_b_navigable = new QCheckBox(tr("Navigable"), _top_widget);
|
||||||
_top_layout->addRow(tr("Navigable"), _end_b_navigable);
|
_top_layout->addRow(QString(), _end_b_navigable);
|
||||||
connect(_end_b_navigable, SIGNAL(clicked(bool)), this, SLOT(onAssociationEndBNavigableChanged(bool)));
|
connect(_end_b_navigable, SIGNAL(clicked(bool)), this, SLOT(onAssociationEndBNavigableChanged(bool)));
|
||||||
}
|
}
|
||||||
if (is_single_selection) {
|
if (is_single_selection) {
|
||||||
@@ -834,8 +834,8 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
|||||||
.arg(object->getRect().bottom()));
|
.arg(object->getRect().bottom()));
|
||||||
#endif
|
#endif
|
||||||
if (_auto_sized_checkbox == 0) {
|
if (_auto_sized_checkbox == 0) {
|
||||||
_auto_sized_checkbox = new QCheckBox(_top_widget);
|
_auto_sized_checkbox = new QCheckBox(tr("Auto sized"), _top_widget);
|
||||||
_top_layout->addRow(tr("Auto sized"), _auto_sized_checkbox);
|
_top_layout->addRow(QString(), _auto_sized_checkbox);
|
||||||
connect(_auto_sized_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoSizedChanged(bool)));
|
connect(_auto_sized_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoSizedChanged(bool)));
|
||||||
}
|
}
|
||||||
if (!_auto_sized_checkbox->hasFocus()) {
|
if (!_auto_sized_checkbox->hasFocus()) {
|
||||||
@@ -892,8 +892,8 @@ void PropertiesView::MView::visitDObject(const DObject *object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_visual_emphasized_checkbox == 0) {
|
if (_visual_emphasized_checkbox == 0) {
|
||||||
_visual_emphasized_checkbox = new QCheckBox(_top_widget);
|
_visual_emphasized_checkbox = new QCheckBox(tr("Emphasized"), _top_widget);
|
||||||
_top_layout->addRow(tr("Emphasized"), _visual_emphasized_checkbox);
|
_top_layout->addRow(QString(), _visual_emphasized_checkbox);
|
||||||
connect(_visual_emphasized_checkbox, SIGNAL(clicked(bool)), this, SLOT(onVisualEmphasizedChanged(bool)));
|
connect(_visual_emphasized_checkbox, SIGNAL(clicked(bool)), this, SLOT(onVisualEmphasizedChanged(bool)));
|
||||||
}
|
}
|
||||||
if (!_visual_emphasized_checkbox->hasFocus()) {
|
if (!_visual_emphasized_checkbox->hasFocus()) {
|
||||||
@@ -957,8 +957,8 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_show_all_members_checkbox == 0) {
|
if (_show_all_members_checkbox == 0) {
|
||||||
_show_all_members_checkbox = new QCheckBox(_top_widget);
|
_show_all_members_checkbox = new QCheckBox(tr("Show members"), _top_widget);
|
||||||
_top_layout->addRow(tr("Show members"), _show_all_members_checkbox);
|
_top_layout->addRow(QString(), _show_all_members_checkbox);
|
||||||
connect(_show_all_members_checkbox, SIGNAL(clicked(bool)), this, SLOT(onShowAllMembersChanged(bool)));
|
connect(_show_all_members_checkbox, SIGNAL(clicked(bool)), this, SLOT(onShowAllMembersChanged(bool)));
|
||||||
}
|
}
|
||||||
if (!_show_all_members_checkbox->hasFocus()) {
|
if (!_show_all_members_checkbox->hasFocus()) {
|
||||||
@@ -978,8 +978,8 @@ void PropertiesView::MView::visitDComponent(const DComponent *component)
|
|||||||
setStyleElementType(StyleEngine::TYPE_COMPONENT);
|
setStyleElementType(StyleEngine::TYPE_COMPONENT);
|
||||||
visitDObject(component);
|
visitDObject(component);
|
||||||
if (_plain_shape_checkbox == 0) {
|
if (_plain_shape_checkbox == 0) {
|
||||||
_plain_shape_checkbox = new QCheckBox(_top_widget);
|
_plain_shape_checkbox = new QCheckBox(tr("Plain shape"), _top_widget);
|
||||||
_top_layout->addRow(tr("Plain shape"), _plain_shape_checkbox);
|
_top_layout->addRow(QString(), _plain_shape_checkbox);
|
||||||
connect(_plain_shape_checkbox, SIGNAL(clicked(bool)), this, SLOT(onPlainShapeChanged(bool)));
|
connect(_plain_shape_checkbox, SIGNAL(clicked(bool)), this, SLOT(onPlainShapeChanged(bool)));
|
||||||
}
|
}
|
||||||
if (!_plain_shape_checkbox->hasFocus()) {
|
if (!_plain_shape_checkbox->hasFocus()) {
|
||||||
@@ -1054,8 +1054,8 @@ void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
|
|||||||
setTitle<DAnnotation>(_diagram_elements, tr("Annotation"), tr("Annotations"));
|
setTitle<DAnnotation>(_diagram_elements, tr("Annotation"), tr("Annotations"));
|
||||||
visitDElement(annotation);
|
visitDElement(annotation);
|
||||||
if (_annotation_auto_width_checkbox == 0) {
|
if (_annotation_auto_width_checkbox == 0) {
|
||||||
_annotation_auto_width_checkbox = new QCheckBox(_top_widget);
|
_annotation_auto_width_checkbox = new QCheckBox(tr("Auto width"), _top_widget);
|
||||||
_top_layout->addRow(tr("Auto width"), _annotation_auto_width_checkbox);
|
_top_layout->addRow(QString(), _annotation_auto_width_checkbox);
|
||||||
connect(_annotation_auto_width_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoWidthChanged(bool)));
|
connect(_annotation_auto_width_checkbox, SIGNAL(clicked(bool)), this, SLOT(onAutoWidthChanged(bool)));
|
||||||
}
|
}
|
||||||
if (!_annotation_auto_width_checkbox->hasFocus()) {
|
if (!_annotation_auto_width_checkbox->hasFocus()) {
|
||||||
|
@@ -137,12 +137,19 @@ void ProjectSerializer::load(const QString &file_name, Project *project)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
QXmlStreamReader reader(xml_device);
|
QXmlStreamReader reader(xml_device);
|
||||||
qark::QXmlInArchive archive(reader);
|
|
||||||
archive.beginDocument();
|
try {
|
||||||
archive >> qark::tag("qmt");
|
qark::QXmlInArchive archive(reader);
|
||||||
archive >> *project;
|
archive.beginDocument();
|
||||||
archive >> qark::end;
|
archive >> qark::tag("qmt");
|
||||||
archive.endDocument();
|
archive >> *project;
|
||||||
|
archive >> qark::end;
|
||||||
|
archive.endDocument();
|
||||||
|
} catch (const qark::QXmlInArchive::FileFormatException &) {
|
||||||
|
throw FileIOException(QStringLiteral("illegal file format"), file_name);
|
||||||
|
} catch (...) {
|
||||||
|
throw FileIOException(QStringLiteral("serialization error"), file_name);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_COMPRESSED_FILES
|
#ifdef USE_COMPRESSED_FILES
|
||||||
uncompressor.close();
|
uncompressor.close();
|
||||||
@@ -155,12 +162,17 @@ void ProjectSerializer::write(QXmlStreamWriter *writer, const Project *project)
|
|||||||
writer->setAutoFormatting(true);
|
writer->setAutoFormatting(true);
|
||||||
writer->setAutoFormattingIndent(1);
|
writer->setAutoFormattingIndent(1);
|
||||||
|
|
||||||
qark::QXmlOutArchive archive(*writer);
|
try {
|
||||||
archive.beginDocument();
|
qark::QXmlOutArchive archive(*writer);
|
||||||
archive << qark::tag("qmt");
|
archive.beginDocument();
|
||||||
archive << *project;
|
archive << qark::tag("qmt");
|
||||||
archive << qark::end;
|
archive << *project;
|
||||||
archive.endDocument();
|
archive << qark::end;
|
||||||
|
archive.endDocument();
|
||||||
|
} catch (...) {
|
||||||
|
throw IOException(QStringLiteral("serialization error"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -548,12 +548,11 @@ protected:
|
|||||||
out(ast->typeToken);
|
out(ast->typeToken);
|
||||||
}
|
}
|
||||||
out(" ");
|
out(" ");
|
||||||
out(ast->identifierToken);
|
|
||||||
if (ast->statement) {
|
if (ast->statement) {
|
||||||
|
out(ast->identifierToken);
|
||||||
out(": ", ast->colonToken);
|
out(": ", ast->colonToken);
|
||||||
accept(ast->statement);
|
accept(ast->statement);
|
||||||
} else if (ast->binding) {
|
} else if (ast->binding) {
|
||||||
out(": ", ast->colonToken);
|
|
||||||
accept(ast->binding);
|
accept(ast->binding);
|
||||||
}
|
}
|
||||||
} else { // signal
|
} else { // signal
|
||||||
|
@@ -280,7 +280,7 @@ extern "C" HRESULT CALLBACK pid(CIDebugClient *client, PCSTR args)
|
|||||||
|
|
||||||
int token;
|
int token;
|
||||||
commandTokens<StringList>(args, &token);
|
commandTokens<StringList>(args, &token);
|
||||||
dprintf("Qt Creator CDB extension version 3.4 %d bit.\n",
|
dprintf("Qt Creator CDB extension version 3.6 %d bit.\n",
|
||||||
sizeof(void *) * 8);
|
sizeof(void *) * 8);
|
||||||
if (const ULONG pid = currentProcessId(client))
|
if (const ULONG pid = currentProcessId(client))
|
||||||
ExtensionContext::instance().report('R', token, 0, "pid", "%u", pid);
|
ExtensionContext::instance().report('R', token, 0, "pid", "%u", pid);
|
||||||
|
@@ -1119,7 +1119,7 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
|
|||||||
std::wstring value = simpleDumpValue(ctx, &encoding);
|
std::wstring value = simpleDumpValue(ctx, &encoding);
|
||||||
|
|
||||||
if (addr) {
|
if (addr) {
|
||||||
str << std::hex << std::showbase << ",addr=\"" << addr << '"';
|
str << std::hex << std::showbase << ",address=\"" << addr << '"';
|
||||||
if (SymbolGroupValue::isPointerType(t)) {
|
if (SymbolGroupValue::isPointerType(t)) {
|
||||||
std::string::size_type pointerPos = value.rfind(L"0x");
|
std::string::size_type pointerPos = value.rfind(L"0x");
|
||||||
if (pointerPos != std::string::npos) {
|
if (pointerPos != std::string::npos) {
|
||||||
@@ -1602,7 +1602,7 @@ int MapNodeSymbolGroupNode::dump(std::ostream &str, const std::string &visitingF
|
|||||||
{
|
{
|
||||||
SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname);
|
SymbolGroupNode::dumpBasicData(str, name(), visitingFullIname);
|
||||||
if (m_address)
|
if (m_address)
|
||||||
str << ",addr=\"0x" << std::hex << m_address << '"';
|
str << ",address=\"0x" << std::hex << m_address << '"';
|
||||||
str << ",type=\"" << m_type << "\",valueencoded=\"0\",value=\"\",valueenabled=\"false\""
|
str << ",type=\"" << m_type << "\",valueencoded=\"0\",value=\"\",valueenabled=\"false\""
|
||||||
",valueeditable=\"false\"";
|
",valueeditable=\"false\"";
|
||||||
return 2;
|
return 2;
|
||||||
|
@@ -343,20 +343,20 @@ template<typename C, typename F>
|
|||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
C filtered(const C &container, F predicate)
|
C filtered(const C &container, F predicate)
|
||||||
{
|
{
|
||||||
C out;
|
C out;
|
||||||
std::copy_if(container.begin(), container.end(),
|
std::copy_if(container.begin(), container.end(),
|
||||||
inserter(out), predicate);
|
inserter(out), predicate);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename C, typename R, typename S>
|
template<typename C, typename R, typename S>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
C filtered(const C &container, R (S::*predicate)() const)
|
C filtered(const C &container, R (S::*predicate)() const)
|
||||||
{
|
{
|
||||||
C out;
|
C out;
|
||||||
std::copy_if(container.begin(), container.end(),
|
std::copy_if(container.begin(), container.end(),
|
||||||
inserter(out), std::mem_fn(predicate));
|
inserter(out), std::mem_fn(predicate));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
@@ -1233,21 +1233,15 @@ static bool equalKits(Kit *a, Kit *b)
|
|||||||
|
|
||||||
void AndroidConfigurations::registerNewToolChains()
|
void AndroidConfigurations::registerNewToolChains()
|
||||||
{
|
{
|
||||||
QList<ToolChain *> existingToolChains = ToolChainManager::toolChains();
|
const QList<ToolChain *> existingAndroidToolChains
|
||||||
QList<ToolChain *> toolchains = AndroidToolChainFactory::createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
|
= Utils::filtered(ToolChainManager::toolChains(),
|
||||||
foreach (ToolChain *tc, toolchains) {
|
Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_ID)));
|
||||||
bool found = false;
|
|
||||||
for (int i = 0; i < existingToolChains.count(); ++i) {
|
const QList<ToolChain *> newToolchains
|
||||||
if (*(existingToolChains.at(i)) == *tc) {
|
= AndroidToolChainFactory::autodetectToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation(),
|
||||||
found = true;
|
existingAndroidToolChains);
|
||||||
break;
|
foreach (ToolChain *tc, newToolchains)
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
delete tc;
|
|
||||||
else
|
|
||||||
ToolChainManager::registerToolChain(tc);
|
ToolChainManager::registerToolChain(tc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfigurations::removeOldToolChains()
|
void AndroidConfigurations::removeOldToolChains()
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include <projectexplorer/toolchainmanager.h>
|
#include <projectexplorer/toolchainmanager.h>
|
||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
@@ -260,8 +261,7 @@ AndroidToolChainFactory::AndroidToolChainFactory()
|
|||||||
|
|
||||||
QList<ToolChain *> AndroidToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> AndroidToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
Q_UNUSED(alreadyKnown);
|
return autodetectToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation(), alreadyKnown);
|
||||||
return createToolChainsForNdk(AndroidConfigurations::currentConfig().ndkLocation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidToolChainFactory::canRestore(const QVariantMap &data)
|
bool AndroidToolChainFactory::canRestore(const QVariantMap &data)
|
||||||
@@ -352,11 +352,23 @@ bool AndroidToolChainFactory::versionCompareLess(AndroidToolChain *atc, AndroidT
|
|||||||
return versionCompareLess(a, b);
|
return versionCompareLess(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileName &ndkPath)
|
static AndroidToolChain *findToolChain(Utils::FileName &compilerPath, const QList<ToolChain *> &alreadyKnown)
|
||||||
|
{
|
||||||
|
return static_cast<AndroidToolChain *>(
|
||||||
|
Utils::findOrDefault(alreadyKnown, [compilerPath](ToolChain *tc) {
|
||||||
|
return tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
|
||||||
|
&& tc->compilerCommand() == compilerPath;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ToolChain *>
|
||||||
|
AndroidToolChainFactory::autodetectToolChainsForNdk(const FileName &ndkPath,
|
||||||
|
const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
QList<ToolChain *> result;
|
QList<ToolChain *> result;
|
||||||
if (ndkPath.isEmpty())
|
if (ndkPath.isEmpty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QRegExp versionRegExp(NDKGccVersionRegExp);
|
QRegExp versionRegExp(NDKGccVersionRegExp);
|
||||||
FileName path = ndkPath;
|
FileName path = ndkPath;
|
||||||
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
|
QDirIterator it(path.appendPath(QLatin1String("toolchains")).toString(),
|
||||||
@@ -373,13 +385,16 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
|
|||||||
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
|
Abi abi = AndroidConfig::abiForToolChainPrefix(platform);
|
||||||
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
|
if (abi.architecture() == Abi::UnknownArchitecture) // e.g. mipsel which is not yet supported
|
||||||
continue;
|
continue;
|
||||||
AndroidToolChain *tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
|
|
||||||
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
|
FileName compilerPath = AndroidConfigurations::currentConfig().gccPath(abi, version);
|
||||||
tc->resetToolChain(compilerPath);
|
|
||||||
|
AndroidToolChain *tc = findToolChain(compilerPath, alreadyKnown);
|
||||||
|
if (!tc) {
|
||||||
|
tc = new AndroidToolChain(abi, version, ToolChain::AutoDetection);
|
||||||
|
tc->resetToolChain(compilerPath);
|
||||||
|
}
|
||||||
result.append(tc);
|
result.append(tc);
|
||||||
|
|
||||||
QHash<Abi, AndroidToolChain *>::const_iterator it
|
auto it = newestToolChainForArch.constFind(abi);
|
||||||
= newestToolChainForArch.constFind(abi);
|
|
||||||
if (it == newestToolChainForArch.constEnd())
|
if (it == newestToolChainForArch.constEnd())
|
||||||
newestToolChainForArch.insert(abi, tc);
|
newestToolChainForArch.insert(abi, tc);
|
||||||
else if (versionCompareLess(it.value(), tc))
|
else if (versionCompareLess(it.value(), tc))
|
||||||
@@ -388,8 +403,7 @@ QList<ToolChain *> AndroidToolChainFactory::createToolChainsForNdk(const FileNam
|
|||||||
|
|
||||||
foreach (ToolChain *tc, result) {
|
foreach (ToolChain *tc, result) {
|
||||||
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
|
AndroidToolChain *atc = static_cast<AndroidToolChain *>(tc);
|
||||||
if (newestToolChainForArch.value(atc->targetAbi()) != atc)
|
atc->setSecondaryToolChain(newestToolChainForArch.value(atc->targetAbi()) != atc);
|
||||||
atc->setSecondaryToolChain(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -113,7 +113,9 @@ public:
|
|||||||
QString version;
|
QString version;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QList<ProjectExplorer::ToolChain *> createToolChainsForNdk(const Utils::FileName &ndkPath);
|
static QList<ProjectExplorer::ToolChain *>
|
||||||
|
autodetectToolChainsForNdk(const Utils::FileName &ndkPath,
|
||||||
|
const QList<ProjectExplorer::ToolChain *> &alreadyKnown);
|
||||||
static QList<AndroidToolChainInformation> toolchainPathsForNdk(const Utils::FileName &ndkPath);
|
static QList<AndroidToolChainInformation> toolchainPathsForNdk(const Utils::FileName &ndkPath);
|
||||||
|
|
||||||
static QList<int> versionNumberFromString(const QString &version);
|
static QList<int> versionNumberFromString(const QString &version);
|
||||||
|
@@ -61,13 +61,14 @@ namespace Internal {
|
|||||||
const char USE_NINJA_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.UseNinja";
|
const char USE_NINJA_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.UseNinja";
|
||||||
const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.InitialArgument";
|
const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.InitialArgument";
|
||||||
|
|
||||||
static FileName shadowBuildDirectory(const FileName &projectFilePath, const Kit *k, const QString &bcName)
|
static FileName shadowBuildDirectory(const FileName &projectFilePath, const Kit *k,
|
||||||
|
const QString &bcName, BuildConfiguration::BuildType buildType)
|
||||||
{
|
{
|
||||||
if (projectFilePath.isEmpty())
|
if (projectFilePath.isEmpty())
|
||||||
return FileName();
|
return FileName();
|
||||||
|
|
||||||
const QString projectName = projectFilePath.parentDir().fileName();
|
const QString projectName = projectFilePath.parentDir().fileName();
|
||||||
ProjectMacroExpander expander(projectName, k, bcName);
|
ProjectMacroExpander expander(projectName, k, bcName, buildType);
|
||||||
QDir projectDir = QDir(Project::projectDirectory(projectFilePath).toString());
|
QDir projectDir = QDir(Project::projectDirectory(projectFilePath).toString());
|
||||||
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
||||||
return FileName::fromUserInput(projectDir.absoluteFilePath(buildPath));
|
return FileName::fromUserInput(projectDir.absoluteFilePath(buildPath));
|
||||||
@@ -79,7 +80,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent
|
|||||||
CMakeProject *project = static_cast<CMakeProject *>(parent->project());
|
CMakeProject *project = static_cast<CMakeProject *>(parent->project());
|
||||||
setBuildDirectory(shadowBuildDirectory(project->projectFilePath(),
|
setBuildDirectory(shadowBuildDirectory(project->projectFilePath(),
|
||||||
parent->kit(),
|
parent->kit(),
|
||||||
displayName()));
|
displayName(), BuildConfiguration::Unknown));
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
|
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
|
||||||
@@ -202,7 +203,8 @@ QList<ProjectExplorer::BuildInfo *> CMakeBuildConfigurationFactory::availableSet
|
|||||||
} else {
|
} else {
|
||||||
info->displayName = info->typeName;
|
info->displayName = info->typeName;
|
||||||
}
|
}
|
||||||
info->buildDirectory = shadowBuildDirectory(projectPathName, k, info->displayName);
|
info->buildDirectory
|
||||||
|
= shadowBuildDirectory(projectPathName, k, info->displayName, info->buildType);
|
||||||
result << info;
|
result << info;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -220,7 +222,7 @@ ProjectExplorer::BuildConfiguration *CMakeBuildConfigurationFactory::create(Proj
|
|||||||
|
|
||||||
if (copy.buildDirectory.isEmpty()) {
|
if (copy.buildDirectory.isEmpty()) {
|
||||||
copy.buildDirectory = shadowBuildDirectory(project->projectFilePath(), parent->kit(),
|
copy.buildDirectory = shadowBuildDirectory(project->projectFilePath(), parent->kit(),
|
||||||
copy.displayName);
|
copy.displayName, info->buildType);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
|
CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
|
||||||
@@ -306,18 +308,22 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp
|
|||||||
case BuildTypeDebug:
|
case BuildTypeDebug:
|
||||||
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Debug");
|
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Debug");
|
||||||
info->typeName = tr("Debug");
|
info->typeName = tr("Debug");
|
||||||
|
info->buildType = BuildConfiguration::Debug;
|
||||||
break;
|
break;
|
||||||
case BuildTypeRelease:
|
case BuildTypeRelease:
|
||||||
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Release");
|
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=Release");
|
||||||
info->typeName = tr("Release");
|
info->typeName = tr("Release");
|
||||||
|
info->buildType = BuildConfiguration::Release;
|
||||||
break;
|
break;
|
||||||
case BuildTypeMinSizeRel:
|
case BuildTypeMinSizeRel:
|
||||||
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=MinSizeRel");
|
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=MinSizeRel");
|
||||||
info->typeName = tr("Minimum Size Release");
|
info->typeName = tr("Minimum Size Release");
|
||||||
|
info->buildType = BuildConfiguration::Release;
|
||||||
break;
|
break;
|
||||||
case BuildTypeRelWithDebInfo:
|
case BuildTypeRelWithDebInfo:
|
||||||
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=RelWithDebInfo");
|
info->arguments = QLatin1String("-DCMAKE_BUILD_TYPE=RelWithDebInfo");
|
||||||
info->typeName = tr("Release with Debug Information");
|
info->typeName = tr("Release with Debug Information");
|
||||||
|
info->buildType = BuildConfiguration::Profile;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
|
@@ -265,10 +265,28 @@ void CMakeCbpParser::parseBuildTargetOption()
|
|||||||
m_buildTarget.targetType = TargetType(value.toInt());
|
m_buildTarget.targetType = TargetType(value.toInt());
|
||||||
} else if (attributes().hasAttribute(QLatin1String("working_dir"))) {
|
} else if (attributes().hasAttribute(QLatin1String("working_dir"))) {
|
||||||
m_buildTarget.workingDirectory = attributes().value(QLatin1String("working_dir")).toString();
|
m_buildTarget.workingDirectory = attributes().value(QLatin1String("working_dir")).toString();
|
||||||
QDir dir(m_buildDirectory);
|
|
||||||
const QString relative = dir.relativeFilePath(m_buildTarget.workingDirectory);
|
QFile cmakeSourceInfoFile(m_buildTarget.workingDirectory
|
||||||
m_buildTarget.sourceDirectory
|
+ QStringLiteral("/CMakeFiles/CMakeDirectoryInformation.cmake"));
|
||||||
= FileName::fromString(m_sourceDirectory).appendPath(relative).toString();
|
if (cmakeSourceInfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream stream(&cmakeSourceInfoFile);
|
||||||
|
const QLatin1String searchSource("SET(CMAKE_RELATIVE_PATH_TOP_SOURCE \"");
|
||||||
|
while (!stream.atEnd()) {
|
||||||
|
const QString lineTopSource = stream.readLine().trimmed();
|
||||||
|
if (lineTopSource.startsWith(searchSource)) {
|
||||||
|
m_buildTarget.sourceDirectory = lineTopSource.mid(searchSource.size());
|
||||||
|
m_buildTarget.sourceDirectory.chop(2); // cut off ")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_buildTarget.sourceDirectory.isEmpty()) {
|
||||||
|
QDir dir(m_buildDirectory);
|
||||||
|
const QString relative = dir.relativeFilePath(m_buildTarget.workingDirectory);
|
||||||
|
m_buildTarget.sourceDirectory
|
||||||
|
= FileName::fromString(m_sourceDirectory).appendPath(relative).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (!atEnd()) {
|
while (!atEnd()) {
|
||||||
readNext();
|
readNext();
|
||||||
|
@@ -61,6 +61,7 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
using namespace CMakeProjectManager;
|
using namespace CMakeProjectManager;
|
||||||
using namespace CMakeProjectManager::Internal;
|
using namespace CMakeProjectManager::Internal;
|
||||||
@@ -495,7 +496,7 @@ void CMakeRunPage::initializePage()
|
|||||||
"You can add command line arguments below. Note that "
|
"You can add command line arguments below. Note that "
|
||||||
"CMake remembers command line arguments from the "
|
"CMake remembers command line arguments from the "
|
||||||
"previous runs.")
|
"previous runs.")
|
||||||
.arg(m_buildDirectory)
|
.arg(QDir::toNativeSeparators(m_buildDirectory))
|
||||||
.arg(m_buildConfigurationName)
|
.arg(m_buildConfigurationName)
|
||||||
.arg(m_kitName));
|
.arg(m_kitName));
|
||||||
} else if (m_mode == CMakeRunPage::Recreate) {
|
} else if (m_mode == CMakeRunPage::Recreate) {
|
||||||
@@ -505,7 +506,7 @@ void CMakeRunPage::initializePage()
|
|||||||
"Some projects require command line arguments to "
|
"Some projects require command line arguments to "
|
||||||
"the initial CMake call. Note that CMake remembers command "
|
"the initial CMake call. Note that CMake remembers command "
|
||||||
"line arguments from the previous runs.")
|
"line arguments from the previous runs.")
|
||||||
.arg(m_buildDirectory)
|
.arg(QDir::toNativeSeparators(m_buildDirectory))
|
||||||
.arg(m_buildConfigurationName)
|
.arg(m_buildConfigurationName)
|
||||||
.arg(m_kitName));
|
.arg(m_kitName));
|
||||||
} else if (m_mode == CMakeRunPage::ChangeDirectory) {
|
} else if (m_mode == CMakeRunPage::ChangeDirectory) {
|
||||||
@@ -516,7 +517,7 @@ void CMakeRunPage::initializePage()
|
|||||||
} else if (m_mode == CMakeRunPage::WantToUpdate) {
|
} else if (m_mode == CMakeRunPage::WantToUpdate) {
|
||||||
m_descriptionLabel->setText(tr("Refreshing the .cbp file in \"%1\" for build configuration \"%2\" "
|
m_descriptionLabel->setText(tr("Refreshing the .cbp file in \"%1\" for build configuration \"%2\" "
|
||||||
"for target \"%3\".")
|
"for target \"%3\".")
|
||||||
.arg(m_buildDirectory)
|
.arg(QDir::toNativeSeparators(m_buildDirectory))
|
||||||
.arg(m_buildConfigurationName)
|
.arg(m_buildConfigurationName)
|
||||||
.arg(m_kitName));
|
.arg(m_kitName));
|
||||||
}
|
}
|
||||||
|
@@ -60,13 +60,18 @@ EditorWindow::EditorWindow(QWidget *parent) :
|
|||||||
|
|
||||||
connect(m_area, &EditorArea::windowTitleNeedsUpdate,
|
connect(m_area, &EditorArea::windowTitleNeedsUpdate,
|
||||||
this, &EditorWindow::updateWindowTitle);
|
this, &EditorWindow::updateWindowTitle);
|
||||||
|
// editor area can be deleted by editor manager
|
||||||
|
connect(m_area, &EditorArea::destroyed, this, [this]() {
|
||||||
|
m_area = nullptr;
|
||||||
|
deleteLater();
|
||||||
|
});
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorWindow::~EditorWindow()
|
EditorWindow::~EditorWindow()
|
||||||
{
|
{
|
||||||
disconnect(m_area, &EditorArea::windowTitleNeedsUpdate,
|
if (m_area)
|
||||||
this, &EditorWindow::updateWindowTitle);
|
disconnect(m_area, 0, this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorArea *EditorWindow::editorArea() const
|
EditorArea *EditorWindow::editorArea() const
|
||||||
|
@@ -214,6 +214,7 @@ void GdbServerStarter::attach(int port)
|
|||||||
|
|
||||||
DebuggerRunParameters rp;
|
DebuggerRunParameters rp;
|
||||||
rp.masterEngineType = GdbEngineType;
|
rp.masterEngineType = GdbEngineType;
|
||||||
|
rp.connParams.host = d->device->sshParameters().host;
|
||||||
rp.connParams.port = port;
|
rp.connParams.port = port;
|
||||||
rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port);
|
rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port);
|
||||||
rp.displayName = tr("Remote: \"%1:%2\"").arg(rp.connParams.host).arg(port);
|
rp.displayName = tr("Remote: \"%1:%2\"").arg(rp.connParams.host).arg(port);
|
||||||
|
@@ -562,7 +562,7 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
|
|||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
data.origaddr = mi.toAddress();
|
data.origaddr = mi.toAddress();
|
||||||
|
|
||||||
mi = item["addr"];
|
mi = item["address"];
|
||||||
if (mi.isValid())
|
if (mi.isValid())
|
||||||
setWatchDataAddress(data, mi.toAddress());
|
setWatchDataAddress(data, mi.toAddress());
|
||||||
|
|
||||||
|
@@ -440,16 +440,16 @@ GerritChangePtr GerritModel::change(const QModelIndex &index) const
|
|||||||
return GerritChangePtr(new GerritChange);
|
return GerritChangePtr(new GerritChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GerritModel::dependencyHtml(const QString &header, const QString &changeId,
|
QString GerritModel::dependencyHtml(const QString &header, const int changeNumber,
|
||||||
const QString &serverPrefix) const
|
const QString &serverPrefix) const
|
||||||
{
|
{
|
||||||
QString res;
|
QString res;
|
||||||
if (changeId.isEmpty())
|
if (!changeNumber)
|
||||||
return res;
|
return res;
|
||||||
QTextStream str(&res);
|
QTextStream str(&res);
|
||||||
str << "<tr><td>" << header << "</td><td><a href="
|
str << "<tr><td>" << header << "</td><td><a href="
|
||||||
<< serverPrefix << "r/" << changeId << '>' << changeId << "</a>";
|
<< serverPrefix << "r/" << changeNumber << '>' << changeNumber << "</a>";
|
||||||
if (const QStandardItem *item = itemForId(changeId))
|
if (const QStandardItem *item = itemForNumber(changeNumber))
|
||||||
str << " (" << changeFromItem(item)->title << ')';
|
str << " (" << changeFromItem(item)->title << ')';
|
||||||
str << "</td></tr>";
|
str << "</td></tr>";
|
||||||
return res;
|
return res;
|
||||||
@@ -479,8 +479,8 @@ QString GerritModel::toHtml(const QModelIndex& index) const
|
|||||||
<< "<tr><td>" << ownerHeader << "</td><td>" << c->owner << ' '
|
<< "<tr><td>" << ownerHeader << "</td><td>" << c->owner << ' '
|
||||||
<< "<a href=\"mailto:" << c->email << "\">" << c->email << "</a></td></tr>"
|
<< "<a href=\"mailto:" << c->email << "\">" << c->email << "</a></td></tr>"
|
||||||
<< "<tr><td>" << projectHeader << "</td><td>" << c->project << " (" << c->branch << ")</td></tr>"
|
<< "<tr><td>" << projectHeader << "</td><td>" << c->project << " (" << c->branch << ")</td></tr>"
|
||||||
<< dependencyHtml(dependsOnHeader, c->dependsOnId, serverPrefix)
|
<< dependencyHtml(dependsOnHeader, c->dependsOnNumber, serverPrefix)
|
||||||
<< dependencyHtml(neededByHeader, c->neededById, serverPrefix)
|
<< dependencyHtml(neededByHeader, c->neededByNumber, serverPrefix)
|
||||||
<< "<tr><td>" << statusHeader << "</td><td>" << c->status
|
<< "<tr><td>" << statusHeader << "</td><td>" << c->status
|
||||||
<< ", " << c->lastUpdated.toString(Qt::DefaultLocaleShortDate) << "</td></tr>"
|
<< ", " << c->lastUpdated.toString(Qt::DefaultLocaleShortDate) << "</td></tr>"
|
||||||
<< "<tr><td>" << patchSetHeader << "</td><td>" << "</td></tr>" << c->currentPatchSet.patchSetNumber << "</td></tr>"
|
<< "<tr><td>" << patchSetHeader << "</td><td>" << "</td></tr>" << c->currentPatchSet.patchSetNumber << "</td></tr>"
|
||||||
@@ -490,25 +490,25 @@ QString GerritModel::toHtml(const QModelIndex& index) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStandardItem *idSearchRecursion(QStandardItem *item, const QString &id)
|
static QStandardItem *numberSearchRecursion(QStandardItem *item, int number)
|
||||||
{
|
{
|
||||||
if (changeFromItem(item)->id == id)
|
if (changeFromItem(item)->number == number)
|
||||||
return item;
|
return item;
|
||||||
const int rowCount = item->rowCount();
|
const int rowCount = item->rowCount();
|
||||||
for (int r = 0; r < rowCount; ++r) {
|
for (int r = 0; r < rowCount; ++r) {
|
||||||
if (QStandardItem *i = idSearchRecursion(item->child(r, 0), id))
|
if (QStandardItem *i = numberSearchRecursion(item->child(r, 0), number))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStandardItem *GerritModel::itemForId(const QString &id) const
|
QStandardItem *GerritModel::itemForNumber(int number) const
|
||||||
{
|
{
|
||||||
if (id.isEmpty())
|
if (!number)
|
||||||
return 0;
|
return 0;
|
||||||
const int numRows = rowCount();
|
const int numRows = rowCount();
|
||||||
for (int r = 0; r < numRows; ++r) {
|
for (int r = 0; r < numRows; ++r) {
|
||||||
if (QStandardItem *i = idSearchRecursion(item(r, 0), id))
|
if (QStandardItem *i = numberSearchRecursion(item(r, 0), number))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -586,7 +586,6 @@ static bool parseOutput(const QSharedPointer<GerritParameters> ¶meters,
|
|||||||
{
|
{
|
||||||
// The output consists of separate lines containing a document each
|
// The output consists of separate lines containing a document each
|
||||||
const QString typeKey = QLatin1String("type");
|
const QString typeKey = QLatin1String("type");
|
||||||
const QString idKey = QLatin1String("id");
|
|
||||||
const QString dependsOnKey = QLatin1String("dependsOn");
|
const QString dependsOnKey = QLatin1String("dependsOn");
|
||||||
const QString neededByKey = QLatin1String("neededBy");
|
const QString neededByKey = QLatin1String("neededBy");
|
||||||
const QString branchKey = QLatin1String("branch");
|
const QString branchKey = QLatin1String("branch");
|
||||||
@@ -656,7 +655,6 @@ static bool parseOutput(const QSharedPointer<GerritParameters> ¶meters,
|
|||||||
change->url = object.value(urlKey).toString();
|
change->url = object.value(urlKey).toString();
|
||||||
if (change->url.isEmpty()) // No "canonicalWebUrl" is in gerrit.config.
|
if (change->url.isEmpty()) // No "canonicalWebUrl" is in gerrit.config.
|
||||||
change->url = defaultUrl(parameters, change->number);
|
change->url = defaultUrl(parameters, change->number);
|
||||||
change->id = object.value(idKey).toString();
|
|
||||||
change->title = object.value(titleKey).toString();
|
change->title = object.value(titleKey).toString();
|
||||||
const QJsonObject ownerJ = object.value(ownerKey).toObject();
|
const QJsonObject ownerJ = object.value(ownerKey).toObject();
|
||||||
change->owner = ownerJ.value(ownerNameKey).toString();
|
change->owner = ownerJ.value(ownerNameKey).toString();
|
||||||
@@ -681,7 +679,7 @@ static bool parseOutput(const QSharedPointer<GerritParameters> ¶meters,
|
|||||||
if (!dependsOnArray.isEmpty()) {
|
if (!dependsOnArray.isEmpty()) {
|
||||||
const QJsonValue first = dependsOnArray.at(0);
|
const QJsonValue first = dependsOnArray.at(0);
|
||||||
if (first.isObject())
|
if (first.isObject())
|
||||||
change->dependsOnId = first.toObject()[idKey].toString();
|
change->dependsOnNumber = first.toObject()[numberKey].toString().toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Read out needed by
|
// Read out needed by
|
||||||
@@ -691,7 +689,7 @@ static bool parseOutput(const QSharedPointer<GerritParameters> ¶meters,
|
|||||||
if (!neededByArray.isEmpty()) {
|
if (!neededByArray.isEmpty()) {
|
||||||
const QJsonValue first = neededByArray.at(0);
|
const QJsonValue first = neededByArray.at(0);
|
||||||
if (first.isObject())
|
if (first.isObject())
|
||||||
change->neededById = first.toObject()[idKey].toString();
|
change->neededByNumber = first.toObject()[numberKey].toString().toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,17 +755,17 @@ void GerritModel::queryFinished(const QByteArray &output)
|
|||||||
setState(parseOutput(m_parameters, output, changes) ? Ok : Error);
|
setState(parseOutput(m_parameters, output, changes) ? Ok : Error);
|
||||||
|
|
||||||
// Populate a hash with indices for faster access.
|
// Populate a hash with indices for faster access.
|
||||||
QHash<QString, int> idIndexHash;
|
QHash<int, int> numberIndexHash;
|
||||||
const int count = changes.size();
|
const int count = changes.size();
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
idIndexHash.insert(changes.at(i)->id, i);
|
numberIndexHash.insert(changes.at(i)->number, i);
|
||||||
// Mark root nodes: Changes that do not have a dependency, depend on a change
|
// Mark root nodes: Changes that do not have a dependency, depend on a change
|
||||||
// not in the list or on a change that is not "NEW".
|
// not in the list or on a change that is not "NEW".
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (changes.at(i)->dependsOnId.isEmpty()) {
|
if (!changes.at(i)->dependsOnNumber) {
|
||||||
changes.at(i)->depth = 0;
|
changes.at(i)->depth = 0;
|
||||||
} else {
|
} else {
|
||||||
const int dependsOnIndex = idIndexHash.value(changes.at(i)->dependsOnId, -1);
|
const int dependsOnIndex = numberIndexHash.value(changes.at(i)->dependsOnNumber, -1);
|
||||||
if (dependsOnIndex < 0 || changes.at(dependsOnIndex)->status != QLatin1String("NEW"))
|
if (dependsOnIndex < 0 || changes.at(dependsOnIndex)->status != QLatin1String("NEW"))
|
||||||
changes.at(i)->depth = 0;
|
changes.at(i)->depth = 0;
|
||||||
}
|
}
|
||||||
@@ -778,7 +776,7 @@ void GerritModel::queryFinished(const QByteArray &output)
|
|||||||
changed = false;
|
changed = false;
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (changes.at(i)->depth < 0) {
|
if (changes.at(i)->depth < 0) {
|
||||||
const int dependsIndex = idIndexHash.value(changes.at(i)->dependsOnId);
|
const int dependsIndex = numberIndexHash.value(changes.at(i)->dependsOnNumber);
|
||||||
const int dependsOnDepth = changes.at(dependsIndex)->depth;
|
const int dependsOnDepth = changes.at(dependsIndex)->depth;
|
||||||
if (dependsOnDepth >= 0) {
|
if (dependsOnDepth >= 0) {
|
||||||
changes.at(i)->depth = dependsOnDepth + 1;
|
changes.at(i)->depth = dependsOnDepth + 1;
|
||||||
@@ -789,19 +787,19 @@ void GerritModel::queryFinished(const QByteArray &output)
|
|||||||
}
|
}
|
||||||
// Sort by depth (root nodes first) and by date.
|
// Sort by depth (root nodes first) and by date.
|
||||||
qStableSort(changes.begin(), changes.end(), gerritChangeLessThan);
|
qStableSort(changes.begin(), changes.end(), gerritChangeLessThan);
|
||||||
idIndexHash.clear();
|
numberIndexHash.clear();
|
||||||
|
|
||||||
foreach (const GerritChangePtr &c, changes) {
|
foreach (const GerritChangePtr &c, changes) {
|
||||||
// Avoid duplicate entries for example in the (unlikely)
|
// Avoid duplicate entries for example in the (unlikely)
|
||||||
// case people do self-reviews.
|
// case people do self-reviews.
|
||||||
if (!itemForId(c->id)) {
|
if (!itemForNumber(c->number)) {
|
||||||
// Determine the verbose user name from the owner of the first query.
|
// Determine the verbose user name from the owner of the first query.
|
||||||
// It used for marking the changes pending for review in bold.
|
// It used for marking the changes pending for review in bold.
|
||||||
if (m_userName.isEmpty() && !m_query->currentQuery())
|
if (m_userName.isEmpty() && !m_query->currentQuery())
|
||||||
m_userName = c->owner;
|
m_userName = c->owner;
|
||||||
const QList<QStandardItem *> newRow = changeToRow(c);
|
const QList<QStandardItem *> newRow = changeToRow(c);
|
||||||
if (c->depth) {
|
if (c->depth) {
|
||||||
QStandardItem *parent = itemForId(c->dependsOnId);
|
QStandardItem *parent = itemForNumber(c->dependsOnNumber);
|
||||||
// Append changes with depth > 1 to the parent with depth=1 to avoid
|
// Append changes with depth > 1 to the parent with depth=1 to avoid
|
||||||
// too-deeply nested items.
|
// too-deeply nested items.
|
||||||
for (; changeFromItem(parent)->depth >= 1; parent = parent->parent()) {}
|
for (; changeFromItem(parent)->depth >= 1; parent = parent->parent()) {}
|
||||||
|
@@ -79,9 +79,8 @@ public:
|
|||||||
|
|
||||||
QString url;
|
QString url;
|
||||||
int number;
|
int number;
|
||||||
QString id;
|
int dependsOnNumber;
|
||||||
QString dependsOnId;
|
int neededByNumber;
|
||||||
QString neededById;
|
|
||||||
QString title;
|
QString title;
|
||||||
QString owner;
|
QString owner;
|
||||||
QString email;
|
QString email;
|
||||||
@@ -123,7 +122,7 @@ public:
|
|||||||
GerritChangePtr change(const QModelIndex &index) const;
|
GerritChangePtr change(const QModelIndex &index) const;
|
||||||
QString toHtml(const QModelIndex &index) const;
|
QString toHtml(const QModelIndex &index) const;
|
||||||
|
|
||||||
QStandardItem *itemForId(const QString &id) const;
|
QStandardItem *itemForNumber(int number) const;
|
||||||
|
|
||||||
enum QueryState { Idle, Running, Ok, Error };
|
enum QueryState { Idle, Running, Ok, Error };
|
||||||
QueryState state() const { return m_state; }
|
QueryState state() const { return m_state; }
|
||||||
@@ -141,7 +140,7 @@ private:
|
|||||||
|
|
||||||
void setState(QueryState s);
|
void setState(QueryState s);
|
||||||
|
|
||||||
QString dependencyHtml(const QString &header, const QString &changeId,
|
QString dependencyHtml(const QString &header, const int changeNumber,
|
||||||
const QString &serverPrefix) const;
|
const QString &serverPrefix) const;
|
||||||
QList<QStandardItem *> changeToRow(const GerritChangePtr &c) const;
|
QList<QStandardItem *> changeToRow(const GerritChangePtr &c) const;
|
||||||
|
|
||||||
|
@@ -2984,6 +2984,7 @@ VcsCommand *GitClient::vcsExecAbortable(const QString &workingDirectory,
|
|||||||
// Git might request an editor, so this must be done asynchronously and without timeout
|
// Git might request an editor, so this must be done asynchronously and without timeout
|
||||||
VcsCommand *command = createCommand(workingDirectory, 0, VcsWindowOutputBind);
|
VcsCommand *command = createCommand(workingDirectory, 0, VcsWindowOutputBind);
|
||||||
command->setCookie(workingDirectory);
|
command->setCookie(workingDirectory);
|
||||||
|
command->addFlags(VcsCommand::ShowSuccessMessage);
|
||||||
command->addJob(vcsBinary(), arguments, 0);
|
command->addJob(vcsBinary(), arguments, 0);
|
||||||
command->execute();
|
command->execute();
|
||||||
ConflictHandler::attachToCommand(command, abortCommand);
|
ConflictHandler::attachToCommand(command, abortCommand);
|
||||||
|
@@ -375,10 +375,10 @@ QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &exi
|
|||||||
foreach (const Platform &platform, platforms) {
|
foreach (const Platform &platform, platforms) {
|
||||||
ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains);
|
ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains);
|
||||||
if (!toolChain) {
|
if (!toolChain) {
|
||||||
ClangToolChain *newToolChain = createToolChain(platform);
|
toolChain = createToolChain(platform);
|
||||||
toolChains.append(newToolChain);
|
existingClangToolChains.append(toolChain);
|
||||||
existingClangToolChains.append(newToolChain);
|
|
||||||
}
|
}
|
||||||
|
toolChains.append(toolChain);
|
||||||
}
|
}
|
||||||
return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; });
|
return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; });
|
||||||
}
|
}
|
||||||
|
@@ -74,9 +74,8 @@ Core::IDocument::OpenResult ModelDocument::open(QString *errorString, const QStr
|
|||||||
{
|
{
|
||||||
Q_UNUSED(fileName);
|
Q_UNUSED(fileName);
|
||||||
|
|
||||||
if (!load(errorString, realFileName))
|
OpenResult result = load(errorString, realFileName);
|
||||||
return Core::IDocument::OpenResult::ReadError;
|
return result;
|
||||||
return Core::IDocument::OpenResult::Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelDocument::save(QString *errorString, const QString &name, bool autoSave)
|
bool ModelDocument::save(QString *errorString, const QString &name, bool autoSave)
|
||||||
@@ -143,7 +142,7 @@ ExtDocumentController *ModelDocument::documentController() const
|
|||||||
return d->documentController;
|
return d->documentController;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelDocument::load(QString *errorString, const QString &fileName)
|
Core::IDocument::OpenResult ModelDocument::load(QString *errorString, const QString &fileName)
|
||||||
{
|
{
|
||||||
d->documentController = ModelEditorPlugin::modelsManager()->createModel(this);
|
d->documentController = ModelEditorPlugin::modelsManager()->createModel(this);
|
||||||
connect(d->documentController, &qmt::DocumentController::changed, this, &IDocument::changed);
|
connect(d->documentController, &qmt::DocumentController::changed, this, &IDocument::changed);
|
||||||
@@ -151,13 +150,16 @@ bool ModelDocument::load(QString *errorString, const QString &fileName)
|
|||||||
try {
|
try {
|
||||||
d->documentController->loadProject(fileName);
|
d->documentController->loadProject(fileName);
|
||||||
setFilePath(Utils::FileName::fromString(d->documentController->getProjectController()->getProject()->getFileName()));
|
setFilePath(Utils::FileName::fromString(d->documentController->getProjectController()->getProject()->getFileName()));
|
||||||
} catch (const qmt::Exception &ex) {
|
} catch (const qmt::FileNotFoundException &ex) {
|
||||||
*errorString = ex.getErrorMsg();
|
*errorString = ex.getErrorMsg();
|
||||||
return false;
|
return OpenResult::ReadError;
|
||||||
|
} catch (const qmt::Exception &ex) {
|
||||||
|
*errorString = tr("Could not open \"%1\" for reading: %2.").arg(fileName).arg(ex.getErrorMsg());
|
||||||
|
return OpenResult::CannotHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit contentSet();
|
emit contentSet();
|
||||||
return true;
|
return OpenResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -54,7 +54,7 @@ signals:
|
|||||||
void contentSet();
|
void contentSet();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IDocument::OpenResult open(QString *errorString, const QString &fileName,
|
OpenResult open(QString *errorString, const QString &fileName,
|
||||||
const QString &realFileName) override;
|
const QString &realFileName) override;
|
||||||
bool save(QString *errorString, const QString &fileName, bool autoSave) override;
|
bool save(QString *errorString, const QString &fileName, bool autoSave) override;
|
||||||
QString defaultPath() const override;
|
QString defaultPath() const override;
|
||||||
@@ -65,7 +65,7 @@ public:
|
|||||||
|
|
||||||
ExtDocumentController *documentController() const;
|
ExtDocumentController *documentController() const;
|
||||||
|
|
||||||
bool load(QString *errorString, const QString &fileName);
|
OpenResult load(QString *errorString, const QString &fileName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModelDocumentPrivate *d;
|
ModelDocumentPrivate *d;
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
|
||||||
|
#include "buildconfiguration.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#include <coreplugin/id.h>
|
#include <coreplugin/id.h>
|
||||||
@@ -54,6 +55,14 @@ public:
|
|||||||
QString typeName;
|
QString typeName;
|
||||||
Utils::FileName buildDirectory;
|
Utils::FileName buildDirectory;
|
||||||
Core::Id kitId;
|
Core::Id kitId;
|
||||||
|
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
|
||||||
|
|
||||||
|
bool operator==(const BuildInfo &o)
|
||||||
|
{
|
||||||
|
return displayName == o.displayName && typeName == o.typeName
|
||||||
|
&& buildDirectory == o.buildDirectory && kitId == o.kitId
|
||||||
|
&& buildType == o.buildType;
|
||||||
|
}
|
||||||
|
|
||||||
virtual QList<Task> reportIssues(const QString &projectPath,
|
virtual QList<Task> reportIssues(const QString &projectPath,
|
||||||
const QString &buildDir) const
|
const QString &buildDir) const
|
||||||
|
@@ -779,10 +779,13 @@ QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alr
|
|||||||
QList<ToolChain *> tcs;
|
QList<ToolChain *> tcs;
|
||||||
if (HostOsInfo::isMacHost()) {
|
if (HostOsInfo::isMacHost()) {
|
||||||
// Old mac compilers needed to support macx-gccXY mkspecs:
|
// Old mac compilers needed to support macx-gccXY mkspecs:
|
||||||
tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi(), alreadyKnown));
|
tcs.append(autoDetectToolchains(QLatin1String("g++-4.0"), Abi::hostAbi(),
|
||||||
tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi(), alreadyKnown));
|
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
|
||||||
|
tcs.append(autoDetectToolchains(QLatin1String("g++-4.2"), Abi::hostAbi(),
|
||||||
|
Constants::GCC_TOOLCHAIN_TYPEID, alreadyKnown));
|
||||||
}
|
}
|
||||||
tcs.append(autoDetectToolchains(QLatin1String("g++"), Abi::hostAbi(), alreadyKnown));
|
tcs.append(autoDetectToolchains(QLatin1String("g++"), Abi::hostAbi(),
|
||||||
|
Constants::GCC_TOOLCHAIN_TYPEID,alreadyKnown));
|
||||||
|
|
||||||
return tcs;
|
return tcs;
|
||||||
}
|
}
|
||||||
@@ -810,6 +813,7 @@ GccToolChain *GccToolChainFactory::createToolChain(bool autoDetect)
|
|||||||
|
|
||||||
QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &compiler,
|
QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &compiler,
|
||||||
const Abi &requiredAbi,
|
const Abi &requiredAbi,
|
||||||
|
const Core::Id requiredTypeId,
|
||||||
const QList<ToolChain *> &alreadyKnown)
|
const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
QList<ToolChain *> result;
|
QList<ToolChain *> result;
|
||||||
@@ -819,7 +823,11 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(const QString &comp
|
|||||||
if (compilerPath.isEmpty())
|
if (compilerPath.isEmpty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (Utils::findOrDefault(alreadyKnown, Utils::equal(&ToolChain::compilerCommand, compilerPath)))
|
result = Utils::filtered(alreadyKnown, [requiredTypeId, compilerPath](ToolChain *tc) {
|
||||||
|
return tc->typeId() == requiredTypeId
|
||||||
|
&& tc->compilerCommand() == compilerPath;
|
||||||
|
});
|
||||||
|
if (!result.isEmpty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
|
GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
|
||||||
@@ -1113,7 +1121,8 @@ ClangToolChainFactory::ClangToolChainFactory()
|
|||||||
|
|
||||||
QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
return autoDetectToolchains(QLatin1String("clang++"), Abi::hostAbi(), alreadyKnown);
|
return autoDetectToolchains(QLatin1String("clang++"), Abi::hostAbi(),
|
||||||
|
Constants::CLANG_TOOLCHAIN_TYPEID, alreadyKnown);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangToolChainFactory::canRestore(const QVariantMap &data)
|
bool ClangToolChainFactory::canRestore(const QVariantMap &data)
|
||||||
@@ -1193,7 +1202,8 @@ QList<ToolChain *> MingwToolChainFactory::autoDetect(const QList<ToolChain *> &a
|
|||||||
{
|
{
|
||||||
Abi ha = Abi::hostAbi();
|
Abi ha = Abi::hostAbi();
|
||||||
ha = Abi(ha.architecture(), Abi::WindowsOS, Abi::WindowsMSysFlavor, Abi::PEFormat, ha.wordWidth());
|
ha = Abi(ha.architecture(), Abi::WindowsOS, Abi::WindowsMSysFlavor, Abi::PEFormat, ha.wordWidth());
|
||||||
return autoDetectToolchains(QLatin1String("g++"), ha, alreadyKnown);
|
return autoDetectToolchains(QLatin1String("g++"), ha,
|
||||||
|
Constants::MINGW_TOOLCHAIN_TYPEID, alreadyKnown);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MingwToolChainFactory::canRestore(const QVariantMap &data)
|
bool MingwToolChainFactory::canRestore(const QVariantMap &data)
|
||||||
@@ -1268,7 +1278,8 @@ LinuxIccToolChainFactory::LinuxIccToolChainFactory()
|
|||||||
|
|
||||||
QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
return autoDetectToolchains(QLatin1String("icpc"), Abi::hostAbi(), alreadyKnown);
|
return autoDetectToolchains(QLatin1String("icpc"), Abi::hostAbi(),
|
||||||
|
Constants::LINUXICC_TOOLCHAIN_TYPEID, alreadyKnown);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxIccToolChainFactory::canRestore(const QVariantMap &data)
|
bool LinuxIccToolChainFactory::canRestore(const QVariantMap &data)
|
||||||
|
@@ -66,8 +66,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual GccToolChain *createToolChain(bool autoDetect);
|
virtual GccToolChain *createToolChain(bool autoDetect);
|
||||||
QList<ToolChain *> autoDetectToolchains(const QString &compiler,
|
QList<ToolChain *> autoDetectToolchains(const QString &compiler, const Abi &requiredAbi,
|
||||||
const Abi &,
|
const Core::Id requiredTypeId,
|
||||||
const QList<ToolChain *> &alreadyKnown);
|
const QList<ToolChain *> &alreadyKnown);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "msvcparser.h"
|
#include "msvcparser.h"
|
||||||
#include "projectexplorerconstants.h"
|
#include "projectexplorerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/synchronousprocess.h>
|
#include <utils/synchronousprocess.h>
|
||||||
#include <utils/winutils.h>
|
#include <utils/winutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -526,9 +527,26 @@ QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChai
|
|||||||
return vcVarsBatFor(basePath, platformName(platform));
|
return vcVarsBatFor(basePath, platformName(platform));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
|
||||||
|
const QString &name, const Abi &abi,
|
||||||
|
const QString &varsBat, const QString &varsBatArg,
|
||||||
|
ToolChain::Detection d = ToolChain::ManualDetection)
|
||||||
|
{
|
||||||
|
ToolChain *tc = Utils::findOrDefault(alreadyKnown,
|
||||||
|
[&varsBat, &varsBatArg](ToolChain *tc) -> bool {
|
||||||
|
if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||||
|
return false;
|
||||||
|
auto mtc = static_cast<MsvcToolChain *>(tc);
|
||||||
|
return mtc->varsBat() == varsBat
|
||||||
|
&& mtc->varsBatArg() == varsBatArg;
|
||||||
|
});
|
||||||
|
if (!tc)
|
||||||
|
tc = new MsvcToolChain(name, abi, varsBat, varsBatArg, d);
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
|
||||||
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
Q_UNUSED(alreadyKnown);
|
|
||||||
QList<ToolChain *> results;
|
QList<ToolChain *> results;
|
||||||
|
|
||||||
// 1) Installed SDKs preferred over standalone Visual studio
|
// 1) Installed SDKs preferred over standalone Visual studio
|
||||||
@@ -550,16 +568,19 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
QList<ToolChain *> tmp;
|
QList<ToolChain *> tmp;
|
||||||
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
|
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey),
|
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::x86),
|
||||||
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection));
|
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::x86, sdkKey),
|
||||||
|
fi.absoluteFilePath(), QLatin1String("/x86"), ToolChain::AutoDetection));
|
||||||
// Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
|
// Add all platforms, cross-compiler is automatically selected by SetEnv.cmd if needed
|
||||||
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
|
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey),
|
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::amd64),
|
||||||
fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection));
|
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::amd64, sdkKey),
|
||||||
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
|
fi.absoluteFilePath(), QLatin1String("/x64"), ToolChain::AutoDetection));
|
||||||
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey),
|
tmp.append(findOrCreateToolChain(alreadyKnown,
|
||||||
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection));
|
generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
|
||||||
|
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, sdkKey),
|
||||||
|
fi.absoluteFilePath(), QLatin1String("/ia64"), ToolChain::AutoDetection));
|
||||||
// Make sure the default is front.
|
// Make sure the default is front.
|
||||||
if (folder == defaultSdkPath)
|
if (folder == defaultSdkPath)
|
||||||
results = tmp + results;
|
results = tmp + results;
|
||||||
@@ -601,11 +622,11 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
|||||||
foreach (const MsvcToolChain::Platform &platform, platforms) {
|
foreach (const MsvcToolChain::Platform &platform, platforms) {
|
||||||
if (hostSupportsPlatform(platform)
|
if (hostSupportsPlatform(platform)
|
||||||
&& QFileInfo(vcVarsBatFor(path, platform)).isFile()) {
|
&& QFileInfo(vcVarsBatFor(path, platform)).isFile()) {
|
||||||
results.append(new MsvcToolChain(
|
results.append(findOrCreateToolChain(
|
||||||
|
alreadyKnown,
|
||||||
generateDisplayName(vsName, MsvcToolChain::VS, platform),
|
generateDisplayName(vsName, MsvcToolChain::VS, platform),
|
||||||
findAbiOfMsvc(MsvcToolChain::VS, platform, vsName),
|
findAbiOfMsvc(MsvcToolChain::VS, platform, vsName),
|
||||||
vcvarsAllbat,
|
vcvarsAllbat, platformName(platform),
|
||||||
platformName(platform),
|
|
||||||
ToolChain::AutoDetection));
|
ToolChain::AutoDetection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -85,7 +85,7 @@
|
|||||||
#include "taskhub.h"
|
#include "taskhub.h"
|
||||||
#include "customtoolchain.h"
|
#include "customtoolchain.h"
|
||||||
#include "selectablefilesmodel.h"
|
#include "selectablefilesmodel.h"
|
||||||
#include <projectexplorer/customwizard/customwizard.h>
|
#include "customwizard/customwizard.h"
|
||||||
#include "devicesupport/desktopdevice.h"
|
#include "devicesupport/desktopdevice.h"
|
||||||
#include "devicesupport/desktopdevicefactory.h"
|
#include "devicesupport/desktopdevicefactory.h"
|
||||||
#include "devicesupport/devicemanager.h"
|
#include "devicesupport/devicemanager.h"
|
||||||
@@ -106,7 +106,6 @@
|
|||||||
#include <extensionsystem/pluginspec.h>
|
#include <extensionsystem/pluginspec.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/editormanager/ieditor.h>
|
|
||||||
#include <coreplugin/id.h>
|
#include <coreplugin/id.h>
|
||||||
#include <coreplugin/idocumentfactory.h>
|
#include <coreplugin/idocumentfactory.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
@@ -117,7 +116,6 @@
|
|||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/infobar.h>
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/findplaceholder.h>
|
#include <coreplugin/findplaceholder.h>
|
||||||
#include <coreplugin/vcsmanager.h>
|
#include <coreplugin/vcsmanager.h>
|
||||||
@@ -143,11 +141,11 @@
|
|||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QWizard>
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\namespace ProjectExplorer
|
\namespace ProjectExplorer
|
||||||
@@ -3141,7 +3139,8 @@ void ProjectExplorerPluginPrivate::handleAddExistingFiles()
|
|||||||
tr("Add Existing Files"), directoryFor(ProjectTree::currentNode()));
|
tr("Add Existing Files"), directoryFor(ProjectTree::currentNode()));
|
||||||
if (fileNames.isEmpty())
|
if (fileNames.isEmpty())
|
||||||
return;
|
return;
|
||||||
ProjectExplorerPlugin::addExistingFiles(fileNames, folderNode);
|
|
||||||
|
ProjectExplorerPlugin::addExistingFiles(folderNode, fileNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorerPluginPrivate::addExistingDirectory()
|
void ProjectExplorerPluginPrivate::addExistingDirectory()
|
||||||
@@ -3154,12 +3153,7 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
|
|||||||
SelectableFilesDialogAddDirectory dialog(directoryFor(ProjectTree::currentNode()), QStringList(), ICore::mainWindow());
|
SelectableFilesDialogAddDirectory dialog(directoryFor(ProjectTree::currentNode()), QStringList(), ICore::mainWindow());
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
ProjectExplorerPlugin::addExistingFiles(dialog.selectedFiles(), folderNode);
|
ProjectExplorerPlugin::addExistingFiles(folderNode, dialog.selectedFiles());
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths, FolderNode *folderNode)
|
|
||||||
{
|
|
||||||
addExistingFiles(folderNode, filePaths);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStringList &filePaths)
|
void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStringList &filePaths)
|
||||||
@@ -3173,13 +3167,15 @@ void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStri
|
|||||||
folderNode->addFiles(fileNames, ¬Added);
|
folderNode->addFiles(fileNames, ¬Added);
|
||||||
|
|
||||||
if (!notAdded.isEmpty()) {
|
if (!notAdded.isEmpty()) {
|
||||||
QString message = tr("Could not add following files to project %1:").arg(folderNode->projectNode()->displayName());
|
const QString message = tr("Could not add following files to project %1:")
|
||||||
message += QLatin1Char('\n');
|
.arg(folderNode->projectNode()->displayName()) + QLatin1Char('\n');
|
||||||
QString files = notAdded.join(QLatin1Char('\n'));
|
const QStringList nativeFiles
|
||||||
|
= Utils::transform(notAdded,
|
||||||
|
[](const QString &f) { return QDir::toNativeSeparators(f); });
|
||||||
QMessageBox::warning(ICore::mainWindow(), tr("Adding Files to Project Failed"),
|
QMessageBox::warning(ICore::mainWindow(), tr("Adding Files to Project Failed"),
|
||||||
message + files);
|
message + nativeFiles.join(QLatin1Char('\n')));
|
||||||
foreach (const QString &file, notAdded)
|
fileNames = Utils::filtered(fileNames,
|
||||||
fileNames.removeOne(file);
|
[¬Added](const QString &f) { return !notAdded.contains(f); });
|
||||||
}
|
}
|
||||||
|
|
||||||
VcsManager::promptToAdd(dir, fileNames);
|
VcsManager::promptToAdd(dir, fileNames);
|
||||||
@@ -3245,7 +3241,9 @@ void ProjectExplorerPluginPrivate::removeFile()
|
|||||||
|
|
||||||
if (!folderNode->removeFiles(QStringList(filePath))) {
|
if (!folderNode->removeFiles(QStringList(filePath))) {
|
||||||
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
|
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
|
||||||
tr("Could not remove file %1 from project %2.").arg(filePath).arg(folderNode->projectNode()->displayName()));
|
tr("Could not remove file %1 from project %2.")
|
||||||
|
.arg(QDir::toNativeSeparators(filePath))
|
||||||
|
.arg(folderNode->projectNode()->displayName()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3266,7 +3264,8 @@ void ProjectExplorerPluginPrivate::deleteFile()
|
|||||||
QMessageBox::StandardButton button =
|
QMessageBox::StandardButton button =
|
||||||
QMessageBox::question(ICore::mainWindow(),
|
QMessageBox::question(ICore::mainWindow(),
|
||||||
tr("Delete File"),
|
tr("Delete File"),
|
||||||
tr("Delete %1 from file system?").arg(filePath),
|
tr("Delete %1 from file system?")
|
||||||
|
.arg(QDir::toNativeSeparators(filePath)),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
if (button != QMessageBox::Yes)
|
if (button != QMessageBox::Yes)
|
||||||
return;
|
return;
|
||||||
@@ -3285,7 +3284,8 @@ void ProjectExplorerPluginPrivate::deleteFile()
|
|||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!file.remove())
|
if (!file.remove())
|
||||||
QMessageBox::warning(ICore::mainWindow(), tr("Deleting File Failed"),
|
QMessageBox::warning(ICore::mainWindow(), tr("Deleting File Failed"),
|
||||||
tr("Could not delete file %1.").arg(filePath));
|
tr("Could not delete file %1.")
|
||||||
|
.arg(QDir::toNativeSeparators(filePath)));
|
||||||
}
|
}
|
||||||
DocumentManager::unexpectFileChange(filePath);
|
DocumentManager::unexpectFileChange(filePath);
|
||||||
}
|
}
|
||||||
@@ -3309,7 +3309,6 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
|||||||
FolderNode *folderNode = node->parentFolderNode();
|
FolderNode *folderNode = node->parentFolderNode();
|
||||||
QString projectFileName = folderNode->projectNode()->path().fileName();
|
QString projectFileName = folderNode->projectNode()->path().fileName();
|
||||||
|
|
||||||
|
|
||||||
if (!folderNode->canRenameFile(orgFilePath, newFilePath)) {
|
if (!folderNode->canRenameFile(orgFilePath, newFilePath)) {
|
||||||
QTimer::singleShot(0, [orgFilePath, newFilePath, projectFileName] {
|
QTimer::singleShot(0, [orgFilePath, newFilePath, projectFileName] {
|
||||||
int res = QMessageBox::question(ICore::mainWindow(),
|
int res = QMessageBox::question(ICore::mainWindow(),
|
||||||
@@ -3317,8 +3316,8 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
|||||||
tr("The project file %1 cannot be automatically changed.\n\n"
|
tr("The project file %1 cannot be automatically changed.\n\n"
|
||||||
"Rename %2 to %3 anyway?")
|
"Rename %2 to %3 anyway?")
|
||||||
.arg(projectFileName)
|
.arg(projectFileName)
|
||||||
.arg(orgFilePath)
|
.arg(QDir::toNativeSeparators(orgFilePath))
|
||||||
.arg(newFilePath));
|
.arg(QDir::toNativeSeparators(newFilePath)));
|
||||||
if (res == QMessageBox::Yes)
|
if (res == QMessageBox::Yes)
|
||||||
FileUtils::renameFile(orgFilePath, newFilePath);
|
FileUtils::renameFile(orgFilePath, newFilePath);
|
||||||
|
|
||||||
@@ -3329,9 +3328,10 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
|||||||
if (FileUtils::renameFile(orgFilePath, newFilePath)) {
|
if (FileUtils::renameFile(orgFilePath, newFilePath)) {
|
||||||
// Tell the project plugin about rename
|
// Tell the project plugin about rename
|
||||||
if (!folderNode->renameFile(orgFilePath, newFilePath)) {
|
if (!folderNode->renameFile(orgFilePath, newFilePath)) {
|
||||||
QString renameFileError = tr("The file %1 was renamed to %2, but the project file %3 could not be automatically changed.")
|
const QString renameFileError
|
||||||
.arg(orgFilePath)
|
= tr("The file %1 was renamed to %2, but the project file %3 could not be automatically changed.")
|
||||||
.arg(newFilePath)
|
.arg(QDir::toNativeSeparators(orgFilePath))
|
||||||
|
.arg(QDir::toNativeSeparators(newFilePath))
|
||||||
.arg(projectFileName);
|
.arg(projectFileName);
|
||||||
|
|
||||||
QTimer::singleShot(0, [renameFileError]() {
|
QTimer::singleShot(0, [renameFileError]() {
|
||||||
@@ -3340,6 +3340,16 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
|||||||
renameFileError);
|
renameFileError);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const QString renameFileError = tr("The file %1 could not be renamed %2.")
|
||||||
|
.arg(QDir::toNativeSeparators(orgFilePath))
|
||||||
|
.arg(QDir::toNativeSeparators(newFilePath));
|
||||||
|
|
||||||
|
QTimer::singleShot(0, [renameFileError]() {
|
||||||
|
QMessageBox::warning(ICore::mainWindow(),
|
||||||
|
tr("Cannot Rename File"),
|
||||||
|
renameFileError);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -144,8 +144,7 @@ public:
|
|||||||
static void runRunConfiguration(RunConfiguration *rc, Core::Id runMode,
|
static void runRunConfiguration(RunConfiguration *rc, Core::Id runMode,
|
||||||
const bool forceSkipDeploy = false);
|
const bool forceSkipDeploy = false);
|
||||||
|
|
||||||
static void addExistingFiles(FolderNode *projectNode, const QStringList &filePaths);
|
static void addExistingFiles(FolderNode *folderNode, const QStringList &filePaths);
|
||||||
static void addExistingFiles(const QStringList &filePaths, FolderNode *folderNode);
|
|
||||||
|
|
||||||
static void buildProject(Project *p);
|
static void buildProject(Project *p);
|
||||||
/// Normally there's no need to call this function.
|
/// Normally there's no need to call this function.
|
||||||
@@ -219,6 +218,9 @@ private slots:
|
|||||||
void testAbiFromTargetTriplet();
|
void testAbiFromTargetTriplet();
|
||||||
|
|
||||||
void testDeviceManager();
|
void testDeviceManager();
|
||||||
|
|
||||||
|
void testToolChainManager_data();
|
||||||
|
void testToolChainManager();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -35,7 +35,8 @@
|
|||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
ProjectMacroExpander::ProjectMacroExpander(const QString &projectName,
|
ProjectMacroExpander::ProjectMacroExpander(const QString &projectName,
|
||||||
const Kit *kit, const QString &bcName)
|
const Kit *kit, const QString &bcName,
|
||||||
|
BuildConfiguration::BuildType buildType)
|
||||||
{
|
{
|
||||||
registerVariable(Constants::VAR_CURRENTPROJECT_NAME,
|
registerVariable(Constants::VAR_CURRENTPROJECT_NAME,
|
||||||
QCoreApplication::translate("ProjectExplorer", "Name of current project"),
|
QCoreApplication::translate("ProjectExplorer", "Name of current project"),
|
||||||
@@ -45,6 +46,10 @@ ProjectMacroExpander::ProjectMacroExpander(const QString &projectName,
|
|||||||
QCoreApplication::translate("ProjectExplorer", "Name of current build"),
|
QCoreApplication::translate("ProjectExplorer", "Name of current build"),
|
||||||
[bcName] { return bcName; });
|
[bcName] { return bcName; });
|
||||||
|
|
||||||
|
registerVariable(Constants::VAR_CURRENTBUILD_TYPE,
|
||||||
|
QCoreApplication::translate("ProjectExplorer", "Type of current build"),
|
||||||
|
[buildType] { return BuildConfiguration::buildTypeName(buildType); });
|
||||||
|
|
||||||
registerSubProvider([kit] { return kit->macroExpander(); });
|
registerSubProvider([kit] { return kit->macroExpander(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,9 @@
|
|||||||
#define PROJECTMACROEXPANDER_H
|
#define PROJECTMACROEXPANDER_H
|
||||||
|
|
||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
|
||||||
|
#include "buildconfiguration.h"
|
||||||
|
|
||||||
#include <utils/macroexpander.h>
|
#include <utils/macroexpander.h>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -40,7 +43,8 @@ class Kit;
|
|||||||
class PROJECTEXPLORER_EXPORT ProjectMacroExpander : public Utils::MacroExpander
|
class PROJECTEXPLORER_EXPORT ProjectMacroExpander : public Utils::MacroExpander
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectMacroExpander(const QString &projectName, const Kit *kit, const QString &bcName);
|
ProjectMacroExpander(const QString &projectName, const Kit *kit, const QString &bcName,
|
||||||
|
BuildConfiguration::BuildType buildType);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -278,6 +278,7 @@ int ProjectTreeWidget::expandedCount(Node *node)
|
|||||||
void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int end)
|
void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||||
{
|
{
|
||||||
Node *node = m_model->nodeForIndex(parent);
|
Node *node = m_model->nodeForIndex(parent);
|
||||||
|
QTC_ASSERT(node, return);
|
||||||
const QString path = node->path().toString();
|
const QString path = node->path().toString();
|
||||||
const QString displayName = node->displayName();
|
const QString displayName = node->displayName();
|
||||||
|
|
||||||
|
@@ -50,7 +50,6 @@ static const char TOOLCHAIN_DATA_KEY[] = "ToolChain.";
|
|||||||
static const char TOOLCHAIN_COUNT_KEY[] = "ToolChain.Count";
|
static const char TOOLCHAIN_COUNT_KEY[] = "ToolChain.Count";
|
||||||
static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version";
|
static const char TOOLCHAIN_FILE_VERSION_KEY[] = "Version";
|
||||||
static const char TOOLCHAIN_FILENAME[] = "/qtcreator/toolchains.xml";
|
static const char TOOLCHAIN_FILENAME[] = "/qtcreator/toolchains.xml";
|
||||||
static const char LEGACY_TOOLCHAIN_FILENAME[] = "/toolChains.xml";
|
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -167,98 +166,146 @@ static QList<ToolChain *> restoreFromFile(const FileName &fileName)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> autoDetectToolChains(const QList<ToolChain *> alreadyKnownTcs)
|
||||||
|
{
|
||||||
|
QList<ToolChain *> result;
|
||||||
|
const QList<ToolChainFactory *> factories
|
||||||
|
= ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
|
||||||
|
foreach (ToolChainFactory *f, factories)
|
||||||
|
result.append(f->autoDetect(alreadyKnownTcs));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> subtractByEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
|
||||||
|
{
|
||||||
|
return Utils::filtered(a, [&b](ToolChain *atc) {
|
||||||
|
return !Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> subtractByPointerEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
|
||||||
|
{
|
||||||
|
return Utils::filtered(a, [&b](ToolChain *atc) { return !b.contains(atc); });
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> subtractById(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
|
||||||
|
{
|
||||||
|
return Utils::filtered(a, [&b](ToolChain *atc) {
|
||||||
|
return !Utils::anyOf(b, Utils::equal(&ToolChain::id, atc->id()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> intersectByEqual(const QList<ToolChain *> &a, const QList<ToolChain *> &b)
|
||||||
|
{
|
||||||
|
return Utils::filtered(a, [&b](ToolChain *atc) {
|
||||||
|
return Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ToolChain *> makeUnique(const QList<ToolChain *> &a)
|
||||||
|
{
|
||||||
|
return QSet<ToolChain *>::fromList(a).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ToolChainOperations
|
||||||
|
{
|
||||||
|
QList<ToolChain *> toDemote;
|
||||||
|
QList<ToolChain *> toRegister;
|
||||||
|
QList<ToolChain *> toDelete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static ToolChainOperations mergeToolChainLists(const QList<ToolChain *> &systemFileTcs,
|
||||||
|
const QList<ToolChain *> &userFileTcs,
|
||||||
|
const QList<ToolChain *> &autodetectedTcs)
|
||||||
|
{
|
||||||
|
const QList<ToolChain *> manualUserTcs
|
||||||
|
= Utils::filtered(userFileTcs, [](ToolChain *t) { return !t->isAutoDetected(); });
|
||||||
|
|
||||||
|
// Remove systemFileTcs from autodetectedUserTcs based on id-matches:
|
||||||
|
const QList<ToolChain *> autodetectedUserFileTcs
|
||||||
|
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
|
||||||
|
const QList<ToolChain *> autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs);
|
||||||
|
|
||||||
|
// Calculate a set of Tcs that were detected before (and saved to userFile) and that
|
||||||
|
// got re-detected again. Take the userTcs (to keep Ids) over the same in autodetectedTcs.
|
||||||
|
const QList<ToolChain *> redetectedUserTcs
|
||||||
|
= intersectByEqual(autodetectedUserTcs, autodetectedTcs);
|
||||||
|
|
||||||
|
// Remove redetected tcs from autodetectedUserTcs:
|
||||||
|
const QList<ToolChain *> notRedetectedUserTcs
|
||||||
|
= subtractByPointerEqual(autodetectedUserTcs, redetectedUserTcs);
|
||||||
|
|
||||||
|
// Remove redetected tcs from autodetectedTcs:
|
||||||
|
const QList<ToolChain *> newlyAutodetectedTcs
|
||||||
|
= subtractByEqual(autodetectedTcs, redetectedUserTcs);
|
||||||
|
|
||||||
|
const QList<ToolChain *> notRedetectedButValidUserTcs
|
||||||
|
= Utils::filtered(notRedetectedUserTcs, &ToolChain::isValid);
|
||||||
|
|
||||||
|
const QList<ToolChain *> validManualUserTcs
|
||||||
|
= Utils::filtered(manualUserTcs, &ToolChain::isValid);
|
||||||
|
|
||||||
|
ToolChainOperations result;
|
||||||
|
result.toDemote = notRedetectedButValidUserTcs;
|
||||||
|
result.toRegister = result.toDemote + systemFileTcs + redetectedUserTcs + newlyAutodetectedTcs
|
||||||
|
+ validManualUserTcs;
|
||||||
|
|
||||||
|
result.toDelete = makeUnique(subtractByPointerEqual(systemFileTcs + userFileTcs + autodetectedTcs,
|
||||||
|
result.toRegister));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void ToolChainManager::restoreToolChains()
|
void ToolChainManager::restoreToolChains()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!d->m_writer, return);
|
QTC_ASSERT(!d->m_writer, return);
|
||||||
d->m_writer =
|
d->m_writer =
|
||||||
new PersistentSettingsWriter(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)), QLatin1String("QtCreatorToolChains"));
|
new PersistentSettingsWriter(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)),
|
||||||
|
QLatin1String("QtCreatorToolChains"));
|
||||||
QList<ToolChain *> tcsToRegister;
|
|
||||||
QList<ToolChain *> tcsToCheck;
|
|
||||||
|
|
||||||
// read all tool chains from SDK
|
// read all tool chains from SDK
|
||||||
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
|
const QList<ToolChain *> systemFileTcs = readSystemFileToolChains();
|
||||||
QList<ToolChain *> readTcs =
|
|
||||||
restoreFromFile(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME)));
|
|
||||||
// make sure we mark these as autodetected!
|
|
||||||
foreach (ToolChain *tc, readTcs)
|
|
||||||
tc->setDetection(ToolChain::AutoDetection);
|
|
||||||
|
|
||||||
tcsToRegister = readTcs; // SDK TCs are always considered to be up-to-date, so no need to
|
|
||||||
// recheck them.
|
|
||||||
|
|
||||||
// read all tool chains from user file.
|
// read all tool chains from user file.
|
||||||
// Read legacy settings once and keep them around...
|
const QList<ToolChain *> userFileTcs
|
||||||
FileName fileName = settingsFileName(QLatin1String(TOOLCHAIN_FILENAME));
|
= restoreFromFile(settingsFileName(QLatin1String(TOOLCHAIN_FILENAME)));
|
||||||
if (!fileName.exists())
|
|
||||||
fileName = settingsFileName(QLatin1String(LEGACY_TOOLCHAIN_FILENAME));
|
|
||||||
readTcs = restoreFromFile(fileName);
|
|
||||||
|
|
||||||
foreach (ToolChain *tc, readTcs) {
|
// Autodetect: Pass autodetected toolchains from user file so the information can be reused:
|
||||||
if (tc->isAutoDetected())
|
const QList<ToolChain *> autodetectedUserFileTcs
|
||||||
tcsToCheck.append(tc);
|
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
|
||||||
else
|
const QList<ToolChain *> autodetectedTcs = autoDetectToolChains(autodetectedUserFileTcs);
|
||||||
tcsToRegister.append(tc);
|
|
||||||
}
|
|
||||||
readTcs.clear();
|
|
||||||
|
|
||||||
// Remove TCs configured by the SDK:
|
// merge tool chains and register those that we need to keep:
|
||||||
foreach (ToolChain *tc, tcsToRegister) {
|
ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
||||||
for (int i = tcsToCheck.count() - 1; i >= 0; --i) {
|
|
||||||
if (tcsToCheck.at(i)->id() == tc->id()) {
|
|
||||||
delete tcsToCheck.at(i);
|
|
||||||
tcsToCheck.removeAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then auto detect
|
// Process ops:
|
||||||
QList<ToolChain *> detectedTcs = tcsToCheck;
|
foreach (ToolChain *tc, ops.toDemote)
|
||||||
QList<ToolChainFactory *> factories = ExtensionSystem::PluginManager::getObjects<ToolChainFactory>();
|
tc->setDetection(ToolChain::ManualDetection);
|
||||||
foreach (ToolChainFactory *f, factories)
|
|
||||||
detectedTcs.append(f->autoDetect(tcsToCheck));
|
|
||||||
|
|
||||||
// Find/update autodetected tool chains:
|
foreach (ToolChain *tc, ops.toRegister)
|
||||||
ToolChain *toStore = 0;
|
|
||||||
foreach (ToolChain *currentDetected, detectedTcs) {
|
|
||||||
toStore = currentDetected;
|
|
||||||
|
|
||||||
// Check whether we had this TC stored and prefer the old one with the old id, marked
|
|
||||||
// as auto-detection.
|
|
||||||
for (int i = 0; i < tcsToCheck.count(); ++i) {
|
|
||||||
if (tcsToCheck.at(i) == currentDetected) {
|
|
||||||
tcsToCheck.removeAt(i);
|
|
||||||
break;
|
|
||||||
} else if (*(tcsToCheck.at(i)) == *currentDetected) {
|
|
||||||
toStore = tcsToCheck.at(i);
|
|
||||||
toStore->setDetection(ToolChain::AutoDetection);
|
|
||||||
tcsToCheck.removeAt(i);
|
|
||||||
delete currentDetected;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcsToRegister += toStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep toolchains that were not rediscovered but are still executable and delete the rest
|
|
||||||
foreach (ToolChain *tc, tcsToCheck) {
|
|
||||||
if (!tc->isValid()) {
|
|
||||||
qWarning() << QString::fromLatin1("ToolChain \"%1\" (%2) dropped since it is not valid")
|
|
||||||
.arg(tc->displayName()).arg(QString::fromUtf8(tc->id()));
|
|
||||||
delete tc;
|
|
||||||
} else {
|
|
||||||
tc->setDetection(ToolChain::ManualDetection); // "demote" to manual toolchain
|
|
||||||
tcsToRegister += tc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store manual tool chains
|
|
||||||
foreach (ToolChain *tc, tcsToRegister)
|
|
||||||
registerToolChain(tc);
|
registerToolChain(tc);
|
||||||
|
|
||||||
|
qDeleteAll(ops.toDelete);
|
||||||
|
|
||||||
emit m_instance->toolChainsLoaded();
|
emit m_instance->toolChainsLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<ToolChain *> ToolChainManager::readSystemFileToolChains()
|
||||||
|
{
|
||||||
|
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
|
||||||
|
QList<ToolChain *> systemTcs
|
||||||
|
= restoreFromFile(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(TOOLCHAIN_FILENAME)));
|
||||||
|
|
||||||
|
foreach (ToolChain *tc, systemTcs)
|
||||||
|
tc->setDetection(ToolChain::AutoDetection);
|
||||||
|
|
||||||
|
return systemTcs;
|
||||||
|
}
|
||||||
|
|
||||||
void ToolChainManager::saveToolChains()
|
void ToolChainManager::saveToolChains()
|
||||||
{
|
{
|
||||||
QVariantMap data;
|
QVariantMap data;
|
||||||
@@ -360,3 +407,193 @@ void ToolChainManager::deregisterToolChain(ToolChain *tc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
#include "projectexplorer.h"
|
||||||
|
|
||||||
|
#include "headerpath.h"
|
||||||
|
|
||||||
|
#include <QSet>
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
typedef QList<ToolChain *> TCList;
|
||||||
|
|
||||||
|
class TTC : public ToolChain
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TTC(ToolChain::Detection d, const QByteArray &t, bool v = true) :
|
||||||
|
ToolChain("TestToolChainType", d),
|
||||||
|
token(t),
|
||||||
|
m_valid(v)
|
||||||
|
{ m_toolChains.append(this); }
|
||||||
|
|
||||||
|
static QList<TTC *> toolChains();
|
||||||
|
static bool hasToolChains() { return !m_toolChains.isEmpty(); }
|
||||||
|
|
||||||
|
QString typeDisplayName() const override { return QLatin1String("Test Tool Chain"); }
|
||||||
|
Abi targetAbi() const override { return Abi::hostAbi(); }
|
||||||
|
bool isValid() const override { return m_valid; }
|
||||||
|
QByteArray predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return QByteArray(); }
|
||||||
|
CompilerFlags compilerFlags(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return NoFlags; }
|
||||||
|
WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return 0; }
|
||||||
|
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags, const FileName &sysRoot) const override
|
||||||
|
{ Q_UNUSED(cxxflags); Q_UNUSED(sysRoot); return QList<HeaderPath>(); }
|
||||||
|
void addToEnvironment(Environment &env) const override { Q_UNUSED(env); }
|
||||||
|
QString makeCommand(const Environment &env) const override { Q_UNUSED(env); return QLatin1String("make"); }
|
||||||
|
FileName compilerCommand() const override { return Utils::FileName::fromString(QLatin1String("/tmp/test/gcc")); }
|
||||||
|
IOutputParser *outputParser() const override { return 0; }
|
||||||
|
ToolChainConfigWidget *configurationWidget() override { return 0; }
|
||||||
|
TTC *clone() const override { return new TTC(*this); }
|
||||||
|
bool operator ==(const ToolChain &other) const override {
|
||||||
|
if (!ToolChain::operator==(other))
|
||||||
|
return false;
|
||||||
|
return static_cast<const TTC *>(&other)->token == token;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray token;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TTC(const TTC &other) :
|
||||||
|
ToolChain(other)
|
||||||
|
{ token = other.token; }
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
|
|
||||||
|
static QList<TTC *> m_toolChains;
|
||||||
|
|
||||||
|
// ToolChain interface
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
QList<TTC *> TTC::m_toolChains;
|
||||||
|
|
||||||
|
} // namespace ProjectExplorer
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ProjectExplorer::ToolChain *)
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
void ProjectExplorerPlugin::testToolChainManager_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<TCList>("system");
|
||||||
|
QTest::addColumn<TCList>("user");
|
||||||
|
QTest::addColumn<TCList>("autodetect");
|
||||||
|
QTest::addColumn<TCList>("toDemote");
|
||||||
|
QTest::addColumn<TCList>("toRegister");
|
||||||
|
|
||||||
|
TTC *system1 = 0;
|
||||||
|
TTC *system1c = 0;
|
||||||
|
TTC *system2 = 0;
|
||||||
|
TTC *system3i = 0;
|
||||||
|
TTC *user1 = 0;
|
||||||
|
TTC *user1c = 0;
|
||||||
|
TTC *user3i = 0;
|
||||||
|
TTC *user2 = 0;
|
||||||
|
TTC *auto1 = 0;
|
||||||
|
TTC *auto1c = 0;
|
||||||
|
TTC *auto1_2 = 0;
|
||||||
|
TTC *auto2 = 0;
|
||||||
|
TTC *auto3i = 0;
|
||||||
|
|
||||||
|
if (!TTC::hasToolChains()) {
|
||||||
|
system1 = new TTC(ToolChain::AutoDetection, "system1"); Q_UNUSED(system1);
|
||||||
|
system1c = system1->clone(); Q_UNUSED(system1c);
|
||||||
|
system2 = new TTC(ToolChain::AutoDetection, "system2"); Q_UNUSED(system2);
|
||||||
|
system3i = new TTC(ToolChain::AutoDetection, "system3", false); Q_UNUSED(system3i);
|
||||||
|
user1 = new TTC(ToolChain::ManualDetection, "user1"); Q_UNUSED(user1);
|
||||||
|
user1c = user1->clone(); Q_UNUSED(user1c);
|
||||||
|
user2 = new TTC(ToolChain::ManualDetection, "user2"); Q_UNUSED(user2);
|
||||||
|
user3i = new TTC(ToolChain::ManualDetection, "user3", false); Q_UNUSED(user3i);
|
||||||
|
auto1 = new TTC(ToolChain::AutoDetectionFromSettings, "auto1"); Q_UNUSED(auto1);
|
||||||
|
auto1c = auto1->clone(); Q_UNUSED(auto1c);
|
||||||
|
auto1_2 = new TTC(ToolChain::AutoDetectionFromSettings, "auto1"); Q_UNUSED(auto1_2);
|
||||||
|
auto2 = new TTC(ToolChain::AutoDetectionFromSettings, "auto2"); Q_UNUSED(auto2);
|
||||||
|
auto3i = new TTC(ToolChain::AutoDetectionFromSettings, "auto3", false); Q_UNUSED(auto3i);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTest::newRow("no toolchains")
|
||||||
|
<< (TCList()) << (TCList()) << (TCList())
|
||||||
|
<< (TCList()) << (TCList());
|
||||||
|
|
||||||
|
QTest::newRow("System: system, no user")
|
||||||
|
<< (TCList() << system1) << (TCList()) << (TCList())
|
||||||
|
<< (TCList()) << (TCList() << system1);
|
||||||
|
QTest::newRow("System: system, user")
|
||||||
|
<< (TCList() << system1) << (TCList() << system1) << (TCList())
|
||||||
|
<< (TCList()) << (TCList() << system1);
|
||||||
|
QTest::newRow("System: no system, user") // keep, the user tool chain as it is still found
|
||||||
|
<< (TCList()) << (TCList() << system1) << (TCList())
|
||||||
|
<< (TCList() << system1) << (TCList() << system1);
|
||||||
|
QTest::newRow("System: no system, invalid user")
|
||||||
|
<< (TCList()) << (TCList() << system3i) << (TCList())
|
||||||
|
<< (TCList()) << (TCList());
|
||||||
|
|
||||||
|
QTest::newRow("Auto: no auto, user")
|
||||||
|
<< (TCList()) << (TCList() << auto1) << (TCList())
|
||||||
|
<< (TCList() << auto1) << (TCList() << auto1);
|
||||||
|
QTest::newRow("Auto: auto, no user")
|
||||||
|
<< (TCList()) << (TCList()) << (TCList() << auto1)
|
||||||
|
<< (TCList()) << (TCList() << auto1);
|
||||||
|
QTest::newRow("Auto: auto, user")
|
||||||
|
<< (TCList()) << (TCList() << auto1) << (TCList() << auto1)
|
||||||
|
<< (TCList()) << (TCList() << auto1);
|
||||||
|
QTest::newRow("Auto: auto-redetect, user")
|
||||||
|
<< (TCList()) << (TCList() << auto1) << (TCList() << auto1_2)
|
||||||
|
<< (TCList()) << (TCList() << auto1);
|
||||||
|
QTest::newRow("Auto: (no) auto, invalid user")
|
||||||
|
<< (TCList()) << (TCList() << auto3i) << (TCList())
|
||||||
|
<< (TCList()) << (TCList());
|
||||||
|
|
||||||
|
QTest::newRow("Delete invalid user")
|
||||||
|
<< (TCList()) << (TCList() << user3i) << (TCList())
|
||||||
|
<< (TCList()) << (TCList());
|
||||||
|
|
||||||
|
QTest::newRow("one of everything")
|
||||||
|
<< (TCList() << system1) << (TCList() << user1) << (TCList() << auto1)
|
||||||
|
<< (TCList()) << (TCList() << system1 << user1 << auto1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectExplorerPlugin::testToolChainManager()
|
||||||
|
{
|
||||||
|
QFETCH(TCList, system);
|
||||||
|
QFETCH(TCList, user);
|
||||||
|
QFETCH(TCList, autodetect);
|
||||||
|
QFETCH(TCList, toRegister);
|
||||||
|
QFETCH(TCList, toDemote);
|
||||||
|
|
||||||
|
ToolChainOperations ops = mergeToolChainLists(system, user, autodetect);
|
||||||
|
|
||||||
|
QSet<ToolChain *> expToRegister = QSet<ToolChain *>::fromList(toRegister);
|
||||||
|
QSet<ToolChain *> expToDemote = QSet<ToolChain *>::fromList(toDemote);
|
||||||
|
|
||||||
|
QSet<ToolChain *> actToRegister = QSet<ToolChain *>::fromList(ops.toRegister);
|
||||||
|
QSet<ToolChain *> actToDemote = QSet<ToolChain *>::fromList(ops.toDemote);
|
||||||
|
QSet<ToolChain *> actToDelete = QSet<ToolChain *>::fromList(ops.toDelete);
|
||||||
|
|
||||||
|
QCOMPARE(actToRegister.count(), ops.toRegister.count()); // no dups!
|
||||||
|
QCOMPARE(actToDemote.count(), ops.toDemote.count()); // no dups!
|
||||||
|
QCOMPARE(actToDelete.count(), ops.toDelete.count()); // no dups!
|
||||||
|
|
||||||
|
QSet<ToolChain *> tmp = actToRegister;
|
||||||
|
tmp.intersect(actToDemote);
|
||||||
|
QCOMPARE(tmp, actToDemote); // all toDemote are in toRegister
|
||||||
|
|
||||||
|
tmp = actToRegister;
|
||||||
|
tmp.intersect(actToDelete);
|
||||||
|
QVERIFY(tmp.isEmpty()); // Nothing that needs to be registered is to be deleted
|
||||||
|
|
||||||
|
tmp = actToRegister;
|
||||||
|
tmp.unite(actToDelete);
|
||||||
|
QCOMPARE(tmp, QSet<ToolChain *>::fromList(system + user + autodetect)); // All input is accounted for
|
||||||
|
|
||||||
|
QCOMPARE(expToRegister, actToRegister);
|
||||||
|
QCOMPARE(expToDemote, actToDemote);
|
||||||
|
QCOMPARE(QSet<ToolChain *>::fromList(system + user + autodetect),
|
||||||
|
QSet<ToolChain *>::fromList(ops.toRegister + ops.toDemote + ops.toDelete));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ProjectExplorer
|
||||||
|
|
||||||
|
#endif // WITH_TESTS
|
||||||
|
@@ -87,6 +87,9 @@ private:
|
|||||||
// Make sure the this is only called after all
|
// Make sure the this is only called after all
|
||||||
// Tool chain Factories are registered!
|
// Tool chain Factories are registered!
|
||||||
static void restoreToolChains();
|
static void restoreToolChains();
|
||||||
|
|
||||||
|
static QList<ToolChain *> readSystemFileToolChains();
|
||||||
|
|
||||||
static void notifyAboutUpdate(ToolChain *);
|
static void notifyAboutUpdate(ToolChain *);
|
||||||
|
|
||||||
friend class ProjectExplorerPlugin; // for constructor
|
friend class ProjectExplorerPlugin; // for constructor
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "msvcparser.h"
|
#include "msvcparser.h"
|
||||||
#include "projectexplorerconstants.h"
|
#include "projectexplorerconstants.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -352,10 +353,33 @@ WinCEToolChainFactory::WinCEToolChainFactory()
|
|||||||
setDisplayName(tr("WinCE"));
|
setDisplayName(tr("WinCE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ToolChain *findOrCreateToolChain(const QList<ToolChain *> &alreadyKnown,
|
||||||
|
const QString &name, const Abi &abi,
|
||||||
|
const QString &vcvarsBat, const QString &msvcVer,
|
||||||
|
const QString &ceVer, const QString &binPath,
|
||||||
|
const QString &includePath, const QString &libPath,
|
||||||
|
ToolChain::Detection d = ToolChain::ManualDetection)
|
||||||
|
{
|
||||||
|
ToolChain *tc
|
||||||
|
= Utils::findOrDefault(alreadyKnown, [&](ToolChain *tc) -> bool {
|
||||||
|
if (tc->typeId() != Constants::WINCE_TOOLCHAIN_TYPEID)
|
||||||
|
return false;
|
||||||
|
auto cetc = static_cast<WinCEToolChain *>(tc);
|
||||||
|
return cetc->targetAbi() == abi
|
||||||
|
&& cetc->varsBat() == vcvarsBat
|
||||||
|
&& cetc->msvcVer() == msvcVer
|
||||||
|
&& cetc->ceVer() == ceVer
|
||||||
|
&& cetc->binPath() == binPath
|
||||||
|
&& cetc->includePath() == includePath
|
||||||
|
&& cetc->libPath() == libPath;
|
||||||
|
});
|
||||||
|
if (!tc)
|
||||||
|
tc = new WinCEToolChain(name, abi, vcvarsBat, msvcVer, ceVer, binPath, includePath, libPath, d);
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
|
||||||
QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
|
||||||
{
|
{
|
||||||
Q_UNUSED(alreadyKnown);
|
|
||||||
QList<ToolChain *> results;
|
QList<ToolChain *> results;
|
||||||
|
|
||||||
// 1) Installed WinCEs
|
// 1) Installed WinCEs
|
||||||
@@ -398,16 +422,16 @@ QList<ToolChain *> WinCEToolChainFactory::autoDetect(const QList<ToolChain *> &a
|
|||||||
QString ceVer;
|
QString ceVer;
|
||||||
|
|
||||||
if (parseSDK(platformReader, theArch, thePlat, ceVer, binPath, includePath, libPath)) {
|
if (parseSDK(platformReader, theArch, thePlat, ceVer, binPath, includePath, libPath)) {
|
||||||
WinCEToolChain *pChain = new WinCEToolChain(thePlat,
|
results.append(findOrCreateToolChain(alreadyKnown,
|
||||||
Abi(theArch, Abi::WindowsOS, Abi::WindowsCEFlavor, Abi::PEFormat, 32),
|
thePlat,
|
||||||
vcvars32bat,
|
Abi(theArch, Abi::WindowsOS, Abi::WindowsCEFlavor, Abi::PEFormat, 32),
|
||||||
msvcVer,
|
vcvars32bat,
|
||||||
ceVer,
|
msvcVer,
|
||||||
binPath,
|
ceVer,
|
||||||
includePath,
|
binPath,
|
||||||
libPath,
|
includePath,
|
||||||
ToolChain::AutoDetection);
|
libPath,
|
||||||
results.append(pChain);
|
ToolChain::AutoDetection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,8 +57,13 @@ public:
|
|||||||
|
|
||||||
QString typeDisplayName() const override;
|
QString typeDisplayName() const override;
|
||||||
|
|
||||||
|
QString msvcVer() const { return m_msvcVer; }
|
||||||
QString ceVer() const;
|
QString ceVer() const;
|
||||||
|
|
||||||
|
QString binPath() const { return m_binPath; }
|
||||||
|
QString includePath() const { return m_includePath; }
|
||||||
|
QString libPath() const { return m_libPath; }
|
||||||
|
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
#include "qbsbuildconfiguration.h"
|
#include "qbsbuildconfiguration.h"
|
||||||
|
|
||||||
#include "qbsbuildconfigurationwidget.h"
|
#include "qbsbuildconfigurationwidget.h"
|
||||||
#include "qbsbuildinfo.h"
|
|
||||||
#include "qbsbuildstep.h"
|
#include "qbsbuildstep.h"
|
||||||
#include "qbscleanstep.h"
|
#include "qbscleanstep.h"
|
||||||
#include "qbsinstallstep.h"
|
#include "qbsinstallstep.h"
|
||||||
@@ -41,6 +40,7 @@
|
|||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <projectexplorer/buildinfo.h>
|
||||||
#include <projectexplorer/buildsteplist.h>
|
#include <projectexplorer/buildsteplist.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
@@ -374,10 +374,10 @@ bool QbsBuildConfigurationFactory::canHandle(const Target *t) const
|
|||||||
BuildInfo *QbsBuildConfigurationFactory::createBuildInfo(const Kit *k,
|
BuildInfo *QbsBuildConfigurationFactory::createBuildInfo(const Kit *k,
|
||||||
BuildConfiguration::BuildType type) const
|
BuildConfiguration::BuildType type) const
|
||||||
{
|
{
|
||||||
QbsBuildInfo *info = new QbsBuildInfo(this);
|
auto info = new ProjectExplorer::BuildInfo(this);
|
||||||
info->typeName = tr("Build");
|
info->typeName = tr("Build");
|
||||||
info->kitId = k->id();
|
info->kitId = k->id();
|
||||||
info->type = type;
|
info->buildType = type;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,10 +405,11 @@ int QbsBuildConfigurationFactory::priority(const Kit *k, const QString &projectP
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Utils::FileName defaultBuildDirectory(const QString &projectFilePath, const Kit *k,
|
static Utils::FileName defaultBuildDirectory(const QString &projectFilePath, const Kit *k,
|
||||||
const QString &bcName)
|
const QString &bcName,
|
||||||
|
BuildConfiguration::BuildType buildType)
|
||||||
{
|
{
|
||||||
const QString projectName = QFileInfo(projectFilePath).completeBaseName();
|
const QString projectName = QFileInfo(projectFilePath).completeBaseName();
|
||||||
ProjectMacroExpander expander(projectName, k, bcName);
|
ProjectMacroExpander expander(projectName, k, bcName, buildType);
|
||||||
QString projectDir = Project::projectDirectory(Utils::FileName::fromString(projectFilePath)).toString();
|
QString projectDir = Project::projectDirectory(Utils::FileName::fromString(projectFilePath)).toString();
|
||||||
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
||||||
return Utils::FileName::fromString(Utils::FileUtils::resolvePath(projectDir, buildPath));
|
return Utils::FileName::fromString(Utils::FileUtils::resolvePath(projectDir, buildPath));
|
||||||
@@ -422,14 +423,18 @@ QList<BuildInfo *> QbsBuildConfigurationFactory::availableSetups(const Kit *k, c
|
|||||||
//: The name of the debug build configuration created by default for a qbs project.
|
//: The name of the debug build configuration created by default for a qbs project.
|
||||||
info->displayName = tr("Debug");
|
info->displayName = tr("Debug");
|
||||||
//: Non-ASCII characters in directory suffix may cause build issues.
|
//: Non-ASCII characters in directory suffix may cause build issues.
|
||||||
info->buildDirectory = defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"));
|
info->buildDirectory
|
||||||
|
= defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"),
|
||||||
|
info->buildType);
|
||||||
result << info;
|
result << info;
|
||||||
|
|
||||||
info = createBuildInfo(k, BuildConfiguration::Release);
|
info = createBuildInfo(k, BuildConfiguration::Release);
|
||||||
//: The name of the release build configuration created by default for a qbs project.
|
//: The name of the release build configuration created by default for a qbs project.
|
||||||
info->displayName = tr("Release");
|
info->displayName = tr("Release");
|
||||||
//: Non-ASCII characters in directory suffix may cause build issues.
|
//: Non-ASCII characters in directory suffix may cause build issues.
|
||||||
info->buildDirectory = defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"));
|
info->buildDirectory
|
||||||
|
= defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"),
|
||||||
|
info->buildType);
|
||||||
result << info;
|
result << info;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -441,18 +446,16 @@ BuildConfiguration *QbsBuildConfigurationFactory::create(Target *parent, const B
|
|||||||
QTC_ASSERT(info->kitId == parent->kit()->id(), return 0);
|
QTC_ASSERT(info->kitId == parent->kit()->id(), return 0);
|
||||||
QTC_ASSERT(!info->displayName.isEmpty(), return 0);
|
QTC_ASSERT(!info->displayName.isEmpty(), return 0);
|
||||||
|
|
||||||
const QbsBuildInfo *qbsInfo = static_cast<const QbsBuildInfo *>(info);
|
|
||||||
|
|
||||||
QVariantMap configData;
|
QVariantMap configData;
|
||||||
configData.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY),
|
configData.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY),
|
||||||
(qbsInfo->type == BuildConfiguration::Debug)
|
(info->buildType == BuildConfiguration::Debug)
|
||||||
? QLatin1String(Constants::QBS_VARIANT_DEBUG)
|
? QLatin1String(Constants::QBS_VARIANT_DEBUG)
|
||||||
: QLatin1String(Constants::QBS_VARIANT_RELEASE));
|
: QLatin1String(Constants::QBS_VARIANT_RELEASE));
|
||||||
|
|
||||||
Utils::FileName buildDir = info->buildDirectory;
|
Utils::FileName buildDir = info->buildDirectory;
|
||||||
if (buildDir.isEmpty())
|
if (buildDir.isEmpty())
|
||||||
buildDir = defaultBuildDirectory(parent->project()->projectDirectory().toString(),
|
buildDir = defaultBuildDirectory(parent->project()->projectDirectory().toString(),
|
||||||
parent->kit(), info->displayName);
|
parent->kit(), info->displayName, info->buildType);
|
||||||
|
|
||||||
BuildConfiguration *bc
|
BuildConfiguration *bc
|
||||||
= QbsBuildConfiguration::setup(parent, info->displayName, info->displayName,
|
= QbsBuildConfiguration::setup(parent, info->displayName, info->displayName,
|
||||||
|
@@ -1,53 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://www.qt.io/licensing
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms and
|
|
||||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
|
||||||
** use the contact form at http://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 2.1 or version 3 as published by the Free
|
|
||||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
||||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
||||||
** following information to ensure the GNU Lesser General Public License
|
|
||||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef QBSBUILDINFO_H
|
|
||||||
#define QBSBUILDINFO_H
|
|
||||||
|
|
||||||
#include "qbsbuildconfiguration.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/buildinfo.h>
|
|
||||||
#include <qtsupport/baseqtversion.h>
|
|
||||||
|
|
||||||
namespace QbsProjectManager {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class QbsBuildInfo : public ProjectExplorer::BuildInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QbsBuildInfo(const QbsBuildConfigurationFactory *f) : ProjectExplorer::BuildInfo(f) { }
|
|
||||||
|
|
||||||
ProjectExplorer::BuildConfiguration::BuildType type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace QbsProjectManager
|
|
||||||
|
|
||||||
#endif // QBSBUILDINFO_H
|
|
@@ -39,6 +39,7 @@
|
|||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <qtsupport/qtsupportconstants.h>
|
#include <qtsupport/qtsupportconstants.h>
|
||||||
|
#include <resourceeditor/resourcenode.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -484,10 +485,11 @@ void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root, const qbs::Gro
|
|||||||
|
|
||||||
foreach (FileTreeNode *c, fileTree->children) {
|
foreach (FileTreeNode *c, fileTree->children) {
|
||||||
Utils::FileName path = Utils::FileName::fromString(c->path());
|
Utils::FileName path = Utils::FileName::fromString(c->path());
|
||||||
|
const ProjectExplorer::FileType newFileType = fileType(group, c->path());
|
||||||
|
const bool isQrcFile = newFileType == ProjectExplorer::ResourceType;
|
||||||
|
|
||||||
// Handle files:
|
// Handle files:
|
||||||
if (c->isFile()) {
|
if (c->isFile() && !isQrcFile) {
|
||||||
const ProjectExplorer::FileType newFileType = fileType(group, c->path());
|
|
||||||
ProjectExplorer::FileNode *fn = 0;
|
ProjectExplorer::FileNode *fn = 0;
|
||||||
foreach (ProjectExplorer::FileNode *f, root->fileNodes()) {
|
foreach (ProjectExplorer::FileNode *f, root->fileNodes()) {
|
||||||
// There can be one match only here!
|
// There can be one match only here!
|
||||||
@@ -514,10 +516,15 @@ void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root, const qbs::Gro
|
|||||||
fn = f;
|
fn = f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
using ResourceEditor::ResourceTopLevelNode;
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
fn = new QbsFolderNode(Utils::FileName::fromString(c->path()),
|
if (isQrcFile) {
|
||||||
ProjectExplorer::FolderNodeType,
|
fn = new ResourceTopLevelNode(Utils::FileName::fromString(c->path()), root);
|
||||||
displayNameFromPath(c->path(), baseDir));
|
} else {
|
||||||
|
fn = new QbsFolderNode(Utils::FileName::fromString(c->path()),
|
||||||
|
ProjectExplorer::FolderNodeType,
|
||||||
|
displayNameFromPath(c->path(), baseDir));
|
||||||
|
}
|
||||||
root->addFolderNodes(QList<FolderNode *>() << fn);
|
root->addFolderNodes(QList<FolderNode *>() << fn);
|
||||||
} else {
|
} else {
|
||||||
foldersToRemove.removeOne(fn);
|
foldersToRemove.removeOne(fn);
|
||||||
@@ -526,7 +533,11 @@ void QbsGroupNode::setupFolder(ProjectExplorer::FolderNode *root, const qbs::Gro
|
|||||||
fn->setDisplayName(displayNameFromPath(c->path(), baseDir));
|
fn->setDisplayName(displayNameFromPath(c->path(), baseDir));
|
||||||
}
|
}
|
||||||
|
|
||||||
setupFolder(fn, group, c, c->path(), updateExisting);
|
if (isQrcFile)
|
||||||
|
static_cast<ResourceTopLevelNode *>(fn)->update();
|
||||||
|
else
|
||||||
|
setupFolder(fn, group, c, c->path(), updateExisting);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root->removeFileNodes(filesToRemove);
|
root->removeFileNodes(filesToRemove);
|
||||||
|
@@ -23,7 +23,6 @@ HEADERS = \
|
|||||||
propertyprovider.h \
|
propertyprovider.h \
|
||||||
qbsbuildconfiguration.h \
|
qbsbuildconfiguration.h \
|
||||||
qbsbuildconfigurationwidget.h \
|
qbsbuildconfigurationwidget.h \
|
||||||
qbsbuildinfo.h \
|
|
||||||
qbsbuildstep.h \
|
qbsbuildstep.h \
|
||||||
qbscleanstep.h \
|
qbscleanstep.h \
|
||||||
qbsdeployconfigurationfactory.h \
|
qbsdeployconfigurationfactory.h \
|
||||||
|
@@ -41,6 +41,7 @@ QtcPlugin {
|
|||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
Depends { name: "Core" }
|
Depends { name: "Core" }
|
||||||
Depends { name: "CppTools" }
|
Depends { name: "CppTools" }
|
||||||
|
Depends { name: "ResourceEditor" }
|
||||||
Depends { name: "QtSupport" }
|
Depends { name: "QtSupport" }
|
||||||
Depends { name: "QmlJSTools" }
|
Depends { name: "QmlJSTools" }
|
||||||
|
|
||||||
@@ -68,7 +69,6 @@ QtcPlugin {
|
|||||||
"qbsbuildconfiguration.h",
|
"qbsbuildconfiguration.h",
|
||||||
"qbsbuildconfigurationwidget.cpp",
|
"qbsbuildconfigurationwidget.cpp",
|
||||||
"qbsbuildconfigurationwidget.h",
|
"qbsbuildconfigurationwidget.h",
|
||||||
"qbsbuildinfo.h",
|
|
||||||
"qbsbuildstep.cpp",
|
"qbsbuildstep.cpp",
|
||||||
"qbsbuildstep.h",
|
"qbsbuildstep.h",
|
||||||
"qbsbuildstepconfigwidget.ui",
|
"qbsbuildstepconfigwidget.ui",
|
||||||
|
@@ -8,4 +8,5 @@ QTC_PLUGIN_DEPENDS += \
|
|||||||
projectexplorer \
|
projectexplorer \
|
||||||
cpptools \
|
cpptools \
|
||||||
qtsupport \
|
qtsupport \
|
||||||
qmljstools
|
qmljstools \
|
||||||
|
resourceeditor
|
||||||
|
@@ -75,13 +75,15 @@ namespace QmakeProjectManager {
|
|||||||
// Helpers:
|
// Helpers:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
QString QmakeBuildConfiguration::shadowBuildDirectory(const QString &proFilePath, const Kit *k, const QString &suffix)
|
QString QmakeBuildConfiguration::shadowBuildDirectory(const QString &proFilePath, const Kit *k,
|
||||||
|
const QString &suffix,
|
||||||
|
BuildConfiguration::BuildType buildType)
|
||||||
{
|
{
|
||||||
if (proFilePath.isEmpty())
|
if (proFilePath.isEmpty())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
const QString projectName = QFileInfo(proFilePath).completeBaseName();
|
const QString projectName = QFileInfo(proFilePath).completeBaseName();
|
||||||
ProjectMacroExpander expander(projectName, k, suffix);
|
ProjectMacroExpander expander(projectName, k, suffix, buildType);
|
||||||
QString projectDir = Project::projectDirectory(FileName::fromString(proFilePath)).toString();
|
QString projectDir = Project::projectDirectory(FileName::fromString(proFilePath)).toString();
|
||||||
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
|
||||||
return FileUtils::resolvePath(projectDir, buildPath);
|
return FileUtils::resolvePath(projectDir, buildPath);
|
||||||
@@ -89,9 +91,11 @@ QString QmakeBuildConfiguration::shadowBuildDirectory(const QString &proFilePath
|
|||||||
|
|
||||||
static Utils::FileName defaultBuildDirectory(const QString &projectPath,
|
static Utils::FileName defaultBuildDirectory(const QString &projectPath,
|
||||||
const ProjectExplorer::Kit *k,
|
const ProjectExplorer::Kit *k,
|
||||||
const QString &suffix)
|
const QString &suffix,
|
||||||
|
BuildConfiguration::BuildType type)
|
||||||
{
|
{
|
||||||
return Utils::FileName::fromString(QmakeBuildConfiguration::shadowBuildDirectory(projectPath, k, suffix));
|
return Utils::FileName::fromString(QmakeBuildConfiguration::shadowBuildDirectory(projectPath, k,
|
||||||
|
suffix, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char QMAKE_BC_ID[] = "Qt4ProjectManager.Qt4BuildConfiguration";
|
const char QMAKE_BC_ID[] = "Qt4ProjectManager.Qt4BuildConfiguration";
|
||||||
@@ -597,9 +601,9 @@ QmakeBuildInfo *QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
|
|||||||
|
|
||||||
info->buildDirectory = Utils::FileName::fromString(absoluteBuildPath);
|
info->buildDirectory = Utils::FileName::fromString(absoluteBuildPath);
|
||||||
} else {
|
} else {
|
||||||
info->buildDirectory = defaultBuildDirectory(projectPath, k, suffix);
|
info->buildDirectory = defaultBuildDirectory(projectPath, k, suffix, type);
|
||||||
}
|
}
|
||||||
info->type = type;
|
info->buildType = type;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,7 +658,7 @@ void QmakeBuildConfigurationFactory::configureBuildConfiguration(Target *parent,
|
|||||||
BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit());
|
BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit());
|
||||||
|
|
||||||
BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig();
|
BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig();
|
||||||
if (qmakeInfo->type == BuildConfiguration::Debug)
|
if (qmakeInfo->buildType == BuildConfiguration::Debug)
|
||||||
config |= QtSupport::BaseQtVersion::DebugBuild;
|
config |= QtSupport::BaseQtVersion::DebugBuild;
|
||||||
else
|
else
|
||||||
config &= ~QtSupport::BaseQtVersion::DebugBuild;
|
config &= ~QtSupport::BaseQtVersion::DebugBuild;
|
||||||
@@ -690,7 +694,7 @@ void QmakeBuildConfigurationFactory::configureBuildConfiguration(Target *parent,
|
|||||||
Utils::FileName directory = qmakeInfo->buildDirectory;
|
Utils::FileName directory = qmakeInfo->buildDirectory;
|
||||||
if (directory.isEmpty()) {
|
if (directory.isEmpty()) {
|
||||||
directory = defaultBuildDirectory(parent->project()->projectFilePath().toString(),
|
directory = defaultBuildDirectory(parent->project()->projectFilePath().toString(),
|
||||||
parent->kit(), qmakeInfo->displayName);
|
parent->kit(), qmakeInfo->displayName, bc->buildType());
|
||||||
}
|
}
|
||||||
|
|
||||||
bc->setBuildDirectory(directory);
|
bc->setBuildDirectory(directory);
|
||||||
|
@@ -70,7 +70,7 @@ public:
|
|||||||
|
|
||||||
/// suffix should be unique
|
/// suffix should be unique
|
||||||
static QString shadowBuildDirectory(const QString &profilePath, const ProjectExplorer::Kit *k,
|
static QString shadowBuildDirectory(const QString &profilePath, const ProjectExplorer::Kit *k,
|
||||||
const QString &suffix);
|
const QString &suffix, BuildConfiguration::BuildType type);
|
||||||
|
|
||||||
/// \internal for qmakestep
|
/// \internal for qmakestep
|
||||||
// used by qmake step to notify that the qmake args have changed
|
// used by qmake step to notify that the qmake args have changed
|
||||||
|
@@ -46,17 +46,13 @@ class QmakeBuildInfo : public ProjectExplorer::BuildInfo
|
|||||||
public:
|
public:
|
||||||
QmakeBuildInfo(const QmakeBuildConfigurationFactory *f) : ProjectExplorer::BuildInfo(f) { }
|
QmakeBuildInfo(const QmakeBuildConfigurationFactory *f) : ProjectExplorer::BuildInfo(f) { }
|
||||||
|
|
||||||
ProjectExplorer::BuildConfiguration::BuildType type = ProjectExplorer::BuildConfiguration::Unknown;
|
|
||||||
QString additionalArguments;
|
QString additionalArguments;
|
||||||
QString makefile;
|
QString makefile;
|
||||||
QMakeStepConfig config;
|
QMakeStepConfig config;
|
||||||
|
|
||||||
bool operator==(const QmakeBuildInfo &o) {
|
bool operator==(const QmakeBuildInfo &o)
|
||||||
return displayName == o.displayName
|
{
|
||||||
&& typeName == o.typeName
|
return ProjectExplorer::BuildInfo::operator==(o)
|
||||||
&& buildDirectory == o.buildDirectory
|
|
||||||
&& kitId == o.kitId
|
|
||||||
&& type == o.type
|
|
||||||
&& additionalArguments == o.additionalArguments
|
&& additionalArguments == o.additionalArguments
|
||||||
&& config == o.config;
|
&& config == o.config;
|
||||||
}
|
}
|
||||||
|
@@ -1267,10 +1267,16 @@ bool QmakePriFileNode::renameFile(const QString &oldName,
|
|||||||
QDir priFileDir = QDir(m_qmakeProFileNode->m_projectDir);
|
QDir priFileDir = QDir(m_qmakeProFileNode->m_projectDir);
|
||||||
QStringList notChanged = ProWriter::removeFiles(includeFile, &lines, priFileDir,
|
QStringList notChanged = ProWriter::removeFiles(includeFile, &lines, priFileDir,
|
||||||
QStringList(oldName), varNamesForRemoving());
|
QStringList(oldName), varNamesForRemoving());
|
||||||
if (!notChanged.isEmpty()) {
|
|
||||||
includeFile->deref();
|
includeFile->deref();
|
||||||
|
if (!notChanged.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
// We need to re-parse here: The file has changed.
|
||||||
|
QMakeParser parser(0, 0, 0);
|
||||||
|
includeFile = parser.parsedProBlock(lines.join(QLatin1Char('\n')),
|
||||||
|
m_projectFilePath.toString(), 1, QMakeParser::FullGrammar);
|
||||||
|
QTC_ASSERT(includeFile, return false); // The file should still be valid after what we did.
|
||||||
|
|
||||||
ProWriter::addFiles(includeFile, &lines,
|
ProWriter::addFiles(includeFile, &lines,
|
||||||
QStringList(newName),
|
QStringList(newName),
|
||||||
|
@@ -54,7 +54,8 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
|
|||||||
m_defaultShadowBuildDir
|
m_defaultShadowBuildDir
|
||||||
= QmakeBuildConfiguration::shadowBuildDirectory(bc->target()->project()->projectFilePath().toString(),
|
= QmakeBuildConfiguration::shadowBuildDirectory(bc->target()->project()->projectFilePath().toString(),
|
||||||
bc->target()->kit(),
|
bc->target()->kit(),
|
||||||
Utils::FileUtils::qmakeFriendlyName(bc->displayName()));
|
Utils::FileUtils::qmakeFriendlyName(bc->displayName()),
|
||||||
|
bc->buildType());
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout(this);
|
QVBoxLayout *vbox = new QVBoxLayout(this);
|
||||||
vbox->setMargin(0);
|
vbox->setMargin(0);
|
||||||
|
@@ -220,10 +220,10 @@ QList<BuildInfo *> QmakeProjectImporter::import(const FileName &importPath, bool
|
|||||||
QmakeBuildInfo *info = new QmakeBuildInfo(factory);
|
QmakeBuildInfo *info = new QmakeBuildInfo(factory);
|
||||||
BaseQtVersion::QmakeBuildConfigs buildConfig = parse.effectiveBuildConfig(version->defaultBuildConfig());
|
BaseQtVersion::QmakeBuildConfigs buildConfig = parse.effectiveBuildConfig(version->defaultBuildConfig());
|
||||||
if (buildConfig & BaseQtVersion::DebugBuild) {
|
if (buildConfig & BaseQtVersion::DebugBuild) {
|
||||||
info->type = BuildConfiguration::Debug;
|
info->buildType = BuildConfiguration::Debug;
|
||||||
info->displayName = QCoreApplication::translate("QmakeProjectManager::Internal::QmakeProjectImporter", "Debug");
|
info->displayName = QCoreApplication::translate("QmakeProjectManager::Internal::QmakeProjectImporter", "Debug");
|
||||||
} else {
|
} else {
|
||||||
info->type = BuildConfiguration::Release;
|
info->buildType = BuildConfiguration::Release;
|
||||||
info->displayName = QCoreApplication::translate("QmakeProjectManager::Internal::QmakeProjectImporter", "Release");
|
info->displayName = QCoreApplication::translate("QmakeProjectManager::Internal::QmakeProjectImporter", "Release");
|
||||||
}
|
}
|
||||||
info->kitId = k->id();
|
info->kitId = k->id();
|
||||||
@@ -264,7 +264,8 @@ QStringList QmakeProjectImporter::importCandidates(const FileName &projectPath)
|
|||||||
candidates << pfi.absolutePath();
|
candidates << pfi.absolutePath();
|
||||||
|
|
||||||
foreach (Kit *k, KitManager::kits()) {
|
foreach (Kit *k, KitManager::kits()) {
|
||||||
QFileInfo fi(QmakeBuildConfiguration::shadowBuildDirectory(projectPath.toString(), k, QString()));
|
QFileInfo fi(QmakeBuildConfiguration::shadowBuildDirectory(projectPath.toString(), k,
|
||||||
|
QString(), BuildConfiguration::Unknown));
|
||||||
const QString baseDir = fi.absolutePath();
|
const QString baseDir = fi.absolutePath();
|
||||||
|
|
||||||
foreach (const QString &dir, QDir(baseDir).entryList()) {
|
foreach (const QString &dir, QDir(baseDir).entryList()) {
|
||||||
|
@@ -551,8 +551,8 @@ void gotoImplementation(const SelectionContext &/*selectionState*/)
|
|||||||
QList<QmlJSEditor::FindReferences::Usage> usages = QmlJSEditor::FindReferences::findUsageOfType(fileName, typeName);
|
QList<QmlJSEditor::FindReferences::Usage> usages = QmlJSEditor::FindReferences::findUsageOfType(fileName, typeName);
|
||||||
|
|
||||||
if (usages.isEmpty()) {
|
if (usages.isEmpty()) {
|
||||||
QString title = QCoreApplication::translate("ModelNodeOperations", "Goto implementation");
|
QString title = QCoreApplication::translate("ModelNodeOperations", "Go to Implementation");
|
||||||
QString description = QCoreApplication::translate("ModelNodeOperations", "Cannot find any implementation.");
|
QString description = QCoreApplication::translate("ModelNodeOperations", "Cannot find an implementation.");
|
||||||
Core::AsynchronousMessageBox::warning(title, description);
|
Core::AsynchronousMessageBox::warning(title, description);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -65,16 +65,16 @@ DebugView::~DebugView()
|
|||||||
|
|
||||||
void DebugView::modelAttached(Model *model)
|
void DebugView::modelAttached(Model *model)
|
||||||
{
|
{
|
||||||
log(tr("Model attached"), tr("FileName %1").arg(model->fileUrl().toLocalFile()));
|
log(tr("Model attached"), tr("Filename %1").arg(model->fileUrl().toLocalFile()));
|
||||||
m_debugViewWidget->setDebugViewEnabled(isDebugViewEnabled());
|
m_debugViewWidget->setDebugViewEnabled(isDebugViewEnabled());
|
||||||
if (isDebugViewEnabled())
|
if (isDebugViewEnabled())
|
||||||
qDebug() << tr("DebugView is enabled");
|
qDebug() << tr("Debug view is enabled");
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugView::modelAboutToBeDetached(Model *model)
|
void DebugView::modelAboutToBeDetached(Model *model)
|
||||||
{
|
{
|
||||||
log(tr("Model detached"), tr("FileName %1").arg(model->fileUrl().toLocalFile()));
|
log(tr("Model detached"), tr("Filename %1").arg(model->fileUrl().toLocalFile()));
|
||||||
AbstractView::modelAboutToBeDetached(model);
|
AbstractView::modelAboutToBeDetached(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ void DebugView::nodeAboutToBeRemoved(const ModelNode &removedNode)
|
|||||||
message.setString(&string);
|
message.setString(&string);
|
||||||
message << removedNode << lineBreak;
|
message << removedNode << lineBreak;
|
||||||
foreach (const ModelNode &modelNode, removedNode.allSubModelNodes()) {
|
foreach (const ModelNode &modelNode, removedNode.allSubModelNodes()) {
|
||||||
message << tr("ChildNode:") << modelNode << lineBreak;
|
message << tr("Child node:") << modelNode << lineBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(tr("Node about to be removed:"), message.readAll());
|
log(tr("Node about to be removed:"), message.readAll());
|
||||||
@@ -136,10 +136,10 @@ void DebugView::nodeReparented(const ModelNode &node, const NodeAbstractProperty
|
|||||||
message << tr("Old parent property:");
|
message << tr("Old parent property:");
|
||||||
message << lineBreak;
|
message << lineBreak;
|
||||||
message << oldPropertyParent;
|
message << oldPropertyParent;
|
||||||
message << tr("PropertyChangeFlag");
|
message << tr("Property change flag");
|
||||||
message << lineBreak;
|
message << lineBreak;
|
||||||
message << propertyChange;
|
message << propertyChange;
|
||||||
log(tr("Node reparanted:"), message.readAll());
|
log(tr("Node reparented:"), message.readAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,8 +150,8 @@ void DebugView::nodeIdChanged(const ModelNode &node, const QString &newId, const
|
|||||||
QString string;
|
QString string;
|
||||||
message.setString(&string);
|
message.setString(&string);
|
||||||
message << node;
|
message << node;
|
||||||
message << tr("New Id:") << ' ' << newId << lineBreak;
|
message << tr("New id:") << ' ' << newId << lineBreak;
|
||||||
message << tr("Old Id:") << ' ' << oldId << lineBreak;
|
message << tr("Old id:") << ' ' << oldId << lineBreak;
|
||||||
log(tr("Node id changed:"), string);
|
log(tr("Node id changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ void DebugView::variantPropertiesChanged(const QList<VariantProperty> &propertyL
|
|||||||
foreach (const VariantProperty &property, propertyList) {
|
foreach (const VariantProperty &property, propertyList) {
|
||||||
message << property;
|
message << property;
|
||||||
}
|
}
|
||||||
log(tr("VariantProperties changed:"), string);
|
log(tr("Variant properties changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ void DebugView::bindingPropertiesChanged(const QList<BindingProperty> &propertyL
|
|||||||
foreach (const BindingProperty &property, propertyList) {
|
foreach (const BindingProperty &property, propertyList) {
|
||||||
message << property;
|
message << property;
|
||||||
}
|
}
|
||||||
log(tr("BindingProperties changed:"), string);
|
log(tr("Binding properties changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ void DebugView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProper
|
|||||||
foreach (const SignalHandlerProperty &property, propertyList) {
|
foreach (const SignalHandlerProperty &property, propertyList) {
|
||||||
message << property;
|
message << property;
|
||||||
}
|
}
|
||||||
log(tr("SignalHandlerProperties changed:"), string);
|
log(tr("Signal handler properties changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ void DebugView::auxiliaryDataChanged(const ModelNode &node, const PropertyName &
|
|||||||
message << name;
|
message << name;
|
||||||
message << data.toString();
|
message << data.toString();
|
||||||
|
|
||||||
log(tr("Auxiliary Data Changed:"), string);
|
log(tr("Auxiliary data changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ void DebugView::instancesCompleted(const QVector<ModelNode> &completedNodeList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logInstance(tr("Instance Completed"), string);
|
logInstance(tr("Instance completed"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ void DebugView::instanceInformationsChange(const QMultiHash<ModelNode, Informati
|
|||||||
message << informationChangeHash.value(modelNode);
|
message << informationChangeHash.value(modelNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
logInstance(tr("Instance Completed"), string);
|
logInstance(tr("Instance completed"), string);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ void DebugView::instancesChildrenChanged(const QVector<ModelNode> & nodeList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logInstance(tr("Instances children changed:"), string);
|
logInstance(tr("Instance's children changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ void DebugView::customNotification(const AbstractView *view, const QString &iden
|
|||||||
message << variant.toString();
|
message << variant.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
log(tr("Custom Notification:"), string);
|
log(tr("Custom notification:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ void DebugView::nodeSourceChanged(const ModelNode &modelNode, const QString &new
|
|||||||
message << modelNode;
|
message << modelNode;
|
||||||
message << newNodeSource;
|
message << newNodeSource;
|
||||||
|
|
||||||
log(tr("Node Source Changed:"), string);
|
log(tr("Node source changed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ void DebugView::nodeRemoved(const ModelNode &removedNode, const NodeAbstractProp
|
|||||||
|
|
||||||
message << removedNode;
|
message << removedNode;
|
||||||
|
|
||||||
log(tr("Node Removed:"), string);
|
log(tr("Node removed:"), string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -115,13 +115,13 @@ QList<QToolButton *> ConnectionViewWidget::createToolBarWidgets()
|
|||||||
|
|
||||||
buttons << new QToolButton();
|
buttons << new QToolButton();
|
||||||
buttons.last()->setIcon(QIcon(QStringLiteral(":/connectionview/plus.png")));
|
buttons.last()->setIcon(QIcon(QStringLiteral(":/connectionview/plus.png")));
|
||||||
buttons.last()->setToolTip(tr("Add binding or connection"));
|
buttons.last()->setToolTip(tr("Add binding or connection."));
|
||||||
connect(buttons.last(), SIGNAL(clicked()), this, SLOT(addButtonClicked()));
|
connect(buttons.last(), SIGNAL(clicked()), this, SLOT(addButtonClicked()));
|
||||||
connect(this, SIGNAL(setEnabledAddButtonChanged(bool)), buttons.last(), SLOT(setEnabled(bool)));
|
connect(this, SIGNAL(setEnabledAddButtonChanged(bool)), buttons.last(), SLOT(setEnabled(bool)));
|
||||||
|
|
||||||
buttons << new QToolButton();
|
buttons << new QToolButton();
|
||||||
buttons.last()->setIcon(QIcon(QStringLiteral(":/connectionview/minus.png")));
|
buttons.last()->setIcon(QIcon(QStringLiteral(":/connectionview/minus.png")));
|
||||||
buttons.last()->setToolTip(tr("Remove selected binding or connection"));
|
buttons.last()->setToolTip(tr("Remove selected binding or connection."));
|
||||||
buttons.last()->setShortcut(QKeySequence(Qt::Key_Delete));
|
buttons.last()->setShortcut(QKeySequence(Qt::Key_Delete));
|
||||||
connect(buttons.last(), SIGNAL(clicked()), this, SLOT(removeButtonClicked()));
|
connect(buttons.last(), SIGNAL(clicked()), this, SLOT(removeButtonClicked()));
|
||||||
connect(this, SIGNAL(setEnabledRemoveButtonChanged(bool)), buttons.last(), SLOT(setEnabled(bool)));
|
connect(this, SIGNAL(setEnabledRemoveButtonChanged(bool)), buttons.last(), SLOT(setEnabled(bool)));
|
||||||
|
@@ -70,7 +70,7 @@ namespace QmlDesigner {
|
|||||||
class SourceToolAction : public AbstractAction
|
class SourceToolAction : public AbstractAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SourceToolAction() : AbstractAction(QCoreApplication::translate("SourceToolAction","Change Source Url...")) {}
|
SourceToolAction() : AbstractAction(QCoreApplication::translate("SourceToolAction","Change Source URL...")) {}
|
||||||
|
|
||||||
QByteArray category() const
|
QByteArray category() const
|
||||||
{
|
{
|
||||||
|
@@ -177,7 +177,7 @@
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Path where Qt Creator can find the qmlpuppet (QML emulation layer) executables.</string>
|
<string>Path where Qt Creator can find the QML emulation layer executable (qmlpuppet).</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@@ -120,8 +120,15 @@ void QmlProfilerClientManager::discardPendingData()
|
|||||||
|
|
||||||
void QmlProfilerClientManager::connectClient(quint16 port)
|
void QmlProfilerClientManager::connectClient(quint16 port)
|
||||||
{
|
{
|
||||||
if (d->connection)
|
if (d->connection) {
|
||||||
delete d->connection;
|
if (port == d->tcpPort) {
|
||||||
|
tryToConnect();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
delete d->connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d->connection = new QmlDebugConnection;
|
d->connection = new QmlDebugConnection;
|
||||||
enableServices();
|
enableServices();
|
||||||
connect(d->connection, SIGNAL(stateMessage(QString)), this, SLOT(logState(QString)));
|
connect(d->connection, SIGNAL(stateMessage(QString)), this, SLOT(logState(QString)));
|
||||||
|
@@ -309,7 +309,7 @@ void ColorSchemeEdit::updateUnderlineControls()
|
|||||||
|
|
||||||
QSignalBlocker comboBoxSignalBlocker(m_ui->underlineComboBox);
|
QSignalBlocker comboBoxSignalBlocker(m_ui->underlineComboBox);
|
||||||
|
|
||||||
bool isVisble= formatDescription.showControl(FormatDescription::ShowFontControls);
|
bool isVisble= formatDescription.showControl(FormatDescription::ShowUnderlineControl);
|
||||||
|
|
||||||
m_ui->underlineLabel->setVisible(isVisble);
|
m_ui->underlineLabel->setVisible(isVisble);
|
||||||
m_ui->underlineColorToolButton->setVisible(isVisble);
|
m_ui->underlineColorToolButton->setVisible(isVisble);
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
|
||||||
|
#include <aggregation/aggregate.h>
|
||||||
|
#include <coreplugin/find/basetextfind.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/outputformatter.h>
|
#include <utils/outputformatter.h>
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
@@ -288,8 +290,12 @@ public:
|
|||||||
|
|
||||||
Internal::OutputWindowPlainTextEdit *VcsOutputWindowPrivate::plainTextEdit()
|
Internal::OutputWindowPlainTextEdit *VcsOutputWindowPrivate::plainTextEdit()
|
||||||
{
|
{
|
||||||
if (!m_plainTextEdit)
|
if (!m_plainTextEdit) {
|
||||||
m_plainTextEdit = new Internal::OutputWindowPlainTextEdit();
|
m_plainTextEdit = new Internal::OutputWindowPlainTextEdit();
|
||||||
|
Aggregation::Aggregate *agg = new Aggregation::Aggregate;
|
||||||
|
agg->add(m_plainTextEdit);
|
||||||
|
agg->add(new Core::BaseTextFind(m_plainTextEdit));
|
||||||
|
}
|
||||||
return m_plainTextEdit;
|
return m_plainTextEdit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -100,12 +100,19 @@ QString IoUtils::resolvePath(const QString &baseDir, const QString &fileName)
|
|||||||
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
|
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static
|
||||||
|
bool isSpecialChar(ushort c, const uchar (&iqm)[16])
|
||||||
|
{
|
||||||
|
if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline static
|
inline static
|
||||||
bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
|
bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
|
||||||
{
|
{
|
||||||
for (int x = arg.length() - 1; x >= 0; --x) {
|
for (int x = arg.length() - 1; x >= 0; --x) {
|
||||||
ushort c = arg.unicode()[x].unicode();
|
if (isSpecialChar(arg.unicode()[x].unicode(), iqm))
|
||||||
if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -120,7 +127,7 @@ QString IoUtils::shellQuoteUnix(const QString &arg)
|
|||||||
}; // 0-32 \'"$`<>|;&(){}*?#!~[]
|
}; // 0-32 \'"$`<>|;&(){}*?#!~[]
|
||||||
|
|
||||||
if (!arg.length())
|
if (!arg.length())
|
||||||
return QString::fromLatin1("\"\"");
|
return QString::fromLatin1("''");
|
||||||
|
|
||||||
QString ret(arg);
|
QString ret(arg);
|
||||||
if (hasSpecialChars(ret, iqm)) {
|
if (hasSpecialChars(ret, iqm)) {
|
||||||
@@ -141,23 +148,38 @@ QString IoUtils::shellQuoteWin(const QString &arg)
|
|||||||
0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
|
0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
|
||||||
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
|
||||||
};
|
};
|
||||||
|
// Shell meta chars that need escaping.
|
||||||
|
static const uchar ism[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x50,
|
||||||
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
|
||||||
|
}; // &()<>^|
|
||||||
|
|
||||||
if (!arg.length())
|
if (!arg.length())
|
||||||
return QString::fromLatin1("\"\"");
|
return QString::fromLatin1("\"\"");
|
||||||
|
|
||||||
QString ret(arg);
|
QString ret(arg);
|
||||||
if (hasSpecialChars(ret, iqm)) {
|
if (hasSpecialChars(ret, iqm)) {
|
||||||
// Quotes are escaped and their preceding backslashes are doubled.
|
// The process-level standard quoting allows escaping quotes with backslashes (note
|
||||||
// It's impossible to escape anything inside a quoted string on cmd
|
// that backslashes don't escape themselves, unless they are followed by a quote).
|
||||||
// level, so the outer quoting must be "suspended".
|
// Consequently, quotes are escaped and their preceding backslashes are doubled.
|
||||||
ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\"\\1\\1\\^\"\""));
|
ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
|
||||||
// The argument must not end with a \ since this would be interpreted
|
// Trailing backslashes must be doubled as well, as they are followed by a quote.
|
||||||
// as escaping the quote -- rather put the \ behind the quote: e.g.
|
ret.replace(QRegExp(QLatin1String("(\\\\+)$")), QLatin1String("\\1\\1"));
|
||||||
// rather use "foo"\ than "foo\"
|
// However, the shell also interprets the command, and no backslash-escaping exists
|
||||||
int i = ret.length();
|
// there - a quote always toggles the quoting state, but is nonetheless passed down
|
||||||
while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
|
// to the called process verbatim. In the unquoted state, the circumflex escapes
|
||||||
--i;
|
// meta chars (including itself and quotes), and is removed from the command.
|
||||||
ret.insert(i, QLatin1Char('"'));
|
bool quoted = true;
|
||||||
|
for (int i = 0; i < ret.length(); i++) {
|
||||||
|
QChar c = ret.unicode()[i];
|
||||||
|
if (c.unicode() == '"')
|
||||||
|
quoted = !quoted;
|
||||||
|
else if (!quoted && isSpecialChar(c.unicode(), ism))
|
||||||
|
ret.insert(i++, QLatin1Char('^'));
|
||||||
|
}
|
||||||
|
if (!quoted)
|
||||||
|
ret.append(QLatin1Char('^'));
|
||||||
|
ret.append(QLatin1Char('"'));
|
||||||
ret.prepend(QLatin1Char('"'));
|
ret.prepend(QLatin1Char('"'));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -156,6 +156,18 @@ QString &ProString::toQString(QString &tmp) const
|
|||||||
return tmp.setRawData(m_string.constData() + m_offset, m_length);
|
return tmp.setRawData(m_string.constData() + m_offset, m_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief ProString::prepareExtend
|
||||||
|
* \param extraLen number of new characters to be added
|
||||||
|
* \param thisTarget offset to which current contents should be moved
|
||||||
|
* \param extraTarget offset at which new characters will be added
|
||||||
|
* \return pointer to storage location for new characters
|
||||||
|
*
|
||||||
|
* Prepares the string for adding new characters.
|
||||||
|
* If the string is detached and has enough space, it will be changed in place.
|
||||||
|
* Otherwise, it will be replaced with a new string object, thus detaching.
|
||||||
|
* In either case, the hash will be reset.
|
||||||
|
*/
|
||||||
QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget)
|
QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget)
|
||||||
{
|
{
|
||||||
if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) {
|
if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) {
|
||||||
@@ -379,6 +391,20 @@ void ProStringList::removeAll(const char *str)
|
|||||||
remove(i);
|
remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProStringList::removeEach(const ProStringList &value)
|
||||||
|
{
|
||||||
|
foreach (const ProString &str, value)
|
||||||
|
if (!str.isEmpty())
|
||||||
|
removeAll(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProStringList::removeEmpty()
|
||||||
|
{
|
||||||
|
for (int i = size(); --i >= 0;)
|
||||||
|
if (at(i).isEmpty())
|
||||||
|
remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
void ProStringList::removeDuplicates()
|
void ProStringList::removeDuplicates()
|
||||||
{
|
{
|
||||||
int n = size();
|
int n = size();
|
||||||
@@ -398,6 +424,13 @@ void ProStringList::removeDuplicates()
|
|||||||
erase(begin() + j, end());
|
erase(begin() + j, end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProStringList::insertUnique(const ProStringList &value)
|
||||||
|
{
|
||||||
|
foreach (const ProString &str, value)
|
||||||
|
if (!str.isEmpty() && !contains(str))
|
||||||
|
append(str);
|
||||||
|
}
|
||||||
|
|
||||||
ProStringList::ProStringList(const QStringList &list)
|
ProStringList::ProStringList(const QStringList &list)
|
||||||
{
|
{
|
||||||
reserve(list.size());
|
reserve(list.size());
|
||||||
@@ -409,8 +442,8 @@ QStringList ProStringList::toQStringList() const
|
|||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
ret.reserve(size());
|
ret.reserve(size());
|
||||||
foreach (const ProString &str, *this)
|
for (int i = 0; i < size(); i++) // foreach causes MSVC2010 ICE
|
||||||
ret << str.toQString();
|
ret << at(i).toQString();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,4 +478,23 @@ ProFile::~ProFile()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProString ProFile::getStr(const ushort *&tPtr)
|
||||||
|
{
|
||||||
|
uint len = *tPtr++;
|
||||||
|
ProString ret(items(), tPtr - tokPtr(), len);
|
||||||
|
ret.setSource(this);
|
||||||
|
tPtr += len;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProKey ProFile::getHashStr(const ushort *&tPtr)
|
||||||
|
{
|
||||||
|
uint hash = *tPtr++;
|
||||||
|
hash |= (uint)*tPtr++ << 16;
|
||||||
|
uint len = *tPtr++;
|
||||||
|
ProKey ret(items(), tPtr - tokPtr(), len, hash);
|
||||||
|
tPtr += len;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@@ -135,6 +135,7 @@ public:
|
|||||||
int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize
|
int toInt(bool *ok = 0, int base = 10) const { return toQString().toInt(ok, base); } // XXX optimize
|
||||||
short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize
|
short toShort(bool *ok = 0, int base = 10) const { return toQString().toShort(ok, base); } // XXX optimize
|
||||||
|
|
||||||
|
uint hash() const { return m_hash; }
|
||||||
static uint hash(const QChar *p, int n);
|
static uint hash(const QChar *p, int n);
|
||||||
|
|
||||||
ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
|
ALWAYS_INLINE QStringRef toQStringRef() const { return QStringRef(&m_string, m_offset, m_length); }
|
||||||
@@ -236,9 +237,13 @@ public:
|
|||||||
QString join(const QString &sep) const;
|
QString join(const QString &sep) const;
|
||||||
QString join(QChar sep) const;
|
QString join(QChar sep) const;
|
||||||
|
|
||||||
|
void insertUnique(const ProStringList &value);
|
||||||
|
|
||||||
void removeAll(const ProString &str);
|
void removeAll(const ProString &str);
|
||||||
void removeAll(const char *str);
|
void removeAll(const char *str);
|
||||||
|
void removeEach(const ProStringList &value);
|
||||||
void removeAt(int idx) { remove(idx); }
|
void removeAt(int idx) { remove(idx); }
|
||||||
|
void removeEmpty();
|
||||||
void removeDuplicates();
|
void removeDuplicates();
|
||||||
|
|
||||||
bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
bool contains(const ProString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
||||||
@@ -345,6 +350,9 @@ public:
|
|||||||
bool isHostBuild() const { return m_hostBuild; }
|
bool isHostBuild() const { return m_hostBuild; }
|
||||||
void setHostBuild(bool host_build) { m_hostBuild = host_build; }
|
void setHostBuild(bool host_build) { m_hostBuild = host_build; }
|
||||||
|
|
||||||
|
ProString getStr(const ushort *&tPtr);
|
||||||
|
ProKey getHashStr(const ushort *&tPtr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProItemRefCount m_refCount;
|
ProItemRefCount m_refCount;
|
||||||
QString m_proitems;
|
QString m_proitems;
|
||||||
|
@@ -88,7 +88,7 @@ enum ExpandFunc {
|
|||||||
E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
|
E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
|
||||||
E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
|
E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
|
||||||
E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
|
E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
|
||||||
E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE
|
E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TestFunc {
|
enum TestFunc {
|
||||||
@@ -145,6 +145,7 @@ void QMakeEvaluator::initFunctionStatics()
|
|||||||
{ "shell_path", E_SHELL_PATH },
|
{ "shell_path", E_SHELL_PATH },
|
||||||
{ "system_quote", E_SYSTEM_QUOTE },
|
{ "system_quote", E_SYSTEM_QUOTE },
|
||||||
{ "shell_quote", E_SHELL_QUOTE },
|
{ "shell_quote", E_SHELL_QUOTE },
|
||||||
|
{ "getenv", E_GETENV },
|
||||||
};
|
};
|
||||||
for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
|
for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
|
||||||
statics.expands.insert(ProKey(expandInits[i].name), expandInits[i].func);
|
statics.expands.insert(ProKey(expandInits[i].name), expandInits[i].func);
|
||||||
@@ -210,12 +211,12 @@ static QString windowsErrorCode()
|
|||||||
NULL);
|
NULL);
|
||||||
QString ret = QString::fromWCharArray(string);
|
QString ret = QString::fromWCharArray(string);
|
||||||
LocalFree((HLOCAL)string);
|
LocalFree((HLOCAL)string);
|
||||||
return ret;
|
return ret.trimmed();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static QString
|
QString
|
||||||
quoteValue(const ProString &val)
|
QMakeEvaluator::quoteValue(const ProString &val)
|
||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
ret.reserve(val.size());
|
ret.reserve(val.size());
|
||||||
@@ -358,7 +359,7 @@ QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::Open
|
|||||||
{
|
{
|
||||||
QString errStr;
|
QString errStr;
|
||||||
if (!m_vfs->writeFile(fn, mode, contents, &errStr)) {
|
if (!m_vfs->writeFile(fn, mode, contents, &errStr)) {
|
||||||
evalError(fL1S("Cannot write %1file %2: %3.")
|
evalError(fL1S("Cannot write %1file %2: %3")
|
||||||
.arg(ctx, QDir::toNativeSeparators(fn), errStr));
|
.arg(ctx, QDir::toNativeSeparators(fn), errStr));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
@@ -425,8 +426,9 @@ QByteArray QMakeEvaluator::getCommandOutput(const QString &args) const
|
|||||||
|
|
||||||
void QMakeEvaluator::populateDeps(
|
void QMakeEvaluator::populateDeps(
|
||||||
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
|
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
|
||||||
|
const ProString &priosfx,
|
||||||
QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
|
QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
|
||||||
ProStringList &rootSet) const
|
QMultiMap<int, ProString> &rootSet) const
|
||||||
{
|
{
|
||||||
foreach (const ProString &item, deps)
|
foreach (const ProString &item, deps)
|
||||||
if (!dependencies.contains(item.toKey())) {
|
if (!dependencies.contains(item.toKey())) {
|
||||||
@@ -435,13 +437,13 @@ void QMakeEvaluator::populateDeps(
|
|||||||
foreach (const ProString &suffix, suffixes)
|
foreach (const ProString &suffix, suffixes)
|
||||||
depends += values(ProKey(prefix + item + suffix));
|
depends += values(ProKey(prefix + item + suffix));
|
||||||
if (depends.isEmpty()) {
|
if (depends.isEmpty()) {
|
||||||
rootSet << item;
|
rootSet.insert(first(ProKey(prefix + item + priosfx)).toInt(), item);
|
||||||
} else {
|
} else {
|
||||||
foreach (const ProString &dep, depends) {
|
foreach (const ProString &dep, depends) {
|
||||||
dset.insert(dep.toKey());
|
dset.insert(dep.toKey());
|
||||||
dependees[dep.toKey()] << item;
|
dependees[dep.toKey()] << item;
|
||||||
}
|
}
|
||||||
populateDeps(depends, prefix, suffixes, dependencies, dependees, rootSet);
|
populateDeps(depends, prefix, suffixes, priosfx, dependencies, dependees, rootSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,27 +964,31 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
break;
|
break;
|
||||||
case E_SORT_DEPENDS:
|
case E_SORT_DEPENDS:
|
||||||
case E_RESOLVE_DEPENDS:
|
case E_RESOLVE_DEPENDS:
|
||||||
if (args.count() < 1 || args.count() > 3) {
|
if (args.count() < 1 || args.count() > 4) {
|
||||||
evalError(fL1S("%1(var, [prefix, [suffixes]]) requires one to three arguments.")
|
evalError(fL1S("%1(var, [prefix, [suffixes, [prio-suffix]]]) requires one to four arguments.")
|
||||||
.arg(func.toQString(m_tmp1)));
|
.arg(func.toQString(m_tmp1)));
|
||||||
} else {
|
} else {
|
||||||
QHash<ProKey, QSet<ProKey> > dependencies;
|
QHash<ProKey, QSet<ProKey> > dependencies;
|
||||||
ProValueMap dependees;
|
ProValueMap dependees;
|
||||||
ProStringList rootSet;
|
QMultiMap<int, ProString> rootSet;
|
||||||
ProStringList orgList = values(args.at(0).toKey());
|
ProStringList orgList = values(args.at(0).toKey());
|
||||||
populateDeps(orgList, (args.count() < 2 ? ProString() : args.at(1)),
|
ProString prefix = args.count() < 2 ? ProString() : args.at(1);
|
||||||
|
ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
|
||||||
|
populateDeps(orgList, prefix,
|
||||||
args.count() < 3 ? ProStringList(ProString(".depends"))
|
args.count() < 3 ? ProStringList(ProString(".depends"))
|
||||||
: split_value_list(args.at(2).toQString(m_tmp2)),
|
: split_value_list(args.at(2).toQString(m_tmp2)),
|
||||||
dependencies, dependees, rootSet);
|
priosfx, dependencies, dependees, rootSet);
|
||||||
for (int i = 0; i < rootSet.size(); ++i) {
|
while (!rootSet.isEmpty()) {
|
||||||
const ProString &item = rootSet.at(i);
|
QMultiMap<int, ProString>::iterator it = rootSet.begin();
|
||||||
|
const ProString item = *it;
|
||||||
|
rootSet.erase(it);
|
||||||
if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
|
if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
|
||||||
ret.prepend(item);
|
ret.prepend(item);
|
||||||
foreach (const ProString &dep, dependees[item.toKey()]) {
|
foreach (const ProString &dep, dependees[item.toKey()]) {
|
||||||
QSet<ProKey> &dset = dependencies[dep.toKey()];
|
QSet<ProKey> &dset = dependencies[dep.toKey()];
|
||||||
dset.remove(rootSet.at(i).toKey()); // *Don't* use 'item' - rootSet may have changed!
|
dset.remove(item.toKey());
|
||||||
if (dset.isEmpty())
|
if (dset.isEmpty())
|
||||||
rootSet << dep;
|
rootSet.insert(first(ProKey(prefix + dep + priosfx)).toInt(), dep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1052,10 +1058,18 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
evalError(fL1S("shell_path(path) requires one argument."));
|
evalError(fL1S("shell_path(path) requires one argument."));
|
||||||
} else {
|
} else {
|
||||||
QString rstr = args.at(0).toQString(m_tmp1);
|
QString rstr = args.at(0).toQString(m_tmp1);
|
||||||
if (m_dirSep.startsWith(QLatin1Char('\\')))
|
if (m_dirSep.startsWith(QLatin1Char('\\'))) {
|
||||||
rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||||
else
|
} else {
|
||||||
rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
|
rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Convert d:/foo/bar to msys-style /d/foo/bar.
|
||||||
|
if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) {
|
||||||
|
rstr[1] = rstr.at(0);
|
||||||
|
rstr[0] = QLatin1Char('/');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1079,6 +1093,15 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case E_GETENV:
|
||||||
|
if (args.count() != 1) {
|
||||||
|
evalError(fL1S("getenv(arg) requires one argument."));
|
||||||
|
} else {
|
||||||
|
const ProString &var = args.at(0);
|
||||||
|
const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1)));
|
||||||
|
ret << val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
evalError(fL1S("Function '%1' is not implemented.").arg(func.toQString(m_tmp1)));
|
evalError(fL1S("Function '%1' is not implemented.").arg(func.toQString(m_tmp1)));
|
||||||
break;
|
break;
|
||||||
@@ -1095,7 +1118,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
switch (func_t) {
|
switch (func_t) {
|
||||||
case T_DEFINED: {
|
case T_DEFINED: {
|
||||||
if (args.count() < 1 || args.count() > 2) {
|
if (args.count() < 1 || args.count() > 2) {
|
||||||
evalError(fL1S("defined(function, [\"test\"|\"replace\"])"
|
evalError(fL1S("defined(function, [\"test\"|\"replace\"|\"var\"])"
|
||||||
" requires one or two arguments."));
|
" requires one or two arguments."));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
@@ -1176,15 +1199,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
VisitReturn ret = ReturnFalse;
|
VisitReturn ret = ReturnFalse;
|
||||||
ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
|
ProFile *pro = m_parser->parsedProBlock(args.join(statics.field_sep),
|
||||||
m_current.pro->fileName(), m_current.line);
|
m_current.pro->fileName(), m_current.line);
|
||||||
if (pro) {
|
if (m_cumulative || pro->isOk()) {
|
||||||
if (m_cumulative || pro->isOk()) {
|
m_locationStack.push(m_current);
|
||||||
m_locationStack.push(m_current);
|
visitProBlock(pro, pro->tokPtr());
|
||||||
visitProBlock(pro, pro->tokPtr());
|
ret = ReturnTrue; // This return value is not too useful, but that's qmake
|
||||||
ret = ReturnTrue; // This return value is not too useful, but that's qmake
|
m_current = m_locationStack.pop();
|
||||||
m_current = m_locationStack.pop();
|
|
||||||
}
|
|
||||||
pro->deref();
|
|
||||||
}
|
}
|
||||||
|
pro->deref();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case T_IF: {
|
case T_IF: {
|
||||||
@@ -1256,9 +1277,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
int cnt = values(map(args.at(0))).count();
|
int cnt = values(map(args.at(0))).count();
|
||||||
|
int val = args.at(1).toQString(m_tmp1).toInt();
|
||||||
if (args.count() == 3) {
|
if (args.count() == 3) {
|
||||||
const ProString &comp = args.at(2);
|
const ProString &comp = args.at(2);
|
||||||
const int val = args.at(1).toQString(m_tmp1).toInt();
|
|
||||||
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
|
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
|
||||||
return returnBool(cnt > val);
|
return returnBool(cnt > val);
|
||||||
} else if (comp == QLatin1String(">=")) {
|
} else if (comp == QLatin1String(">=")) {
|
||||||
@@ -1269,13 +1290,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
return returnBool(cnt <= val);
|
return returnBool(cnt <= val);
|
||||||
} else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|
} else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|
||||||
|| comp == QLatin1String("=") || comp == QLatin1String("==")) {
|
|| comp == QLatin1String("=") || comp == QLatin1String("==")) {
|
||||||
return returnBool(cnt == val);
|
// fallthrough
|
||||||
} else {
|
} else {
|
||||||
evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1)));
|
evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1)));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnBool(cnt == args.at(1).toQString(m_tmp1).toInt());
|
return returnBool(cnt == val);
|
||||||
}
|
}
|
||||||
case T_GREATERTHAN:
|
case T_GREATERTHAN:
|
||||||
case T_LESSTHAN: {
|
case T_LESSTHAN: {
|
||||||
@@ -1562,7 +1583,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
GENERIC_READ, FILE_SHARE_READ,
|
GENERIC_READ, FILE_SHARE_READ,
|
||||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (rHand == INVALID_HANDLE_VALUE) {
|
if (rHand == INVALID_HANDLE_VALUE) {
|
||||||
evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode()));
|
evalError(fL1S("Cannot open reference file %1: %2").arg(rfn, windowsErrorCode()));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
FILETIME ft;
|
FILETIME ft;
|
||||||
@@ -1572,7 +1593,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
GENERIC_WRITE, FILE_SHARE_READ,
|
GENERIC_WRITE, FILE_SHARE_READ,
|
||||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (wHand == INVALID_HANDLE_VALUE) {
|
if (wHand == INVALID_HANDLE_VALUE) {
|
||||||
evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode()));
|
evalError(fL1S("Cannot open %1: %2").arg(tfn, windowsErrorCode()));
|
||||||
return ReturnFalse;
|
return ReturnFalse;
|
||||||
}
|
}
|
||||||
SetFileTime(wHand, 0, 0, &ft);
|
SetFileTime(wHand, 0, 0, &ft);
|
||||||
@@ -1667,7 +1688,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
if (mode == CacheAdd)
|
if (mode == CacheAdd)
|
||||||
newval += diffval;
|
newval += diffval;
|
||||||
else
|
else
|
||||||
removeEach(&newval, diffval);
|
newval.removeEach(diffval);
|
||||||
}
|
}
|
||||||
if (oldval != newval) {
|
if (oldval != newval) {
|
||||||
if (target != TargetStash || !m_stashfile.isEmpty()) {
|
if (target != TargetStash || !m_stashfile.isEmpty()) {
|
||||||
@@ -1720,14 +1741,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
if (target == TargetSuper) {
|
if (target == TargetSuper) {
|
||||||
if (m_superfile.isEmpty()) {
|
if (m_superfile.isEmpty()) {
|
||||||
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
|
m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
|
||||||
printf("Info: creating super cache file %s\n", qPrintable(m_superfile));
|
printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
|
||||||
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
|
valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
|
||||||
}
|
}
|
||||||
fn = m_superfile;
|
fn = m_superfile;
|
||||||
} else if (target == TargetCache) {
|
} else if (target == TargetCache) {
|
||||||
if (m_cachefile.isEmpty()) {
|
if (m_cachefile.isEmpty()) {
|
||||||
m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
|
m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
|
||||||
printf("Info: creating cache file %s\n", qPrintable(m_cachefile));
|
printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
|
||||||
valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
|
valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
|
||||||
// We could update m_{source,build}Root and m_featureRoots here, or even
|
// We could update m_{source,build}Root and m_featureRoots here, or even
|
||||||
// "re-home" our rootEnv, but this doesn't sound too useful - if somebody
|
// "re-home" our rootEnv, but this doesn't sound too useful - if somebody
|
||||||
@@ -1741,7 +1762,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
if (fn.isEmpty())
|
if (fn.isEmpty())
|
||||||
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
|
fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
|
||||||
if (!m_vfs->exists(fn)) {
|
if (!m_vfs->exists(fn)) {
|
||||||
printf("Info: creating stash file %s\n", qPrintable(fn));
|
printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
|
||||||
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
|
valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,9 @@
|
|||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
# ifdef Q_OS_BSD4
|
||||||
|
# include <sys/sysctl.h>
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -67,6 +70,39 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
#define fL1S(s) QString::fromLatin1(s)
|
#define fL1S(s) QString::fromLatin1(s)
|
||||||
|
|
||||||
|
// we can't use QThread in qmake
|
||||||
|
// this function is a merger of QThread::idealThreadCount from qthread_win.cpp and qthread_unix.cpp
|
||||||
|
static int idealThreadCount()
|
||||||
|
{
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
return QThread::idealThreadCount();
|
||||||
|
#elif defined(Q_OS_WIN)
|
||||||
|
SYSTEM_INFO sysinfo;
|
||||||
|
GetSystemInfo(&sysinfo);
|
||||||
|
return sysinfo.dwNumberOfProcessors;
|
||||||
|
#else
|
||||||
|
// there are a couple more definitions in the Unix QThread::idealThreadCount, but
|
||||||
|
// we don't need them all here
|
||||||
|
int cores = 1;
|
||||||
|
# if defined(Q_OS_BSD4)
|
||||||
|
// FreeBSD, OpenBSD, NetBSD, BSD/OS, OS X
|
||||||
|
size_t len = sizeof(cores);
|
||||||
|
int mib[2];
|
||||||
|
mib[0] = CTL_HW;
|
||||||
|
mib[1] = HW_NCPU;
|
||||||
|
if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) {
|
||||||
|
perror("sysctl");
|
||||||
|
}
|
||||||
|
# elif defined(_SC_NPROCESSORS_ONLN)
|
||||||
|
// the rest: Linux, Solaris, AIX, Tru64
|
||||||
|
cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
if (cores == -1)
|
||||||
|
return 1;
|
||||||
|
# endif
|
||||||
|
return cores;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _hostBuild)
|
QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _hostBuild)
|
||||||
: root(_root), stash(_stash), hostBuild(_hostBuild)
|
: root(_root), stash(_stash), hostBuild(_hostBuild)
|
||||||
@@ -149,7 +185,8 @@ void QMakeEvaluator::initStatics()
|
|||||||
{ "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" },
|
{ "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" },
|
||||||
{ "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" },
|
{ "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" },
|
||||||
{ "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" },
|
{ "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" },
|
||||||
{ "IN_PWD", "PWD" }
|
{ "IN_PWD", "PWD" },
|
||||||
|
{ "DEPLOYMENT", "INSTALLS" }
|
||||||
};
|
};
|
||||||
for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i)
|
for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i)
|
||||||
statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname));
|
statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname));
|
||||||
@@ -219,24 +256,6 @@ uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProString QMakeEvaluator::getStr(const ushort *&tokPtr)
|
|
||||||
{
|
|
||||||
uint len = *tokPtr++;
|
|
||||||
ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len);
|
|
||||||
ret.setSource(m_current.pro);
|
|
||||||
tokPtr += len;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProKey QMakeEvaluator::getHashStr(const ushort *&tokPtr)
|
|
||||||
{
|
|
||||||
uint hash = getBlockLen(tokPtr);
|
|
||||||
uint len = *tokPtr++;
|
|
||||||
ProKey ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, hash);
|
|
||||||
tokPtr += len;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMakeEvaluator::skipStr(const ushort *&tokPtr)
|
void QMakeEvaluator::skipStr(const ushort *&tokPtr)
|
||||||
{
|
{
|
||||||
uint len = *tokPtr++;
|
uint len = *tokPtr++;
|
||||||
@@ -275,7 +294,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
|
|||||||
switch (unicode) {
|
switch (unicode) {
|
||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
quote = unicode;
|
if (!quote)
|
||||||
|
quote = unicode;
|
||||||
hadWord = true;
|
hadWord = true;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
@@ -311,34 +331,6 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zipEmpty(ProStringList *value)
|
|
||||||
{
|
|
||||||
for (int i = value->size(); --i >= 0;)
|
|
||||||
if (value->at(i).isEmpty())
|
|
||||||
value->remove(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void insertUnique(ProStringList *varlist, const ProStringList &value)
|
|
||||||
{
|
|
||||||
foreach (const ProString &str, value)
|
|
||||||
if (!str.isEmpty() && !varlist->contains(str))
|
|
||||||
varlist->append(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void removeAll(ProStringList *varlist, const ProString &value)
|
|
||||||
{
|
|
||||||
for (int i = varlist->size(); --i >= 0; )
|
|
||||||
if (varlist->at(i) == value)
|
|
||||||
varlist->remove(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMakeEvaluator::removeEach(ProStringList *varlist, const ProStringList &value)
|
|
||||||
{
|
|
||||||
foreach (const ProString &str, value)
|
|
||||||
if (!str.isEmpty())
|
|
||||||
removeAll(varlist, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void replaceInList(ProStringList *varlist,
|
static void replaceInList(ProStringList *varlist,
|
||||||
const QRegExp ®exp, const QString &replace, bool global, QString &tmp)
|
const QRegExp ®exp, const QString &replace, bool global, QString &tmp)
|
||||||
{
|
{
|
||||||
@@ -418,6 +410,7 @@ void QMakeEvaluator::evaluateExpression(
|
|||||||
const ushort *&tokPtr, ProStringList *ret, bool joined)
|
const ushort *&tokPtr, ProStringList *ret, bool joined)
|
||||||
{
|
{
|
||||||
debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
|
debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
|
||||||
|
ProFile *pro = m_current.pro;
|
||||||
if (joined)
|
if (joined)
|
||||||
*ret << ProString();
|
*ret << ProString();
|
||||||
bool pending = false;
|
bool pending = false;
|
||||||
@@ -433,35 +426,35 @@ void QMakeEvaluator::evaluateExpression(
|
|||||||
m_current.line = *tokPtr++;
|
m_current.line = *tokPtr++;
|
||||||
break;
|
break;
|
||||||
case TokLiteral: {
|
case TokLiteral: {
|
||||||
const ProString &val = getStr(tokPtr);
|
const ProString &val = pro->getStr(tokPtr);
|
||||||
debugMsg(2, "literal %s", dbgStr(val));
|
debugMsg(2, "literal %s", dbgStr(val));
|
||||||
addStr(val, ret, pending, joined);
|
addStr(val, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
case TokHashLiteral: {
|
case TokHashLiteral: {
|
||||||
const ProKey &val = getHashStr(tokPtr);
|
const ProKey &val = pro->getHashStr(tokPtr);
|
||||||
debugMsg(2, "hashed literal %s", dbgStr(val.toString()));
|
debugMsg(2, "hashed literal %s", dbgStr(val.toString()));
|
||||||
addStr(val, ret, pending, joined);
|
addStr(val, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
case TokVariable: {
|
case TokVariable: {
|
||||||
const ProKey &var = getHashStr(tokPtr);
|
const ProKey &var = pro->getHashStr(tokPtr);
|
||||||
const ProStringList &val = values(map(var));
|
const ProStringList &val = values(map(var));
|
||||||
debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val));
|
debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val));
|
||||||
addStrList(val, tok, ret, pending, joined);
|
addStrList(val, tok, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
case TokProperty: {
|
case TokProperty: {
|
||||||
const ProKey &var = getHashStr(tokPtr);
|
const ProKey &var = pro->getHashStr(tokPtr);
|
||||||
const ProString &val = propertyValue(var);
|
const ProString &val = propertyValue(var);
|
||||||
debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val));
|
debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val));
|
||||||
addStr(val, ret, pending, joined);
|
addStr(val, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
case TokEnvVar: {
|
case TokEnvVar: {
|
||||||
const ProString &var = getStr(tokPtr);
|
const ProString &var = pro->getStr(tokPtr);
|
||||||
const ProString &val = ProString(m_option->getEnv(var.toQString()));
|
const ProString &val = ProString(m_option->getEnv(var.toQString()));
|
||||||
debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val));
|
debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val));
|
||||||
addStr(val, ret, pending, joined);
|
addStr(val, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
case TokFuncName: {
|
case TokFuncName: {
|
||||||
const ProKey &func = getHashStr(tokPtr);
|
const ProKey &func = pro->getHashStr(tokPtr);
|
||||||
debugMsg(2, "function %s", dbgKey(func));
|
debugMsg(2, "function %s", dbgKey(func));
|
||||||
addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined);
|
addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined);
|
||||||
break; }
|
break; }
|
||||||
@@ -526,6 +519,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
|
|||||||
{
|
{
|
||||||
traceMsg("entering block");
|
traceMsg("entering block");
|
||||||
ProStringList curr;
|
ProStringList curr;
|
||||||
|
ProFile *pro = m_current.pro;
|
||||||
bool okey = true, or_op = false, invert = false;
|
bool okey = true, or_op = false, invert = false;
|
||||||
uint blockLen;
|
uint blockLen;
|
||||||
while (ushort tok = *tokPtr++) {
|
while (ushort tok = *tokPtr++) {
|
||||||
@@ -579,7 +573,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
|
|||||||
break;
|
break;
|
||||||
case TokForLoop:
|
case TokForLoop:
|
||||||
if (m_cumulative || okey != or_op) {
|
if (m_cumulative || okey != or_op) {
|
||||||
const ProKey &variable = getHashStr(tokPtr);
|
const ProKey &variable = pro->getHashStr(tokPtr);
|
||||||
uint exprLen = getBlockLen(tokPtr);
|
uint exprLen = getBlockLen(tokPtr);
|
||||||
const ushort *exprPtr = tokPtr;
|
const ushort *exprPtr = tokPtr;
|
||||||
tokPtr += exprLen;
|
tokPtr += exprLen;
|
||||||
@@ -599,7 +593,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
|
|||||||
case TokTestDef:
|
case TokTestDef:
|
||||||
case TokReplaceDef:
|
case TokReplaceDef:
|
||||||
if (m_cumulative || okey != or_op) {
|
if (m_cumulative || okey != or_op) {
|
||||||
const ProKey &name = getHashStr(tokPtr);
|
const ProKey &name = pro->getHashStr(tokPtr);
|
||||||
blockLen = getBlockLen(tokPtr);
|
blockLen = getBlockLen(tokPtr);
|
||||||
visitProFunctionDef(tok, name, tokPtr);
|
visitProFunctionDef(tok, name, tokPtr);
|
||||||
traceMsg("defined %s function %s",
|
traceMsg("defined %s function %s",
|
||||||
@@ -790,8 +784,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
|
|||||||
forever {
|
forever {
|
||||||
if (infinite) {
|
if (infinite) {
|
||||||
if (!variable.isEmpty())
|
if (!variable.isEmpty())
|
||||||
m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++)));
|
m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index)));
|
||||||
if (index > 1000) {
|
if (++index > 1000) {
|
||||||
evalError(fL1S("Ran into infinite loop (> 1000 iterations)."));
|
evalError(fL1S("Ran into infinite loop (> 1000 iterations)."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -882,24 +876,24 @@ void QMakeEvaluator::visitProVariable(
|
|||||||
switch (tok) {
|
switch (tok) {
|
||||||
default: // whatever - cannot happen
|
default: // whatever - cannot happen
|
||||||
case TokAssign: // =
|
case TokAssign: // =
|
||||||
zipEmpty(&varVal);
|
varVal.removeEmpty();
|
||||||
// FIXME: add check+warning about accidental value removal.
|
// FIXME: add check+warning about accidental value removal.
|
||||||
// This may be a bit too noisy, though.
|
// This may be a bit too noisy, though.
|
||||||
m_valuemapStack.top()[varName] = varVal;
|
m_valuemapStack.top()[varName] = varVal;
|
||||||
debugMsg(2, "assigning");
|
debugMsg(2, "assigning");
|
||||||
break;
|
break;
|
||||||
case TokAppendUnique: // *=
|
case TokAppendUnique: // *=
|
||||||
insertUnique(&valuesRef(varName), varVal);
|
valuesRef(varName).insertUnique(varVal);
|
||||||
debugMsg(2, "appending unique");
|
debugMsg(2, "appending unique");
|
||||||
break;
|
break;
|
||||||
case TokAppend: // +=
|
case TokAppend: // +=
|
||||||
zipEmpty(&varVal);
|
varVal.removeEmpty();
|
||||||
valuesRef(varName) += varVal;
|
valuesRef(varName) += varVal;
|
||||||
debugMsg(2, "appending");
|
debugMsg(2, "appending");
|
||||||
break;
|
break;
|
||||||
case TokRemove: // -=
|
case TokRemove: // -=
|
||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
removeEach(&valuesRef(varName), varVal);
|
valuesRef(varName).removeEach(varVal);
|
||||||
} else {
|
} else {
|
||||||
// We are stingy with our values.
|
// We are stingy with our values.
|
||||||
}
|
}
|
||||||
@@ -949,6 +943,49 @@ void QMakeEvaluator::setTemplate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(Q_CC_MSVC)
|
||||||
|
static ProString msvcBinDirToQMakeArch(QString subdir)
|
||||||
|
{
|
||||||
|
int idx = subdir.indexOf(QLatin1Char('\\'));
|
||||||
|
if (idx == -1)
|
||||||
|
return ProString("x86");
|
||||||
|
subdir.remove(0, idx + 1);
|
||||||
|
idx = subdir.indexOf(QLatin1Char('_'));
|
||||||
|
if (idx >= 0)
|
||||||
|
subdir.remove(0, idx + 1);
|
||||||
|
subdir = subdir.toLower();
|
||||||
|
if (subdir == QStringLiteral("amd64"))
|
||||||
|
return ProString("x86_64");
|
||||||
|
return ProString(subdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProString defaultMsvcArchitecture()
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_WIN64)
|
||||||
|
return ProString("x86_64");
|
||||||
|
#else
|
||||||
|
return ProString("x86");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProString msvcArchitecture(const QString &vcInstallDir, const QString &pathVar)
|
||||||
|
{
|
||||||
|
if (vcInstallDir.isEmpty())
|
||||||
|
return defaultMsvcArchitecture();
|
||||||
|
QString vcBinDir = vcInstallDir;
|
||||||
|
if (vcBinDir.endsWith(QLatin1Char('\\')))
|
||||||
|
vcBinDir.chop(1);
|
||||||
|
foreach (const QString &dir, pathVar.split(QLatin1Char(';'))) {
|
||||||
|
if (!dir.startsWith(vcBinDir, Qt::CaseInsensitive))
|
||||||
|
continue;
|
||||||
|
const ProString arch = msvcBinDirToQMakeArch(dir.mid(vcBinDir.length() + 1));
|
||||||
|
if (!arch.isEmpty())
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
return defaultMsvcArchitecture();
|
||||||
|
}
|
||||||
|
#endif // defined(Q_CC_MSVC)
|
||||||
|
|
||||||
void QMakeEvaluator::loadDefaults()
|
void QMakeEvaluator::loadDefaults()
|
||||||
{
|
{
|
||||||
ProValueMap &vars = m_valuemapStack.top();
|
ProValueMap &vars = m_valuemapStack.top();
|
||||||
@@ -960,6 +997,7 @@ void QMakeEvaluator::loadDefaults()
|
|||||||
vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation);
|
vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation);
|
||||||
if (!m_option->qmake_args.isEmpty())
|
if (!m_option->qmake_args.isEmpty())
|
||||||
vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args);
|
vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args);
|
||||||
|
vars[ProKey("QMAKE_HOST.cpu_count")] = ProString(QString::number(idealThreadCount()));
|
||||||
#if defined(Q_OS_WIN32)
|
#if defined(Q_OS_WIN32)
|
||||||
vars[ProKey("QMAKE_HOST.os")] << ProString("Windows");
|
vars[ProKey("QMAKE_HOST.os")] << ProString("Windows");
|
||||||
|
|
||||||
@@ -1009,21 +1047,9 @@ void QMakeEvaluator::loadDefaults()
|
|||||||
vars[ProKey("QMAKE_HOST.arch")] << archStr;
|
vars[ProKey("QMAKE_HOST.arch")] << archStr;
|
||||||
|
|
||||||
# if defined(Q_CC_MSVC) // ### bogus condition, but nobody x-builds for msvc with a different qmake
|
# if defined(Q_CC_MSVC) // ### bogus condition, but nobody x-builds for msvc with a different qmake
|
||||||
QLatin1Char backslash('\\');
|
vars[ProKey("QMAKE_TARGET.arch")] = msvcArchitecture(
|
||||||
QString paths = m_option->getEnv(QLatin1String("PATH"));
|
m_option->getEnv(QLatin1String("VCINSTALLDIR")),
|
||||||
QString vcBin64 = m_option->getEnv(QLatin1String("VCINSTALLDIR"));
|
m_option->getEnv(QLatin1String("PATH")));
|
||||||
if (!vcBin64.endsWith(backslash))
|
|
||||||
vcBin64.append(backslash);
|
|
||||||
vcBin64.append(QLatin1String("bin\\amd64"));
|
|
||||||
QString vcBinX86_64 = m_option->getEnv(QLatin1String("VCINSTALLDIR"));
|
|
||||||
if (!vcBinX86_64.endsWith(backslash))
|
|
||||||
vcBinX86_64.append(backslash);
|
|
||||||
vcBinX86_64.append(QLatin1String("bin\\x86_amd64"));
|
|
||||||
if (paths.contains(vcBin64, Qt::CaseInsensitive)
|
|
||||||
|| paths.contains(vcBinX86_64, Qt::CaseInsensitive))
|
|
||||||
vars[ProKey("QMAKE_TARGET.arch")] << ProString("x86_64");
|
|
||||||
else
|
|
||||||
vars[ProKey("QMAKE_TARGET.arch")] << ProString("x86");
|
|
||||||
# endif
|
# endif
|
||||||
#elif defined(Q_OS_UNIX)
|
#elif defined(Q_OS_UNIX)
|
||||||
struct utsname name;
|
struct utsname name;
|
||||||
@@ -1247,14 +1273,13 @@ void QMakeEvaluator::setupProject()
|
|||||||
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
|
||||||
{
|
{
|
||||||
if (!cmds.isEmpty()) {
|
if (!cmds.isEmpty()) {
|
||||||
if (ProFile *pro = m_parser->parsedProBlock(cmds, where, -1)) {
|
ProFile *pro = m_parser->parsedProBlock(cmds, where, -1);
|
||||||
if (pro->isOk()) {
|
if (pro->isOk()) {
|
||||||
m_locationStack.push(m_current);
|
m_locationStack.push(m_current);
|
||||||
visitProBlock(pro, pro->tokPtr());
|
visitProBlock(pro, pro->tokPtr());
|
||||||
m_current = m_locationStack.pop();
|
m_current = m_locationStack.pop();
|
||||||
}
|
|
||||||
pro->deref();
|
|
||||||
}
|
}
|
||||||
|
pro->deref();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1734,14 +1759,12 @@ bool QMakeEvaluator::evaluateConditional(const QString &cond, const QString &whe
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
|
ProFile *pro = m_parser->parsedProBlock(cond, where, line, QMakeParser::TestGrammar);
|
||||||
if (pro) {
|
if (pro->isOk()) {
|
||||||
if (pro->isOk()) {
|
m_locationStack.push(m_current);
|
||||||
m_locationStack.push(m_current);
|
ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
|
||||||
ret = visitProBlock(pro, pro->tokPtr()) == ReturnTrue;
|
m_current = m_locationStack.pop();
|
||||||
m_current = m_locationStack.pop();
|
|
||||||
}
|
|
||||||
pro->deref();
|
|
||||||
}
|
}
|
||||||
|
pro->deref();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,8 +38,10 @@
|
|||||||
#include "qmakeparser.h"
|
#include "qmakeparser.h"
|
||||||
#include "ioutils.h"
|
#include "ioutils.h"
|
||||||
|
|
||||||
|
#include <qiodevice.h>
|
||||||
#include <qlist.h>
|
#include <qlist.h>
|
||||||
#include <qlinkedlist.h>
|
#include <qlinkedlist.h>
|
||||||
|
#include <qmap.h>
|
||||||
#include <qset.h>
|
#include <qset.h>
|
||||||
#include <qstack.h>
|
#include <qstack.h>
|
||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
@@ -145,8 +147,6 @@ public:
|
|||||||
{ return b ? ReturnTrue : ReturnFalse; }
|
{ return b ? ReturnTrue : ReturnFalse; }
|
||||||
|
|
||||||
static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
|
static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr);
|
||||||
ProString getStr(const ushort *&tokPtr);
|
|
||||||
ProKey getHashStr(const ushort *&tokPtr);
|
|
||||||
void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
|
void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined);
|
||||||
static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
|
static ALWAYS_INLINE void skipStr(const ushort *&tokPtr);
|
||||||
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
|
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
|
||||||
@@ -227,8 +227,9 @@ public:
|
|||||||
|
|
||||||
void populateDeps(
|
void populateDeps(
|
||||||
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
|
const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
|
||||||
QHash<ProKey, QSet<ProKey> > &dependencies,
|
const ProString &priosfx,
|
||||||
ProValueMap &dependees, ProStringList &rootSet) const;
|
QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
|
||||||
|
QMultiMap<int, ProString> &rootSet) const;
|
||||||
|
|
||||||
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
|
||||||
const QString &contents);
|
const QString &contents);
|
||||||
@@ -237,8 +238,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
QByteArray getCommandOutput(const QString &args) const;
|
QByteArray getCommandOutput(const QString &args) const;
|
||||||
|
|
||||||
static void removeEach(ProStringList *varlist, const ProStringList &value);
|
|
||||||
|
|
||||||
QMakeEvaluator *m_caller;
|
QMakeEvaluator *m_caller;
|
||||||
#ifdef PROEVALUATOR_CUMULATIVE
|
#ifdef PROEVALUATOR_CUMULATIVE
|
||||||
bool m_cumulative;
|
bool m_cumulative;
|
||||||
@@ -248,6 +247,8 @@ public:
|
|||||||
enum { m_skipLevel = 0 };
|
enum { m_skipLevel = 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static QString quoteValue(const ProString &val);
|
||||||
|
|
||||||
#ifdef PROEVALUATOR_DEBUG
|
#ifdef PROEVALUATOR_DEBUG
|
||||||
void debugMsgInternal(int level, const char *fmt, ...) const;
|
void debugMsgInternal(int level, const char *fmt, ...) const;
|
||||||
void traceMsgInternal(const char *fmt, ...) const;
|
void traceMsgInternal(const char *fmt, ...) const;
|
||||||
@@ -306,6 +307,7 @@ public:
|
|||||||
QMakeHandler *m_handler;
|
QMakeHandler *m_handler;
|
||||||
QMakeVfs *m_vfs;
|
QMakeVfs *m_vfs;
|
||||||
};
|
};
|
||||||
|
Q_DECLARE_TYPEINFO(QMakeEvaluator::Location, Q_PRIMITIVE_TYPE);
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags)
|
||||||
|
|
||||||
|
@@ -132,6 +132,7 @@ public:
|
|||||||
bool initProperties();
|
bool initProperties();
|
||||||
# else
|
# else
|
||||||
void setProperties(const QHash<QString, QString> &props);
|
void setProperties(const QHash<QString, QString> &props);
|
||||||
|
void setProperties(const QHash<ProKey, ProString> &props) { properties = props; }
|
||||||
# endif
|
# endif
|
||||||
ProString propertyValue(const ProKey &name) const { return properties.value(name); }
|
ProString propertyValue(const ProKey &name) const { return properties.value(name); }
|
||||||
#endif
|
#endif
|
||||||
|
@@ -229,10 +229,7 @@ ProFile *QMakeParser::parsedProBlock(
|
|||||||
const QString &contents, const QString &name, int line, SubGrammar grammar)
|
const QString &contents, const QString &name, int line, SubGrammar grammar)
|
||||||
{
|
{
|
||||||
ProFile *pro = new ProFile(name);
|
ProFile *pro = new ProFile(name);
|
||||||
if (!read(pro, contents, line, grammar)) {
|
read(pro, contents, line, grammar);
|
||||||
delete pro;
|
|
||||||
pro = 0;
|
|
||||||
}
|
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +249,8 @@ bool QMakeParser::read(ProFile *pro, ParseFlags flags)
|
|||||||
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
|
fL1S("Cannot read %1: %2").arg(pro->fileName(), errStr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return read(pro, content, 1, FullGrammar);
|
read(pro, content, 1, FullGrammar);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMakeParser::putTok(ushort *&tokPtr, ushort tok)
|
void QMakeParser::putTok(ushort *&tokPtr, ushort tok)
|
||||||
@@ -292,7 +290,7 @@ void QMakeParser::finalizeHashStr(ushort *buf, uint len)
|
|||||||
buf[-2] = (ushort)(hash >> 16);
|
buf[-2] = (ushort)(hash >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
|
void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar grammar)
|
||||||
{
|
{
|
||||||
m_proFile = pro;
|
m_proFile = pro;
|
||||||
m_lineNo = line;
|
m_lineNo = line;
|
||||||
@@ -342,7 +340,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
m_canElse = false;
|
m_canElse = false;
|
||||||
freshLine:
|
freshLine:
|
||||||
m_state = StNew;
|
m_state = StNew;
|
||||||
m_invert = false;
|
m_invert = 0;
|
||||||
m_operator = NoOperator;
|
m_operator = NoOperator;
|
||||||
m_markLine = m_lineNo;
|
m_markLine = m_lineNo;
|
||||||
m_inError = false;
|
m_inError = false;
|
||||||
@@ -599,7 +597,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
parseError(fL1S("Missing %1 terminator [found %2]")
|
parseError(fL1S("Missing %1 terminator [found %2]")
|
||||||
.arg(QChar(term))
|
.arg(QChar(term))
|
||||||
.arg(c ? QString(c) : QString::fromLatin1("end-of-line")));
|
.arg(c ? QString(c) : QString::fromLatin1("end-of-line")));
|
||||||
pro->setOk(false);
|
|
||||||
m_inError = true;
|
m_inError = true;
|
||||||
// Just parse on, as if there was a terminator ...
|
// Just parse on, as if there was a terminator ...
|
||||||
} else {
|
} else {
|
||||||
@@ -626,7 +623,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
quote = 0;
|
quote = 0;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
} else if (c == '!' && ptr == xprPtr && context == CtxTest) {
|
} else if (c == '!' && ptr == xprPtr && context == CtxTest) {
|
||||||
m_invert ^= true;
|
m_invert++;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
}
|
}
|
||||||
} else if (c == '\'' || c == '"') {
|
} else if (c == '\'' || c == '"') {
|
||||||
@@ -683,20 +680,20 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
parseError(fL1S("Extra characters after test expression."));
|
parseError(fL1S("Extra characters after test expression."));
|
||||||
else
|
else
|
||||||
parseError(fL1S("Opening parenthesis without prior test name."));
|
parseError(fL1S("Opening parenthesis without prior test name."));
|
||||||
pro->setOk(false);
|
|
||||||
ptr = buf; // Put empty function name
|
ptr = buf; // Put empty function name
|
||||||
}
|
}
|
||||||
*ptr++ = TokTestCall;
|
*ptr++ = TokTestCall;
|
||||||
term = ':';
|
term = ':';
|
||||||
goto funcCall;
|
goto funcCall;
|
||||||
} else if (c == '!' && ptr == xprPtr) {
|
} else if (c == '!' && ptr == xprPtr) {
|
||||||
m_invert ^= true;
|
m_invert++;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
} else if (c == ':') {
|
} else if (c == ':') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("in front of AND operator");
|
||||||
if (m_state == StNew)
|
if (m_state == StNew)
|
||||||
parseError(fL1S("And operator without prior condition."));
|
parseError(fL1S("AND operator without prior condition."));
|
||||||
else
|
else
|
||||||
m_operator = AndOperator;
|
m_operator = AndOperator;
|
||||||
nextItem:
|
nextItem:
|
||||||
@@ -705,26 +702,33 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
} else if (c == '|') {
|
} else if (c == '|') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("in front of OR operator");
|
||||||
if (m_state != StCond)
|
if (m_state != StCond)
|
||||||
parseError(fL1S("Or operator without prior condition."));
|
parseError(fL1S("OR operator without prior condition."));
|
||||||
else
|
else
|
||||||
m_operator = OrOperator;
|
m_operator = OrOperator;
|
||||||
goto nextItem;
|
goto nextItem;
|
||||||
} else if (c == '{') {
|
} else if (c == '{') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
flushCond(tokPtr);
|
if (m_operator == AndOperator) {
|
||||||
++m_blockstack.top().braceLevel;
|
languageWarning(fL1S("Excess colon in front of opening brace."));
|
||||||
if (grammar == TestGrammar) {
|
m_operator = NoOperator;
|
||||||
parseError(fL1S("Opening scope not permitted in this context."));
|
|
||||||
pro->setOk(false);
|
|
||||||
}
|
}
|
||||||
|
failOperator("in front of opening brace");
|
||||||
|
flushCond(tokPtr);
|
||||||
|
m_state = StNew; // Reset possible StCtrl, so colons get rejected.
|
||||||
|
++m_blockstack.top().braceLevel;
|
||||||
|
if (grammar == TestGrammar)
|
||||||
|
parseError(fL1S("Opening scope not permitted in this context."));
|
||||||
goto nextItem;
|
goto nextItem;
|
||||||
} else if (c == '}') {
|
} else if (c == '}') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
flushScopes(tokPtr);
|
m_state = StNew; // De-facto newline
|
||||||
closeScope:
|
closeScope:
|
||||||
|
flushScopes(tokPtr);
|
||||||
|
failOperator("in front of closing brace");
|
||||||
if (!m_blockstack.top().braceLevel) {
|
if (!m_blockstack.top().braceLevel) {
|
||||||
parseError(fL1S("Excess closing brace."));
|
parseError(fL1S("Excess closing brace."));
|
||||||
} else if (!--m_blockstack.top().braceLevel
|
} else if (!--m_blockstack.top().braceLevel
|
||||||
@@ -756,13 +760,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
doOp:
|
doOp:
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
flushCond(tokPtr);
|
flushCond(tokPtr);
|
||||||
|
acceptColon("in front of assignment");
|
||||||
putLineMarker(tokPtr);
|
putLineMarker(tokPtr);
|
||||||
if (grammar == TestGrammar) {
|
if (grammar == TestGrammar) {
|
||||||
parseError(fL1S("Assignment not permitted in this context."));
|
parseError(fL1S("Assignment not permitted in this context."));
|
||||||
pro->setOk(false);
|
|
||||||
} else if (wordCount != 1) {
|
} else if (wordCount != 1) {
|
||||||
parseError(fL1S("Assignment needs exactly one word on the left hand side."));
|
parseError(fL1S("Assignment needs exactly one word on the left hand side."));
|
||||||
pro->setOk(false);
|
|
||||||
// Put empty variable name.
|
// Put empty variable name.
|
||||||
} else {
|
} else {
|
||||||
putBlock(tokPtr, buf, ptr - buf);
|
putBlock(tokPtr, buf, ptr - buf);
|
||||||
@@ -831,7 +834,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
} else if (context == CtxPureValue) {
|
} else if (context == CtxPureValue) {
|
||||||
putTok(tokPtr, TokValueTerminator);
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
bogusTest(tokPtr);
|
bogusTest(tokPtr, QString());
|
||||||
}
|
}
|
||||||
} else if (context == CtxValue) {
|
} else if (context == CtxValue) {
|
||||||
FLUSH_VALUE_LIST();
|
FLUSH_VALUE_LIST();
|
||||||
@@ -842,6 +845,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
putTok(tokPtr, TokValueTerminator);
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("at end of line");
|
||||||
}
|
}
|
||||||
if (!cur)
|
if (!cur)
|
||||||
break;
|
break;
|
||||||
@@ -857,15 +861,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
}
|
}
|
||||||
|
|
||||||
flushScopes(tokPtr);
|
flushScopes(tokPtr);
|
||||||
if (m_blockstack.size() > 1) {
|
if (m_blockstack.size() > 1 || m_blockstack.top().braceLevel)
|
||||||
parseError(fL1S("Missing closing brace(s)."));
|
parseError(fL1S("Missing closing brace(s)."));
|
||||||
pro->setOk(false);
|
|
||||||
}
|
|
||||||
while (m_blockstack.size())
|
while (m_blockstack.size())
|
||||||
leaveScope(tokPtr);
|
leaveScope(tokPtr);
|
||||||
tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays
|
tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays
|
||||||
*pro->itemsRef() = tokBuff;
|
*pro->itemsRef() = tokBuff;
|
||||||
return true;
|
|
||||||
|
|
||||||
#undef FLUSH_VALUE_LIST
|
#undef FLUSH_VALUE_LIST
|
||||||
#undef FLUSH_LITERAL
|
#undef FLUSH_LITERAL
|
||||||
@@ -938,39 +939,90 @@ void QMakeParser::flushCond(ushort *&tokPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QMakeParser::warnOperator(const char *msg)
|
||||||
|
{
|
||||||
|
if (m_invert) {
|
||||||
|
languageWarning(fL1S("Stray NOT operator %1.").arg(fL1S(msg)));
|
||||||
|
m_invert = 0;
|
||||||
|
}
|
||||||
|
if (m_operator == AndOperator) {
|
||||||
|
languageWarning(fL1S("Stray AND operator %1.").arg(fL1S(msg)));
|
||||||
|
m_operator = NoOperator;
|
||||||
|
} else if (m_operator == OrOperator) {
|
||||||
|
languageWarning(fL1S("Stray OR operator %1.").arg(fL1S(msg)));
|
||||||
|
m_operator = NoOperator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMakeParser::failOperator(const char *msg)
|
||||||
|
{
|
||||||
|
bool fail = false;
|
||||||
|
if (m_invert) {
|
||||||
|
parseError(fL1S("Unexpected NOT operator %1.").arg(fL1S(msg)));
|
||||||
|
m_invert = 0;
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
if (m_operator == AndOperator) {
|
||||||
|
parseError(fL1S("Unexpected AND operator %1.").arg(fL1S(msg)));
|
||||||
|
m_operator = NoOperator;
|
||||||
|
fail = true;
|
||||||
|
} else if (m_operator == OrOperator) {
|
||||||
|
parseError(fL1S("Unexpected OR operator %1.").arg(fL1S(msg)));
|
||||||
|
m_operator = NoOperator;
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMakeParser::acceptColon(const char *msg)
|
||||||
|
{
|
||||||
|
if (m_operator == AndOperator)
|
||||||
|
m_operator = NoOperator;
|
||||||
|
return !failOperator(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMakeParser::putOperator(ushort *&tokPtr)
|
||||||
|
{
|
||||||
|
if (m_operator== AndOperator) {
|
||||||
|
// A colon must be used after else and for() if no brace is used,
|
||||||
|
// but in this case it is obviously not a binary operator.
|
||||||
|
if (m_state == StCond)
|
||||||
|
putTok(tokPtr, TokAnd);
|
||||||
|
m_operator = NoOperator;
|
||||||
|
} else if (m_operator == OrOperator) {
|
||||||
|
putTok(tokPtr, TokOr);
|
||||||
|
m_operator = NoOperator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QMakeParser::finalizeTest(ushort *&tokPtr)
|
void QMakeParser::finalizeTest(ushort *&tokPtr)
|
||||||
{
|
{
|
||||||
flushScopes(tokPtr);
|
flushScopes(tokPtr);
|
||||||
putLineMarker(tokPtr);
|
putLineMarker(tokPtr);
|
||||||
if (m_operator != NoOperator) {
|
putOperator(tokPtr);
|
||||||
putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
|
if (m_invert & 1)
|
||||||
m_operator = NoOperator;
|
|
||||||
}
|
|
||||||
if (m_invert) {
|
|
||||||
putTok(tokPtr, TokNot);
|
putTok(tokPtr, TokNot);
|
||||||
m_invert = false;
|
m_invert = 0;
|
||||||
}
|
|
||||||
m_state = StCond;
|
m_state = StCond;
|
||||||
m_canElse = true;
|
m_canElse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMakeParser::bogusTest(ushort *&tokPtr)
|
void QMakeParser::bogusTest(ushort *&tokPtr, const QString &msg)
|
||||||
{
|
{
|
||||||
|
if (!msg.isEmpty())
|
||||||
|
parseError(msg);
|
||||||
flushScopes(tokPtr);
|
flushScopes(tokPtr);
|
||||||
m_operator = NoOperator;
|
m_operator = NoOperator;
|
||||||
m_invert = false;
|
m_invert = 0;
|
||||||
m_state = StCond;
|
m_state = StCond;
|
||||||
m_canElse = true;
|
m_canElse = true;
|
||||||
m_proFile->setOk(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
|
void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
|
||||||
{
|
{
|
||||||
if (wordCount != 1) {
|
if (wordCount != 1) {
|
||||||
if (wordCount) {
|
if (wordCount)
|
||||||
parseError(fL1S("Extra characters after test expression."));
|
bogusTest(tokPtr, fL1S("Extra characters after test expression."));
|
||||||
bogusTest(tokPtr);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,10 +1033,8 @@ void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wor
|
|||||||
if (uce == ptr) {
|
if (uce == ptr) {
|
||||||
m_tmp.setRawData((QChar *)uc + 4, nlen);
|
m_tmp.setRawData((QChar *)uc + 4, nlen);
|
||||||
if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
|
if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
|
||||||
if (m_invert || m_operator != NoOperator) {
|
if (failOperator("in front of else"))
|
||||||
parseError(fL1S("Unexpected operator in front of else."));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
BlockScope &top = m_blockstack.top();
|
BlockScope &top = m_blockstack.top();
|
||||||
if (m_canElse && (!top.special || top.braceLevel)) {
|
if (m_canElse && (!top.special || top.braceLevel)) {
|
||||||
// A list of tests (the last one likely with side effects),
|
// A list of tests (the last one likely with side effects),
|
||||||
@@ -1029,18 +1079,18 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
const QString *defName;
|
const QString *defName;
|
||||||
ushort defType;
|
ushort defType;
|
||||||
if (m_tmp == statics.strfor) {
|
if (m_tmp == statics.strfor) {
|
||||||
if (m_invert || m_operator == OrOperator) {
|
if (!acceptColon("in front of for()")) {
|
||||||
// '|' could actually work reasonably, but qmake does nonsense here.
|
bogusTest(tokPtr, QString());
|
||||||
parseError(fL1S("Unexpected operator in front of for()."));
|
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flushCond(tokPtr);
|
flushCond(tokPtr);
|
||||||
putLineMarker(tokPtr);
|
putLineMarker(tokPtr);
|
||||||
|
--ptr;
|
||||||
|
Q_ASSERT(*ptr == TokFuncTerminator);
|
||||||
if (*uce == (TokLiteral|TokNewStr)) {
|
if (*uce == (TokLiteral|TokNewStr)) {
|
||||||
nlen = uce[1];
|
nlen = uce[1];
|
||||||
uc = uce + 2 + nlen;
|
uc = uce + 2 + nlen;
|
||||||
if (*uc == TokFuncTerminator) {
|
if (uc == ptr) {
|
||||||
// for(literal) (only "ever" would be legal if qmake was sane)
|
// for(literal) (only "ever" would be legal if qmake was sane)
|
||||||
putTok(tokPtr, TokForLoop);
|
putTok(tokPtr, TokForLoop);
|
||||||
putHashStr(tokPtr, (ushort *)0, (uint)0);
|
putHashStr(tokPtr, (ushort *)0, (uint)0);
|
||||||
@@ -1081,8 +1131,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
defType = TokTestDef;
|
defType = TokTestDef;
|
||||||
deffunc:
|
deffunc:
|
||||||
if (m_invert) {
|
if (m_invert) {
|
||||||
parseError(fL1S("Unexpected operator in front of function definition."));
|
bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of function definition."));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flushScopes(tokPtr);
|
flushScopes(tokPtr);
|
||||||
@@ -1090,10 +1139,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
if (*uce == (TokLiteral|TokNewStr)) {
|
if (*uce == (TokLiteral|TokNewStr)) {
|
||||||
uint nlen = uce[1];
|
uint nlen = uce[1];
|
||||||
if (uce[nlen + 2] == TokFuncTerminator) {
|
if (uce[nlen + 2] == TokFuncTerminator) {
|
||||||
if (m_operator != NoOperator) {
|
putOperator(tokPtr);
|
||||||
putTok(tokPtr, (m_operator == AndOperator) ? TokAnd : TokOr);
|
|
||||||
m_operator = NoOperator;
|
|
||||||
}
|
|
||||||
putTok(tokPtr, defType);
|
putTok(tokPtr, defType);
|
||||||
putHashStr(tokPtr, uce + 2, nlen);
|
putHashStr(tokPtr, uce + 2, nlen);
|
||||||
enterScope(tokPtr, true, StCtrl);
|
enterScope(tokPtr, true, StCtrl);
|
||||||
@@ -1106,14 +1152,12 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
} else if (m_tmp == statics.strreturn) {
|
} else if (m_tmp == statics.strreturn) {
|
||||||
if (m_blockstack.top().nest & NestFunction) {
|
if (m_blockstack.top().nest & NestFunction) {
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
parseError(fL1S("return() requires zero or one argument."));
|
bogusTest(tokPtr, fL1S("return() requires zero or one argument."));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (*uce != TokFuncTerminator) {
|
if (*uce != TokFuncTerminator) {
|
||||||
parseError(fL1S("Top-level return() requires zero arguments."));
|
bogusTest(tokPtr, fL1S("Top-level return() requires zero arguments."));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,19 +1170,16 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
defType = TokBreak;
|
defType = TokBreak;
|
||||||
ctrlstm:
|
ctrlstm:
|
||||||
if (*uce != TokFuncTerminator) {
|
if (*uce != TokFuncTerminator) {
|
||||||
parseError(fL1S("%1() requires zero arguments.").arg(m_tmp));
|
bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(m_blockstack.top().nest & NestLoop)) {
|
if (!(m_blockstack.top().nest & NestLoop)) {
|
||||||
parseError(fL1S("Unexpected %1().").arg(m_tmp));
|
bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctrlstm2:
|
ctrlstm2:
|
||||||
if (m_invert) {
|
if (m_invert) {
|
||||||
parseError(fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
|
bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
finalizeTest(tokPtr);
|
finalizeTest(tokPtr);
|
||||||
@@ -1148,8 +1189,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
|
|||||||
} else if (m_tmp == statics.stroption) {
|
} else if (m_tmp == statics.stroption) {
|
||||||
if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1
|
if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1
|
||||||
|| m_invert || m_operator != NoOperator) {
|
|| m_invert || m_operator != NoOperator) {
|
||||||
parseError(fL1S("option() must appear outside any control structures."));
|
bogusTest(tokPtr, fL1S("option() must appear outside any control structures."));
|
||||||
bogusTest(tokPtr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (*uce == (TokLiteral|TokNewStr)) {
|
if (*uce == (TokLiteral|TokNewStr)) {
|
||||||
@@ -1230,4 +1270,258 @@ void QMakeParser::message(int type, const QString &msg) const
|
|||||||
m_handler->message(type, msg, m_proFile->fileName(), m_lineNo);
|
m_handler->message(type, msg, m_proFile->fileName(), m_lineNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PROPARSER_DEBUG
|
||||||
|
|
||||||
|
#define BOUNDS_CHECK(need) \
|
||||||
|
do { \
|
||||||
|
int have = limit - offset; \
|
||||||
|
if (have < (int)need) { \
|
||||||
|
*outStr += fL1S("<out of bounds (need %1, got %2)>").arg(need).arg(have); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static bool getRawUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
|
||||||
|
{
|
||||||
|
BOUNDS_CHECK(1);
|
||||||
|
uint val = tokens[offset++];
|
||||||
|
*outVal = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
|
||||||
|
{
|
||||||
|
*outStr += fL1S(" << H(");
|
||||||
|
if (!getRawUshort(tokens, limit, offset, outVal, outStr))
|
||||||
|
return false;
|
||||||
|
*outStr += QString::number(*outVal) + QLatin1Char(')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getRawUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
|
||||||
|
{
|
||||||
|
BOUNDS_CHECK(2);
|
||||||
|
uint val = tokens[offset++];
|
||||||
|
val |= (uint)tokens[offset++] << 16;
|
||||||
|
*outVal = val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
|
||||||
|
{
|
||||||
|
*outStr += fL1S(" << I(");
|
||||||
|
if (!getRawUint(tokens, limit, offset, outVal, outStr))
|
||||||
|
return false;
|
||||||
|
*outStr += QString::number(*outVal) + QLatin1Char(')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getRawStr(const ushort *tokens, int limit, int &offset, int strLen, QString *outStr)
|
||||||
|
{
|
||||||
|
BOUNDS_CHECK(strLen);
|
||||||
|
*outStr += fL1S("L\"");
|
||||||
|
bool attn = false;
|
||||||
|
for (int i = 0; i < strLen; i++) {
|
||||||
|
ushort val = tokens[offset++];
|
||||||
|
switch (val) {
|
||||||
|
case '"': *outStr += fL1S("\\\""); break;
|
||||||
|
case '\n': *outStr += fL1S("\\n"); break;
|
||||||
|
case '\r': *outStr += fL1S("\\r"); break;
|
||||||
|
case '\t': *outStr += fL1S("\\t"); break;
|
||||||
|
case '\\': *outStr += fL1S("\\\\"); break;
|
||||||
|
default:
|
||||||
|
if (val < 32 || val > 126) {
|
||||||
|
*outStr += (val > 255 ? fL1S("\\u") : fL1S("\\x")) + QString::number(val, 16);
|
||||||
|
attn = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (attn && isxdigit(val))
|
||||||
|
*outStr += fL1S("\"\"");
|
||||||
|
*outStr += QChar(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
attn = false;
|
||||||
|
}
|
||||||
|
*outStr += QLatin1Char('"');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getStr(const ushort *tokens, int limit, int &offset, QString *outStr)
|
||||||
|
{
|
||||||
|
*outStr += fL1S(" << S(");
|
||||||
|
ushort len;
|
||||||
|
if (!getRawUshort(tokens, limit, offset, &len, outStr))
|
||||||
|
return false;
|
||||||
|
if (!getRawStr(tokens, limit, offset, len, outStr))
|
||||||
|
return false;
|
||||||
|
*outStr += QLatin1Char(')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getHashStr(const ushort *tokens, int limit, int &offset, QString *outStr)
|
||||||
|
{
|
||||||
|
*outStr += fL1S(" << HS(");
|
||||||
|
uint hash;
|
||||||
|
if (!getRawUint(tokens, limit, offset, &hash, outStr))
|
||||||
|
return false;
|
||||||
|
ushort len;
|
||||||
|
if (!getRawUshort(tokens, limit, offset, &len, outStr))
|
||||||
|
return false;
|
||||||
|
const QChar *chars = (const QChar *)tokens + offset;
|
||||||
|
if (!getRawStr(tokens, limit, offset, len, outStr))
|
||||||
|
return false;
|
||||||
|
uint realhash = ProString::hash(chars, len);
|
||||||
|
if (realhash != hash)
|
||||||
|
*outStr += fL1S(" /* Bad hash ") + QString::number(hash) + fL1S(" */");
|
||||||
|
*outStr += QLatin1Char(')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent);
|
||||||
|
|
||||||
|
static bool getSubBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent,
|
||||||
|
const char *scope)
|
||||||
|
{
|
||||||
|
*outStr += fL1S("\n /* %1 */ ").arg(offset, 5)
|
||||||
|
+ QString(indent * 4, QLatin1Char(' '))
|
||||||
|
+ fL1S("/* ") + fL1S(scope) + fL1S(" */");
|
||||||
|
uint len;
|
||||||
|
if (!getUint(tokens, limit, offset, &len, outStr))
|
||||||
|
return false;
|
||||||
|
if (len) {
|
||||||
|
BOUNDS_CHECK(len);
|
||||||
|
int tmpOff = offset;
|
||||||
|
offset += len;
|
||||||
|
forever {
|
||||||
|
if (!getBlock(tokens, offset, tmpOff, outStr, indent + 1))
|
||||||
|
break; // Error was already reported, try to continue
|
||||||
|
if (tmpOff == offset)
|
||||||
|
break;
|
||||||
|
*outStr += QLatin1Char('\n') + QString(20 + indent * 4, QLatin1Char(' '))
|
||||||
|
+ fL1S("/* Warning: Excess tokens follow. */");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent)
|
||||||
|
{
|
||||||
|
static const char * const tokNames[] = {
|
||||||
|
"TokTerminator",
|
||||||
|
"TokLine",
|
||||||
|
"TokAssign", "TokAppend", "TokAppendUnique", "TokRemove", "TokReplace",
|
||||||
|
"TokValueTerminator",
|
||||||
|
"TokLiteral", "TokHashLiteral", "TokVariable", "TokProperty", "TokEnvVar",
|
||||||
|
"TokFuncName", "TokArgSeparator", "TokFuncTerminator",
|
||||||
|
"TokCondition", "TokTestCall",
|
||||||
|
"TokReturn", "TokBreak", "TokNext",
|
||||||
|
"TokNot", "TokAnd", "TokOr",
|
||||||
|
"TokBranch", "TokForLoop",
|
||||||
|
"TokTestDef", "TokReplaceDef"
|
||||||
|
};
|
||||||
|
|
||||||
|
while (offset != limit) {
|
||||||
|
*outStr += fL1S("\n /* %1 */").arg(offset, 5)
|
||||||
|
+ QString(indent * 4, QLatin1Char(' '));
|
||||||
|
BOUNDS_CHECK(1);
|
||||||
|
ushort tok = tokens[offset++];
|
||||||
|
ushort maskedTok = tok & TokMask;
|
||||||
|
if (maskedTok >= sizeof(tokNames)/sizeof(tokNames[0])
|
||||||
|
|| (tok & ~(TokNewStr | TokQuoted | TokMask))) {
|
||||||
|
*outStr += fL1S(" << {invalid token %1}").arg(tok);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*outStr += fL1S(" << H(") + fL1S(tokNames[maskedTok]);
|
||||||
|
if (tok & TokNewStr)
|
||||||
|
*outStr += fL1S(" | TokNewStr");
|
||||||
|
if (tok & TokQuoted)
|
||||||
|
*outStr += fL1S(" | TokQuoted");
|
||||||
|
*outStr += QLatin1Char(')');
|
||||||
|
bool ok;
|
||||||
|
switch (maskedTok) {
|
||||||
|
case TokFuncTerminator: // Recursion, but not a sub-block
|
||||||
|
return true;
|
||||||
|
case TokArgSeparator:
|
||||||
|
case TokValueTerminator: // Not recursion
|
||||||
|
case TokTerminator: // Recursion, and limited by (sub-)block length
|
||||||
|
case TokCondition:
|
||||||
|
case TokReturn:
|
||||||
|
case TokBreak:
|
||||||
|
case TokNext:
|
||||||
|
case TokNot:
|
||||||
|
case TokAnd:
|
||||||
|
case TokOr:
|
||||||
|
ok = true;
|
||||||
|
break;
|
||||||
|
case TokTestCall:
|
||||||
|
ok = getBlock(tokens, limit, offset, outStr, indent + 1);
|
||||||
|
break;
|
||||||
|
case TokBranch:
|
||||||
|
ok = getSubBlock(tokens, limit, offset, outStr, indent, "then branch");
|
||||||
|
if (ok)
|
||||||
|
ok = getSubBlock(tokens, limit, offset, outStr, indent, "else branch");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (maskedTok) {
|
||||||
|
case TokAssign:
|
||||||
|
case TokAppend:
|
||||||
|
case TokAppendUnique:
|
||||||
|
case TokRemove:
|
||||||
|
case TokReplace:
|
||||||
|
// The parameter is the sizehint for the output.
|
||||||
|
// fallthrough
|
||||||
|
case TokLine: {
|
||||||
|
ushort dummy;
|
||||||
|
ok = getUshort(tokens, limit, offset, &dummy, outStr);
|
||||||
|
break; }
|
||||||
|
case TokLiteral:
|
||||||
|
case TokEnvVar:
|
||||||
|
ok = getStr(tokens, limit, offset, outStr);
|
||||||
|
break;
|
||||||
|
case TokHashLiteral:
|
||||||
|
case TokVariable:
|
||||||
|
case TokProperty:
|
||||||
|
ok = getHashStr(tokens, limit, offset, outStr);
|
||||||
|
break;
|
||||||
|
case TokFuncName:
|
||||||
|
ok = getHashStr(tokens, limit, offset, outStr);
|
||||||
|
if (ok)
|
||||||
|
ok = getBlock(tokens, limit, offset, outStr, indent + 1);
|
||||||
|
break;
|
||||||
|
case TokForLoop:
|
||||||
|
ok = getHashStr(tokens, limit, offset, outStr);
|
||||||
|
if (ok)
|
||||||
|
ok = getSubBlock(tokens, limit, offset, outStr, indent, "iterator");
|
||||||
|
if (ok)
|
||||||
|
ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
|
||||||
|
break;
|
||||||
|
case TokTestDef:
|
||||||
|
case TokReplaceDef:
|
||||||
|
ok = getHashStr(tokens, limit, offset, outStr);
|
||||||
|
if (ok)
|
||||||
|
ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Q_ASSERT(!"unhandled token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMakeParser::formatProBlock(const QString &block)
|
||||||
|
{
|
||||||
|
QString outStr;
|
||||||
|
outStr += fL1S("\n << TS(");
|
||||||
|
int offset = 0;
|
||||||
|
getBlock(reinterpret_cast<const ushort *>(block.constData()), block.length(),
|
||||||
|
offset, &outStr, 0);
|
||||||
|
outStr += QLatin1Char(')');
|
||||||
|
return outStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PROPARSER_DEBUG
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@@ -93,6 +93,10 @@ public:
|
|||||||
|
|
||||||
void discardFileFromCache(const QString &fileName);
|
void discardFileFromCache(const QString &fileName);
|
||||||
|
|
||||||
|
#ifdef PROPARSER_DEBUG
|
||||||
|
static QString formatProBlock(const QString &block);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ScopeNesting {
|
enum ScopeNesting {
|
||||||
NestNone = 0,
|
NestNone = 0,
|
||||||
@@ -127,7 +131,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool read(ProFile *pro, ParseFlags flags);
|
bool read(ProFile *pro, ParseFlags flags);
|
||||||
bool read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
|
void read(ProFile *pro, const QString &content, int line, SubGrammar grammar);
|
||||||
|
|
||||||
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
|
ALWAYS_INLINE void putTok(ushort *&tokPtr, ushort tok);
|
||||||
ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
|
ALWAYS_INLINE void putBlockLen(ushort *&tokPtr, uint len);
|
||||||
@@ -141,8 +145,12 @@ private:
|
|||||||
const ushort *cur, const QString &in);
|
const ushort *cur, const QString &in);
|
||||||
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
||||||
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
||||||
|
void warnOperator(const char *msg);
|
||||||
|
bool failOperator(const char *msg);
|
||||||
|
bool acceptColon(const char *msg);
|
||||||
|
void putOperator(ushort *&tokPtr);
|
||||||
void finalizeTest(ushort *&tokPtr);
|
void finalizeTest(ushort *&tokPtr);
|
||||||
void bogusTest(ushort *&tokPtr);
|
void bogusTest(ushort *&tokPtr, const QString &msg);
|
||||||
void enterScope(ushort *&tokPtr, bool special, ScopeState state);
|
void enterScope(ushort *&tokPtr, bool special, ScopeState state);
|
||||||
void leaveScope(ushort *&tokPtr);
|
void leaveScope(ushort *&tokPtr);
|
||||||
void flushCond(ushort *&tokPtr);
|
void flushCond(ushort *&tokPtr);
|
||||||
@@ -150,7 +158,10 @@ private:
|
|||||||
|
|
||||||
void message(int type, const QString &msg) const;
|
void message(int type, const QString &msg) const;
|
||||||
void parseError(const QString &msg) const
|
void parseError(const QString &msg) const
|
||||||
{ message(QMakeParserHandler::ParserError, msg); }
|
{
|
||||||
|
message(QMakeParserHandler::ParserError, msg);
|
||||||
|
m_proFile->setOk(false);
|
||||||
|
}
|
||||||
void languageWarning(const QString &msg) const
|
void languageWarning(const QString &msg) const
|
||||||
{ message(QMakeParserHandler::ParserWarnLanguage, msg); }
|
{ message(QMakeParserHandler::ParserWarnLanguage, msg); }
|
||||||
void deprecationWarning(const QString &msg) const
|
void deprecationWarning(const QString &msg) const
|
||||||
@@ -165,7 +176,7 @@ private:
|
|||||||
int m_markLine; // Put marker for this line
|
int m_markLine; // Put marker for this line
|
||||||
bool m_inError; // Current line had a parsing error; suppress followup error messages
|
bool m_inError; // Current line had a parsing error; suppress followup error messages
|
||||||
bool m_canElse; // Conditionals met on previous line, but no scope was opened
|
bool m_canElse; // Conditionals met on previous line, but no scope was opened
|
||||||
bool m_invert; // Pending conditional is negated
|
int m_invert; // Pending conditional is negated
|
||||||
enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed
|
enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed
|
||||||
|
|
||||||
QString m_tmp; // Temporary for efficient toQString
|
QString m_tmp; // Temporary for efficient toQString
|
||||||
|
Submodule src/shared/qbs updated: 55ff3783ce...9bbbf55ea6
@@ -12,7 +12,6 @@ SUBDIRS += \
|
|||||||
generichighlighter \
|
generichighlighter \
|
||||||
profilewriter \
|
profilewriter \
|
||||||
treeviewfind \
|
treeviewfind \
|
||||||
ioutils \
|
|
||||||
qtcprocess \
|
qtcprocess \
|
||||||
utils \
|
utils \
|
||||||
filesearch \
|
filesearch \
|
||||||
|
@@ -14,7 +14,6 @@ Project {
|
|||||||
"externaltool/externaltool.qbs",
|
"externaltool/externaltool.qbs",
|
||||||
"filesearch/filesearch.qbs",
|
"filesearch/filesearch.qbs",
|
||||||
"generichighlighter/generichighlighter.qbs",
|
"generichighlighter/generichighlighter.qbs",
|
||||||
"ioutils/ioutils.qbs",
|
|
||||||
"profilewriter/profilewriter.qbs",
|
"profilewriter/profilewriter.qbs",
|
||||||
"qml/qml.qbs",
|
"qml/qml.qbs",
|
||||||
"qtcprocess/qtcprocess.qbs",
|
"qtcprocess/qtcprocess.qbs",
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
include(../qttest.pri)
|
|
||||||
|
|
||||||
INCLUDEPATH += $$IDE_SOURCE_TREE/src/shared
|
|
||||||
SOURCES += tst_ioutils.cpp \
|
|
||||||
$$IDE_SOURCE_TREE/src/shared/proparser/ioutils.cpp
|
|
@@ -1,11 +0,0 @@
|
|||||||
import qbs
|
|
||||||
|
|
||||||
QtcAutotest {
|
|
||||||
name: "IoUtils autotest"
|
|
||||||
Depends { name: "Qt.core" }
|
|
||||||
files: [
|
|
||||||
project.sharedSourcesDir + "/proparser/ioutils.cpp",
|
|
||||||
"tst_ioutils.cpp"
|
|
||||||
]
|
|
||||||
cpp.includePaths: base.concat([project.sharedSourcesDir])
|
|
||||||
}
|
|
@@ -1,84 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
|
||||||
** Contact: http://www.qt.io/licensing
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms and
|
|
||||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
|
||||||
** use the contact form at http://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 2.1 or version 3 as published by the Free
|
|
||||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
|
||||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
|
||||||
** following information to ensure the GNU Lesser General Public License
|
|
||||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
|
||||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
|
||||||
** rights. These rights are described in The Qt Company LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include <QtTest>
|
|
||||||
#include <proparser/ioutils.h>
|
|
||||||
|
|
||||||
|
|
||||||
class tst_IoUtils : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void quoteArg_data();
|
|
||||||
void quoteArg();
|
|
||||||
};
|
|
||||||
|
|
||||||
void tst_IoUtils::quoteArg_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("in");
|
|
||||||
QTest::addColumn<QString>("out");
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char * const in;
|
|
||||||
const char * const out;
|
|
||||||
} vals[] = {
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
{ "", "\"\"" },
|
|
||||||
{ "hallo", "hallo" },
|
|
||||||
{ "hallo du", "\"hallo du\"" },
|
|
||||||
{ "hallo\\", "hallo\\" },
|
|
||||||
{ "hallo du\\", "\"hallo du\"\\" },
|
|
||||||
{ "ha\"llo", "\"ha\"\\^\"\"llo\"" },
|
|
||||||
{ "ha\\\"llo", "\"ha\"\\\\\\^\"\"llo\"" },
|
|
||||||
#else
|
|
||||||
{ "", "\"\"" },
|
|
||||||
{ "hallo", "hallo" },
|
|
||||||
{ "hallo du", "'hallo du'" },
|
|
||||||
{ "ha'llo", "'ha'\\''llo'" },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
|
|
||||||
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
|
|
||||||
<< QString::fromLatin1(vals[i].out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_IoUtils::quoteArg()
|
|
||||||
{
|
|
||||||
QFETCH(QString, in);
|
|
||||||
QFETCH(QString, out);
|
|
||||||
|
|
||||||
QCOMPARE(QMakeInternal::IoUtils::shellQuote(in), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(tst_IoUtils)
|
|
||||||
|
|
||||||
#include "tst_ioutils.moc"
|
|
@@ -180,7 +180,6 @@
|
|||||||
:QtSupport__Internal__QtVersionManager.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' text?='Qt version *' type='QLabel' unnamed='1' visible='1'}
|
:QtSupport__Internal__QtVersionManager.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' text?='Qt version *' type='QLabel' unnamed='1' visible='1'}
|
||||||
:QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'}
|
:QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'}
|
||||||
:QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'}
|
:QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'}
|
||||||
:QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qtdirList' type='QTreeWidget' visible='1'}
|
|
||||||
:QtVersionLabel_KitPage {container=':qt_tabwidget_stackedwidget_QWidget' text='Qt version:' type='QLabel' unnamed='1' visible='1'}
|
:QtVersionLabel_KitPage {container=':qt_tabwidget_stackedwidget_QWidget' text='Qt version:' type='QLabel' unnamed='1' visible='1'}
|
||||||
:Restart required.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Restart required_QMessageBox'}
|
:Restart required.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Restart required_QMessageBox'}
|
||||||
:Restart required_QMessageBox {text='The language change will take effect after a restart of Qt Creator.' type='QMessageBox' unnamed='1' visible='1'}
|
:Restart required_QMessageBox {text='The language change will take effect after a restart of Qt Creator.' type='QMessageBox' unnamed='1' visible='1'}
|
||||||
@@ -225,7 +224,9 @@
|
|||||||
:qt_tabwidget_stackedwidget.CppTools__Internal__CompletionSettingsPage_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='CppTools__Internal__CompletionSettingsPage' type='QWidget' visible='1'}
|
:qt_tabwidget_stackedwidget.CppTools__Internal__CompletionSettingsPage_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='CppTools__Internal__CompletionSettingsPage' type='QWidget' visible='1'}
|
||||||
:qt_tabwidget_stackedwidget.Form_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='Help__Internal__GeneralSettingsPage' type='QWidget' visible='1' windowTitle='Form'}
|
:qt_tabwidget_stackedwidget.Form_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='Help__Internal__GeneralSettingsPage' type='QWidget' visible='1' windowTitle='Form'}
|
||||||
:qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='QtSupport__Internal__QtVersionManager' type='QtSupport::Internal::QtOptionsPageWidget' visible='1'}
|
:qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='QtSupport__Internal__QtVersionManager' type='QtSupport::Internal::QtOptionsPageWidget' visible='1'}
|
||||||
|
:qt_tabwidget_stackedwidget_QScrollArea {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QScrollArea' unnamed='1' visible='1'}
|
||||||
:qt_tabwidget_stackedwidget_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QWidget' unnamed='1' visible='1'}
|
:qt_tabwidget_stackedwidget_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QWidget' unnamed='1' visible='1'}
|
||||||
|
:qtdirList_QTreeView {container=':qt_tabwidget_stackedwidget_QScrollArea' name='qtdirList' type='QTreeView' visible='1'}
|
||||||
:scrollArea.Details_Utils::DetailsButton {text='Details' type='Utils::DetailsButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
:scrollArea.Details_Utils::DetailsButton {text='Details' type='Utils::DetailsButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||||
:scrollArea.Edit build configuration:_QComboBox {leftWidget=':scrollArea.Edit build configuration:_QLabel' type='QComboBox' unnamed='1' visible='1'}
|
:scrollArea.Edit build configuration:_QComboBox {leftWidget=':scrollArea.Edit build configuration:_QLabel' type='QComboBox' unnamed='1' visible='1'}
|
||||||
:scrollArea.Edit build configuration:_QLabel {text='Edit build configuration:' type='QLabel' unnamed='1' visible='1'}
|
:scrollArea.Edit build configuration:_QLabel {text='Edit build configuration:' type='QLabel' unnamed='1' visible='1'}
|
||||||
|
@@ -72,16 +72,10 @@ def openCmakeProject(projectPath, buildDir):
|
|||||||
return __handleCmakeWizardPage__()
|
return __handleCmakeWizardPage__()
|
||||||
|
|
||||||
def __handleCmakeWizardPage__():
|
def __handleCmakeWizardPage__():
|
||||||
generatorCombo = waitForObject(":Generator:_QComboBox")
|
|
||||||
generatorText = "Unix Generator (Desktop 480 GCC)"
|
generatorText = "Unix Generator (Desktop 480 GCC)"
|
||||||
if platform.system() in ('Windows', 'Microsoft'):
|
if platform.system() in ('Windows', 'Microsoft'):
|
||||||
generatorText = "NMake Generator (Desktop 480 MSVC2010)"
|
generatorText = "NMake Generator (Desktop 480 MSVC2010)"
|
||||||
index = generatorCombo.findText(generatorText)
|
selectFromCombo(waitForObject(":Generator:_QComboBox"), generatorText)
|
||||||
if index == -1:
|
|
||||||
test.warning("No matching CMake generator for found.")
|
|
||||||
else:
|
|
||||||
generatorCombo.setCurrentIndex(index)
|
|
||||||
|
|
||||||
clickButton(waitForObject(":CMake Wizard.Run CMake_QPushButton"))
|
clickButton(waitForObject(":CMake Wizard.Run CMake_QPushButton"))
|
||||||
try:
|
try:
|
||||||
clickButton(waitForObject(":CMake Wizard.Finish_QPushButton", 60000))
|
clickButton(waitForObject(":CMake Wizard.Finish_QPushButton", 60000))
|
||||||
|
@@ -194,8 +194,8 @@ def getQtInformationForQmlProject():
|
|||||||
qtVersionStr = str(waitForObject(":Kits_QtVersion_QComboBox").currentText)
|
qtVersionStr = str(waitForObject(":Kits_QtVersion_QComboBox").currentText)
|
||||||
test.log("Kit '%s' uses Qt Version '%s'" % (kit, qtVersionStr))
|
test.log("Kit '%s' uses Qt Version '%s'" % (kit, qtVersionStr))
|
||||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
||||||
treeWidget = waitForObject(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget")
|
treeView = waitForObject(":qtdirList_QTreeView")
|
||||||
if not __selectTreeItemOnBuildAndRun__(treeWidget, qtVersionStr):
|
if not __selectTreeItemOnBuildAndRun__(treeView, qtVersionStr):
|
||||||
test.fatal("Found no matching Qt Version for kit - this shouldn't happen.")
|
test.fatal("Found no matching Qt Version for kit - this shouldn't happen.")
|
||||||
clickButton(waitForObject(":Options.Cancel_QPushButton"))
|
clickButton(waitForObject(":Options.Cancel_QPushButton"))
|
||||||
return None, None, None, None
|
return None, None, None, None
|
||||||
|
@@ -363,8 +363,8 @@ def __checkParentAccess__(filePath):
|
|||||||
# and a list of information of its configured Qt
|
# and a list of information of its configured Qt
|
||||||
def getConfiguredKits():
|
def getConfiguredKits():
|
||||||
def __retrieveQtVersionName__(target, version):
|
def __retrieveQtVersionName__(target, version):
|
||||||
treeWidget = waitForObject(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget")
|
treeView = waitForObject(":qtdirList_QTreeView")
|
||||||
return treeWidget.currentItem().text(0)
|
return str(treeView.currentIndex().data().toString())
|
||||||
# end of internal function for iterateQtVersions
|
# end of internal function for iterateQtVersions
|
||||||
def __setQtVersionForKit__(kit, kitName, kitsQtVersionName):
|
def __setQtVersionForKit__(kit, kitName, kitsQtVersionName):
|
||||||
treeView = waitForObject(":BuildAndRun_QTreeView")
|
treeView = waitForObject(":BuildAndRun_QTreeView")
|
||||||
@@ -443,13 +443,13 @@ def iterateQtVersions(keepOptionsOpen=False, alreadyOnOptionsDialog=False,
|
|||||||
clickItem(":Options_QListView", "Build & Run", 14, 15, 0, Qt.LeftButton)
|
clickItem(":Options_QListView", "Build & Run", 14, 15, 0, Qt.LeftButton)
|
||||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
||||||
pattern = re.compile("Qt version (?P<version>.*?) for (?P<target>.*)")
|
pattern = re.compile("Qt version (?P<version>.*?) for (?P<target>.*)")
|
||||||
treeWidget = waitForObject(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget")
|
treeView = waitForObject(":qtdirList_QTreeView")
|
||||||
root = treeWidget.invisibleRootItem()
|
model = treeView.model()
|
||||||
for rootChild in dumpChildren(root):
|
for rootIndex in dumpIndices(model):
|
||||||
rootChildText = str(rootChild.text(0)).replace(".", "\\.").replace("_", "\\_")
|
rootChildText = str(rootIndex.data()).replace(".", "\\.").replace("_", "\\_")
|
||||||
for subChild in dumpChildren(rootChild):
|
for subIndex in dumpIndices(model, rootIndex):
|
||||||
subChildText = str(subChild.text(0)).replace(".", "\\.").replace("_", "\\_")
|
subChildText = str(subIndex.data()).replace(".", "\\.").replace("_", "\\_")
|
||||||
clickItem(treeWidget, ".".join([rootChildText,subChildText]), 5, 5, 0, Qt.LeftButton)
|
clickItem(treeView, ".".join([rootChildText,subChildText]), 5, 5, 0, Qt.LeftButton)
|
||||||
currentText = str(waitForObject(":QtSupport__Internal__QtVersionManager.QLabel").text)
|
currentText = str(waitForObject(":QtSupport__Internal__QtVersionManager.QLabel").text)
|
||||||
matches = pattern.match(currentText)
|
matches = pattern.match(currentText)
|
||||||
if matches:
|
if matches:
|
||||||
|
@@ -80,8 +80,7 @@ def __checkBuildAndRun__():
|
|||||||
qmakePath = which("qmake")
|
qmakePath = which("qmake")
|
||||||
foundQt = []
|
foundQt = []
|
||||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions")
|
||||||
__iterateTree__(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget",
|
__iterateTree__(":qtdirList_QTreeView", __qtFunc__, foundQt, qmakePath)
|
||||||
__qtFunc__, foundQt, qmakePath)
|
|
||||||
test.verify(not qmakePath or len(foundQt) == 1,
|
test.verify(not qmakePath or len(foundQt) == 1,
|
||||||
"Was qmake from %s autodetected? Found %s" % (qmakePath, foundQt))
|
"Was qmake from %s autodetected? Found %s" % (qmakePath, foundQt))
|
||||||
if foundQt:
|
if foundQt:
|
||||||
|
@@ -39,7 +39,7 @@ def main():
|
|||||||
invokeMenuItem("Tools", "Options...")
|
invokeMenuItem("Tools", "Options...")
|
||||||
waitForObjectItem(":Options_QListView", "Environment")
|
waitForObjectItem(":Options_QListView", "Environment")
|
||||||
clickItem(":Options_QListView", "Environment", 14, 15, 0, Qt.LeftButton)
|
clickItem(":Options_QListView", "Environment", 14, 15, 0, Qt.LeftButton)
|
||||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "General")
|
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Interface")
|
||||||
languageName = testData.field(lang, "language")
|
languageName = testData.field(lang, "language")
|
||||||
if "%1" in languageName:
|
if "%1" in languageName:
|
||||||
country = str(QLocale.countryToString(QLocale(testData.field(lang, "ISO")).country()))
|
country = str(QLocale.countryToString(QLocale(testData.field(lang, "ISO")).country()))
|
||||||
|
Reference in New Issue
Block a user