Merge "Merge remote-tracking branch 'origin/15.0'"

This commit is contained in:
The Qt Project
2024-10-23 08:23:34 +00:00
70 changed files with 1235 additions and 1072 deletions

View File

@@ -1,6 +1,6 @@
set(IDE_VERSION "14.0.82") # The IDE version. set(IDE_VERSION "14.0.83") # The IDE version.
set(IDE_VERSION_COMPAT "14.0.82") # The IDE Compatibility version. set(IDE_VERSION_COMPAT "14.0.83") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "15.0.0-beta1") # The IDE display version. set(IDE_VERSION_DISPLAY "15.0.0-beta2") # The IDE display version.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name. set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name.

View File

@@ -181,8 +181,10 @@ Projects
### Workspace ### Workspace
* Added the option to add build configurations * Added the option to add build configurations into
* Added automatic updating of the project tree `Projects > Build & Run > Build > Add`
([Documentation](https://doc.qt.io/qtcreator/creator-project-opening.html))
* Added automatic updating of the project tree in `Projects`
* Fixed that cloned run configurations were not editable * Fixed that cloned run configurations were not editable
### vcpkg ### vcpkg
@@ -296,6 +298,7 @@ Platforms
### VxWorks ### VxWorks
* Added support for VxWorks 24.03 * Added support for VxWorks 24.03
([Documentation](https://doc-snapshots.qt.io/qtcreator-15.0/creator-how-to-create-vxworks-kits.html))
Credits for these changes go to: Credits for these changes go to:
-------------------------------- --------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -421,6 +421,8 @@
generated from crashed processes on Linux and Unix systems if the system is generated from crashed processes on Linux and Unix systems if the system is
set up to allow this. set up to allow this.
\section1 Get core files
To enable the dumping of core files on a Unix system, enter the following To enable the dumping of core files on a Unix system, enter the following
command in the shell from which the application is launched: command in the shell from which the application is launched:
@@ -428,11 +430,13 @@
ulimit -c unlimited ulimit -c unlimited
\endcode \endcode
\section1 Attach to a core file
To launch the debugger in the core mode: To launch the debugger in the core mode:
\list 1 \list 1
\li Go to \uicontrol Debug > \uicontrol {Start Debugging} > \li Go to \uicontrol Debug > \uicontrol {Start Debugging}, and then
\uicontrol {Load Core File}. select \uicontrol {Load Core File}.
\image qtcreator-debugger-load-core-file.png \image qtcreator-debugger-load-core-file.png
\li In \uicontrol Kit, select a build and run kit that was \li In \uicontrol Kit, select a build and run kit that was
used for building the binary for which the core file was created. used for building the binary for which the core file was created.
@@ -452,8 +456,17 @@
the \c sysroot to use instead of the default \c sysroot. the \c sysroot to use instead of the default \c sysroot.
\endlist \endlist
Even though using a properly configured project that has the sources of the For better results, use a properly configured project that has the sources of
crashed application is not strictly necessary, it is helpful. the crashed application.
\section1 Attach to the latest core file
On Linux systems, \QC uses the \c coredumpctl command provided by the
\c systemd crash handling to get core files. For more information, see
\l {systemd-coredump}.
To attach to the latest core file, go to \uicontrol Debug >
\uicontrol {Start Debugging}, and then select \uicontrol {Load Last Core File}.
\sa {Debug}{How To: Debug}, {Debugging}, {Debuggers}, {Debugger}, {Kits} \sa {Debug}{How To: Debug}, {Debugging}, {Debuggers}, {Debugger}, {Kits}
*/ */

View File

@@ -5,6 +5,10 @@
\externalpage https://doc.qt.io/index.html \externalpage https://doc.qt.io/index.html
\title Qt Documentation \title Qt Documentation
*/ */
/*!
\externalpage https://www.freedesktop.org/software/systemd/man/latest/systemd-coredump.html
\title systemd-coredump
*/
/*! /*!
\externalpage https://www.perforce.com/manuals/cmdref/Content/CmdRef/P4CONFIG.html \externalpage https://www.perforce.com/manuals/cmdref/Content/CmdRef/P4CONFIG.html
\title Perforce: P4CONFIG \title Perforce: P4CONFIG
@@ -233,3 +237,7 @@
\externalpage https://www.openssh.com/ \externalpage https://www.openssh.com/
\title OpenSSH \title OpenSSH
*/ */
/*!
\externalpage https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/share/qtcreator/jsonschemas/project.json
\title project.json
*/

View File

@@ -56,8 +56,26 @@
\uicontrol {Open Workspace}. \uicontrol {Open Workspace}.
\QC generates the \e .qtcreator/project.json project file in the directory \QC generates the \e .qtcreator/project.json project file in the directory
for setting a project name and file exclusion filters. You can open either for setting a project name and file exclusion filters. You can add build and
the JSON file or the workspace to open the project the next time. run settings to the file, as defined by its \l{project.json}{JSON schema}.
You can open either the JSON file or the workspace to open the project the
next time.
When you add files to the directory or remove them from there, the contents
of the \l Projects view are updated automatically.
To add a build configuration to the workspace:
\list 1
\li Go to \uicontrol Projects > \uicontrol {Build & Run} >
\uicontrol Build.
\li Select \uicontrol Add > \uicontrol Build.
\li Specify build settings.
\endlist
To specify run settings for the workspace, go to \uicontrol Projects >
\uicontrol {Build & Run} > \uicontrol Run.
\section1 Re-configure projects \section1 Re-configure projects
@@ -123,5 +141,6 @@
later. Select the \inlineimage icons/pin.png later. Select the \inlineimage icons/pin.png
(\uicontrol Pin) button to pin the progress bar back to the toggle button. (\uicontrol Pin) button to pin the progress bar back to the toggle button.
\sa {Manage Kits}{How To: Manage Kits}, {Kits}, \sa {Configure projects for building}, {Configure projects for running},
{Manage Kits}{How To: Manage Kits}, {Kits}
*/ */

View File

@@ -95,7 +95,7 @@
\li Add and remove subprojects. \li Add and remove subprojects.
\li Find unused functions. \li Find unused functions.
\li Search in the selected directory. \li Search in the selected directory.
\li View version control system log for the current directory.
\li Open a terminal window in the project directory. To specify the \li Open a terminal window in the project directory. To specify the
terminal to use on Linux and \macos, select \preferences > terminal to use on Linux and \macos, select \preferences >
\uicontrol Environment > \uicontrol System. \uicontrol Environment > \uicontrol System.

View File

@@ -4,16 +4,16 @@ import qbs.FileInfo
import qbs.Utilities import qbs.Utilities
Module { Module {
property string qtcreator_display_version: '15.0.0-beta1' property string qtcreator_display_version: '15.0.0-beta2'
property string ide_version_major: '14' property string ide_version_major: '14'
property string ide_version_minor: '0' property string ide_version_minor: '0'
property string ide_version_release: '82' property string ide_version_release: '83'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release + ide_version_release
property string ide_compat_version_major: '14' property string ide_compat_version_major: '14'
property string ide_compat_version_minor: '0' property string ide_compat_version_minor: '0'
property string ide_compat_version_release: '82' property string ide_compat_version_release: '83'
property string qtcreator_compat_version: ide_compat_version_major + '.' property string qtcreator_compat_version: ide_compat_version_major + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release + ide_compat_version_minor + '.' + ide_compat_version_release

View File

@@ -14,20 +14,9 @@ struct gl_PerVertex {
float gl_PointSize; float gl_PointSize;
float gl_ClipDistance[]; float gl_ClipDistance[];
}; };
uniform gl_PerVertex[] gl_in;
struct gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
int gl_PrimitiveIDIn; int gl_PrimitiveIDIn;
struct gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
int gl_PrimitiveID; int gl_PrimitiveID;
int gl_Layer; int gl_Layer;
@@ -38,13 +27,7 @@ struct gl_PerVertex {
float gl_ClipDistance[]; float gl_ClipDistance[];
vec4 gl_ClipVertex; vec4 gl_ClipVertex;
}; };
uniform gl_PerVertex[] gl_in;
struct gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
vec4 gl_ClipVertex;
} gl_in[];
vec4 gl_Color; vec4 gl_Color;
vec4 gl_SecondaryColor; vec4 gl_SecondaryColor;
@@ -59,3 +42,6 @@ vec4 gl_MultiTexCoord5;
vec4 gl_MultiTexCoord6; vec4 gl_MultiTexCoord6;
vec4 gl_MultiTexCoord7; vec4 gl_MultiTexCoord7;
float gl_FogCoord; float gl_FogCoord;
void EmitVertex();
void EndPrimitive();

View File

@@ -42,7 +42,7 @@ Token_Notification_Success_Default=ff1EC974
Token_Notification_Success_Muted=ff12834B Token_Notification_Success_Muted=ff12834B
Token_Notification_Success_Subtle=ff092C1B Token_Notification_Success_Subtle=ff092C1B
Token_Gradient01_Start=ff057880 Token_Gradient01_Start=ff00414A
Token_Gradient01_End=ff12A75D Token_Gradient01_End=ff12A75D
Token_Gradient02_Start=ff4A4A4A Token_Gradient02_Start=ff4A4A4A
Token_Gradient02_End=ff909090 Token_Gradient02_End=ff909090

View File

@@ -238,12 +238,19 @@ Spinner::Spinner(SpinnerSize size, QWidget *parent)
: QObject(parent) : QObject(parent)
, m_widget(new SpinnerOverlay(size, parent)) {} , m_widget(new SpinnerOverlay(size, parent)) {}
Spinner::~Spinner()
{
if (m_widget)
delete m_widget;
}
/*! /*!
Sets the size of the spinner to the given \a size. Sets the size of the spinner to the given \a size.
*/ */
void Spinner::setSize(SpinnerSize size) void Spinner::setSize(SpinnerSize size)
{ {
m_widget->setSize(size); if (m_widget)
m_widget->setSize(size);
} }
/*! /*!
@@ -251,7 +258,8 @@ void Spinner::setSize(SpinnerSize size)
*/ */
void Spinner::setColor(const QColor &color) void Spinner::setColor(const QColor &color)
{ {
m_widget->setColor(color); if (m_widget)
m_widget->setColor(color);
} }
/*! /*!
@@ -260,7 +268,8 @@ void Spinner::setColor(const QColor &color)
*/ */
void Spinner::show() void Spinner::show()
{ {
m_widget->show(); if (m_widget)
m_widget->show();
} }
/*! /*!
@@ -268,7 +277,8 @@ void Spinner::show()
*/ */
void Spinner::hide() void Spinner::hide()
{ {
m_widget->hide(); if (m_widget)
m_widget->hide();
} }
/*! /*!
@@ -276,7 +286,7 @@ void Spinner::hide()
*/ */
bool Spinner::isVisible() const bool Spinner::isVisible() const
{ {
return m_widget->isVisible(); return m_widget ? m_widget->isVisible() : false;
} }
/*! /*!
@@ -285,7 +295,8 @@ bool Spinner::isVisible() const
*/ */
void Spinner::setVisible(bool visible) void Spinner::setVisible(bool visible)
{ {
m_widget->setVisible(visible); if (m_widget)
m_widget->setVisible(visible);
} }
static QString colorButtonStyleSheet(const QColor &bgColor) static QString colorButtonStyleSheet(const QColor &bgColor)

View File

@@ -6,6 +6,7 @@
#include "spinner_global.h" #include "spinner_global.h"
#include <QPointer>
#include <QWidget> #include <QWidget>
namespace SpinnerSolution { namespace SpinnerSolution {
@@ -20,12 +21,15 @@ Q_ENUM_NS(SpinnerState)
// TODO: SpinnerOverlay and SpinnerWidget? // TODO: SpinnerOverlay and SpinnerWidget?
class SpinnerOverlay;
class SPINNER_EXPORT Spinner : public QObject class SPINNER_EXPORT Spinner : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Spinner(SpinnerSize size, QWidget *parent = nullptr); explicit Spinner(SpinnerSize size, QWidget *parent = nullptr);
~Spinner() override;
void setSize(SpinnerSize size); void setSize(SpinnerSize size);
void setColor(const QColor &color); void setColor(const QColor &color);
void show(); void show();
@@ -34,7 +38,7 @@ public:
void setVisible(bool visible); void setVisible(bool visible);
private: private:
class SpinnerOverlay *m_widget = nullptr; QPointer<SpinnerOverlay> m_widget;
}; };
class SPINNER_EXPORT SpinnerWidget : public QWidget class SPINNER_EXPORT SpinnerWidget : public QWidget

View File

@@ -896,7 +896,7 @@ public:
template<class Widget> template<class Widget>
void updateWidgetFromCheckStatus(BaseAspect *aspect, Widget *w) void updateWidgetFromCheckStatus(BaseAspect *aspect, Widget *w)
{ {
const bool enabled = !m_checked || m_checked->value(); const bool enabled = !m_checked || m_checked->volatileValue();
if (m_uncheckedSemantics == UncheckedSemantics::Disabled) if (m_uncheckedSemantics == UncheckedSemantics::Disabled)
w->setEnabled(enabled && aspect->isEnabled()); w->setEnabled(enabled && aspect->isEnabled());
else else

View File

@@ -43,8 +43,7 @@ namespace Utils {
\class Utils::ProcessArgs \class Utils::ProcessArgs
\inmodule QtCreator \inmodule QtCreator
\brief The ProcessArgs class provides functionality for dealing with \brief Handles shell-quoted process arguments.
shell-quoted process arguments.
*/ */
inline static bool isMetaCharWin(ushort c) inline static bool isMetaCharWin(ushort c)
@@ -695,11 +694,27 @@ static int quoteArgInternalWin(QString &ret, int bslashes)
// TODO: This documentation is relevant for end-users. Where to put it? // TODO: This documentation is relevant for end-users. Where to put it?
/** /*!
* Perform safe macro expansion (substitution) on a string for use * Uses the macro expander \a mx to perform in-place macro expansion
* in shell commands. * (substitution) on the string \a cmd, which is expected to contain a shell
* command. \a osType specifies the syntax, which is Bourne Shell compatible
* for Unix and \c cmd compatible for Windows.
* *
* \section Unix notes * Returns \c false if substitution cannot be performed safely, because the
* command cannot be parsed -- for example due to quoting errors.
*
* \note This function is designed to be safe to use with expando objects
* that contain shell meta-characters. However, placing expandos in the wrong
* place of the command may defeat the expander's efforts to quote their
* contents, which will likely result in incorrect command execution.
* In particular, expandos that contain untrusted data might expose the
* end-user of the application to critical shell code injection
* vulnerabilities. To avoid these issues, follow the guidelines in
* \l {Unix security considerations} and \l {Windows security considerations}.
* Generally, it is a better idea to invoke shell scripts rather than to
* assemble complex one-line commands.
*
* \section1 Unix notes
* *
* Explicitly supported shell constructs: * Explicitly supported shell constructs:
* \\ '' "" {} () $(()) ${} $() `` * \\ '' "" {} () $(()) ${} $() ``
@@ -713,41 +728,45 @@ static int quoteArgInternalWin(QString &ret, int bslashes)
* \li Bash-style \c{$""} and \c{$''} string quoting syntax. * \li Bash-style \c{$""} and \c{$''} string quoting syntax.
* \endlist * \endlist
* *
* The rest of the shell (incl. bash) syntax is simply ignored, * The rest of the shell syntax (including bash syntax) should not cause
* as it is not expected to cause problems. * problems and is ignored.
* *
* Security considerations: * \section2 Unix security considerations
* \list * \list
* \li Backslash-escaping an expando is treated as a quoting error * \li Backslash-escaping an expando is treated as a quoting error.
* \li Do not put expandos into double quoted substitutions: * \li Do not put expandos into double quoted substitutions as this may
* trigger parser bugs in some shells:
* \badcode * \badcode
* "${VAR:-%{macro}}" * "${VAR:-%{macro}}"
* \endcode * \endcode
* \li Do not put expandos into command line arguments which are nested * \li Do not put expandos into command line arguments that are nested shell
* shell commands: * commands. For example, the following is unsafe:
* \badcode * \badcode
* sh -c 'foo \%{file}' * su %{user} -c 'foo %{file}'
* \endcode * \endcode
* \goodcode * Instead you can assign the macro to an environment variable and pass
* file=\%{file} sh -c 'foo "$file"' * that into the call:
* \badcode
* file=%{file} su %{user} -c 'foo "$file"'
* \endcode * \endcode
* \endlist * \endlist
* *
* \section Windows notes * \section1 Windows notes
* *
* All quoting syntax supported by splitArgs() is supported here as well. * All quoting syntax supported by \c splitArgs() is supported here as well.
* Additionally, command grouping via parentheses is recognized - note * Additionally, command grouping via parentheses is recognized -- but
* however, that the parser is much stricter about unquoted parentheses * note that the parser is much stricter about unquoted parentheses
* than cmd itself. * than \c cmd itself.
* The rest of the cmd syntax is simply ignored, as it is not expected * The rest of the \c cmd syntax should not cause problems and is ignored.
* to cause problems.
* *
* Security considerations: *
* \section2 Windows security considerations
* \list * \list
* \li Circumflex-escaping an expando is treated as a quoting error * \li Circumflex-escaping an expando is treated as a quoting error.
* \li Closing double quotes right before expandos and opening double quotes * \li Closing double quotes right before expandos and opening double quotes
* right after expandos are treated as quoting errors * right after expandos are treated as quoting errors.
* \li Do not put expandos into nested commands: * \li Do not put expandos into nested commands.
* For example, the following is unsafe:
* \badcode * \badcode
* for /f "usebackq" \%v in (`foo \%{file}`) do \@echo \%v * for /f "usebackq" \%v in (`foo \%{file}`) do \@echo \%v
* \endcode * \endcode
@@ -755,18 +774,15 @@ static int quoteArgInternalWin(QString &ret, int bslashes)
* as an environment variable expansion. A solution is replacing any * as an environment variable expansion. A solution is replacing any
* percent signs with a fixed string like \c{\%PERCENT_SIGN\%} and * percent signs with a fixed string like \c{\%PERCENT_SIGN\%} and
* injecting \c{PERCENT_SIGN=\%} into the shell's environment. * injecting \c{PERCENT_SIGN=\%} into the shell's environment.
* \li Enabling delayed environment variable expansion (cmd /v:on) should have * \li Enabling delayed environment variable expansion (\c{cmd /v:on}) should
* no security implications, but may still wreak havoc due to the * have no security implications. But it might still cause issues because
* need for doubling circumflexes if any exclamation marks are present, * the parser is not prepared for the fact that literal exclamation marks
* and the need to circumflex-escape the exclamation marks themselves. * in the command need to be \e circumflex-escaped, and pre-existing
* circumflexes need to be doubled.
* \endlist * \endlist
* *
* \param cmd pointer to the string in which macros are expanded in-place
* \param mx pointer to a macro expander instance
* \return false if the string could not be parsed and therefore no safe
* substitution was possible
*/ */
bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType osType) bool ProcessArgs::expandMacros(QString *cmd, const FindMacro &findMacro, OsType osType)
{ {
QString str = *cmd; QString str = *cmd;
if (str.isEmpty()) if (str.isEmpty())
@@ -775,7 +791,7 @@ bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType o
QString rsts; QString rsts;
int varLen; int varLen;
int varPos = 0; int varPos = 0;
if (!(varLen = mx->findMacro(str, &varPos, &rsts))) if (!(varLen = findMacro(str, &varPos, &rsts)))
return true; return true;
int pos = 0; int pos = 0;
@@ -839,7 +855,7 @@ bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType o
str.replace(pos, varLen, rsts); str.replace(pos, varLen, rsts);
pos += rsts.length(); pos += rsts.length();
varPos = pos; varPos = pos;
if (!(varLen = mx->findMacro(str, &varPos, &rsts))) { if (!(varLen = findMacro(str, &varPos, &rsts))) {
// Don't leave immediately, as we may be in CrtNeedWord state which could // Don't leave immediately, as we may be in CrtNeedWord state which could
// be still resolved, or we may have inserted trailing backslashes. // be still resolved, or we may have inserted trailing backslashes.
varPos = INT_MAX; varPos = INT_MAX;
@@ -954,7 +970,7 @@ bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType o
str.replace(pos, varLen, rsts); str.replace(pos, varLen, rsts);
pos += rsts.length(); pos += rsts.length();
varPos = pos; varPos = pos;
if (!(varLen = mx->findMacro(str, &varPos, &rsts))) if (!(varLen = findMacro(str, &varPos, &rsts)))
break; break;
continue; continue;
} }

View File

@@ -59,9 +59,11 @@ public:
static QStringList splitArgs(const QString &cmd, OsType osType, static QStringList splitArgs(const QString &cmd, OsType osType,
bool abortOnMeta = false, SplitError *err = nullptr, bool abortOnMeta = false, SplitError *err = nullptr,
const Environment *env = nullptr, const QString *pwd = nullptr); const Environment *env = nullptr, const QString *pwd = nullptr);
using FindMacro = std::function<int(const QString &str, int *pos, QString *ret)>;
//! Safely replace the expandos in a shell command //! Safely replace the expandos in a shell command
static bool expandMacros(QString *cmd, AbstractMacroExpander *mx, static bool expandMacros(QString *cmd, const FindMacro &findMacro, OsType osType);
OsType osType = HostOsInfo::hostOs());
/*! Iterate over arguments from a command line. /*! Iterate over arguments from a command line.
* Assumes that the name of the actual command is *not* part of the line. * Assumes that the name of the actual command is *not* part of the line.

View File

@@ -337,7 +337,7 @@ QString Environment::expandVariables(const QString &input) const
FilePath Environment::expandVariables(const FilePath &variables) const FilePath Environment::expandVariables(const FilePath &variables) const
{ {
return FilePath::fromString(expandVariables(variables.toString())); return FilePath::fromUserInput(expandVariables(variables.toString()));
} }
QStringList Environment::expandVariables(const QStringList &variables) const QStringList Environment::expandVariables(const QStringList &variables) const

View File

@@ -419,8 +419,10 @@ bool EnvironmentModel::currentEntryIsPathList(const QModelIndex &current) const
const QString varName = indexToVariable(current); const QString varName = indexToVariable(current);
if (varName.compare("PATH", Utils::HostOsInfo::fileNameCaseSensitivity()) == 0) if (varName.compare("PATH", Utils::HostOsInfo::fileNameCaseSensitivity()) == 0)
return true; return true;
if (Utils::HostOsInfo::isMacHost() && varName == "DYLD_LIBRARY_PATH") if (Utils::HostOsInfo::isMacHost()
&& (varName == "DYLD_LIBRARY_PATH" || varName == "DYLD_FRAMEWORK_PATH")) {
return true; return true;
}
if (Utils::HostOsInfo::isAnyUnixHost() && varName == "LD_LIBRARY_PATH") if (Utils::HostOsInfo::isAnyUnixHost() && varName == "LD_LIBRARY_PATH")
return true; return true;
if (varName == "PKG_CONFIG_DIR") if (varName == "PKG_CONFIG_DIR")

View File

@@ -35,9 +35,24 @@
namespace Utils { namespace Utils {
static DeviceFileHooks s_deviceHooks; static DeviceFileHooks &deviceFileHooks()
inline bool isWindowsDriveLetter(QChar ch); {
static DeviceFileHooks theDeviceHooks;
return theDeviceHooks;
}
void DeviceFileHooks::setupDeviceFileHooks(const DeviceFileHooks &hooks)
{
static bool wasAlreadySet = false;
QTC_ASSERT(!wasAlreadySet, return);
wasAlreadySet = true;
deviceFileHooks() = hooks;
}
static bool isWindowsDriveLetter(QChar ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
/*! /*!
\class Utils::FilePath \class Utils::FilePath
@@ -328,6 +343,11 @@ Utils::expected_str<std::unique_ptr<FilePathWatcher>> FilePath::watch() const
return fileAccess()->watch(*this); return fileAccess()->watch(*this);
} }
void FilePath::openTerminal(const Environment &env) const
{
deviceFileHooks().openTerminal(*this, env);
}
/*! /*!
Returns a QString for passing on to QString based APIs. Returns a QString for passing on to QString based APIs.
@@ -705,8 +725,8 @@ expected_str<QByteArray> FilePath::fileContents(qint64 maxSize, qint64 offset) c
bool FilePath::ensureReachable(const FilePath &other) const bool FilePath::ensureReachable(const FilePath &other) const
{ {
if (needsDevice()) { if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.ensureReachable, return false); QTC_ASSERT(deviceFileHooks().ensureReachable, return false);
return s_deviceHooks.ensureReachable(*this, other); return deviceFileHooks().ensureReachable(*this, other);
} else if (!other.needsDevice()) { } else if (!other.needsDevice()) {
return true; return true;
} }
@@ -747,8 +767,8 @@ bool FilePath::isSameDevice(const FilePath &other) const
if (!needsDevice() && !other.needsDevice()) if (!needsDevice() && !other.needsDevice())
return true; return true;
QTC_ASSERT(s_deviceHooks.isSameDevice, return true); QTC_ASSERT(deviceFileHooks().isSameDevice, return true);
return s_deviceHooks.isSameDevice(*this, other); return deviceFileHooks().isSameDevice(*this, other);
} }
bool FilePath::isSameFile(const FilePath &other) const bool FilePath::isSameFile(const FilePath &other) const
@@ -1116,8 +1136,8 @@ QString FilePath::displayName(const QString &args) const
{ {
QString deviceName; QString deviceName;
if (needsDevice()) { if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.deviceDisplayName, return nativePath()); QTC_ASSERT(deviceFileHooks().deviceDisplayName, return nativePath());
deviceName = s_deviceHooks.deviceDisplayName(*this); deviceName = deviceFileHooks().deviceDisplayName(*this);
} }
const QString fullPath = nativePath(); const QString fullPath = nativePath();
@@ -1169,11 +1189,6 @@ FilePath FilePath::fromString(const QString &filepath)
return fn; return fn;
} }
bool isWindowsDriveLetter(QChar ch)
{
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
void FilePath::setPath(QStringView path) void FilePath::setPath(QStringView path)
{ {
setParts(scheme(), host(), path); setParts(scheme(), host(), path);
@@ -1250,13 +1265,13 @@ static expected_str<DeviceFileAccess *> getFileAccess(const FilePath &filePath)
if (!filePath.needsDevice()) if (!filePath.needsDevice())
return DesktopDeviceFileAccess::instance(); return DesktopDeviceFileAccess::instance();
if (!s_deviceHooks.fileAccess) { if (!deviceFileHooks().fileAccess) {
// Happens during startup and in tst_fsengine // Happens during startup and in tst_fsengine
QTC_CHECK(false); QTC_CHECK(false);
return DesktopDeviceFileAccess::instance(); return DesktopDeviceFileAccess::instance();
} }
return s_deviceHooks.fileAccess(filePath); return deviceFileHooks().fileAccess(filePath);
} }
DeviceFileAccess *FilePath::fileAccess() const DeviceFileAccess *FilePath::fileAccess() const
@@ -1863,8 +1878,8 @@ Environment FilePath::deviceEnvironment() const
expected_str<Environment> FilePath::deviceEnvironmentWithError() const expected_str<Environment> FilePath::deviceEnvironmentWithError() const
{ {
if (needsDevice()) { if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.environment, return {}); QTC_ASSERT(deviceFileHooks().environment, return {});
return s_deviceHooks.environment(*this); return deviceFileHooks().environment(*this);
} }
return Environment::systemEnvironment(); return Environment::systemEnvironment();
} }
@@ -1976,8 +1991,8 @@ OsType FilePath::osType() const
if (!needsDevice()) if (!needsDevice())
return HostOsInfo::hostOs(); return HostOsInfo::hostOs();
QTC_ASSERT(s_deviceHooks.osType, return HostOsInfo::hostOs()); QTC_ASSERT(deviceFileHooks().osType, return HostOsInfo::hostOs());
return s_deviceHooks.osType(*this); return deviceFileHooks().osType(*this);
} }
Result FilePath::removeFile() const Result FilePath::removeFile() const
@@ -2295,9 +2310,9 @@ expected_str<FilePath> FilePath::localSource() const
if (!needsDevice()) if (!needsDevice())
return *this; return *this;
QTC_ASSERT(s_deviceHooks.localSource, QTC_ASSERT(deviceFileHooks().localSource,
return make_unexpected(Tr::tr("No \"localSource\" device hook set."))); return make_unexpected(Tr::tr("No \"localSource\" device hook set.")));
return s_deviceHooks.localSource(*this); return deviceFileHooks().localSource(*this);
} }
/*! /*!
@@ -2436,11 +2451,6 @@ QStringList FileFilter::asFindArguments(const QString &path) const
return arguments; return arguments;
} }
DeviceFileHooks &DeviceFileHooks::instance()
{
return s_deviceHooks;
}
QTCREATOR_UTILS_EXPORT bool operator==(const FilePath &first, const FilePath &second) QTCREATOR_UTILS_EXPORT bool operator==(const FilePath &first, const FilePath &second)
{ {
return FilePath::equals(first, second, first.caseSensitivity()); return FilePath::equals(first, second, first.caseSensitivity());

View File

@@ -314,6 +314,7 @@ public:
bool equalsCaseSensitive(const FilePath &other) const; bool equalsCaseSensitive(const FilePath &other) const;
Utils::expected_str<std::unique_ptr<FilePathWatcher>> watch() const; Utils::expected_str<std::unique_ptr<FilePathWatcher>> watch() const;
void openTerminal(const Environment &env) const;
private: private:
// These are needed. // These are needed.
@@ -349,8 +350,6 @@ private:
class QTCREATOR_UTILS_EXPORT DeviceFileHooks class QTCREATOR_UTILS_EXPORT DeviceFileHooks
{ {
public: public:
static DeviceFileHooks &instance();
std::function<expected_str<DeviceFileAccess *>(const FilePath &)> fileAccess; std::function<expected_str<DeviceFileAccess *>(const FilePath &)> fileAccess;
std::function<QString(const FilePath &)> deviceDisplayName; std::function<QString(const FilePath &)> deviceDisplayName;
std::function<bool(const FilePath &, const FilePath &)> ensureReachable; std::function<bool(const FilePath &, const FilePath &)> ensureReachable;
@@ -359,8 +358,12 @@ public:
std::function<expected_str<FilePath>(const FilePath &)> localSource; std::function<expected_str<FilePath>(const FilePath &)> localSource;
std::function<void(const FilePath &, const Environment &)> openTerminal; std::function<void(const FilePath &, const Environment &)> openTerminal;
std::function<OsType(const FilePath &)> osType; std::function<OsType(const FilePath &)> osType;
// Only call once.
static void setupDeviceFileHooks(const DeviceFileHooks &hooks);
}; };
// For testing // For testing
QTCREATOR_UTILS_EXPORT QString doCleanPath(const QString &input); QTCREATOR_UTILS_EXPORT QString doCleanPath(const QString &input);

View File

@@ -14,12 +14,11 @@
#include <QFileInfo> #include <QFileInfo>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMap> #include <QMap>
#include <QRegularExpression>
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {
static Q_LOGGING_CATEGORY(expanderLog, "qtc.utils.macroexpander", QtWarningMsg)
const char kFilePathPostfix[] = ":FilePath"; const char kFilePathPostfix[] = ":FilePath";
const char kPathPostfix[] = ":Path"; const char kPathPostfix[] = ":Path";
const char kNativeFilePathPostfix[] = ":NativeFilePath"; const char kNativeFilePathPostfix[] = ":NativeFilePath";
@@ -27,12 +26,112 @@ const char kNativePathPostfix[] = ":NativePath";
const char kFileNamePostfix[] = ":FileName"; const char kFileNamePostfix[] = ":FileName";
const char kFileBaseNamePostfix[] = ":FileBaseName"; const char kFileBaseNamePostfix[] = ":FileBaseName";
class MacroExpanderPrivate : public AbstractMacroExpander class MacroExpanderPrivate
{ {
public: public:
MacroExpanderPrivate() = default; MacroExpanderPrivate() = default;
bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander *> &seen) override static bool validateVarName(const QString &varName) { return !varName.startsWith("JS:"); }
bool expandNestedMacros(const QString &str, int *pos, QString *ret)
{
QString varName;
QString pattern, replace;
QString defaultValue;
QString *currArg = &varName;
QChar prev;
QChar c;
QChar replacementChar;
bool replaceAll = false;
int i = *pos;
int strLen = str.length();
varName.reserve(strLen - i);
for (; i < strLen; prev = c) {
c = str.at(i++);
if (c == '\\' && i < strLen) {
c = str.at(i++);
// For the replacement, do not skip the escape sequence when followed by a digit.
// This is needed for enabling convenient capture group replacement,
// like %{var/(.)(.)/\2\1}, without escaping the placeholders.
if (currArg == &replace && c.isDigit())
*currArg += '\\';
*currArg += c;
} else if (c == '}') {
if (varName.isEmpty()) { // replace "%{}" with "%"
*ret = QString('%');
*pos = i;
return true;
}
QSet<MacroExpanderPrivate *> seen;
if (resolveMacro(varName, ret, seen)) {
*pos = i;
if (!pattern.isEmpty() && currArg == &replace) {
const QRegularExpression regexp(pattern);
if (regexp.isValid()) {
if (replaceAll) {
ret->replace(regexp, replace);
} else {
// There isn't an API for replacing once...
const QRegularExpressionMatch match = regexp.match(*ret);
if (match.hasMatch()) {
*ret = ret->left(match.capturedStart(0))
+ match.captured(0).replace(regexp, replace)
+ ret->mid(match.capturedEnd(0));
}
}
}
}
return true;
}
if (!defaultValue.isEmpty()) {
*pos = i;
*ret = defaultValue;
return true;
}
return false;
} else if (c == '{' && prev == '%') {
if (!expandNestedMacros(str, &i, ret))
return false;
varName.chop(1);
varName += *ret;
} else if (currArg == &varName && c == '-' && prev == ':' && validateVarName(varName)) {
varName.chop(1);
currArg = &defaultValue;
} else if (currArg == &varName && (c == '/' || c == '#') && validateVarName(varName)) {
replacementChar = c;
currArg = &pattern;
if (i < strLen && str.at(i) == replacementChar) {
++i;
replaceAll = true;
}
} else if (currArg == &pattern && c == replacementChar) {
currArg = &replace;
} else {
*currArg += c;
}
}
return false;
}
int findMacro(const QString &str, int *pos, QString *ret)
{
forever {
int openPos = str.indexOf("%{", *pos);
if (openPos < 0)
return 0;
int varPos = openPos + 2;
if (expandNestedMacros(str, &varPos, ret)) {
*pos = openPos;
return varPos - openPos;
}
// An actual expansion may be nested into a "false" one,
// so we continue right after the last %{.
*pos = openPos + 2;
}
}
bool resolveMacro(const QString &name, QString *ret, QSet<MacroExpanderPrivate *> &seen)
{ {
// Prevent loops: // Prevent loops:
const int count = seen.count(); const int count = seen.count();
@@ -229,7 +328,7 @@ MacroExpander::~MacroExpander()
*/ */
bool MacroExpander::resolveMacro(const QString &name, QString *ret) const bool MacroExpander::resolveMacro(const QString &name, QString *ret) const
{ {
QSet<AbstractMacroExpander*> seen; QSet<MacroExpanderPrivate *> seen;
return d->resolveMacro(name, ret, seen); return d->resolveMacro(name, ret, seen);
} }
@@ -242,6 +341,16 @@ QString MacroExpander::value(const QByteArray &variable, bool *found) const
return d->value(variable, found); return d->value(variable, found);
} }
static void expandMacros(QString *str, MacroExpanderPrivate *mx)
{
QString rsts;
for (int pos = 0; int len = mx->findMacro(*str, &pos, &rsts);) {
str->replace(pos, len, rsts);
pos += rsts.length();
}
}
/*! /*!
* Returns \a stringWithVariables with all variables replaced by their values. * Returns \a stringWithVariables with all variables replaced by their values.
* See the MacroExpander overview documentation for other ways to expand variables. * See the MacroExpander overview documentation for other ways to expand variables.
@@ -261,7 +370,7 @@ QString MacroExpander::expand(const QString &stringWithVariables) const
++d->m_lockDepth; ++d->m_lockDepth;
QString res = stringWithVariables; QString res = stringWithVariables;
Utils::expandMacros(&res, d); expandMacros(&res, d);
--d->m_lockDepth; --d->m_lockDepth;
@@ -302,11 +411,19 @@ QVariant MacroExpander::expandVariant(const QVariant &v) const
return v; return v;
} }
QString MacroExpander::expandProcessArgs(const QString &argsWithVariables) const expected_str<QString> MacroExpander::expandProcessArgs(
const QString &argsWithVariables, Utils::OsType osType) const
{ {
QString result = argsWithVariables; QString result = argsWithVariables;
const bool ok = ProcessArgs::expandMacros(&result, d); const bool ok = ProcessArgs::expandMacros(
QTC_ASSERT(ok, qCDebug(expanderLog) << "Expanding failed: " << argsWithVariables); &result,
[this](const QString &str, int *pos, QString *ret) { return d->findMacro(str, pos, ret); },
osType);
if (!ok) {
return make_unexpected(
Tr::tr("Failed to expand macros in process arguments: %1").arg(argsWithVariables));
}
return result; return result;
} }

View File

@@ -5,6 +5,8 @@
#include "utils_global.h" #include "utils_global.h"
#include "hostosinfo.h"
#include <QList> #include <QList>
#include <functional> #include <functional>
@@ -35,7 +37,8 @@ public:
QByteArray expand(const QByteArray &stringWithVariables) const; QByteArray expand(const QByteArray &stringWithVariables) const;
QVariant expandVariant(const QVariant &v) const; QVariant expandVariant(const QVariant &v) const;
QString expandProcessArgs(const QString &argsWithVariables) const; expected_str<QString> expandProcessArgs(
const QString &argsWithVariables, Utils::OsType osType = Utils::HostOsInfo::hostOs()) const;
using PrefixFunction = std::function<QString(QString)>; using PrefixFunction = std::function<QString(QString)>;
using ResolverFunction = std::function<bool(QString, QString *)>; using ResolverFunction = std::function<bool(QString, QString *)>;

View File

@@ -78,126 +78,6 @@ QTCREATOR_UTILS_EXPORT QString commonPrefix(const QStringList &strings)
return strings.at(0).left(commonLength); return strings.at(0).left(commonLength);
} }
static bool validateVarName(const QString &varName)
{
return !varName.startsWith("JS:");
}
bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QString *ret)
{
QString varName;
QString pattern, replace;
QString defaultValue;
QString *currArg = &varName;
QChar prev;
QChar c;
QChar replacementChar;
bool replaceAll = false;
int i = *pos;
int strLen = str.length();
varName.reserve(strLen - i);
for (; i < strLen; prev = c) {
c = str.at(i++);
if (c == '\\' && i < strLen) {
c = str.at(i++);
// For the replacement, do not skip the escape sequence when followed by a digit.
// This is needed for enabling convenient capture group replacement,
// like %{var/(.)(.)/\2\1}, without escaping the placeholders.
if (currArg == &replace && c.isDigit())
*currArg += '\\';
*currArg += c;
} else if (c == '}') {
if (varName.isEmpty()) { // replace "%{}" with "%"
*ret = QString('%');
*pos = i;
return true;
}
QSet<AbstractMacroExpander*> seen;
if (resolveMacro(varName, ret, seen)) {
*pos = i;
if (!pattern.isEmpty() && currArg == &replace) {
const QRegularExpression regexp(pattern);
if (regexp.isValid()) {
if (replaceAll) {
ret->replace(regexp, replace);
} else {
// There isn't an API for replacing once...
const QRegularExpressionMatch match = regexp.match(*ret);
if (match.hasMatch()) {
*ret = ret->left(match.capturedStart(0))
+ match.captured(0).replace(regexp, replace)
+ ret->mid(match.capturedEnd(0));
}
}
}
}
return true;
}
if (!defaultValue.isEmpty()) {
*pos = i;
*ret = defaultValue;
return true;
}
return false;
} else if (c == '{' && prev == '%') {
if (!expandNestedMacros(str, &i, ret))
return false;
varName.chop(1);
varName += *ret;
} else if (currArg == &varName && c == '-' && prev == ':' && validateVarName(varName)) {
varName.chop(1);
currArg = &defaultValue;
} else if (currArg == &varName && (c == '/' || c == '#') && validateVarName(varName)) {
replacementChar = c;
currArg = &pattern;
if (i < strLen && str.at(i) == replacementChar) {
++i;
replaceAll = true;
}
} else if (currArg == &pattern && c == replacementChar) {
currArg = &replace;
} else {
*currArg += c;
}
}
return false;
}
int AbstractMacroExpander::findMacro(const QString &str, int *pos, QString *ret)
{
forever {
int openPos = str.indexOf("%{", *pos);
if (openPos < 0)
return 0;
int varPos = openPos + 2;
if (expandNestedMacros(str, &varPos, ret)) {
*pos = openPos;
return varPos - openPos;
}
// An actual expansion may be nested into a "false" one,
// so we continue right after the last %{.
*pos = openPos + 2;
}
}
QTCREATOR_UTILS_EXPORT void expandMacros(QString *str, AbstractMacroExpander *mx)
{
QString rsts;
for (int pos = 0; int len = mx->findMacro(*str, &pos, &rsts); ) {
str->replace(pos, len, rsts);
pos += rsts.length();
}
}
QTCREATOR_UTILS_EXPORT QString expandMacros(const QString &str, AbstractMacroExpander *mx)
{
QString ret = str;
expandMacros(&ret, mx);
return ret;
}
QTCREATOR_UTILS_EXPORT QString stripAccelerator(const QString &text) QTCREATOR_UTILS_EXPORT QString stripAccelerator(const QString &text)
{ {
QString res = text; QString res = text;

View File

@@ -41,29 +41,6 @@ QTCREATOR_UTILS_EXPORT bool readMultiLineString(const QJsonValue &value, QString
// Compare case insensitive and use case sensitive comparison in case of that being equal. // Compare case insensitive and use case sensitive comparison in case of that being equal.
QTCREATOR_UTILS_EXPORT int caseFriendlyCompare(const QString &a, const QString &b); QTCREATOR_UTILS_EXPORT int caseFriendlyCompare(const QString &a, const QString &b);
class QTCREATOR_UTILS_EXPORT AbstractMacroExpander
{
public:
virtual ~AbstractMacroExpander() {}
// Not const, as it may change the state of the expander.
//! Find an expando to replace and provide a replacement string.
//! \param str The string to scan
//! \param pos Position to start scan on input, found position on output
//! \param ret Replacement string on output
//! \return Length of string part to replace, zero if no (further) matches found
virtual int findMacro(const QString &str, int *pos, QString *ret);
//! Provide a replacement string for an expando
//! \param name The name of the expando
//! \param ret Replacement string on output
//! \return True if the expando was found
virtual bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander *> &seen) = 0;
private:
bool expandNestedMacros(const QString &str, int *pos, QString *ret);
};
QTCREATOR_UTILS_EXPORT void expandMacros(QString *str, AbstractMacroExpander *mx);
QTCREATOR_UTILS_EXPORT QString expandMacros(const QString &str, AbstractMacroExpander *mx);
QTCREATOR_UTILS_EXPORT int parseUsedPortFromNetstatOutput(const QByteArray &line); QTCREATOR_UTILS_EXPORT int parseUsedPortFromNetstatOutput(const QByteArray &line);
QTCREATOR_UTILS_EXPORT QString appendHelper(const QString &base, int n); QTCREATOR_UTILS_EXPORT QString appendHelper(const QString &base, int n);

View File

@@ -38,9 +38,8 @@ public:
HooksPrivate() HooksPrivate()
{ {
auto openTerminal = [](const OpenTerminalParameters &parameters) { auto openTerminal = [](const OpenTerminalParameters &parameters) {
DeviceFileHooks::instance().openTerminal(parameters.workingDirectory.value_or( parameters.workingDirectory.value_or(FilePath{})
FilePath{}), .openTerminal(parameters.environment.value_or(Environment{}));
parameters.environment.value_or(Environment{}));
}; };
auto createProcessInterface = [] { return new ExternalTerminalProcessImpl; }; auto createProcessInterface = [] { return new ExternalTerminalProcessImpl; };

View File

@@ -316,7 +316,7 @@ void Theme::readSettings(QSettings &settings)
for (int i = 0, total = e.keyCount(); i < total; ++i) { for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i)); const QString key = QLatin1String(e.key(i));
if (!d->unresolvedPalette.contains(key)) { if (!d->unresolvedPalette.contains(key)) {
if (i < PaletteWindow || i > PalettePlaceholderTextDisabled) if (i < PaletteWindow || i > PaletteAccentDisabled)
qWarning("Theme \"%s\" misses color setting for key \"%s\".", qWarning("Theme \"%s\" misses color setting for key \"%s\".",
qPrintable(d->fileName), qPrintable(d->fileName),
qPrintable(key)); qPrintable(key));

View File

@@ -415,7 +415,10 @@ static ExecutableItem logcatRecipe(const Storage<RunnerStorage> &storage)
const QString pidString = QString::number(storagePtr->m_processPID); const QString pidString = QString::number(storagePtr->m_processPID);
for (const QByteArray &msg : std::as_const(lines)) { for (const QByteArray &msg : std::as_const(lines)) {
const QString line = QString::fromUtf8(msg).trimmed() + QLatin1Char('\n'); const QString line = QString::fromUtf8(msg).trimmed() + QLatin1Char('\n');
if (!line.contains(pidString)) // Get type excluding the initial color characters
const QString msgType = line.mid(5, 2);
const bool isFatal = msgType == "F/";
if (!line.contains(pidString) && !isFatal)
continue; continue;
if (storagePtr->m_useCppDebugger) { if (storagePtr->m_useCppDebugger) {
@@ -427,32 +430,31 @@ static ExecutableItem logcatRecipe(const Storage<RunnerStorage> &storage)
static const QRegularExpression regExpLogcat{ static const QRegularExpression regExpLogcat{
"^\\x1B\\[[0-9]+m" // color "^\\x1B\\[[0-9]+m" // color
"(\\w/)" // message type 1. capture "\\w/" // message type
".*" // source ".*" // source
"(\\(\\s*\\d*\\)):" // pid 2. capture "(\\(\\s*\\d*\\)):" // pid 1. capture
"\\s*" "\\s*"
".*" // message ".*" // message
"\\x1B\\[[0-9]+m" // color "\\x1B\\[[0-9]+m" // color
"[\\n\\r]*$" "[\\n\\r]*$"
}; };
static QStringList errorMsgTypes{"F/", "E/", "W/"}; static QStringList errorMsgTypes{"W/", "E/", "F/"};
const bool onlyError = channel == QProcess::StandardError; const bool onlyError = channel == QProcess::StandardError;
const QRegularExpressionMatch match = regExpLogcat.match(line); const QRegularExpressionMatch match = regExpLogcat.match(line);
if (match.hasMatch()) { if (match.hasMatch()) {
const QString pidMatch = match.captured(2); const QString pidMatch = match.captured(1);
const QString cleanPidMatch = pidMatch.mid(1, pidMatch.size() - 2).trimmed(); const QString cleanPidMatch = pidMatch.mid(1, pidMatch.size() - 2).trimmed();
if (cleanPidMatch == pidString) { const QString output = QString(line).remove(pidMatch);
const QString msgType = match.captured(1); if (isFatal) {
const QString output = QString(line).remove(pidMatch); storagePtr->m_glue->addStdErr(output);
} else if (cleanPidMatch == pidString) {
if (onlyError || errorMsgTypes.contains(msgType)) if (onlyError || errorMsgTypes.contains(msgType))
storagePtr->m_glue->addStdErr(output); storagePtr->m_glue->addStdErr(output);
else else
storagePtr->m_glue->addStdOut(output); storagePtr->m_glue->addStdOut(output);
} }
} else { } else {
// Get type excluding the initial color characters
const QString msgType = line.mid(5, 7);
if (onlyError || errorMsgTypes.contains(msgType)) if (onlyError || errorMsgTypes.contains(msgType))
storagePtr->m_glue->addStdErr(line); storagePtr->m_glue->addStdErr(line);
else else

View File

@@ -235,6 +235,7 @@ private:
IssuesWidget::IssuesWidget(QWidget *parent) IssuesWidget::IssuesWidget(QWidget *parent)
: QScrollArea(parent) : QScrollArea(parent)
{ {
setFrameStyle(QFrame::NoFrame);
QWidget *widget = new QWidget(this); QWidget *widget = new QWidget(this);
m_dashboards = new QComboBox(this); m_dashboards = new QComboBox(this);
m_dashboards->setMinimumContentsLength(15); m_dashboards->setMinimumContentsLength(15);
@@ -253,6 +254,7 @@ IssuesWidget::IssuesWidget(QWidget *parent)
m_dashboardProjects->clear(); m_dashboardProjects->clear();
} }
updateBasicProjectInfo(std::nullopt); updateBasicProjectInfo(std::nullopt);
m_issuesView->hideProgressIndicator();
} }
}); });
@@ -450,14 +452,23 @@ void IssuesWidget::reinitProjectList(const QString &currentProject)
{ {
const auto onDashboardInfoFetched const auto onDashboardInfoFetched
= [this, currentProject] (const expected_str<DashboardInfo> &info) { = [this, currentProject] (const expected_str<DashboardInfo> &info) {
if (!info) if (!info) {
m_issuesView->hideProgressIndicator();
return; return;
}
GuardLocker lock(m_signalBlocker); GuardLocker lock(m_signalBlocker);
m_dashboardProjects->clear();
m_dashboardProjects->addItems(info->projects); m_dashboardProjects->addItems(info->projects);
if (!currentProject.isEmpty() && info->projects.contains(currentProject)) if (!currentProject.isEmpty() && info->projects.contains(currentProject))
m_dashboardProjects->setCurrentText(currentProject); m_dashboardProjects->setCurrentText(currentProject);
}; };
{
GuardLocker lock(m_signalBlocker);
m_dashboardProjects->clear();
}
updateBasicProjectInfo(std::nullopt);
if (m_overlay)
m_overlay->hide();
m_issuesView->showProgressIndicator();
fetchDashboardAndProjectInfo(onDashboardInfoFetched, currentProject); fetchDashboardAndProjectInfo(onDashboardInfoFetched, currentProject);
} }
@@ -668,7 +679,11 @@ void IssuesWidget::updateBasicProjectInfo(const std::optional<Dto::ProjectInfoDt
m_totalRowCount = 0; m_totalRowCount = 0;
m_addedFilter->setText("0"); m_addedFilter->setText("0");
m_removedFilter->setText("0"); m_removedFilter->setText("0");
setFiltersEnabled(false);
m_issuesModel->clear(); m_issuesModel->clear();
m_issuesModel->setHeader({});
if (m_overlay)
m_overlay->hide();
return; return;
} }
@@ -874,6 +889,7 @@ void AxivionPerspective::initPerspective()
m_issuesWidget->setPalette(pal); m_issuesWidget->setPalette(pal);
m_issueDetails = new QTextBrowser; m_issueDetails = new QTextBrowser;
m_issueDetails->setFrameStyle(QFrame::NoFrame);
m_issueDetails->setObjectName("AxivionIssuesDetails"); m_issueDetails->setObjectName("AxivionIssuesDetails");
m_issueDetails->setWindowTitle(Tr::tr("Issue Details")); m_issueDetails->setWindowTitle(Tr::tr("Issue Details"));
const QString text = Tr::tr( const QString text = Tr::tr(
@@ -888,6 +904,7 @@ void AxivionPerspective::initPerspective()
reloadDataAct->setIcon(Utils::Icons::RELOAD_TOOLBAR.icon()); reloadDataAct->setIcon(Utils::Icons::RELOAD_TOOLBAR.icon());
reloadDataAct->setToolTip(Tr::tr("Reload")); reloadDataAct->setToolTip(Tr::tr("Reload"));
connect(reloadDataAct, &QAction::triggered, this, [this] { connect(reloadDataAct, &QAction::triggered, this, [this] {
switchActiveDashboardId(activeDashboardId()); // reset cached data
reinitDashboardList({}); reinitDashboardList({});
}); });

View File

@@ -798,22 +798,12 @@ Group projectInfoRecipe(const QString &projectName)
return SetupResult::StopWithError; return SetupResult::StopWithError;
} }
const QString targetProjectName if (dd->m_dashboardInfo->projects.isEmpty()) {
= (projectName.isEmpty() && !dd->m_dashboardInfo->projects.isEmpty()) updatePerspectiveToolbar();
? dd->m_dashboardInfo->projects.first() : projectName;
if (targetProjectName.isEmpty()) {
updateDashboard(); updateDashboard();
return SetupResult::StopWithSuccess; return SetupResult::StopWithSuccess;
} }
const auto it = dd->m_dashboardInfo->projectUrls.constFind(targetProjectName);
if (it == dd->m_dashboardInfo->projectUrls.constEnd()) {
MessageManager::writeDisrupting(QString("Axivion: %1")
.arg(Tr::tr("The DashboardInfo doesn't contain project \"%1\".").arg(targetProjectName)));
return SetupResult::StopWithError;
}
const auto handler = [](const Dto::ProjectInfoDto &data) { const auto handler = [](const Dto::ProjectInfoDto &data) {
dd->m_currentProjectInfo = data; dd->m_currentProjectInfo = data;
if (!dd->m_currentProjectInfo->versions.empty()) if (!dd->m_currentProjectInfo->versions.empty())
@@ -822,6 +812,11 @@ Group projectInfoRecipe(const QString &projectName)
updateDashboard(); updateDashboard();
}; };
const QString targetProjectName = projectName.isEmpty()
? dd->m_dashboardInfo->projects.first() : projectName;
auto it = dd->m_dashboardInfo->projectUrls.constFind(targetProjectName);
if (it == dd->m_dashboardInfo->projectUrls.constEnd())
it = dd->m_dashboardInfo->projectUrls.constBegin();
taskTree.setRecipe( taskTree.setRecipe(
fetchDataRecipe<Dto::ProjectInfoDto>(dd->m_dashboardInfo->source.resolved(*it), handler)); fetchDataRecipe<Dto::ProjectInfoDto>(dd->m_dashboardInfo->source.resolved(*it), handler));
return SetupResult::Continue; return SetupResult::Continue;

View File

@@ -923,7 +923,12 @@ void ExternalToolConfig::addCategory()
void ExternalToolConfig::updateEffectiveArguments() void ExternalToolConfig::updateEffectiveArguments()
{ {
m_arguments->setToolTip(Utils::globalMacroExpander()->expandProcessArgs(m_arguments->text())); const expected_str<QString> result = Utils::globalMacroExpander()->expandProcessArgs(
m_arguments->text());
if (result)
m_arguments->setToolTip(*result);
else
m_arguments->setToolTip(result.error());
} }
void ExternalToolConfig::editEnvironmentChanges() void ExternalToolConfig::editEnvironmentChanges()

View File

@@ -598,7 +598,10 @@ bool ExternalToolRunner::resolve()
} }
} }
m_resolvedArguments = expander->expandProcessArgs(m_tool->arguments()); const expected_str<QString> args = expander->expandProcessArgs(m_tool->arguments());
QTC_ASSERT_EXPECTED(args, return false);
m_resolvedArguments = *args;
m_resolvedInput = expander->expand(m_tool->input()); m_resolvedInput = expander->expand(m_tool->input());
m_resolvedWorkingDirectory = expander->expand(m_tool->workingDirectory()); m_resolvedWorkingDirectory = expander->expand(m_tool->workingDirectory());

View File

@@ -223,7 +223,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inpu
} }
// Register Vcs(s) with the cache // Register Vcs(s) with the cache
FilePath tmpDir = directory.absolutePath(); FilePath tmpDir = directory.absoluteFilePath();
#if defined WITH_TESTS #if defined WITH_TESTS
// Force caching of test directories (even though they do not exist): // Force caching of test directories (even though they do not exist):
if (directory.startsWith(TEST_PREFIX)) if (directory.startsWith(TEST_PREFIX))

View File

@@ -763,8 +763,14 @@ void DockerDevicePrivate::stopCurrentContainer()
return; return;
auto fileAccess = m_fileAccess.writeLocked(); auto fileAccess = m_fileAccess.writeLocked();
if (*fileAccess) if (*fileAccess) {
fileAccess->reset(); if (QThread::currentThread() == thread()) {
fileAccess->reset();
} else {
QMetaObject::invokeMethod(
this, [ptr = fileAccess->release()]() { delete ptr; }, Qt::QueuedConnection);
}
}
Process proc; Process proc;
proc.setCommand({settings().dockerBinaryPath(), {"container", "kill", m_container}}); proc.setCommand({settings().dockerBinaryPath(), {"container", "kill", m_container}});

View File

@@ -264,6 +264,7 @@ Toolchains KitDetectorPrivate::autoDetectToolchains()
.arg(toolchain->compilerCommand().toUserOutput())); .arg(toolchain->compilerCommand().toUserOutput()));
toolchain->setDetectionSource(m_sharedId); toolchain->setDetectionSource(m_sharedId);
} }
ToolchainManager::registerToolchains(newToolchains);
const QList<ToolchainBundle> bundles const QList<ToolchainBundle> bundles
= ToolchainBundle::collectBundles(newToolchains, ToolchainBundle::AutoRegister::On); = ToolchainBundle::collectBundles(newToolchains, ToolchainBundle::AutoRegister::On);
alreadyKnown.append(newToolchains); alreadyKnown.append(newToolchains);

View File

@@ -4,6 +4,8 @@
#include "effectshaderscodeeditor.h" #include "effectshaderscodeeditor.h"
#include "effectcodeeditorwidget.h" #include "effectcodeeditorwidget.h"
#include <utils/fileutils.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>

View File

@@ -9,6 +9,7 @@
#include "extensionsmodel.h" #include "extensionsmodel.h"
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/coreplugintr.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/iwelcomepage.h> #include <coreplugin/iwelcomepage.h>
@@ -27,6 +28,7 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/icon.h> #include <utils/icon.h>
#include <utils/infobar.h>
#include <utils/infolabel.h> #include <utils/infolabel.h>
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
#include <utils/markdownbrowser.h> #include <utils/markdownbrowser.h>
@@ -239,6 +241,8 @@ private:
QString m_currentVendor; QString m_currentVendor;
}; };
const char kRestartSetting[] = "RestartAfterPluginEnabledChanged";
class PluginStatusWidget : public QWidget class PluginStatusWidget : public QWidget
{ {
public: public:
@@ -246,9 +250,7 @@ public:
: QWidget(parent) : QWidget(parent)
{ {
m_label = new InfoLabel; m_label = new InfoLabel;
m_switch = new Switch(Tr::tr("Load on start")); m_switch = new Switch(Tr::tr("Active"));
m_restartButton = new Button(Tr::tr("Restart Now"), Button::MediumPrimary);
m_restartButton->setVisible(false);
m_pluginView.hide(); m_pluginView.hide();
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
@@ -256,7 +258,6 @@ public:
Column { Column {
m_label, m_label,
m_switch, m_switch,
m_restartButton,
}.attachTo(this); }.attachTo(this);
connect(m_switch, &QCheckBox::clicked, this, [this](bool checked) { connect(m_switch, &QCheckBox::clicked, this, [this](bool checked) {
@@ -265,7 +266,18 @@ public:
return; return;
const bool doIt = m_pluginView.data().setPluginsEnabled({spec}, checked); const bool doIt = m_pluginView.data().setPluginsEnabled({spec}, checked);
if (doIt) { if (doIt) {
m_restartButton->show(); if (!ICore::infoBar()->canInfoBeAdded(kRestartSetting))
return;
Utils::InfoBarEntry info(
kRestartSetting,
Core::Tr::tr("Plugin changes will take effect after restart."));
info.addCustomButton(Tr::tr("Restart Now"), [] {
ICore::infoBar()->removeInfo(kRestartSetting);
QTimer::singleShot(0, ICore::instance(), &ICore::restart);
});
ICore::infoBar()->addInfo(info);
ExtensionSystem::PluginManager::writeSettings(); ExtensionSystem::PluginManager::writeSettings();
} else { } else {
m_switch->setChecked(!checked); m_switch->setChecked(!checked);
@@ -274,8 +286,6 @@ public:
connect(ExtensionSystem::PluginManager::instance(), connect(ExtensionSystem::PluginManager::instance(),
&ExtensionSystem::PluginManager::pluginsChanged, this, &PluginStatusWidget::update); &ExtensionSystem::PluginManager::pluginsChanged, this, &PluginStatusWidget::update);
connect(m_restartButton, &QAbstractButton::clicked,
ICore::instance(), &ICore::restart, Qt::QueuedConnection);
update(); update();
} }
@@ -311,7 +321,6 @@ private:
InfoLabel *m_label; InfoLabel *m_label;
Switch *m_switch; Switch *m_switch;
QAbstractButton *m_restartButton;
QString m_pluginId; QString m_pluginId;
ExtensionSystem::PluginView m_pluginView{this}; ExtensionSystem::PluginView m_pluginView{this};
}; };
@@ -493,7 +502,6 @@ ExtensionManagerWidget::ExtensionManagerWidget()
WelcomePageHelpers::createRule(Qt::Vertical), WelcomePageHelpers::createRule(Qt::Vertical),
Column { Column {
m_secondaryContent, m_secondaryContent,
m_pluginStatus,
}, },
noMargin, spacing(0), noMargin, spacing(0),
}.attachTo(m_secondaryDescriptionWidget); }.attachTo(m_secondaryDescriptionWidget);
@@ -501,8 +509,9 @@ ExtensionManagerWidget::ExtensionManagerWidget()
Row { Row {
Row { Row {
Column { Column {
Column { Row {
m_headingWidget, m_headingWidget,
m_pluginStatus,
customMargins(SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl, customMargins(SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl,
SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl), SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl),
}, },

View File

@@ -157,9 +157,9 @@ static QString extensionStateDisplayString(ExtensionState state)
{ {
switch (state) { switch (state) {
case InstalledEnabled: case InstalledEnabled:
return Tr::tr("Loaded"); return Tr::tr("Active");
case InstalledDisabled: case InstalledDisabled:
return Tr::tr("Installed"); return Tr::tr("Inactive");
default: default:
return {}; return {};
} }
@@ -180,8 +180,10 @@ public:
constexpr static TextFormat vendorTF constexpr static TextFormat vendorTF
{Theme::Token_Text_Muted, UiElement::UiElementLabelSmall, {Theme::Token_Text_Muted, UiElement::UiElementLabelSmall,
Qt::AlignVCenter | Qt::TextDontClip}; Qt::AlignVCenter | Qt::TextDontClip};
constexpr static TextFormat stateTF constexpr static TextFormat stateActiveTF
{vendorTF.themeColor, UiElement::UiElementCaption, vendorTF.drawTextFlags}; {vendorTF.themeColor, UiElement::UiElementCaption, vendorTF.drawTextFlags};
constexpr static TextFormat stateInactiveTF
{Theme::Token_Text_Subtle, stateActiveTF.uiElement, stateActiveTF.drawTextFlags};
constexpr static TextFormat descriptionTF constexpr static TextFormat descriptionTF
{itemNameTF.themeColor, UiElement::UiElementCaption}; {itemNameTF.themeColor, UiElement::UiElementCaption};
@@ -213,7 +215,7 @@ public:
m_releaseStatus = tfLabel(releaseStatusTF, false); m_releaseStatus = tfLabel(releaseStatusTF, false);
m_releaseStatus->setAlignment(Qt::AlignLeft); m_releaseStatus->setAlignment(Qt::AlignLeft);
m_releaseStatus->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_releaseStatus->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_installStateLabel = tfLabel(stateTF, false); m_installStateLabel = tfLabel(stateActiveTF, false);
m_installStateLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_installStateLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_installStateIcon = new QLabel; m_installStateIcon = new QLabel;
m_installStateIcon->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); m_installStateIcon->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
@@ -284,13 +286,17 @@ public:
const bool showState = !stateString.isEmpty(); const bool showState = !stateString.isEmpty();
m_installState->setVisible(showState); m_installState->setVisible(showState);
if (showState) { if (showState) {
const bool active = state == InstalledEnabled;
QPalette pal = m_installStateLabel->palette();
pal.setColor(QPalette::WindowText, (active ? stateActiveTF : stateInactiveTF).color());
m_installStateLabel->setPalette(pal);
m_installStateLabel->setText(stateString); m_installStateLabel->setText(stateString);
const FilePath checkmarkMask = ":/extensionmanager/images/checkmark.png"; const FilePath checkmarkMask = ":/extensionmanager/images/checkmark.png";
static const QPixmap enabled = Icon({{checkmarkMask, Theme::Token_Accent_Muted}}, static const QPixmap iconActive = Icon({{checkmarkMask, Theme::Token_Accent_Muted}},
Icon::Tint).pixmap(); Icon::Tint).pixmap();
static const QPixmap disabled = Icon({{checkmarkMask, stateTF.themeColor}}, static const QPixmap iconInactive = Icon({{checkmarkMask, stateInactiveTF.themeColor}},
Icon::Tint).pixmap(); Icon::Tint).pixmap();
m_installStateIcon->setPixmap(state == InstalledEnabled ? enabled : disabled); m_installStateIcon->setPixmap(active ? iconActive : iconInactive);
} }
m_vendorLabel->setText(index.data(RoleVendor).toString()); m_vendorLabel->setText(index.data(RoleVendor).toString());
@@ -772,10 +778,8 @@ QPixmap itemIcon(const QModelIndex &index, Size size)
const PluginSpec *ps = pluginSpecForId(index.data(RoleId).toString()); const PluginSpec *ps = pluginSpecForId(index.data(RoleId).toString());
const bool isEnabled = ps == nullptr || ps->isEffectivelyEnabled(); const bool isEnabled = ps == nullptr || ps->isEffectivelyEnabled();
const QGradientStops gradientStops = { const QGradientStops gradientStops = {
{0, creatorColor(isEnabled ? Theme::Token_Gradient01_Start {0, creatorColor(Theme::Token_Gradient01_Start)},
: Theme::Token_Gradient02_Start)}, {1, creatorColor(Theme::Token_Gradient01_End)},
{1, creatorColor(isEnabled ? Theme::Token_Gradient01_End
: Theme::Token_Gradient02_End)},
}; };
const Theme::Color color = Theme::Token_Basic_White; const Theme::Color color = Theme::Token_Basic_White;
@@ -790,14 +794,14 @@ QPixmap itemIcon(const QModelIndex &index, Size size)
const ItemType itemType = index.data(RoleItemType).value<ItemType>(); const ItemType itemType = index.data(RoleItemType).value<ItemType>();
const QIcon &icon = (itemType == ItemTypePack) ? (size == SizeSmall ? packS : packB) const QIcon &icon = (itemType == ItemTypePack) ? (size == SizeSmall ? packS : packB)
: (size == SizeSmall ? extensionS : extensionB); : (size == SizeSmall ? extensionS : extensionB);
const qreal iconOpacityDisabled = 0.6; const qreal iconOpacityDisabled = 0.5;
QPainter p(&pixmap); QPainter p(&pixmap);
QLinearGradient gradient(iconBgR.topRight(), iconBgR.bottomLeft()); QLinearGradient gradient(iconBgR.topRight(), iconBgR.bottomLeft());
gradient.setStops(gradientStops); gradient.setStops(gradientStops);
WelcomePageHelpers::drawCardBackground(&p, iconBgR, gradient, Qt::NoPen, iconRectRounding);
if (!isEnabled) if (!isEnabled)
p.setOpacity(iconOpacityDisabled); p.setOpacity(iconOpacityDisabled);
WelcomePageHelpers::drawCardBackground(&p, iconBgR, gradient, Qt::NoPen, iconRectRounding);
icon.paint(&p, iconBgR); icon.paint(&p, iconBgR);
return pixmap; return pixmap;

View File

@@ -298,12 +298,21 @@ void BuildConsoleBuildStep::setupOutputFormatter(OutputFormatter *formatter)
// BuildConsoleStepFactory // BuildConsoleStepFactory
BuildConsoleStepFactory::BuildConsoleStepFactory() class BuildConsoleStepFactory final : public BuildStepFactory
{ {
registerStep<BuildConsoleBuildStep>(IncrediBuild::Constants::BUILDCONSOLE_BUILDSTEP_ID); public:
setDisplayName(Tr::tr("IncrediBuild for Windows")); BuildConsoleStepFactory()
setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD, {
ProjectExplorer::Constants::BUILDSTEPS_CLEAN}); registerStep<BuildConsoleBuildStep>(IncrediBuild::Constants::BUILDCONSOLE_BUILDSTEP_ID);
setDisplayName(Tr::tr("IncrediBuild for Windows"));
setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD,
ProjectExplorer::Constants::BUILDSTEPS_CLEAN});
}
};
void setupBuildConsoleStep()
{
static BuildConsoleStepFactory theBuildConsoleStepFactory;
} }
} // IncrediBuild::Internal } // IncrediBuild::Internal

View File

@@ -3,14 +3,8 @@
#pragma once #pragma once
#include <projectexplorer/buildstep.h>
namespace IncrediBuild::Internal { namespace IncrediBuild::Internal {
class BuildConsoleStepFactory final : public ProjectExplorer::BuildStepFactory void setupBuildConsoleStep();
{
public:
BuildConsoleStepFactory();
};
} // IncrediBuild::Internal } // IncrediBuild::Internal

View File

@@ -100,12 +100,21 @@ void IBConsoleBuildStep::setupOutputFormatter(OutputFormatter *formatter)
// IBConsoleStepFactory // IBConsoleStepFactory
IBConsoleStepFactory::IBConsoleStepFactory() class IBConsoleStepFactory final : public BuildStepFactory
{ {
registerStep<IBConsoleBuildStep>(IncrediBuild::Constants::IBCONSOLE_BUILDSTEP_ID); public:
setDisplayName(Tr::tr("IncrediBuild for Linux")); IBConsoleStepFactory()
setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD, {
ProjectExplorer::Constants::BUILDSTEPS_CLEAN}); registerStep<IBConsoleBuildStep>(IncrediBuild::Constants::IBCONSOLE_BUILDSTEP_ID);
setDisplayName(Tr::tr("IncrediBuild for Linux"));
setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD,
ProjectExplorer::Constants::BUILDSTEPS_CLEAN});
}
};
void setupIBConsoleStep()
{
static IBConsoleStepFactory theIBConsoleStepFactory;
} }
} // IncrediBuild::Internal } // IncrediBuild::Internal

View File

@@ -3,14 +3,8 @@
#pragma once #pragma once
#include <projectexplorer/buildstep.h>
namespace IncrediBuild::Internal { namespace IncrediBuild::Internal {
class IBConsoleStepFactory : public ProjectExplorer::BuildStepFactory void setupIBConsoleStep();
{
public:
IBConsoleStepFactory();
};
} // IncrediBuild::Internal } // IncrediBuild::Internal

View File

@@ -8,25 +8,17 @@
namespace IncrediBuild::Internal { namespace IncrediBuild::Internal {
class IncrediBuildPluginPrivate
{
public:
BuildConsoleStepFactory buildConsoleStepFactory;
IBConsoleStepFactory ibConsolStepFactory;
};
class IncrediBuildPlugin final : public ExtensionSystem::IPlugin class IncrediBuildPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "IncrediBuild.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "IncrediBuild.json")
public: public:
void initialize() override void initialize() final
{ {
d = std::make_unique<IncrediBuildPluginPrivate>(); setupBuildConsoleStep();
setupIBConsoleStep();
} }
std::unique_ptr<IncrediBuildPluginPrivate> d;
}; };
} // IncrediBuild::Internal } // IncrediBuild::Internal

View File

@@ -54,6 +54,7 @@ public:
int progress, int maxProgress, const QString &info) { int progress, int maxProgress, const QString &info) {
emit progressValueChanged(progress * 100 / maxProgress, info); emit progressValueChanged(progress * 100 / maxProgress, info);
}); });
connect(m_toolHandler.get(), &IosToolHandler::message, this, &IosTransfer::message);
connect( connect(
m_toolHandler.get(), m_toolHandler.get(),
&IosToolHandler::errorMsg, &IosToolHandler::errorMsg,
@@ -85,6 +86,7 @@ public:
signals: signals:
void done(DoneResult result); void done(DoneResult result);
void progressValueChanged(int progress, const QString &info); // progress in % void progressValueChanged(int progress, const QString &info); // progress in %
void message(const QString &message);
void errorMessage(const QString &message); void errorMessage(const QString &message);
private: private:
@@ -253,6 +255,9 @@ GroupItem IosDeployStep::runRecipe()
transfer.setExpectSuccess(checkProvisioningProfile()); transfer.setExpectSuccess(checkProvisioningProfile());
emit progress(0, transferringMessage); emit progress(0, transferringMessage);
connect(&transfer, &IosTransfer::progressValueChanged, this, &IosDeployStep::progress); connect(&transfer, &IosTransfer::progressValueChanged, this, &IosDeployStep::progress);
connect(&transfer, &IosTransfer::message, this, [this](const QString &message) {
emit addOutput(message, OutputFormat::NormalMessage);
});
connect(&transfer, &IosTransfer::errorMessage, this, [this](const QString &message) { connect(&transfer, &IosTransfer::errorMessage, this, [this](const QString &message) {
emit addOutput(message, OutputFormat::ErrorMessage); emit addOutput(message, OutputFormat::ErrorMessage);
}); });

View File

@@ -421,6 +421,7 @@ private:
void handleGotInferiorPid(Ios::IosToolHandler *handler, const FilePath &bundlePath, void handleGotInferiorPid(Ios::IosToolHandler *handler, const FilePath &bundlePath,
const QString &deviceId, qint64 pid); const QString &deviceId, qint64 pid);
void handleAppOutput(Ios::IosToolHandler *handler, const QString &output); void handleAppOutput(Ios::IosToolHandler *handler, const QString &output);
void handleMessage(const QString &msg);
void handleErrorMsg(Ios::IosToolHandler *handler, const QString &msg); void handleErrorMsg(Ios::IosToolHandler *handler, const QString &msg);
void handleToolExited(Ios::IosToolHandler *handler, int code); void handleToolExited(Ios::IosToolHandler *handler, int code);
void handleFinished(Ios::IosToolHandler *handler); void handleFinished(Ios::IosToolHandler *handler);
@@ -529,8 +530,8 @@ void IosRunner::start()
m_toolHandler = new IosToolHandler(m_deviceType, this); m_toolHandler = new IosToolHandler(m_deviceType, this);
connect(m_toolHandler, &IosToolHandler::appOutput, connect(m_toolHandler, &IosToolHandler::appOutput,
this, &IosRunner::handleAppOutput); this, &IosRunner::handleAppOutput);
connect(m_toolHandler, &IosToolHandler::errorMsg, connect(m_toolHandler, &IosToolHandler::message, this, &IosRunner::handleMessage);
this, &IosRunner::handleErrorMsg); connect(m_toolHandler, &IosToolHandler::errorMsg, this, &IosRunner::handleErrorMsg);
connect(m_toolHandler, &IosToolHandler::gotServerPorts, connect(m_toolHandler, &IosToolHandler::gotServerPorts,
this, &IosRunner::handleGotServerPorts); this, &IosRunner::handleGotServerPorts);
connect(m_toolHandler, &IosToolHandler::gotInferiorPid, connect(m_toolHandler, &IosToolHandler::gotInferiorPid,
@@ -627,6 +628,16 @@ void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output)
appendMessage(output, StdOutFormat); appendMessage(output, StdOutFormat);
} }
void IosRunner::handleMessage(const QString &msg)
{
QString res(msg);
QRegularExpression qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)...");
const QRegularExpressionMatch match = qmlPortRe.match(msg);
if (match.hasMatch() && m_qmlServerPort.isValid())
res.replace(match.captured(1), QString::number(m_qmlServerPort.number()));
appendMessage(res, StdOutFormat);
}
void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg) void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
{ {
Q_UNUSED(handler) Q_UNUSED(handler)
@@ -640,11 +651,6 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
TaskHub::addTask(DeploymentTask(Task::Error, message)); TaskHub::addTask(DeploymentTask(Task::Error, message));
res.replace(lockedErr, message); res.replace(lockedErr, message);
} }
QRegularExpression qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)...");
const QRegularExpressionMatch match = qmlPortRe.match(msg);
if (match.hasMatch() && m_qmlServerPort.isValid())
res.replace(match.captured(1), QString::number(m_qmlServerPort.number()));
appendMessage(res, StdErrFormat); appendMessage(res, StdErrFormat);
} }

View File

@@ -93,6 +93,7 @@ signals:
struct ParserState { struct ParserState {
enum Kind { enum Kind {
Msg, Msg,
Error,
DeviceId, DeviceId,
Key, Key,
Value, Value,
@@ -119,6 +120,7 @@ struct ParserState {
bool collectChars() { bool collectChars() {
switch (kind) { switch (kind) {
case Msg: case Msg:
case Error:
case DeviceId: case DeviceId:
case Key: case Key:
case Value: case Value:
@@ -386,6 +388,8 @@ void IosDeviceToolHandlerPrivate::processXml()
const auto elName = outputParser.name(); const auto elName = outputParser.name();
if (elName == QLatin1String("msg")) { if (elName == QLatin1String("msg")) {
stack.append(ParserState(ParserState::Msg)); stack.append(ParserState(ParserState::Msg));
} else if (elName == QLatin1String("error")) {
stack.append(ParserState(ParserState::Error));
} else if (elName == QLatin1String("exit")) { } else if (elName == QLatin1String("exit")) {
stack.append(ParserState(ParserState::Exit)); stack.append(ParserState(ParserState::Exit));
toolExited(outputParser.attributes().value(QLatin1String("code")) toolExited(outputParser.attributes().value(QLatin1String("code"))
@@ -459,6 +463,9 @@ void IosDeviceToolHandlerPrivate::processXml()
stack.removeLast(); stack.removeLast();
switch (p.kind) { switch (p.kind) {
case ParserState::Msg: case ParserState::Msg:
emit q->message(p.chars);
break;
case ParserState::Error:
errorMsg(p.chars); errorMsg(p.chars);
break; break;
case ParserState::DeviceId: case ParserState::DeviceId:

View File

@@ -62,6 +62,7 @@ signals:
void deviceInfo(Ios::IosToolHandler *handler, const QString &deviceId, void deviceInfo(Ios::IosToolHandler *handler, const QString &deviceId,
const Ios::IosToolHandler::Dict &info); const Ios::IosToolHandler::Dict &info);
void appOutput(Ios::IosToolHandler *handler, const QString &output); void appOutput(Ios::IosToolHandler *handler, const QString &output);
void message(const QString &msg);
void errorMsg(Ios::IosToolHandler *handler, const QString &msg); void errorMsg(Ios::IosToolHandler *handler, const QString &msg);
void toolExited(Ios::IosToolHandler *handler, int code); void toolExited(Ios::IosToolHandler *handler, int code);
void finished(Ios::IosToolHandler *handler); void finished(Ios::IosToolHandler *handler);

View File

@@ -400,7 +400,7 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested,
this, &DeviceManager::save); this, &DeviceManager::save);
DeviceFileHooks &deviceHooks = DeviceFileHooks::instance(); DeviceFileHooks deviceHooks;
deviceHooks.isSameDevice = [](const FilePath &left, const FilePath &right) { deviceHooks.isSameDevice = [](const FilePath &left, const FilePath &right) {
auto leftDevice = DeviceManager::deviceForPath(left); auto leftDevice = DeviceManager::deviceForPath(left);
@@ -467,6 +467,8 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return device->osType(); return device->osType();
}; };
DeviceFileHooks::setupDeviceFileHooks(deviceHooks);
DeviceProcessHooks processHooks; DeviceProcessHooks processHooks;
processHooks.processImplHook = [](const FilePath &filePath) -> ProcessInterface * { processHooks.processImplHook = [](const FilePath &filePath) -> ProcessInterface * {

View File

@@ -1606,6 +1606,12 @@ std::unique_ptr<ToolchainConfigWidget> GccToolchainFactory::createConfigurationW
FilePath GccToolchainFactory::correspondingCompilerCommand( FilePath GccToolchainFactory::correspondingCompilerCommand(
const FilePath &srcPath, Id targetLang) const const FilePath &srcPath, Id targetLang) const
{ {
// llvm-mingw
if (supportedToolchainType() == Constants::MINGW_TOOLCHAIN_TYPEID
&& srcPath.fileName().contains("clang")) {
return GccToolchain::correspondingCompilerCommand(srcPath, targetLang, "clang", "clang++");
}
if (supportedToolchainType() == Constants::GCC_TOOLCHAIN_TYPEID if (supportedToolchainType() == Constants::GCC_TOOLCHAIN_TYPEID
|| supportedToolchainType() == Constants::MINGW_TOOLCHAIN_TYPEID) { || supportedToolchainType() == Constants::MINGW_TOOLCHAIN_TYPEID) {
return GccToolchain::correspondingCompilerCommand(srcPath, targetLang, "gcc", "g++"); return GccToolchain::correspondingCompilerCommand(srcPath, targetLang, "gcc", "g++");
@@ -1626,7 +1632,7 @@ Toolchains GccToolchainFactory::autoDetectSdkClangToolchain(const Toolchains &kn
for (Toolchain * const existingTc : known) { for (Toolchain * const existingTc : known) {
if (existingTc->compilerCommand() == *compilerPath) if (existingTc->compilerCommand() == *compilerPath)
return {existingTc}; return {};
} }
return {autoDetectToolchain({*compilerPath, Constants::C_LANGUAGE_ID}, GccToolchain::Clang)}; return {autoDetectToolchain({*compilerPath, Constants::C_LANGUAGE_ID}, GccToolchain::Clang)};

View File

@@ -1623,9 +1623,8 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
.arg(QLatin1String(isDefault ? "Default " : "")) .arg(QLatin1String(isDefault ? "Default " : ""))
.arg(targetAbi.wordWidth()) .arg(targetAbi.wordWidth())
.arg(Abi::toString(targetAbi.osFlavor()).toUpper()); .arg(Abi::toString(targetAbi.osFlavor()).toUpper());
for (auto language : {Id(Constants::C_LANGUAGE_ID), Id(Constants::CXX_LANGUAGE_ID)}) { for (const Id language : {Id(Constants::C_LANGUAGE_ID), Id(Constants::CXX_LANGUAGE_ID)}) {
ClangClToolchain *tc = static_cast<ClangClToolchain *>( if (Utils::findOrDefault(alreadyKnown, [&](Toolchain *tc) {
Utils::findOrDefault(alreadyKnown, [&](Toolchain *tc) -> bool {
if (tc->typeId() != Constants::CLANG_CL_TOOLCHAIN_TYPEID) if (tc->typeId() != Constants::CLANG_CL_TOOLCHAIN_TYPEID)
return false; return false;
if (tc->targetAbi() != targetAbi) if (tc->targetAbi() != targetAbi)
@@ -1633,18 +1632,17 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath,
if (tc->language() != language) if (tc->language() != language)
return false; return false;
return tc->compilerCommand().isSameExecutable(clangClPath); return tc->compilerCommand().isSameExecutable(clangClPath);
})); })) {
if (tc) { continue;
res << tc;
} else {
auto cltc = new ClangClToolchain;
cltc->setClangPath(clangClPath);
cltc->setDisplayName(name);
cltc->setDetection(Toolchain::AutoDetection);
cltc->setLanguage(language);
cltc->setupVarsBat(toolChain->targetAbi(), toolChain->varsBat(), toolChain->varsBatArg());
res << cltc;
} }
auto cltc = new ClangClToolchain;
cltc->setClangPath(clangClPath);
cltc->setDisplayName(name);
cltc->setDetection(Toolchain::AutoDetection);
cltc->setLanguage(language);
cltc->setupVarsBat(toolChain->targetAbi(), toolChain->varsBat(), toolChain->varsBatArg());
res << cltc;
} }
return res; return res;
} }

View File

@@ -248,13 +248,10 @@ FilePath WorkingDirectoryAspect::workingDirectory() const
{ {
const Environment env = m_envAspect ? m_envAspect->environment() const Environment env = m_envAspect ? m_envAspect->environment()
: Environment::systemEnvironment(); : Environment::systemEnvironment();
QString workingDir = m_workingDirectory.path(); const FilePath workingDir = macroExpander()->expand(m_workingDirectory);
if (auto expander = macroExpander()) if (m_envAspect)
workingDir = expander->expandProcessArgs(workingDir); return env.expandVariables(workingDir);
return workingDir;
QString res = workingDir.isEmpty() ? QString() : QDir::cleanPath(env.expandVariables(workingDir));
return m_workingDirectory.withNewPath(res);
} }
FilePath WorkingDirectoryAspect::defaultWorkingDirectory() const FilePath WorkingDirectoryAspect::defaultWorkingDirectory() const
@@ -331,9 +328,11 @@ QString ArgumentsAspect::arguments() const
return m_arguments; return m_arguments;
m_currentlyExpanding = true; m_currentlyExpanding = true;
const QString expanded = macroExpander()->expandProcessArgs(m_arguments); const expected_str<QString> expanded = macroExpander()->expandProcessArgs(m_arguments);
QTC_ASSERT_EXPECTED(expanded, return m_arguments);
m_currentlyExpanding = false; m_currentlyExpanding = false;
return expanded; return *expanded;
} }
/*! /*!
@@ -956,8 +955,7 @@ X11ForwardingAspect::X11ForwardingAspect(AspectContainer *container)
setDisplayStyle(LineEditDisplay); setDisplayStyle(LineEditDisplay);
setId("X11ForwardingAspect"); setId("X11ForwardingAspect");
setSettingsKey("RunConfiguration.X11Forwarding"); setSettingsKey("RunConfiguration.X11Forwarding");
makeCheckable(CheckBoxPlacement::Right, Tr::tr("Forward to local display"), makeCheckable(CheckBoxPlacement::Right, Tr::tr("Enable"), "RunConfiguration.UseX11Forwarding");
"RunConfiguration.UseX11Forwarding");
setValue(defaultDisplay()); setValue(defaultDisplay());
addDataExtractor(this, &X11ForwardingAspect::display, &Data::display); addDataExtractor(this, &X11ForwardingAspect::display, &Data::display);
@@ -965,7 +963,7 @@ X11ForwardingAspect::X11ForwardingAspect(AspectContainer *container)
QString X11ForwardingAspect::display() const QString X11ForwardingAspect::display() const
{ {
return !isChecked() ? QString() : macroExpander()->expandProcessArgs(value()); return !isChecked() ? QString() : macroExpander()->expand(value());
} }

View File

@@ -921,8 +921,9 @@ ToolchainBundle::ToolchainBundle(const Toolchains &toolchains, AutoRegister auto
// Check pre-conditions. // Check pre-conditions.
QTC_ASSERT(!m_toolchains.isEmpty(), return); QTC_ASSERT(!m_toolchains.isEmpty(), return);
QTC_ASSERT(m_toolchains.size() <= factory()->supportedLanguages().size(), return); QTC_ASSERT(m_toolchains.size() <= factory()->supportedLanguages().size(), return);
for (const Toolchain * const tc : toolchains) for (const Toolchain * const tc : toolchains) {
QTC_ASSERT(factory()->supportedLanguages().contains(tc->language()), return); QTC_ASSERT(factory()->supportedLanguages().contains(tc->language()), return);
}
for (int i = 1; i < int(toolchains.size()); ++i) { for (int i = 1; i < int(toolchains.size()); ++i) {
const Toolchain * const tc = toolchains.at(i); const Toolchain * const tc = toolchains.at(i);
QTC_ASSERT(tc->typeId() == toolchains.first()->typeId(), return); QTC_ASSERT(tc->typeId() == toolchains.first()->typeId(), return);

View File

@@ -102,30 +102,30 @@ static QString targetPlatform(const ProjectExplorer::Abi &abi, const ProjectExpl
return QString(); return QString();
} }
static QStringList toolchainList(const ProjectExplorer::Toolchain *tc) static QString toolchainType(const ProjectExplorer::Toolchain *tc)
{ {
const Utils::Id type = tc->typeId(); const Utils::Id type = tc->typeId();
if (type == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID if (type == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID
|| (type == Android::Constants::ANDROID_TOOLCHAIN_TYPEID || (type == Android::Constants::ANDROID_TOOLCHAIN_TYPEID
&& tc->compilerCommand().fileName().contains("clang"))) { && tc->compilerCommand().fileName().contains("clang"))) {
return {"clang", "llvm", "gcc"}; return "clang";
} }
if (type == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID if (type == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
|| type == Android::Constants::ANDROID_TOOLCHAIN_TYPEID) { || type == Android::Constants::ANDROID_TOOLCHAIN_TYPEID) {
return {"gcc"}; // TODO: Detect llvm-gcc return "gcc"; // TODO: Detect llvm-gcc
} }
if (type == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) if (type == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID)
return {"mingw", "gcc"}; return "mingw";
if (type == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) if (type == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)
return {"clang-cl", "msvc"}; return "clang-cl";
if (type == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) if (type == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
return {"msvc"}; return "msvc";
if (type == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID) if (type == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID)
return {"iar"}; return "iar";
if (type == BareMetal::Constants::KEIL_TOOLCHAIN_TYPEID) if (type == BareMetal::Constants::KEIL_TOOLCHAIN_TYPEID)
return {"keil"}; return "keil";
if (type == BareMetal::Constants::SDCC_TOOLCHAIN_TYPEID) if (type == BareMetal::Constants::SDCC_TOOLCHAIN_TYPEID)
return {"sdcc"}; return "sdcc";
return {}; return {};
} }
@@ -258,7 +258,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
} }
data.insert(QLatin1String(QBS_TARGETPLATFORM), targetPlatform(targetAbi, k)); data.insert(QLatin1String(QBS_TARGETPLATFORM), targetPlatform(targetAbi, k));
QStringList toolchain = toolchainList(mainTc); QString toolchain = toolchainType(mainTc);
if (targetAbi.osFlavor() == Abi::AndroidLinuxFlavor) { if (targetAbi.osFlavor() == Abi::AndroidLinuxFlavor) {
const IDevice::ConstPtr dev = DeviceKitAspect::device(k); const IDevice::ConstPtr dev = DeviceKitAspect::device(k);
if (dev) { if (dev) {
@@ -313,12 +313,12 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
if (!mainToolchainPrefix.isEmpty()) if (!mainToolchainPrefix.isEmpty())
data.insert(QLatin1String(CPP_TOOLCHAINPREFIX), mainToolchainPrefix); data.insert(QLatin1String(CPP_TOOLCHAINPREFIX), mainToolchainPrefix);
if (toolchain.contains(QLatin1String("clang-cl"))) { if (toolchain == "clang-cl") {
data.insert(QLatin1String(CPP_COMPILERNAME), mainCompilerName); data.insert(QLatin1String(CPP_COMPILERNAME), mainCompilerName);
const auto clangClToolchain = const auto clangClToolchain =
static_cast<ProjectExplorer::Internal::ClangClToolchain *>(mainTc); static_cast<ProjectExplorer::Internal::ClangClToolchain *>(mainTc);
data.insert(QLatin1String(CPP_VCVARSALLPATH), clangClToolchain->varsBat()); data.insert(QLatin1String(CPP_VCVARSALLPATH), clangClToolchain->varsBat());
} else if (toolchain.contains(QLatin1String("msvc"))) { } else if (toolchain == "msvc") {
data.insert(QLatin1String(CPP_COMPILERNAME), mainCompilerName); data.insert(QLatin1String(CPP_COMPILERNAME), mainCompilerName);
} else { } else {
if (!mainCompilerName.isEmpty()) if (!mainCompilerName.isEmpty())
@@ -353,7 +353,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
if (compilerReMatch.hasMatch()) { if (compilerReMatch.hasMatch()) {
const QString developerPath = compilerReMatch.captured(QStringLiteral("developerpath")); const QString developerPath = compilerReMatch.captured(QStringLiteral("developerpath"));
data.insert(QLatin1String(XCODE_DEVELOPERPATH), developerPath); data.insert(QLatin1String(XCODE_DEVELOPERPATH), developerPath);
toolchain.insert(0, QStringLiteral("xcode")); toolchain = "xcode";
// If the sysroot is part of this developer path, set the canonical SDK name // If the sysroot is part of this developer path, set the canonical SDK name
const QDir sysrootdir(QDir::cleanPath(sysroot)); const QDir sysrootdir(QDir::cleanPath(sysroot));
@@ -382,7 +382,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
} }
if (!toolchain.isEmpty()) if (!toolchain.isEmpty())
data.insert(QLatin1String(QBS_TOOLCHAIN), toolchain); data.insert("qbs.toolchainType", toolchain);
return data; return data;
} }

View File

@@ -54,7 +54,6 @@ const char QBS_TARGETPLATFORM[] = "qbs.targetPlatform";
const char QBS_SYSROOT[] = "qbs.sysroot"; const char QBS_SYSROOT[] = "qbs.sysroot";
const char QBS_ARCHITECTURES[] = "qbs.architectures"; const char QBS_ARCHITECTURES[] = "qbs.architectures";
const char QBS_ARCHITECTURE[] = "qbs.architecture"; const char QBS_ARCHITECTURE[] = "qbs.architecture";
const char QBS_TOOLCHAIN[] = "qbs.toolchain";
const char CPP_TOOLCHAINPATH[] = "cpp.toolchainInstallPath"; const char CPP_TOOLCHAINPATH[] = "cpp.toolchainInstallPath";
const char CPP_TOOLCHAINPREFIX[] = "cpp.toolchainPrefix"; const char CPP_TOOLCHAINPREFIX[] = "cpp.toolchainPrefix";
const char CPP_COMPILERNAME[] = "cpp.compilerName"; const char CPP_COMPILERNAME[] = "cpp.compilerName";

View File

@@ -241,6 +241,7 @@ void QmakeBuildConfiguration::updateProblemLabel()
bool targetMismatch = false; bool targetMismatch = false;
bool incompatibleBuild = false; bool incompatibleBuild = false;
bool allGood = false; bool allGood = false;
bool invalidArguments = false;
// we only show if we actually have a qmake and makestep // we only show if we actually have a qmake and makestep
QString errorString; QString errorString;
if (qmakeStep() && makeStep()) { if (qmakeStep() && makeStep()) {
@@ -258,6 +259,9 @@ void QmakeBuildConfiguration::updateProblemLabel()
case QmakeBuildConfiguration::MakefileForWrongProject: case QmakeBuildConfiguration::MakefileForWrongProject:
targetMismatch = true; targetMismatch = true;
break; break;
case QmakeBuildConfiguration::InvalidArguments:
invalidArguments = true;
break;
} }
} }
@@ -305,6 +309,10 @@ void QmakeBuildConfiguration::updateProblemLabel()
} else if (unalignedBuildDir) { } else if (unalignedBuildDir) {
buildDirectoryAspect()->setProblem(unalignedBuildDirWarning()); buildDirectoryAspect()->setProblem(unalignedBuildDirWarning());
return; return;
} else if (invalidArguments) {
buildDirectoryAspect()->setProblem(
Tr::tr("Starting qmake failed with the following error: %1").arg(errorString));
return;
} }
buildDirectoryAspect()->setProblem({}); buildDirectoryAspect()->setProblem({});
@@ -516,8 +524,16 @@ QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportF
// and compare that on its own // and compare that on its own
FilePath workingDirectory = makefile.parentDir(); FilePath workingDirectory = makefile.parentDir();
QStringList actualArgs; QStringList actualArgs;
QString allArgs = macroExpander()->expandProcessArgs(qs->allArguments( expected_str<QString> expandResult = macroExpander()->expandProcessArgs(
QtKitAspect::qtVersion(target()->kit()), QMakeStep::ArgumentFlag::Expand)); qs->allArguments(QtKitAspect::qtVersion(target()->kit()), QMakeStep::ArgumentFlag::Expand));
if (!expandResult) {
if (errorString)
*errorString = expandResult.error();
return InvalidArguments;
}
QString allArgs = *expandResult;
// This copies the settings from allArgs to actualArgs (minus some we // This copies the settings from allArgs to actualArgs (minus some we
// are not interested in), splitting them up into individual strings: // are not interested in), splitting them up into individual strings:
extractSpecFromArguments(&allArgs, workingDirectory, version, &actualArgs); extractSpecFromArguments(&allArgs, workingDirectory, version, &actualArgs);

View File

@@ -61,7 +61,13 @@ public:
Utils::FilePath makefile() const; Utils::FilePath makefile() const;
enum MakefileState { MakefileMatches, MakefileForWrongProject, MakefileIncompatible, MakefileMissing }; enum MakefileState {
MakefileMatches,
MakefileForWrongProject,
MakefileIncompatible,
MakefileMissing,
InvalidArguments
};
MakefileState compareToImportFrom(const Utils::FilePath &makefile, QString *errorString = nullptr); MakefileState compareToImportFrom(const Utils::FilePath &makefile, QString *errorString = nullptr);
static QString extractSpecFromArguments( static QString extractSpecFromArguments(
QString *arguments, const Utils::FilePath &directory, const QtSupport::QtVersion *version, QString *arguments, const Utils::FilePath &directory, const QtSupport::QtVersion *version,

View File

@@ -126,7 +126,7 @@ void QmlTaskManager::updateSemanticMessagesNow()
// abort any update that's going on already, and remove old codemodel warnings // abort any update that's going on already, and remove old codemodel warnings
m_messageCollector.cancel(); m_messageCollector.cancel();
removeAllTasks(true); removeAllTasks(true);
buildSystem->buildTarget(Constants::QMLLINT_BUILD_TARGET); buildSystem->buildNamedTarget(Constants::QMLLINT_BUILD_TARGET);
return; return;
} }

View File

@@ -332,7 +332,7 @@ public:
LinuxDevice *q = nullptr; LinuxDevice *q = nullptr;
QThread m_shellThread; QThread m_shellThread;
ShellThreadHandler *m_handler = nullptr; ShellThreadHandler *m_handler = nullptr;
mutable QMutex m_shellMutex; mutable QRecursiveMutex m_shellMutex;
LinuxDeviceFileAccess m_fileAccess{this}; LinuxDeviceFileAccess m_fileAccess{this};
QReadWriteLock m_environmentCacheLock; QReadWriteLock m_environmentCacheLock;
@@ -431,7 +431,6 @@ public:
QByteArray m_output; QByteArray m_output;
QByteArray m_error; QByteArray m_error;
bool m_pidParsed = false; bool m_pidParsed = false;
bool m_useConnectionSharing = false;
}; };
SshProcessInterface::SshProcessInterface(const IDevice::ConstPtr &device) SshProcessInterface::SshProcessInterface(const IDevice::ConstPtr &device)
@@ -689,13 +688,17 @@ void SshProcessInterfacePrivate::start()
return; return;
} }
m_useConnectionSharing = SshSettings::connectionSharingEnabled() && !q->m_setup.m_extraData.value(Constants::DisableSharing).toBool(); auto linuxDevice = std::dynamic_pointer_cast<const LinuxDevice>(m_device);
QTC_ASSERT(linuxDevice, handleDone(); return);
const bool useConnectionSharing = !linuxDevice->isDisconnected()
&& SshSettings::connectionSharingEnabled()
&& !q->m_setup.m_extraData.value(Constants::DisableSharing).toBool();
// TODO: Do we really need it for master process? // TODO: Do we really need it for master process?
m_sshParameters.x11DisplayName m_sshParameters.x11DisplayName
= q->m_setup.m_extraData.value("Ssh.X11ForwardToDisplay").toString(); = q->m_setup.m_extraData.value("Ssh.X11ForwardToDisplay").toString();
if (m_useConnectionSharing) { if (useConnectionSharing) {
m_connecting = true; m_connecting = true;
m_connectionHandle.reset(new SshConnectionHandle(m_device)); m_connectionHandle.reset(new SshConnectionHandle(m_device));
m_connectionHandle->setParent(this); m_connectionHandle->setParent(this);
@@ -703,16 +706,6 @@ void SshProcessInterfacePrivate::start()
this, &SshProcessInterfacePrivate::handleConnected); this, &SshProcessInterfacePrivate::handleConnected);
connect(m_connectionHandle.get(), &SshConnectionHandle::disconnected, connect(m_connectionHandle.get(), &SshConnectionHandle::disconnected,
this, &SshProcessInterfacePrivate::handleDisconnected); this, &SshProcessInterfacePrivate::handleDisconnected);
auto linuxDevice = std::dynamic_pointer_cast<const LinuxDevice>(m_device);
QTC_ASSERT(linuxDevice, handleDone(); return);
if (linuxDevice->isDisconnected()) {
emit q->done(
{-1,
QProcess::CrashExit,
QProcess::FailedToStart,
Tr::tr("Device \"%1\" is disconnected.").arg(linuxDevice->displayName())});
return;
}
linuxDevice->connectionAccess() linuxDevice->connectionAccess()
->attachToSharedConnection(m_connectionHandle.get(), m_sshParameters); ->attachToSharedConnection(m_connectionHandle.get(), m_sshParameters);
} else { } else {

View File

@@ -12,6 +12,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stylehelper.h> #include <utils/stylehelper.h>
#include <QDesktopServices>
#include <QEvent> #include <QEvent>
#include <QGuiApplication> #include <QGuiApplication>
#include <QImage> #include <QImage>
@@ -86,8 +87,12 @@ IntroductionWidget::IntroductionWidget()
m_stepText->setTextFormat(Qt::RichText); m_stepText->setTextFormat(Qt::RichText);
// why is palette not inherited??? // why is palette not inherited???
m_stepText->setPalette(palette()); m_stepText->setPalette(palette());
m_stepText->setOpenExternalLinks(true); connect(m_stepText, &QLabel::linkActivated, this, [this](const QString &link) {
m_stepText->installEventFilter(this); // clicking the User Interface link should both open the documentation page
// and step forward (=end the tour)
step();
QDesktopServices::openUrl(link);
});
layout->addWidget(m_stepText); layout->addWidget(m_stepText);
m_continueLabel = new QLabel(this); m_continueLabel = new QLabel(this);
@@ -173,12 +178,8 @@ bool IntroductionWidget::event(QEvent *e)
bool IntroductionWidget::eventFilter(QObject *obj, QEvent *ev) bool IntroductionWidget::eventFilter(QObject *obj, QEvent *ev)
{ {
if (obj == parent() && ev->type() == QEvent::Resize) { if (obj == parent() && ev->type() == QEvent::Resize)
resizeToParent(); resizeToParent();
} else if (obj == m_stepText && ev->type() == QEvent::MouseButtonRelease) {
step();
return true;
}
return QWidget::eventFilter(obj, ev); return QWidget::eventFilter(obj, ev);
} }

View File

@@ -218,6 +218,7 @@ public:
void startDeviceLookup(int timeout); void startDeviceLookup(int timeout);
bool connectToPort(quint16 port, ServiceSocket *fd) override; bool connectToPort(quint16 port, ServiceSocket *fd) override;
int qmljsDebugPort() const override; int qmljsDebugPort() const override;
void addMessage(const QString &msg);
void addError(const QString &msg); void addError(const QString &msg);
bool writeAll(ServiceSocket fd, const char *cmd, qptrdiff len = -1); bool writeAll(ServiceSocket fd, const char *cmd, qptrdiff len = -1);
bool mountDeveloperDiskImage(); bool mountDeveloperDiskImage();
@@ -957,6 +958,11 @@ void CommandSession::startDeviceLookup(int timeout)
this); this);
} }
void CommandSession::addMessage(const QString &msg)
{
IosDeviceManager::instance()->message(msg);
}
void CommandSession::addError(const QString &msg) void CommandSession::addError(const QString &msg)
{ {
qCCritical(loggingCategory) << "CommandSession ERROR:" << msg; qCCritical(loggingCategory) << "CommandSession ERROR:" << msg;
@@ -1303,7 +1309,7 @@ bool AppOpSession::installApp()
bool success = false; bool success = false;
if (device) { if (device) {
if (!installAppNew()) { if (!installAppNew()) {
addError(QString::fromLatin1( addMessage(QString::fromLatin1(
"Failed to transfer and install application, trying old way ...")); "Failed to transfer and install application, trying old way ..."));
const CFUrl_t bundleUrl(QUrl::fromLocalFile(bundlePath).toCFURL()); const CFUrl_t bundleUrl(QUrl::fromLocalFile(bundlePath).toCFURL());

View File

@@ -58,6 +58,7 @@ signals:
Ios::DeviceSession *deviceSession); Ios::DeviceSession *deviceSession);
void deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &info); void deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &info);
void appOutput(const QString &output); void appOutput(const QString &output);
void message(const QString &msg);
void errorMsg(const QString &msg); void errorMsg(const QString &msg);
private: private:

View File

@@ -92,7 +92,7 @@ void IosTool::run(const QStringList &args)
bool ok = false; bool ok = false;
timeout = cmdLineParser.value("timeout").toInt(&ok); timeout = cmdLineParser.value("timeout").toInt(&ok);
if (!ok || timeout < 0) { if (!ok || timeout < 0) {
writeMsg("timeout value should be an integer"); writeError("timeout value should be an integer");
printHelp = true; printHelp = true;
} }
} }
@@ -118,7 +118,8 @@ void IosTool::run(const QStringList &args)
connect(manager, &IosDeviceManager::didStartApp, this, &IosTool::didStartApp); connect(manager, &IosDeviceManager::didStartApp, this, &IosTool::didStartApp);
connect(manager, &IosDeviceManager::deviceInfo, this, &IosTool::deviceInfo); connect(manager, &IosDeviceManager::deviceInfo, this, &IosTool::deviceInfo);
connect(manager, &IosDeviceManager::appOutput, this, &IosTool::appOutput); connect(manager, &IosDeviceManager::appOutput, this, &IosTool::appOutput);
connect(manager, &IosDeviceManager::errorMsg, this, &IosTool::errorMsg); connect(manager, &IosDeviceManager::message, this, &IosTool::writeMsg);
connect(manager, &IosDeviceManager::errorMsg, this, &IosTool::writeError);
manager->watchDevices(); manager->watchDevices();
const QRegularExpression qmlPortRe(QLatin1String("-qmljsdebugger=port:([0-9]+)")); const QRegularExpression qmlPortRe(QLatin1String("-qmljsdebugger=port:([0-9]+)"));
for (const QString &arg : extraArgs) { for (const QString &arg : extraArgs) {
@@ -233,12 +234,12 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
return; return;
} }
if (gdbFd <= 0) { if (gdbFd <= 0) {
writeMsg("no gdb connection"); writeError("no gdb connection");
doExit(-2); doExit(-2);
return; return;
} }
if (m_requestedOperation != IosDeviceManager::InstallAndRun && m_requestedOperation != IosDeviceManager::Run) { if (m_requestedOperation != IosDeviceManager::InstallAndRun && m_requestedOperation != IosDeviceManager::Run) {
writeMsg(QString::fromLatin1("unexpected appOp value %1").arg(m_requestedOperation)); writeError(QString::fromLatin1("unexpected appOp value %1").arg(m_requestedOperation));
doExit(-3); doExit(-3);
return; return;
} }
@@ -283,15 +284,15 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
} }
} }
void IosTool::writeMsg(const char *msg)
{
writeMsg(QString::fromLatin1(msg));
}
void IosTool::writeMsg(const QString &msg) void IosTool::writeMsg(const QString &msg)
{
writeMessageElement(msg, "msg");
}
void IosTool::writeMessageElement(const QString &msg, const QString &element)
{ {
QMutexLocker l(&m_xmlMutex); QMutexLocker l(&m_xmlMutex);
m_xmlWriter.writeStartElement(QLatin1String("msg")); m_xmlWriter.writeStartElement(element);
writeTextInElement(msg); writeTextInElement(msg);
m_xmlWriter.writeCharacters(QLatin1String("\n")); m_xmlWriter.writeCharacters(QLatin1String("\n"));
m_xmlWriter.writeEndElement(); m_xmlWriter.writeEndElement();
@@ -380,15 +381,15 @@ void IosTool::readStdin()
int c = getchar(); int c = getchar();
if (c == 'k') { if (c == 'k') {
QMetaObject::invokeMethod(this, "stopGdbRunner"); QMetaObject::invokeMethod(this, "stopGdbRunner");
errorMsg(QLatin1String("iostool: Killing inferior.\n")); writeError(QLatin1String("iostool: Killing inferior.\n"));
} else if (c != EOF) { } else if (c != EOF) {
errorMsg(QLatin1String("iostool: Unexpected character in stdin, stop listening.\n")); writeError(QLatin1String("iostool: Unexpected character in stdin, stop listening.\n"));
} }
} }
void IosTool::errorMsg(const QString &msg) void IosTool::writeError(const QString &msg)
{ {
writeMsg(msg); writeMessageElement(msg, "error");
} }
void IosTool::stopGdbRunner() void IosTool::stopGdbRunner()

View File

@@ -27,17 +27,17 @@ public:
virtual ~IosTool(); virtual ~IosTool();
void run(const QStringList &args); void run(const QStringList &args);
void doExit(int errorCode = 0); void doExit(int errorCode = 0);
void writeMsg(const char *msg);
void writeMsg(const QString &msg); void writeMsg(const QString &msg);
void stopXml(int errorCode); void stopXml(int errorCode);
void writeTextInElement(const QString &output); void writeTextInElement(const QString &output);
void stopRelayServers(int errorCode = 0); void stopRelayServers(int errorCode = 0);
void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len); void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len);
void errorMsg(const QString &msg); void writeError(const QString &msg);
Q_INVOKABLE void stopGdbRunner(); Q_INVOKABLE void stopGdbRunner();
bool echoRelays() const { return m_echoRelays; } bool echoRelays() const { return m_echoRelays; }
private: private:
void writeMessageElement(const QString &msg, const QString &element);
void stopGdbRunner2(); void stopGdbRunner2();
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress, void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
const QString &info); const QString &info);

View File

@@ -69,7 +69,7 @@ void Relayer::handleSocketHasData(int socket)
m_serverNotifier->setEnabled(true); m_serverNotifier->setEnabled(true);
return; return;
} }
iosTool()->errorMsg(qt_error_string(errno)); iosTool()->writeError(qt_error_string(errno));
close(socket); close(socket);
iosTool()->stopRelayServers(-1); iosTool()->stopRelayServers(-1);
return; return;
@@ -86,7 +86,7 @@ void Relayer::handleSocketHasData(int socket)
while (true) { while (true) {
qint64 writtenNow = m_clientSocket->write(buf + int(pos), rRead); qint64 writtenNow = m_clientSocket->write(buf + int(pos), rRead);
if (writtenNow == -1) { if (writtenNow == -1) {
iosTool()->writeMsg(m_clientSocket->errorString()); iosTool()->writeError(m_clientSocket->errorString());
iosTool()->stopRelayServers(-1); iosTool()->stopRelayServers(-1);
return; return;
} }
@@ -110,7 +110,7 @@ void Relayer::handleClientHasData()
toRead = sizeof(buf)-1; toRead = sizeof(buf)-1;
qint64 rRead = m_clientSocket->read(buf, toRead); qint64 rRead = m_clientSocket->read(buf, toRead);
if (rRead == -1) { if (rRead == -1) {
iosTool()->errorMsg(m_clientSocket->errorString()); iosTool()->writeError(m_clientSocket->errorString());
iosTool()->stopRelayServers(); iosTool()->stopRelayServers();
return; return;
} }
@@ -137,7 +137,7 @@ void Relayer::handleClientHasData()
} }
continue; continue;
} }
iosTool()->errorMsg(qt_error_string(errno)); iosTool()->writeError(qt_error_string(errno));
iosTool()->stopRelayServers(); iosTool()->stopRelayServers();
return; return;
} }
@@ -157,7 +157,7 @@ void Relayer::handleClientHasData()
void Relayer::handleClientHasError(QAbstractSocket::SocketError error) void Relayer::handleClientHasError(QAbstractSocket::SocketError error)
{ {
iosTool()->errorMsg(tr("iOS Debugging connection to creator failed with error %1").arg(error)); iosTool()->writeError(tr("iOS debugging connection failed with error %1").arg(error));
server()->removeRelayConnection(this); server()->removeRelayConnection(this);
} }
@@ -207,7 +207,7 @@ RemotePortRelayer::RemotePortRelayer(QmlRelayServer *parent, QTcpSocket *clientS
void RemotePortRelayer::tryRemoteConnect() void RemotePortRelayer::tryRemoteConnect()
{ {
iosTool()->errorMsg(QLatin1String("tryRemoteConnect")); iosTool()->writeMsg(QLatin1String("tryRemoteConnect"));
if (m_serverFileDescriptor > 0) if (m_serverFileDescriptor > 0)
return; return;
ServiceSocket ss; ServiceSocket ss;
@@ -216,15 +216,16 @@ void RemotePortRelayer::tryRemoteConnect()
return; return;
if (grServer->m_deviceSession->connectToPort(grServer->m_remotePort, &ss)) { if (grServer->m_deviceSession->connectToPort(grServer->m_remotePort, &ss)) {
if (ss > 0) { if (ss > 0) {
iosTool()->errorMsg(QString::fromLatin1("tryRemoteConnect *succeeded* on remote port %1") iosTool()->writeMsg(
.arg(grServer->m_remotePort)); QString::fromLatin1("tryRemoteConnect *succeeded* on remote port %1")
.arg(grServer->m_remotePort));
startRelay(ss); startRelay(ss);
emit didConnect(grServer); emit didConnect(grServer);
return; return;
} }
} }
iosTool()->errorMsg(QString::fromLatin1("tryRemoteConnect *failed* on remote port %1") iosTool()->writeMsg(QString::fromLatin1("tryRemoteConnect *failed* on remote port %1")
.arg(grServer->m_remotePort)); .arg(grServer->m_remotePort));
m_remoteConnectTimer.start(); m_remoteConnectTimer.start();
} }
@@ -277,7 +278,7 @@ IosTool *RelayServer::iosTool() const
void RelayServer::handleNewRelayConnection() void RelayServer::handleNewRelayConnection()
{ {
iosTool()->errorMsg(QLatin1String("handleNewRelayConnection")); iosTool()->writeMsg(QLatin1String("handleNewRelayConnection"));
newRelayConnection(); newRelayConnection();
} }
@@ -318,7 +319,7 @@ QmlRelayServer::QmlRelayServer(IosTool *parent, int remotePort,
m_remotePort(remotePort), m_remotePort(remotePort),
m_deviceSession(deviceSession) m_deviceSession(deviceSession)
{ {
parent->errorMsg(QLatin1String("created qml server")); parent->writeMsg(QLatin1String("created qml server"));
} }
@@ -327,7 +328,7 @@ void QmlRelayServer::newRelayConnection()
QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections() QTcpSocket *clientSocket = m_ipv4Server.hasPendingConnections()
? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection(); ? m_ipv4Server.nextPendingConnection() : m_ipv6Server.nextPendingConnection();
if (clientSocket) { if (clientSocket) {
iosTool()->errorMsg(QString::fromLatin1("setting up relayer for new connection")); iosTool()->writeMsg(QString::fromLatin1("setting up relayer for new connection"));
RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket); RemotePortRelayer *newConnection = new RemotePortRelayer(this, clientSocket);
m_connections.append(newConnection); m_connections.append(newConnection);
newConnection->tryRemoteConnect(); newConnection->tryRemoteConnect();

View File

@@ -2,6 +2,7 @@ add_subdirectory(ansiescapecodehandler)
add_subdirectory(async) add_subdirectory(async)
add_subdirectory(commandline) add_subdirectory(commandline)
add_subdirectory(deviceshell) add_subdirectory(deviceshell)
add_subdirectory(expander)
add_subdirectory(expected) add_subdirectory(expected)
add_subdirectory(filepath) add_subdirectory(filepath)
add_subdirectory(fileutils) add_subdirectory(fileutils)

View File

@@ -0,0 +1,4 @@
add_qtc_test(tst_utils_expander
DEPENDS Utils
SOURCES tst_expander.cpp
)

View File

@@ -0,0 +1,9 @@
QtcAutotest {
name: "Macro Expander autotest"
Depends { name: "Utils" }
files: [
"tst_expander.cpp",
]
}

View File

@@ -0,0 +1,610 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <utils/filepath.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <QTest>
using namespace Utils;
class tst_expander : public QObject
{
Q_OBJECT
private slots:
void expandFilePath_data()
{
QTest::addColumn<FilePath>("input");
QTest::addColumn<FilePath>("expected");
QTest::addColumn<std::function<void(MacroExpander &)>>("setup");
std::function<void(MacroExpander &)> empty;
std::function<void(MacroExpander &)> home = [](MacroExpander &expander) {
expander.registerVariable("Home", "", [] { return QDir::homePath(); });
};
std::function<void(MacroExpander &)> remotehome = [](MacroExpander &expander) {
expander.registerVariable("Home", "", [] { return "ssh://127.0.0.1/home"; });
};
std::function<void(MacroExpander &)> buildfolderwithspecialchars =
[](MacroExpander &expander) {
expander.registerVariable("BuildFolder", "", [] {
return "C:/Test/Some.Dots.In.File";
});
};
QTest::newRow("empty") << FilePath() << FilePath() << empty;
QTest::newRow("no expansion") << FilePath("foo") << FilePath("foo") << empty;
QTest::newRow("no expansion with slash")
<< FilePath("foo/bar") << FilePath("foo/bar") << empty;
QTest::newRow("home") << FilePath("%{Home}/foo")
<< FilePath::fromString(QDir::homePath() + "/foo") << home;
QTest::newRow("remote-home")
<< FilePath("%{Home}/foo")
<< FilePath::fromParts(QString("ssh"), QString("127.0.0.1"), QString("/home/foo"))
<< remotehome;
QTest::newRow("colon") << FilePath("foo:bar")
<< FilePath::fromParts({}, {}, QString("foo:bar")) << empty;
QTest::newRow("win-dots")
<< FilePath("%{BuildFolder}/Debug/my.file.with.dots.elf")
<< FilePath::fromParts(
{}, {}, QString("C:/Test/Some.Dots.In.File/Debug/my.file.with.dots.elf"))
<< buildfolderwithspecialchars;
}
void expandFilePath()
{
QFETCH(FilePath, input);
QFETCH(FilePath, expected);
QFETCH(std::function<void(MacroExpander &)>, setup);
MacroExpander expander;
if (setup)
setup(expander);
QCOMPARE(expander.expand(input), expected);
}
void expandString_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<QString>("expected");
QTest::addColumn<std::function<void(MacroExpander &)>>("setup");
std::function<void(MacroExpander &)> empty;
std::function<void(MacroExpander &)> user = [](MacroExpander &expander) {
expander.registerVariable("UserName", "", [] { return "JohnDoe"; });
expander.registerVariable("FirstName", "", [] { return "John"; });
expander.registerVariable("LastName", "", [] { return "Doe"; });
expander.registerVariable("Email", "", [] { return "john.doe@example.com"; });
};
QTest::newRow("empty") << QString() << QString() << empty;
QTest::newRow("no expansion") << QString("foo") << QString("foo") << empty;
QTest::newRow("simple-expansion")
<< QString("My name is: %{FirstName}") << QString("My name is: John") << user;
QTest::newRow("multiple-expansions")
<< QString("My name is: %{FirstName} %{LastName} (%{UserName})")
<< QString("My name is: John Doe (JohnDoe)") << user;
QTest::newRow("email") << QString("My email is: %{Email}")
<< QString("My email is: john.doe@example.com") << user;
}
void expandString()
{
QFETCH(QString, input);
QFETCH(QString, expected);
QFETCH(std::function<void(MacroExpander &)>, setup);
MacroExpander expander;
if (setup)
setup(expander);
QCOMPARE(expander.expand(input), expected);
}
void subProvider()
{
MacroExpander expander;
expander.registerVariable("MainVar", "", [] { return "MainValue"; });
expander.registerSubProvider([] {
static MacroExpander *sub = new MacroExpander;
sub->registerVariable("SubVar", "", [] { return "SubValue"; });
return sub;
});
QCOMPARE(expander.expand(QString("%{MainVar} %{SubVar}")), QString("MainValue SubValue"));
QString resolved;
expander.resolveMacro("MainVar", &resolved);
QCOMPARE(resolved, QString("MainValue"));
expander.resolveMacro("SubVar", &resolved);
QCOMPARE(resolved, QString("SubValue"));
}
void expandByteArray_data()
{
QTest::addColumn<QByteArray>("input");
QTest::addColumn<QByteArray>("expected");
QTest::addColumn<std::function<void(MacroExpander &)>>("setup");
std::function<void(MacroExpander &)> empty;
std::function<void(MacroExpander &)> user = [](MacroExpander &expander) {
expander.registerVariable("UserName", "", [] { return "JohnDoe"; });
expander.registerVariable("FirstName", "", [] { return "John"; });
expander.registerVariable("LastName", "", [] { return "Doe"; });
};
QTest::newRow("empty") << QByteArray() << QByteArray() << empty;
QTest::newRow("no expansion")
<< QByteArray("\0\x10\xff", 3) << QByteArray("\0\x10\xff", 3) << empty;
QTest::newRow("simple-expansion")
<< QByteArray("My name is: %{FirstName}") << QByteArray("My name is: John") << user;
QTest::newRow("with-zeroes") << QByteArray("My name is: \0%{FirstName}", 25)
<< QByteArray("My name is: \0John", 17) << user;
}
void expandByteArray()
{
QFETCH(QByteArray, input);
QFETCH(QByteArray, expected);
QFETCH(std::function<void(MacroExpander &)>, setup);
MacroExpander expander;
if (setup)
setup(expander);
QCOMPARE(expander.expand(input), expected);
}
void expandCommandArgs_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<QString>("expected");
QTest::addColumn<OsType>("os");
QTest::addColumn<std::function<void(MacroExpander &)>>("setup");
std::function<void(MacroExpander &)> empty;
std::function<void(MacroExpander &)> file = [](MacroExpander &expander) {
expander.registerVariable("file", "", [] { return "foo.txt"; });
};
std::function<void(MacroExpander &)> withspace = [](MacroExpander &expander) {
expander.registerVariable("WithSpace", "", [] { return "This has spaces"; });
};
QTest::newRow("empty") << QString() << QString() << Utils::OsTypeLinux << empty;
QTest::newRow("no expansion")
<< QString("foo") << QString("foo") << Utils::OsTypeLinux << empty;
QTest::newRow("simple-expansion")
<< QString("cat %{file}") << QString("cat foo.txt") << Utils::OsTypeLinux << file;
QTest::newRow("with-ticks")
<< QString("echo -n 'foo %{file}'") << QString("echo -n 'foo foo.txt'")
<< Utils::OsTypeLinux << file;
QTest::newRow("with-ticks-env")
<< QString("file=%{file} echo -n 'foo \"$file\"'")
<< QString("file=foo.txt echo -n 'foo \"$file\"'") << Utils::OsTypeLinux << file;
QTest::newRow("with-spaces")
<< QString("echo %{WithSpace}") << QString("echo 'This has spaces'")
<< Utils::OsTypeLinux << withspace;
QTest::newRow("with-spaces-pre-quoted")
<< QString("echo 'Some: %{WithSpace}'") << QString("echo 'Some: This has spaces'")
<< Utils::OsTypeLinux << withspace;
QTest::newRow("with-spaces-nested")
<< QString("sh -c 'echo %{WithSpace}'") << QString("sh -c 'echo This has spaces'")
<< Utils::OsTypeLinux << withspace;
QTest::newRow("expando-within-shell-substitution")
<< QString("${VAR:-%{file}}") << QString("${VAR:-foo.txt}") << Utils::OsTypeLinux
<< file;
QTest::newRow("expando-within-shell-substitution-with-space")
<< QString("echo \"Some: ${VAR:-%{WithSpace}}\"")
<< QString("echo \"Some: ${VAR:-This has spaces}\"") << Utils::OsTypeLinux << withspace;
// Windows tests
QTest::newRow("with-spaces")
<< QString("echo %{WithSpace}") << QString("echo \"This has spaces\"")
<< Utils::OsTypeWindows << withspace;
QTest::newRow("with-spaces-manual")
<< QString("echo \"Some: %{WithSpace}\"") << QString("echo \"Some: This has spaces\"")
<< Utils::OsTypeWindows << withspace;
QTest::newRow("with-spaces-nested")
<< QString("cmd /k \"echo %{WithSpace}\"") << QString("cmd /k \"echo This has spaces\"")
<< Utils::OsTypeWindows << withspace;
}
void expandCommandArgs()
{
QFETCH(QString, input);
QFETCH(QString, expected);
QFETCH(OsType, os);
QFETCH(std::function<void(MacroExpander &)>, setup);
MacroExpander expander;
if (setup)
setup(expander);
QCOMPARE(expander.expandProcessArgs(input, os), expected);
}
void expandProcessArgs_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
QTest::addColumn<OsType>("os");
QChar sp(QLatin1Char(' '));
struct Val
{
const char *in;
const char *out;
OsType os;
};
const std::array vals
= {Val{"plain", 0, OsTypeWindows},
Val{"%{a}", "hi", OsTypeWindows},
Val{"%{aa}", "\"hi ho\"", OsTypeWindows},
Val{"%{b}", "h\\i", OsTypeWindows},
Val{"%{c}", "\\hi", OsTypeWindows},
Val{"%{d}", "hi\\", OsTypeWindows},
Val{"%{ba}", "\"h\\i ho\"", OsTypeWindows},
Val{"%{ca}", "\"\\hi ho\"", OsTypeWindows},
Val{"%{da}", "\"hi ho\\\\\"", OsTypeWindows}, // or "\"hi ho\"\\"
Val{"%{e}", "\"h\"\\^\"\"i\"", OsTypeWindows},
Val{"%{f}", "\"\"\\^\"\"hi\"", OsTypeWindows},
Val{"%{g}", "\"hi\"\\^\"\"\"", OsTypeWindows},
Val{"%{h}", "\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
Val{"%{i}", "\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
Val{"%{j}", "\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"%{k}", "\"&special;\"", OsTypeWindows},
Val{"%{x}", "\\", OsTypeWindows},
Val{"%{y}", "\"\"\\^\"\"\"", OsTypeWindows},
Val{"%{z}", "\"\"", OsTypeWindows},
Val{"quoted", 0, OsTypeWindows},
Val{"\"%{a}\"", "\"hi\"", OsTypeWindows},
Val{"\"%{aa}\"", "\"hi ho\"", OsTypeWindows},
Val{"\"%{b}\"", "\"h\\i\"", OsTypeWindows},
Val{"\"%{c}\"", "\"\\hi\"", OsTypeWindows},
Val{"\"%{d}\"", "\"hi\\\\\"", OsTypeWindows},
Val{"\"%{ba}\"", "\"h\\i ho\"", OsTypeWindows},
Val{"\"%{ca}\"", "\"\\hi ho\"", OsTypeWindows},
Val{"\"%{da}\"", "\"hi ho\\\\\"", OsTypeWindows},
Val{"\"%{e}\"", "\"h\"\\^\"\"i\"", OsTypeWindows},
Val{"\"%{f}\"", "\"\"\\^\"\"hi\"", OsTypeWindows},
Val{"\"%{g}\"", "\"hi\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{h}\"", "\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
Val{"\"%{i}\"", "\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
Val{"\"%{j}\"", "\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{k}\"", "\"&special;\"", OsTypeWindows},
Val{"\"%{x}\"", "\"\\\\\"", OsTypeWindows},
Val{"\"%{y}\"", "\"\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{z}\"", "\"\"", OsTypeWindows},
Val{"leading bs", 0, OsTypeWindows},
Val{"\\%{a}", "\\hi", OsTypeWindows},
Val{"\\%{aa}", "\\\\\"hi ho\"", OsTypeWindows},
Val{"\\%{b}", "\\h\\i", OsTypeWindows},
Val{"\\%{c}", "\\\\hi", OsTypeWindows},
Val{"\\%{d}", "\\hi\\", OsTypeWindows},
Val{"\\%{ba}", "\\\\\"h\\i ho\"", OsTypeWindows},
Val{"\\%{ca}", "\\\\\"\\hi ho\"", OsTypeWindows},
Val{"\\%{da}", "\\\\\"hi ho\\\\\"", OsTypeWindows},
Val{"\\%{e}", "\\\\\"h\"\\^\"\"i\"", OsTypeWindows},
Val{"\\%{f}", "\\\\\"\"\\^\"\"hi\"", OsTypeWindows},
Val{"\\%{g}", "\\\\\"hi\"\\^\"\"\"", OsTypeWindows},
Val{"\\%{h}", "\\\\\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
Val{"\\%{i}", "\\\\\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
Val{"\\%{j}", "\\\\\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"\\%{x}", "\\\\", OsTypeWindows},
Val{"\\%{y}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
Val{"\\%{z}", "\\", OsTypeWindows},
Val{"trailing bs", 0, OsTypeWindows},
Val{"%{a}\\", "hi\\", OsTypeWindows},
Val{"%{aa}\\", "\"hi ho\"\\", OsTypeWindows},
Val{"%{b}\\", "h\\i\\", OsTypeWindows},
Val{"%{c}\\", "\\hi\\", OsTypeWindows},
Val{"%{d}\\", "hi\\\\", OsTypeWindows},
Val{"%{ba}\\", "\"h\\i ho\"\\", OsTypeWindows},
Val{"%{ca}\\", "\"\\hi ho\"\\", OsTypeWindows},
Val{"%{da}\\", "\"hi ho\\\\\"\\", OsTypeWindows},
Val{"%{e}\\", "\"h\"\\^\"\"i\"\\", OsTypeWindows},
Val{"%{f}\\", "\"\"\\^\"\"hi\"\\", OsTypeWindows},
Val{"%{g}\\", "\"hi\"\\^\"\"\"\\", OsTypeWindows},
Val{"%{h}\\", "\"h\\\\\"\\^\"\"i\"\\", OsTypeWindows},
Val{"%{i}\\", "\"\\\\\"\\^\"\"hi\"\\", OsTypeWindows},
Val{"%{j}\\", "\"hi\\\\\"\\^\"\"\"\\", OsTypeWindows},
Val{"%{x}\\", "\\\\", OsTypeWindows},
Val{"%{y}\\", "\"\"\\^\"\"\"\\", OsTypeWindows},
Val{"%{z}\\", "\\", OsTypeWindows},
Val{"bs-enclosed", 0, OsTypeWindows},
Val{"\\%{a}\\", "\\hi\\", OsTypeWindows},
Val{"\\%{aa}\\", "\\\\\"hi ho\"\\", OsTypeWindows},
Val{"\\%{b}\\", "\\h\\i\\", OsTypeWindows},
Val{"\\%{c}\\", "\\\\hi\\", OsTypeWindows},
Val{"\\%{d}\\", "\\hi\\\\", OsTypeWindows},
Val{"\\%{ba}\\", "\\\\\"h\\i ho\"\\", OsTypeWindows},
Val{"\\%{ca}\\", "\\\\\"\\hi ho\"\\", OsTypeWindows},
Val{"\\%{da}\\", "\\\\\"hi ho\\\\\"\\", OsTypeWindows},
Val{"\\%{e}\\", "\\\\\"h\"\\^\"\"i\"\\", OsTypeWindows},
Val{"\\%{f}\\", "\\\\\"\"\\^\"\"hi\"\\", OsTypeWindows},
Val{"\\%{g}\\", "\\\\\"hi\"\\^\"\"\"\\", OsTypeWindows},
Val{"\\%{h}\\", "\\\\\"h\\\\\"\\^\"\"i\"\\", OsTypeWindows},
Val{"\\%{i}\\", "\\\\\"\\\\\"\\^\"\"hi\"\\", OsTypeWindows},
Val{"\\%{j}\\", "\\\\\"hi\\\\\"\\^\"\"\"\\", OsTypeWindows},
Val{"\\%{x}\\", "\\\\\\", OsTypeWindows},
Val{"\\%{y}\\", "\\\\\"\"\\^\"\"\"\\", OsTypeWindows},
Val{"\\%{z}\\", "\\\\", OsTypeWindows},
Val{"bs-enclosed and trailing literal quote", 0, OsTypeWindows},
Val{"\\%{a}\\\\\\^\"", "\\hi\\\\\\^\"", OsTypeWindows},
Val{"\\%{aa}\\\\\\^\"", "\\\\\"hi ho\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{b}\\\\\\^\"", "\\h\\i\\\\\\^\"", OsTypeWindows},
Val{"\\%{c}\\\\\\^\"", "\\\\hi\\\\\\^\"", OsTypeWindows},
Val{"\\%{d}\\\\\\^\"", "\\hi\\\\\\\\\\^\"", OsTypeWindows},
Val{"\\%{ba}\\\\\\^\"", "\\\\\"h\\i ho\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{ca}\\\\\\^\"", "\\\\\"\\hi ho\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{da}\\\\\\^\"", "\\\\\"hi ho\\\\\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{e}\\\\\\^\"", "\\\\\"h\"\\^\"\"i\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{f}\\\\\\^\"", "\\\\\"\"\\^\"\"hi\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{g}\\\\\\^\"", "\\\\\"hi\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{h}\\\\\\^\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{i}\\\\\\^\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{j}\\\\\\^\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{x}\\\\\\^\"", "\\\\\\\\\\\\\\^\"", OsTypeWindows},
Val{"\\%{y}\\\\\\^\"", "\\\\\"\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
Val{"\\%{z}\\\\\\^\"", "\\\\\\\\\\^\"", OsTypeWindows},
Val{"bs-enclosed and trailing unclosed quote", 0, OsTypeWindows},
Val{"\\%{a}\\\\\"", "\\hi\\\\\"", OsTypeWindows},
Val{"\\%{aa}\\\\\"", "\\\\\"hi ho\"\\\\\"", OsTypeWindows},
Val{"\\%{b}\\\\\"", "\\h\\i\\\\\"", OsTypeWindows},
Val{"\\%{c}\\\\\"", "\\\\hi\\\\\"", OsTypeWindows},
Val{"\\%{d}\\\\\"", "\\hi\\\\\\\\\"", OsTypeWindows},
Val{"\\%{ba}\\\\\"", "\\\\\"h\\i ho\"\\\\\"", OsTypeWindows},
Val{"\\%{ca}\\\\\"", "\\\\\"\\hi ho\"\\\\\"", OsTypeWindows},
Val{"\\%{da}\\\\\"", "\\\\\"hi ho\\\\\"\\\\\"", OsTypeWindows},
Val{"\\%{e}\\\\\"", "\\\\\"h\"\\^\"\"i\"\\\\\"", OsTypeWindows},
Val{"\\%{f}\\\\\"", "\\\\\"\"\\^\"\"hi\"\\\\\"", OsTypeWindows},
Val{"\\%{g}\\\\\"", "\\\\\"hi\"\\^\"\"\"\\\\\"", OsTypeWindows},
Val{"\\%{h}\\\\\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\"", OsTypeWindows},
Val{"\\%{i}\\\\\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\"", OsTypeWindows},
Val{"\\%{j}\\\\\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\"", OsTypeWindows},
Val{"\\%{x}\\\\\"", "\\\\\\\\\\\\\"", OsTypeWindows},
Val{"\\%{y}\\\\\"", "\\\\\"\"\\^\"\"\"\\\\\"", OsTypeWindows},
Val{"\\%{z}\\\\\"", "\\\\\\\\\"", OsTypeWindows},
Val{"multi-var", 0, OsTypeWindows},
Val{"%{x}%{y}%{z}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
Val{"%{x}%{z}%{y}%{z}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
Val{"%{x}%{z}%{y}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
Val{"%{x}\\^\"%{z}", "\\\\\\^\"", OsTypeWindows},
Val{"%{x}%{z}\\^\"%{z}", "\\\\\\^\"", OsTypeWindows},
Val{"%{x}%{z}\\^\"", "\\\\\\^\"", OsTypeWindows},
Val{"%{x}\\%{z}", "\\\\", OsTypeWindows},
Val{"%{x}%{z}\\%{z}", "\\\\", OsTypeWindows},
Val{"%{x}%{z}\\", "\\\\", OsTypeWindows},
Val{"%{aa}%{a}", "\"hi hohi\"", OsTypeWindows},
Val{"%{aa}%{aa}", "\"hi hohi ho\"", OsTypeWindows},
Val{"%{aa}:%{aa}", "\"hi ho\":\"hi ho\"", OsTypeWindows},
Val{"hallo ^|%{aa}^|", "hallo ^|\"hi ho\"^|", OsTypeWindows},
Val{"quoted multi-var", 0, OsTypeWindows},
Val{"\"%{x}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{x}%{z}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{x}%{z}%{y}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
Val{"\"%{x}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
Val{"\"%{x}%{z}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
Val{"\"%{x}%{z}\"^\"\"\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
Val{"\"%{x}\\%{z}\"", "\"\\\\\\\\\"", OsTypeWindows},
Val{"\"%{x}%{z}\\%{z}\"", "\"\\\\\\\\\"", OsTypeWindows},
Val{"\"%{x}%{z}\\\\\"", "\"\\\\\\\\\"", OsTypeWindows},
Val{"\"%{aa}%{a}\"", "\"hi hohi\"", OsTypeWindows},
Val{"\"%{aa}%{aa}\"", "\"hi hohi ho\"", OsTypeWindows},
Val{"\"%{aa}:%{aa}\"", "\"hi ho:hi ho\"", OsTypeWindows},
Val{"plain", 0, OsTypeLinux},
Val{"%{a}", "hi", OsTypeLinux},
Val{"%{b}", "'hi ho'", OsTypeLinux},
Val{"%{c}", "'&special;'", OsTypeLinux},
Val{"%{d}", "'h\\i'", OsTypeLinux},
Val{"%{e}", "'h\"i'", OsTypeLinux},
Val{"%{f}", "'h'\\''i'", OsTypeLinux},
Val{"%{z}", "''", OsTypeLinux},
Val{"single-quoted", 0, OsTypeLinux},
Val{"'%{a}'", "'hi'", OsTypeLinux},
Val{"'%{b}'", "'hi ho'", OsTypeLinux},
Val{"'%{c}'", "'&special;'", OsTypeLinux},
Val{"'%{d}'", "'h\\i'", OsTypeLinux},
Val{"'%{e}'", "'h\"i'", OsTypeLinux},
Val{"'%{f}'", "'h'\\''i'", OsTypeLinux},
Val{"'%{z}'", "''", OsTypeLinux},
Val{"double-quoted", 0, OsTypeLinux},
Val{"\"%{a}\"", "\"hi\"", OsTypeLinux},
Val{"\"%{b}\"", "\"hi ho\"", OsTypeLinux},
Val{"\"%{c}\"", "\"&special;\"", OsTypeLinux},
Val{"\"%{d}\"", "\"h\\\\i\"", OsTypeLinux},
Val{"\"%{e}\"", "\"h\\\"i\"", OsTypeLinux},
Val{"\"%{f}\"", "\"h'i\"", OsTypeLinux},
Val{"\"%{z}\"", "\"\"", OsTypeLinux},
Val{"complex", 0, OsTypeLinux},
Val{"echo \"$(echo %{a})\"", "echo \"$(echo hi)\"", OsTypeLinux},
Val{"echo \"$(echo %{b})\"", "echo \"$(echo 'hi ho')\"", OsTypeLinux},
Val{"echo \"$(echo \"%{a}\")\"", "echo \"$(echo \"hi\")\"", OsTypeLinux},
// These make no sense shell-wise, but they test expando nesting
Val{"echo \"%{echo %{a}}\"", "echo \"%{echo hi}\"", OsTypeLinux},
Val{"echo \"%{echo %{b}}\"", "echo \"%{echo hi ho}\"", OsTypeLinux},
Val{"echo \"%{echo \"%{a}\"}\"", "echo \"%{echo \"hi\"}\"", OsTypeLinux}};
const char *title = 0;
for (const auto &val : vals) {
if (!val.out) {
title = val.in;
} else {
QString name
= QString("%1: %2 (%3)")
.arg(title, val.in, val.os == OsTypeWindows ? "windows" : "linux");
QTest::newRow(name.toLatin1())
<< QString::fromLatin1(val.in) << QString::fromLatin1(val.out) << val.os;
QTest::newRow(("padded " + name).toLatin1())
<< QString(sp + QString::fromLatin1(val.in) + sp)
<< QString(sp + QString::fromLatin1(val.out) + sp) << val.os;
}
}
}
void expandProcessArgs()
{
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(OsType, os);
MacroExpander expander;
if (os == Utils::OsTypeWindows) {
expander.registerVariable("aa", "", [] { return "hi ho"; });
expander.registerVariable("b", "", [] { return "h\\i"; });
expander.registerVariable("c", "", [] { return "\\hi"; });
expander.registerVariable("d", "", [] { return "hi\\"; });
expander.registerVariable("ba", "", [] { return "h\\i ho"; });
expander.registerVariable("ca", "", [] { return "\\hi ho"; });
expander.registerVariable("da", "", [] { return "hi ho\\"; });
expander.registerVariable("e", "", [] { return "h\"i"; });
expander.registerVariable("f", "", [] { return "\"hi"; });
expander.registerVariable("g", "", [] { return "hi\""; });
expander.registerVariable("h", "", [] { return "h\\\"i"; });
expander.registerVariable("i", "", [] { return "\\\"hi"; });
expander.registerVariable("j", "", [] { return "hi\\\""; });
expander.registerVariable("k", "", [] { return "&special;"; });
expander.registerVariable("x", "", [] { return "\\"; });
expander.registerVariable("y", "", [] { return "\""; });
} else {
expander.registerVariable("b", "", [] { return "hi ho"; });
expander.registerVariable("c", "", [] { return "&special;"; });
expander.registerVariable("d", "", [] { return "h\\i"; });
expander.registerVariable("e", "", [] { return "h\"i"; });
expander.registerVariable("f", "", [] { return "h'i"; });
}
expander.registerVariable("a", "", [] { return "hi"; });
expander.registerVariable("z", "", [] { return ""; });
QCOMPARE(expander.expandProcessArgs(in, os), out);
}
void testProcessArgsFails()
{
MacroExpander expander;
expander.registerVariable("z", "", [] { return ""; });
expander.registerVariable("file", "", [] { return "foo.txt"; });
QVERIFY(!expander.expandProcessArgs("\\%{z}%{z}", OsTypeLinux));
QVERIFY(!expander.expandProcessArgs("echo \\%{file}", OsTypeLinux));
QVERIFY(!expander.expandProcessArgs("^%{z}%{z}", OsTypeWindows));
}
void testMacroExpander_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
struct Val
{
const char *in;
const char *out;
};
const std::array vals = {
Val{"text", "text"},
Val{"%{a}", "hi"},
Val{"%%{a}", "%hi"},
Val{"%%%{a}", "%%hi"},
Val{"%{b}", "%{b}"},
Val{"pre%{a}", "prehi"},
Val{"%{a}post", "hipost"},
Val{"pre%{a}post", "prehipost"},
Val{"%{a}%{a}", "hihi"},
Val{"%{a}text%{a}", "hitexthi"},
Val{"%{foo}%{a}text%{a}", "ahitexthi"},
Val{"%{}{a}", "%{a}"},
Val{"%{}", "%"},
Val{"test%{}", "test%"},
Val{"%{}test", "%test"},
Val{"%{abc", "%{abc"},
Val{"%{%{a}", "%{hi"},
Val{"%{%{a}}", "ho"},
Val{"%{%{a}}}post", "ho}post"},
Val{"%{hi%{a}}", "bar"},
Val{"%{hi%{%{foo}}}", "bar"},
Val{"%{hihi/b/c}", "car"},
Val{"%{hihi/a/}", "br"}, // empty replacement
Val{"%{hihi/b}", "bar"}, // incomplete substitution
Val{"%{hihi/./c}", "car"},
Val{"%{hihi//./c}", "ccc"},
Val{"%{hihi/(.)(.)r/\\2\\1c}", "abc"}, // no escape for capture groups
Val{"%{hihi/b/c/d}", "c/dar"},
Val{"%{hihi/a/e{\\}e}", "be{}er"}, // escape closing brace
Val{"%{JS:with \\} inside}", "yay"}, // escape closing brace also in JS:
Val{"%{JS:literal%\\{}", "hurray"},
Val{"%{slash/o\\/b/ol's c}", "fool's car"},
Val{"%{sl\\/sh/(.)(a)(.)/\\2\\1\\3as}", "salsash"}, // escape in variable name
Val{"%{JS:foo/b/c}", "%{JS:foo/b/c}"}, // No replacement for JS (all considered varName)
Val{"%{%{a}%{a}/b/c}", "car"},
Val{"%{nonsense:-sense}", "sense"},
};
for (const auto &val : vals)
QTest::newRow(val.in) << QString::fromLatin1(val.in) << QString::fromLatin1(val.out);
}
void testMacroExpander()
{
QFETCH(QString, in);
QFETCH(QString, out);
MacroExpander expander;
expander.registerVariable("foo", "", [] { return "a"; });
expander.registerVariable("a", "", [] { return "hi"; });
expander.registerVariable("hi", "", [] { return "ho"; });
expander.registerVariable("hihi", "", [] { return "bar"; });
expander.registerVariable("slash", "", [] { return "foo/bar"; });
expander.registerVariable("sl/sh", "", [] { return "slash"; });
expander.registerVariable("JS:foor", "", [] { return "bar"; });
expander.registerVariable("JS:with } inside", "", [] { return "yay"; });
expander.registerVariable("JS:literal%{", "", [] { return "hurray"; });
QCOMPARE(expander.expand(in), out);
}
};
QTEST_GUILESS_MAIN(tst_expander)
#include "tst_expander.moc"

View File

@@ -66,29 +66,6 @@ protected:
int MessageHandler::s_destroyCount = 0; int MessageHandler::s_destroyCount = 0;
QtMessageHandler MessageHandler::s_oldMessageHandler = 0; QtMessageHandler MessageHandler::s_oldMessageHandler = 0;
class MacroMapExpander : public AbstractMacroExpander {
public:
bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander*> &seen)
override
{
// loop prevention
const int count = seen.count();
seen.insert(this);
if (seen.count() == count)
return false;
QHash<QString, QString>::const_iterator it = m_map.constFind(name);
if (it != m_map.constEnd()) {
*ret = it.value();
return true;
}
return false;
}
void insert(const QString &key, const QString &value) { m_map.insert(key, value); }
private:
QHash<QString, QString> m_map;
};
static constexpr char s_skipTerminateOnWindows[] = static constexpr char s_skipTerminateOnWindows[] =
"Windows implementation of this test is lacking handling of WM_CLOSE message."; "Windows implementation of this test is lacking handling of WM_CLOSE message.";
@@ -135,8 +112,6 @@ private slots:
void prepareArgs(); void prepareArgs();
void prepareArgsEnv_data(); void prepareArgsEnv_data();
void prepareArgsEnv(); void prepareArgsEnv();
void expandMacros_data();
void expandMacros();
void iterations_data(); void iterations_data();
void iterations(); void iterations();
void iteratorEditsWindows(); void iteratorEditsWindows();
@@ -181,8 +156,6 @@ private:
Environment envWindows; Environment envWindows;
Environment envLinux; Environment envLinux;
MacroMapExpander mxWin;
MacroMapExpander mxUnix;
QString homeStr; QString homeStr;
QString home; QString home;
@@ -206,38 +179,6 @@ void tst_Process::initTestCase()
env << "empty=" << "word=hi" << "words=hi ho" << "spacedwords= hi ho sucker "; env << "empty=" << "word=hi" << "words=hi ho" << "spacedwords= hi ho sucker ";
envWindows = Environment(env, OsTypeWindows); envWindows = Environment(env, OsTypeWindows);
envLinux = Environment(env, OsTypeLinux); envLinux = Environment(env, OsTypeLinux);
mxWin.insert("a", "hi");
mxWin.insert("aa", "hi ho");
mxWin.insert("b", "h\\i");
mxWin.insert("c", "\\hi");
mxWin.insert("d", "hi\\");
mxWin.insert("ba", "h\\i ho");
mxWin.insert("ca", "\\hi ho");
mxWin.insert("da", "hi ho\\");
mxWin.insert("e", "h\"i");
mxWin.insert("f", "\"hi");
mxWin.insert("g", "hi\"");
mxWin.insert("h", "h\\\"i");
mxWin.insert("i", "\\\"hi");
mxWin.insert("j", "hi\\\"");
mxWin.insert("k", "&special;");
mxWin.insert("x", "\\");
mxWin.insert("y", "\"");
mxWin.insert("z", "");
mxUnix.insert("a", "hi");
mxUnix.insert("b", "hi ho");
mxUnix.insert("c", "&special;");
mxUnix.insert("d", "h\\i");
mxUnix.insert("e", "h\"i");
mxUnix.insert("f", "h'i");
mxUnix.insert("z", "");
} }
void tst_Process::cleanupTestCase() void tst_Process::cleanupTestCase()
@@ -550,252 +491,7 @@ void tst_Process::prepareArgsEnv()
QCOMPARE(outstr, out); QCOMPARE(outstr, out);
} }
void tst_Process::expandMacros_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
QTest::addColumn<OsType>("os");
QChar sp(QLatin1Char(' '));
static const struct {
const char * const in;
const char * const out;
OsType os;
} vals[] = {
{"plain", 0, OsTypeWindows},
{"%{a}", "hi", OsTypeWindows},
{"%{aa}", "\"hi ho\"", OsTypeWindows},
{"%{b}", "h\\i", OsTypeWindows},
{"%{c}", "\\hi", OsTypeWindows},
{"%{d}", "hi\\", OsTypeWindows},
{"%{ba}", "\"h\\i ho\"", OsTypeWindows},
{"%{ca}", "\"\\hi ho\"", OsTypeWindows},
{"%{da}", "\"hi ho\\\\\"", OsTypeWindows}, // or "\"hi ho\"\\"
{"%{e}", "\"h\"\\^\"\"i\"", OsTypeWindows},
{"%{f}", "\"\"\\^\"\"hi\"", OsTypeWindows},
{"%{g}", "\"hi\"\\^\"\"\"", OsTypeWindows},
{"%{h}", "\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
{"%{i}", "\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
{"%{j}", "\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
{"%{k}", "\"&special;\"", OsTypeWindows},
{"%{x}", "\\", OsTypeWindows},
{"%{y}", "\"\"\\^\"\"\"", OsTypeWindows},
{"%{z}", "\"\"", OsTypeWindows},
{"^%{z}%{z}", "^%{z}%{z}", OsTypeWindows}, // stupid user check
{"quoted", 0, OsTypeWindows},
{"\"%{a}\"", "\"hi\"", OsTypeWindows},
{"\"%{aa}\"", "\"hi ho\"", OsTypeWindows},
{"\"%{b}\"", "\"h\\i\"", OsTypeWindows},
{"\"%{c}\"", "\"\\hi\"", OsTypeWindows},
{"\"%{d}\"", "\"hi\\\\\"", OsTypeWindows},
{"\"%{ba}\"", "\"h\\i ho\"", OsTypeWindows},
{"\"%{ca}\"", "\"\\hi ho\"", OsTypeWindows},
{"\"%{da}\"", "\"hi ho\\\\\"", OsTypeWindows},
{"\"%{e}\"", "\"h\"\\^\"\"i\"", OsTypeWindows},
{"\"%{f}\"", "\"\"\\^\"\"hi\"", OsTypeWindows},
{"\"%{g}\"", "\"hi\"\\^\"\"\"", OsTypeWindows},
{"\"%{h}\"", "\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
{"\"%{i}\"", "\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
{"\"%{j}\"", "\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
{"\"%{k}\"", "\"&special;\"", OsTypeWindows},
{"\"%{x}\"", "\"\\\\\"", OsTypeWindows},
{"\"%{y}\"", "\"\"\\^\"\"\"", OsTypeWindows},
{"\"%{z}\"", "\"\"", OsTypeWindows},
{"leading bs", 0, OsTypeWindows},
{"\\%{a}", "\\hi", OsTypeWindows},
{"\\%{aa}", "\\\\\"hi ho\"", OsTypeWindows},
{"\\%{b}", "\\h\\i", OsTypeWindows},
{"\\%{c}", "\\\\hi", OsTypeWindows},
{"\\%{d}", "\\hi\\", OsTypeWindows},
{"\\%{ba}", "\\\\\"h\\i ho\"", OsTypeWindows},
{"\\%{ca}", "\\\\\"\\hi ho\"", OsTypeWindows},
{"\\%{da}", "\\\\\"hi ho\\\\\"", OsTypeWindows},
{"\\%{e}", "\\\\\"h\"\\^\"\"i\"", OsTypeWindows},
{"\\%{f}", "\\\\\"\"\\^\"\"hi\"", OsTypeWindows},
{"\\%{g}", "\\\\\"hi\"\\^\"\"\"", OsTypeWindows},
{"\\%{h}", "\\\\\"h\\\\\"\\^\"\"i\"", OsTypeWindows},
{"\\%{i}", "\\\\\"\\\\\"\\^\"\"hi\"", OsTypeWindows},
{"\\%{j}", "\\\\\"hi\\\\\"\\^\"\"\"", OsTypeWindows},
{"\\%{x}", "\\\\", OsTypeWindows},
{"\\%{y}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
{"\\%{z}", "\\", OsTypeWindows},
{"trailing bs", 0, OsTypeWindows},
{"%{a}\\", "hi\\", OsTypeWindows},
{"%{aa}\\", "\"hi ho\"\\", OsTypeWindows},
{"%{b}\\", "h\\i\\", OsTypeWindows},
{"%{c}\\", "\\hi\\", OsTypeWindows},
{"%{d}\\", "hi\\\\", OsTypeWindows},
{"%{ba}\\", "\"h\\i ho\"\\", OsTypeWindows},
{"%{ca}\\", "\"\\hi ho\"\\", OsTypeWindows},
{"%{da}\\", "\"hi ho\\\\\"\\", OsTypeWindows},
{"%{e}\\", "\"h\"\\^\"\"i\"\\", OsTypeWindows},
{"%{f}\\", "\"\"\\^\"\"hi\"\\", OsTypeWindows},
{"%{g}\\", "\"hi\"\\^\"\"\"\\", OsTypeWindows},
{"%{h}\\", "\"h\\\\\"\\^\"\"i\"\\", OsTypeWindows},
{"%{i}\\", "\"\\\\\"\\^\"\"hi\"\\", OsTypeWindows},
{"%{j}\\", "\"hi\\\\\"\\^\"\"\"\\", OsTypeWindows},
{"%{x}\\", "\\\\", OsTypeWindows},
{"%{y}\\", "\"\"\\^\"\"\"\\", OsTypeWindows},
{"%{z}\\", "\\", OsTypeWindows},
{"bs-enclosed", 0, OsTypeWindows},
{"\\%{a}\\", "\\hi\\", OsTypeWindows},
{"\\%{aa}\\", "\\\\\"hi ho\"\\", OsTypeWindows},
{"\\%{b}\\", "\\h\\i\\", OsTypeWindows},
{"\\%{c}\\", "\\\\hi\\", OsTypeWindows},
{"\\%{d}\\", "\\hi\\\\", OsTypeWindows},
{"\\%{ba}\\", "\\\\\"h\\i ho\"\\", OsTypeWindows},
{"\\%{ca}\\", "\\\\\"\\hi ho\"\\", OsTypeWindows},
{"\\%{da}\\", "\\\\\"hi ho\\\\\"\\", OsTypeWindows},
{"\\%{e}\\", "\\\\\"h\"\\^\"\"i\"\\", OsTypeWindows},
{"\\%{f}\\", "\\\\\"\"\\^\"\"hi\"\\", OsTypeWindows},
{"\\%{g}\\", "\\\\\"hi\"\\^\"\"\"\\", OsTypeWindows},
{"\\%{h}\\", "\\\\\"h\\\\\"\\^\"\"i\"\\", OsTypeWindows},
{"\\%{i}\\", "\\\\\"\\\\\"\\^\"\"hi\"\\", OsTypeWindows},
{"\\%{j}\\", "\\\\\"hi\\\\\"\\^\"\"\"\\", OsTypeWindows},
{"\\%{x}\\", "\\\\\\", OsTypeWindows},
{"\\%{y}\\", "\\\\\"\"\\^\"\"\"\\", OsTypeWindows},
{"\\%{z}\\", "\\\\", OsTypeWindows},
{"bs-enclosed and trailing literal quote", 0, OsTypeWindows},
{"\\%{a}\\\\\\^\"", "\\hi\\\\\\^\"", OsTypeWindows},
{"\\%{aa}\\\\\\^\"", "\\\\\"hi ho\"\\\\\\^\"", OsTypeWindows},
{"\\%{b}\\\\\\^\"", "\\h\\i\\\\\\^\"", OsTypeWindows},
{"\\%{c}\\\\\\^\"", "\\\\hi\\\\\\^\"", OsTypeWindows},
{"\\%{d}\\\\\\^\"", "\\hi\\\\\\\\\\^\"", OsTypeWindows},
{"\\%{ba}\\\\\\^\"", "\\\\\"h\\i ho\"\\\\\\^\"", OsTypeWindows},
{"\\%{ca}\\\\\\^\"", "\\\\\"\\hi ho\"\\\\\\^\"", OsTypeWindows},
{"\\%{da}\\\\\\^\"", "\\\\\"hi ho\\\\\"\\\\\\^\"", OsTypeWindows},
{"\\%{e}\\\\\\^\"", "\\\\\"h\"\\^\"\"i\"\\\\\\^\"", OsTypeWindows},
{"\\%{f}\\\\\\^\"", "\\\\\"\"\\^\"\"hi\"\\\\\\^\"", OsTypeWindows},
{"\\%{g}\\\\\\^\"", "\\\\\"hi\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
{"\\%{h}\\\\\\^\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\\^\"", OsTypeWindows},
{"\\%{i}\\\\\\^\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\\^\"", OsTypeWindows},
{"\\%{j}\\\\\\^\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
{"\\%{x}\\\\\\^\"", "\\\\\\\\\\\\\\^\"", OsTypeWindows},
{"\\%{y}\\\\\\^\"", "\\\\\"\"\\^\"\"\"\\\\\\^\"", OsTypeWindows},
{"\\%{z}\\\\\\^\"", "\\\\\\\\\\^\"", OsTypeWindows},
{"bs-enclosed and trailing unclosed quote", 0, OsTypeWindows},
{"\\%{a}\\\\\"", "\\hi\\\\\"", OsTypeWindows},
{"\\%{aa}\\\\\"", "\\\\\"hi ho\"\\\\\"", OsTypeWindows},
{"\\%{b}\\\\\"", "\\h\\i\\\\\"", OsTypeWindows},
{"\\%{c}\\\\\"", "\\\\hi\\\\\"", OsTypeWindows},
{"\\%{d}\\\\\"", "\\hi\\\\\\\\\"", OsTypeWindows},
{"\\%{ba}\\\\\"", "\\\\\"h\\i ho\"\\\\\"", OsTypeWindows},
{"\\%{ca}\\\\\"", "\\\\\"\\hi ho\"\\\\\"", OsTypeWindows},
{"\\%{da}\\\\\"", "\\\\\"hi ho\\\\\"\\\\\"", OsTypeWindows},
{"\\%{e}\\\\\"", "\\\\\"h\"\\^\"\"i\"\\\\\"", OsTypeWindows},
{"\\%{f}\\\\\"", "\\\\\"\"\\^\"\"hi\"\\\\\"", OsTypeWindows},
{"\\%{g}\\\\\"", "\\\\\"hi\"\\^\"\"\"\\\\\"", OsTypeWindows},
{"\\%{h}\\\\\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\"", OsTypeWindows},
{"\\%{i}\\\\\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\"", OsTypeWindows},
{"\\%{j}\\\\\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\"", OsTypeWindows},
{"\\%{x}\\\\\"", "\\\\\\\\\\\\\"", OsTypeWindows},
{"\\%{y}\\\\\"", "\\\\\"\"\\^\"\"\"\\\\\"", OsTypeWindows},
{"\\%{z}\\\\\"", "\\\\\\\\\"", OsTypeWindows},
{"multi-var", 0, OsTypeWindows},
{"%{x}%{y}%{z}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
{"%{x}%{z}%{y}%{z}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
{"%{x}%{z}%{y}", "\\\\\"\"\\^\"\"\"", OsTypeWindows},
{"%{x}\\^\"%{z}", "\\\\\\^\"", OsTypeWindows},
{"%{x}%{z}\\^\"%{z}", "\\\\\\^\"", OsTypeWindows},
{"%{x}%{z}\\^\"", "\\\\\\^\"", OsTypeWindows},
{"%{x}\\%{z}", "\\\\", OsTypeWindows},
{"%{x}%{z}\\%{z}", "\\\\", OsTypeWindows},
{"%{x}%{z}\\", "\\\\", OsTypeWindows},
{"%{aa}%{a}", "\"hi hohi\"", OsTypeWindows},
{"%{aa}%{aa}", "\"hi hohi ho\"", OsTypeWindows},
{"%{aa}:%{aa}", "\"hi ho\":\"hi ho\"", OsTypeWindows},
{"hallo ^|%{aa}^|", "hallo ^|\"hi ho\"^|", OsTypeWindows},
{"quoted multi-var", 0, OsTypeWindows},
{"\"%{x}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
{"\"%{x}%{z}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
{"\"%{x}%{z}%{y}\"", "\"\\\\\"\\^\"\"\"", OsTypeWindows},
{"\"%{x}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
{"\"%{x}%{z}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
{"\"%{x}%{z}\"^\"\"\"", "\"\\\\\"^\"\"\"", OsTypeWindows},
{"\"%{x}\\%{z}\"", "\"\\\\\\\\\"", OsTypeWindows},
{"\"%{x}%{z}\\%{z}\"", "\"\\\\\\\\\"", OsTypeWindows},
{"\"%{x}%{z}\\\\\"", "\"\\\\\\\\\"", OsTypeWindows},
{"\"%{aa}%{a}\"", "\"hi hohi\"", OsTypeWindows},
{"\"%{aa}%{aa}\"", "\"hi hohi ho\"", OsTypeWindows},
{"\"%{aa}:%{aa}\"", "\"hi ho:hi ho\"", OsTypeWindows},
{"plain", 0, OsTypeLinux},
{"%{a}", "hi", OsTypeLinux},
{"%{b}", "'hi ho'", OsTypeLinux},
{"%{c}", "'&special;'", OsTypeLinux},
{"%{d}", "'h\\i'", OsTypeLinux},
{"%{e}", "'h\"i'", OsTypeLinux},
{"%{f}", "'h'\\''i'", OsTypeLinux},
{"%{z}", "''", OsTypeLinux},
{"\\%{z}%{z}", "\\%{z}%{z}", OsTypeLinux}, // stupid user check
{"single-quoted", 0, OsTypeLinux},
{"'%{a}'", "'hi'", OsTypeLinux},
{"'%{b}'", "'hi ho'", OsTypeLinux},
{"'%{c}'", "'&special;'", OsTypeLinux},
{"'%{d}'", "'h\\i'", OsTypeLinux},
{"'%{e}'", "'h\"i'", OsTypeLinux},
{"'%{f}'", "'h'\\''i'", OsTypeLinux},
{"'%{z}'", "''", OsTypeLinux},
{"double-quoted", 0, OsTypeLinux},
{"\"%{a}\"", "\"hi\"", OsTypeLinux},
{"\"%{b}\"", "\"hi ho\"", OsTypeLinux},
{"\"%{c}\"", "\"&special;\"", OsTypeLinux},
{"\"%{d}\"", "\"h\\\\i\"", OsTypeLinux},
{"\"%{e}\"", "\"h\\\"i\"", OsTypeLinux},
{"\"%{f}\"", "\"h'i\"", OsTypeLinux},
{"\"%{z}\"", "\"\"", OsTypeLinux},
{"complex", 0, OsTypeLinux},
{"echo \"$(echo %{a})\"", "echo \"$(echo hi)\"", OsTypeLinux},
{"echo \"$(echo %{b})\"", "echo \"$(echo 'hi ho')\"", OsTypeLinux},
{"echo \"$(echo \"%{a}\")\"", "echo \"$(echo \"hi\")\"", OsTypeLinux},
// These make no sense shell-wise, but they test expando nesting
{"echo \"%{echo %{a}}\"", "echo \"%{echo hi}\"", OsTypeLinux},
{"echo \"%{echo %{b}}\"", "echo \"%{echo hi ho}\"", OsTypeLinux},
{"echo \"%{echo \"%{a}\"}\"", "echo \"%{echo \"hi\"}\"", OsTypeLinux },
};
const char *title = 0;
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
if (!vals[i].out) {
title = vals[i].in;
} else {
char buf[80];
snprintf(buf, 80, "%s: %s", title, vals[i].in);
QTest::newRow(buf) << QString::fromLatin1(vals[i].in)
<< QString::fromLatin1(vals[i].out)
<< vals[i].os;
snprintf(buf, 80, "padded %s: %s", title, vals[i].in);
QTest::newRow(buf) << QString(sp + QString::fromLatin1(vals[i].in) + sp)
<< QString(sp + QString::fromLatin1(vals[i].out) + sp)
<< vals[i].os;
}
}
}
void tst_Process::expandMacros()
{
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(OsType, os);
if (os == OsTypeWindows)
ProcessArgs::expandMacros(&in, &mxWin, os);
else
ProcessArgs::expandMacros(&in, &mxUnix, os);
QCOMPARE(in, out);
}
void tst_Process::iterations_data() void tst_Process::iterations_data()
{ {

View File

@@ -10,66 +10,12 @@
using namespace Utils; using namespace Utils;
class TestMacroExpander : public Utils::AbstractMacroExpander
{
public:
bool resolveMacro(const QString &name, QString *ret, QSet<AbstractMacroExpander*> &seen)
override
{
// loop prevention
const int count = seen.count();
seen.insert(this);
if (seen.count() == count)
return false;
if (name == QLatin1String("foo")) {
*ret = QLatin1String("a");
return true;
}
if (name == QLatin1String("a")) {
*ret = QLatin1String("hi");
return true;
}
if (name == QLatin1String("hi")) {
*ret = QLatin1String("ho");
return true;
}
if (name == QLatin1String("hihi")) {
*ret = QLatin1String("bar");
return true;
}
if (name == "slash") {
*ret = "foo/bar";
return true;
}
if (name == "sl/sh") {
*ret = "slash";
return true;
}
if (name == "JS:foo") {
*ret = "bar";
return true;
}
if (name == "JS:with } inside") {
*ret = "yay";
return true;
}
if (name == "JS:literal%{") {
*ret = "hurray";
return true;
}
return false;
}
};
class tst_StringUtils : public QObject class tst_StringUtils : public QObject
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void testWithTildeHomePath(); void testWithTildeHomePath();
void testMacroExpander_data();
void testMacroExpander();
void testStripAccelerator_data(); void testStripAccelerator_data();
void testStripAccelerator(); void testStripAccelerator();
void testParseUsedPortFromNetstatOutput_data(); void testParseUsedPortFromNetstatOutput_data();
@@ -84,9 +30,6 @@ private slots:
void testSplitAtFirst(); void testSplitAtFirst();
void testAsciify_data(); void testAsciify_data();
void testAsciify(); void testAsciify();
private:
TestMacroExpander mx;
}; };
void tst_StringUtils::testWithTildeHomePath() void tst_StringUtils::testWithTildeHomePath()
@@ -118,68 +61,6 @@ void tst_StringUtils::testWithTildeHomePath()
#endif #endif
} }
void tst_StringUtils::testMacroExpander_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
static const struct {
const char * const in;
const char * const out;
} vals[] = {
{"text", "text"},
{"%{a}", "hi"},
{"%%{a}", "%hi"},
{"%%%{a}", "%%hi"},
{"%{b}", "%{b}"},
{"pre%{a}", "prehi"},
{"%{a}post", "hipost"},
{"pre%{a}post", "prehipost"},
{"%{a}%{a}", "hihi"},
{"%{a}text%{a}", "hitexthi"},
{"%{foo}%{a}text%{a}", "ahitexthi"},
{"%{}{a}", "%{a}"},
{"%{}", "%"},
{"test%{}", "test%"},
{"%{}test", "%test"},
{"%{abc", "%{abc"},
{"%{%{a}", "%{hi"},
{"%{%{a}}", "ho"},
{"%{%{a}}}post", "ho}post"},
{"%{hi%{a}}", "bar"},
{"%{hi%{%{foo}}}", "bar"},
{"%{hihi/b/c}", "car"},
{"%{hihi/a/}", "br"}, // empty replacement
{"%{hihi/b}", "bar"}, // incomplete substitution
{"%{hihi/./c}", "car"},
{"%{hihi//./c}", "ccc"},
{"%{hihi/(.)(.)r/\\2\\1c}", "abc"}, // no escape for capture groups
{"%{hihi/b/c/d}", "c/dar"},
{"%{hihi/a/e{\\}e}", "be{}er"}, // escape closing brace
{"%{JS:with \\} inside}", "yay"}, // escape closing brace also in JS:
{"%{JS:literal%\\{}", "hurray"},
{"%{slash/o\\/b/ol's c}", "fool's car"},
{"%{sl\\/sh/(.)(a)(.)/\\2\\1\\3as}", "salsash"}, // escape in variable name
{"%{JS:foo/b/c}", "%{JS:foo/b/c}"}, // No replacement for JS (all considered varName)
{"%{%{a}%{a}/b/c}", "car"},
{"%{nonsense:-sense}", "sense"},
};
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_StringUtils::testMacroExpander()
{
QFETCH(QString, in);
QFETCH(QString, out);
Utils::expandMacros(&in, &mx);
QCOMPARE(in, out);
}
void tst_StringUtils::testStripAccelerator_data() void tst_StringUtils::testStripAccelerator_data()
{ {
QTest::addColumn<QString>("expected"); QTest::addColumn<QString>("expected");

View File

@@ -7,6 +7,7 @@ Project {
"async/async.qbs", "async/async.qbs",
"commandline/commandline.qbs", "commandline/commandline.qbs",
"deviceshell/deviceshell.qbs", "deviceshell/deviceshell.qbs",
"expander/expander.qbs",
"expected/expected.qbs", "expected/expected.qbs",
"filepath/filepath.qbs", "filepath/filepath.qbs",
"fileutils/fileutils.qbs", "fileutils/fileutils.qbs",

View File

@@ -7678,8 +7678,6 @@
"mesonprojectmanager.qbs:3" "3" "mesonprojectmanager.qbs:3" "3"
"mesoninfoparser" "3" "mesoninfoparser" "3"
"mesonprojectmanager.qbs:113" "4" "mesonprojectmanager.qbs:113" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -7699,8 +7697,6 @@
"toolwrapper.h" "4" "toolwrapper.h" "4"
"mesonparser" "3" "mesonparser" "3"
"mesonprojectmanager.qbs:151" "4" "mesonprojectmanager.qbs:151" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -7801,8 +7797,6 @@
"versionhelper.h" "4" "versionhelper.h" "4"
"mesonwrapper" "3" "mesonwrapper" "3"
"mesonprojectmanager.qbs:93" "4" "mesonprojectmanager.qbs:93" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -7821,8 +7815,6 @@
"toolwrapper.h" "4" "toolwrapper.h" "4"
"ninjaparser" "3" "ninjaparser" "3"
"mesonprojectmanager.qbs:134" "4" "mesonprojectmanager.qbs:134" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -11729,8 +11721,6 @@
"proparser.qbs:3" "2" "proparser.qbs:3" "2"
"qtcjson" "1" "qtcjson" "1"
"json.qbs:3" "2" "json.qbs:3" "2"
"Group 1" "2"
"Library.qbs:81" "3"
"json.cpp" "2" "json.cpp" "2"
"json.h" "2" "json.h" "2"
"qtcreator" "1" "qtcreator" "1"
@@ -12867,8 +12857,6 @@
"auto.qbs:3" "2" "auto.qbs:3" "2"
"Aggregation autotest" "2" "Aggregation autotest" "2"
"aggregation.qbs:3" "3" "aggregation.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -12880,8 +12868,6 @@
"tst_aggregate.cpp" "3" "tst_aggregate.cpp" "3"
"Algorithm autotest" "2" "Algorithm autotest" "2"
"algorithm.qbs:3" "3" "algorithm.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -12893,8 +12879,6 @@
"tst_algorithm.cpp" "3" "tst_algorithm.cpp" "3"
"Android AVD Manager autotest" "2" "Android AVD Manager autotest" "2"
"android.qbs:3" "3" "android.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"Resource files" "3" "Resource files" "3"
"android.qbs:25" "4" "android.qbs:25" "4"
"Test.avd" "4" "Test.avd" "4"
@@ -12920,8 +12904,6 @@
"tst_avdmanageroutputparser.cpp" "4" "tst_avdmanageroutputparser.cpp" "4"
"ChangeSet autotest" "2" "ChangeSet autotest" "2"
"changeset.qbs:3" "3" "changeset.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -12938,8 +12920,6 @@
"Data Files" "4" "Data Files" "4"
"c99.qbs:11" "5" "c99.qbs:11" "5"
"designatedInitializer.1.c" "5" "designatedInitializer.1.c" "5"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Source Files" "4" "Source Files" "4"
"c99.qbs:6" "5" "c99.qbs:6" "5"
"tst_c99.cpp" "5" "tst_c99.cpp" "5"
@@ -12953,8 +12933,6 @@
"qtcreator_pch.h" "6" "qtcreator_pch.h" "6"
"CPlusPlus AST autotest" "3" "CPlusPlus AST autotest" "3"
"ast.qbs:4" "4" "ast.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -12966,8 +12944,6 @@
"tst_ast.cpp" "4" "tst_ast.cpp" "4"
"CPlusPlus check symbols autotest" "3" "CPlusPlus check symbols autotest" "3"
"checksymbols.qbs:4" "4" "checksymbols.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -12981,8 +12957,6 @@
"tst_checksymbols.cpp" "4" "tst_checksymbols.cpp" "4"
"CPlusPlus code formatter autotest" "3" "CPlusPlus code formatter autotest" "3"
"codeformatter.qbs:4" "4" "codeformatter.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -12994,8 +12968,6 @@
"tst_codeformatter.cpp" "4" "tst_codeformatter.cpp" "4"
"CPlusPlus fileiterationorder autotest" "3" "CPlusPlus fileiterationorder autotest" "3"
"fileiterationorder.qbs:4" "4" "fileiterationorder.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13007,8 +12979,6 @@
"tst_fileiterationorder.cpp" "4" "tst_fileiterationorder.cpp" "4"
"CPlusPlus find usages autotest" "3" "CPlusPlus find usages autotest" "3"
"findusages.qbs:4" "4" "findusages.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13022,8 +12992,6 @@
"tst_findusages.cpp" "4" "tst_findusages.cpp" "4"
"CPlusPlus lexer autotest" "3" "CPlusPlus lexer autotest" "3"
"lexer.qbs:4" "4" "lexer.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13037,8 +13005,6 @@
"tst_lexer.cpp" "4" "tst_lexer.cpp" "4"
"CPlusPlus lookup autotest" "3" "CPlusPlus lookup autotest" "3"
"lookup.qbs:4" "4" "lookup.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13050,8 +13016,6 @@
"tst_lookup.cpp" "4" "tst_lookup.cpp" "4"
"CPlusPlus miscellaneous autotest" "3" "CPlusPlus miscellaneous autotest" "3"
"misc.qbs:4" "4" "misc.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13092,8 +13056,6 @@
"recursive.1.out.cpp" "5" "recursive.1.out.cpp" "5"
"reserved.1.cpp" "5" "reserved.1.cpp" "5"
"reserved.1.out.cpp" "5" "reserved.1.out.cpp" "5"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Source Files" "4" "Source Files" "4"
"preprocessor.qbs:6" "5" "preprocessor.qbs:6" "5"
"tst_preprocessor.cpp" "5" "tst_preprocessor.cpp" "5"
@@ -13107,8 +13069,6 @@
"qtcreator_pch.h" "6" "qtcreator_pch.h" "6"
"CPlusPlus pretty printer autotest" "3" "CPlusPlus pretty printer autotest" "3"
"typeprettyprinter.qbs:4" "4" "typeprettyprinter.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13123,8 +13083,6 @@
"Data Files" "4" "Data Files" "4"
"cppselectionchanger.qbs:12" "5" "cppselectionchanger.qbs:12" "5"
"testCppFile.cpp" "5" "testCppFile.cpp" "5"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Source Files" "4" "Source Files" "4"
"cppselectionchanger.qbs:7" "5" "cppselectionchanger.qbs:7" "5"
"tst_cppselectionchangertest.cpp" "5" "tst_cppselectionchangertest.cpp" "5"
@@ -13138,8 +13096,6 @@
"qtcreator_pch.h" "6" "qtcreator_pch.h" "6"
"CPlusPlus semantic autotest" "3" "CPlusPlus semantic autotest" "3"
"semantic.qbs:4" "4" "semantic.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13151,8 +13107,6 @@
"tst_semantic.cpp" "4" "tst_semantic.cpp" "4"
"CPlusPlus translation unit autotest" "3" "CPlusPlus translation unit autotest" "3"
"translationunit.qbs:4" "4" "translationunit.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13174,8 +13128,6 @@
"noExcept.1.errors.txt" "5" "noExcept.1.errors.txt" "5"
"staticAssert.1.cpp" "5" "staticAssert.1.cpp" "5"
"staticAssert.1.errors.txt" "5" "staticAssert.1.errors.txt" "5"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Source Files" "4" "Source Files" "4"
"cxx11.qbs:6" "5" "cxx11.qbs:6" "5"
"tst_cxx11.cpp" "5" "tst_cxx11.cpp" "5"
@@ -13189,8 +13141,6 @@
"qtcreator_pch.h" "6" "qtcreator_pch.h" "6"
"declaration comments autotest" "3" "declaration comments autotest" "3"
"declarationcomments.qbs:3" "4" "declarationcomments.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13204,8 +13154,6 @@
"debugger.qbs:3" "3" "debugger.qbs:3" "3"
"Debugger dumpers autotest" "3" "Debugger dumpers autotest" "3"
"dumpers.qbs:3" "4" "dumpers.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Sources from Debugger plugin" "4" "Sources from Debugger plugin" "4"
"dumpers.qbs:8" "5" "dumpers.qbs:8" "5"
"debuggerprotocol.cpp" "5" "debuggerprotocol.cpp" "5"
@@ -13230,8 +13178,6 @@
"tst_dumpers.cpp" "5" "tst_dumpers.cpp" "5"
"debugger protocol autotest" "3" "debugger protocol autotest" "3"
"protocol.qbs:3" "4" "protocol.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Sources from Debugger plugin" "4" "Sources from Debugger plugin" "4"
"protocol.qbs:7" "5" "protocol.qbs:7" "5"
"debuggerprotocol.cpp" "5" "debuggerprotocol.cpp" "5"
@@ -13249,8 +13195,6 @@
"tst_protocol.cpp" "5" "tst_protocol.cpp" "5"
"disassembler autotest" "3" "disassembler autotest" "3"
"disassembler.qbs:3" "4" "disassembler.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Sources from Debugger plugin" "4" "Sources from Debugger plugin" "4"
"disassembler.qbs:5" "5" "disassembler.qbs:5" "5"
"disassemblerlines.cpp" "5" "disassemblerlines.cpp" "5"
@@ -13267,8 +13211,6 @@
"tst_disassembler.cpp" "5" "tst_disassembler.cpp" "5"
"gdb autotest" "3" "gdb autotest" "3"
"gdb.qbs:3" "4" "gdb.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Sources from Debugger plugin" "4" "Sources from Debugger plugin" "4"
"gdb.qbs:7" "5" "gdb.qbs:7" "5"
"debuggerprotocol.cpp" "5" "debuggerprotocol.cpp" "5"
@@ -13286,8 +13228,6 @@
"tst_gdb.cpp" "5" "tst_gdb.cpp" "5"
"offsets autotest" "3" "offsets autotest" "3"
"offsets.qbs:3" "4" "offsets.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13301,8 +13241,6 @@
"tst_offsets.cpp" "5" "tst_offsets.cpp" "5"
"simplifytypes autotest" "3" "simplifytypes autotest" "3"
"simplifytypes.qbs:3" "4" "simplifytypes.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Sources from Debugger plugin" "4" "Sources from Debugger plugin" "4"
"simplifytypes.qbs:6" "5" "simplifytypes.qbs:6" "5"
"simplifytype.cpp" "5" "simplifytype.cpp" "5"
@@ -13321,8 +13259,6 @@
"diff.qbs:3" "3" "diff.qbs:3" "3"
"Differ autotest" "3" "Differ autotest" "3"
"differ.qbs:3" "4" "differ.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13334,8 +13270,6 @@
"tst_differ.cpp" "4" "tst_differ.cpp" "4"
"Environment autotest" "2" "Environment autotest" "2"
"environment.qbs:3" "3" "environment.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13347,8 +13281,6 @@
"tst_environment.cpp" "3" "tst_environment.cpp" "3"
"Examples autotest" "2" "Examples autotest" "2"
"examples.qbs:3" "3" "examples.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13364,8 +13296,6 @@
"pluginspec.qbs:3" "4" "pluginspec.qbs:3" "4"
"ExtensionSystem pluginspec autotest" "4" "ExtensionSystem pluginspec autotest" "4"
"test.qbs:3" "5" "test.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"Sources" "5" "Sources" "5"
"test.qbs:7" "6" "test.qbs:7" "6"
"tst_pluginspec.cpp" "6" "tst_pluginspec.cpp" "6"
@@ -13435,8 +13365,6 @@
"plugin3.h" "6" "plugin3.h" "6"
"PluginManager autotest" "4" "PluginManager autotest" "4"
"test.qbs:3" "5" "test.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -13448,8 +13376,6 @@
"tst_pluginmanager.cpp" "5" "tst_pluginmanager.cpp" "5"
"ExternalTool autotest" "2" "ExternalTool autotest" "2"
"externaltool.qbs:3" "3" "externaltool.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13463,8 +13389,6 @@
"tst_externaltooltest.cpp" "4" "tst_externaltooltest.cpp" "4"
"File search autotest" "2" "File search autotest" "2"
"filesearch.qbs:3" "3" "filesearch.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13480,8 +13404,6 @@
"testfile.txt" "5" "testfile.txt" "5"
"json autotest" "2" "json autotest" "2"
"json.qbs:3" "3" "json.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13500,8 +13422,6 @@
"tst_json.cpp" "3" "tst_json.cpp" "3"
"Language Server Protocol autotest" "2" "Language Server Protocol autotest" "2"
"languageserverprotocol.qbs:3" "3" "languageserverprotocol.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13513,8 +13433,6 @@
"tst_languageserverprotocol.cpp" "3" "tst_languageserverprotocol.cpp" "3"
"ProFileWriter autotest" "2" "ProFileWriter autotest" "2"
"profilewriter.qbs:3" "3" "profilewriter.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"Sources from ProParser" "3" "Sources from ProParser" "3"
"profilewriter.qbs:7" "4" "profilewriter.qbs:7" "4"
"ioutils.cpp" "4" "ioutils.cpp" "4"
@@ -13553,8 +13471,6 @@
"codemodel.qbs:3" "4" "codemodel.qbs:3" "4"
"QML code model check autotest" "4" "QML code model check autotest" "4"
"check.qbs:3" "5" "check.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -13566,8 +13482,6 @@
"tst_check.cpp" "5" "tst_check.cpp" "5"
"QML code model dependencies autotest" "4" "QML code model dependencies autotest" "4"
"dependencies.qbs:3" "5" "dependencies.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -13579,8 +13493,6 @@
"tst_dependencies.cpp" "5" "tst_dependencies.cpp" "5"
"QML code model imports check autotest" "4" "QML code model imports check autotest" "4"
"importscheck.qbs:3" "5" "importscheck.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -13594,8 +13506,6 @@
"qmleditor.qbs:3" "4" "qmleditor.qbs:3" "4"
"QML code formatter autotest" "4" "QML code formatter autotest" "4"
"qmlcodeformatter.qbs:3" "5" "qmlcodeformatter.qbs:3" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -13607,8 +13517,6 @@
"tst_qmlcodeformatter.cpp" "5" "tst_qmlcodeformatter.cpp" "5"
"QML persistenttrie autotest" "3" "QML persistenttrie autotest" "3"
"persistenttrie.qbs:3" "4" "persistenttrie.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13621,8 +13529,6 @@
"tst_testtrie.h" "4" "tst_testtrie.h" "4"
"QML reformatter autotest" "3" "QML reformatter autotest" "3"
"reformatter.qbs:3" "4" "reformatter.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13634,8 +13540,6 @@
"tst_reformatter.cpp" "4" "tst_reformatter.cpp" "4"
"QMLJS simple reader autotest" "3" "QMLJS simple reader autotest" "3"
"qmljssimplereader.qbs:3" "4" "qmljssimplereader.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13647,8 +13551,6 @@
"tst_qmljssimplereader.cpp" "4" "tst_qmljssimplereader.cpp" "4"
"qrc parser autotest" "3" "qrc parser autotest" "3"
"qrcparser.qbs:3" "4" "qrcparser.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13660,8 +13562,6 @@
"tst_qrcparser.cpp" "4" "tst_qrcparser.cpp" "4"
"sdktool autotest" "2" "sdktool autotest" "2"
"sdktool.qbs:3" "3" "sdktool.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13677,8 +13577,6 @@
"solutions.qbs:3" "3" "solutions.qbs:3" "3"
"Tasking autotest" "3" "Tasking autotest" "3"
"tasking.qbs:1" "4" "tasking.qbs:1" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13692,8 +13590,6 @@
"texteditor.qbs:3" "3" "texteditor.qbs:3" "3"
"Highlighter autotest" "3" "Highlighter autotest" "3"
"highlighter.qbs:3" "4" "highlighter.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Source Files" "4" "Source Files" "4"
"highlighter.qbs:11" "5" "highlighter.qbs:11" "5"
"tst_highlighter.cpp" "5" "tst_highlighter.cpp" "5"
@@ -13707,8 +13603,6 @@
"qtcreator_pch.h" "6" "qtcreator_pch.h" "6"
"ToolChainCache autotest" "2" "ToolChainCache autotest" "2"
"toolchaincache.qbs:3" "3" "toolchaincache.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13724,8 +13618,6 @@
"tracing.qbs:3" "3" "tracing.qbs:3" "3"
"FlameGraph autotest" "3" "FlameGraph autotest" "3"
"flamegraph.qbs:4" "4" "flamegraph.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13739,8 +13631,6 @@
"tst_flamegraph.cpp" "5" "tst_flamegraph.cpp" "5"
"FlameGraphView autotest" "3" "FlameGraphView autotest" "3"
"flamegraphview.qbs:4" "4" "flamegraphview.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"Qml Files" "4" "Qml Files" "4"
"flamegraphview.qbs:18" "5" "flamegraphview.qbs:18" "5"
"TestFlameGraphView.qml" "5" "TestFlameGraphView.qml" "5"
@@ -13758,8 +13648,6 @@
"tst_flamegraphview.cpp" "5" "tst_flamegraphview.cpp" "5"
"TimelineAbstractRenderer autotest" "3" "TimelineAbstractRenderer autotest" "3"
"timelineabstractrenderer.qbs:4" "4" "timelineabstractrenderer.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13773,8 +13661,6 @@
"tst_timelineabstractrenderer.cpp" "5" "tst_timelineabstractrenderer.cpp" "5"
"TimelineItemsRenderPass autotest" "3" "TimelineItemsRenderPass autotest" "3"
"timelineitemsrenderpass.qbs:5" "4" "timelineitemsrenderpass.qbs:5" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13788,8 +13674,6 @@
"tst_timelineitemsrenderpass.cpp" "5" "tst_timelineitemsrenderpass.cpp" "5"
"TimelineModel autotest" "3" "TimelineModel autotest" "3"
"timelinemodel.qbs:4" "4" "timelinemodel.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13803,8 +13687,6 @@
"tst_timelinemodel.cpp" "5" "tst_timelinemodel.cpp" "5"
"TimelineModelAggregator autotest" "3" "TimelineModelAggregator autotest" "3"
"timelinemodelaggregator.qbs:4" "4" "timelinemodelaggregator.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13818,8 +13700,6 @@
"tst_timelinemodelaggregator.cpp" "5" "tst_timelinemodelaggregator.cpp" "5"
"TimelineNotesModel autotest" "3" "TimelineNotesModel autotest" "3"
"timelinenotesmodel.qbs:4" "4" "timelinenotesmodel.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13833,8 +13713,6 @@
"tst_timelinenotesmodel.cpp" "5" "tst_timelinenotesmodel.cpp" "5"
"TimelineNotesRenderPass autotest" "3" "TimelineNotesRenderPass autotest" "3"
"timelinenotesrenderpass.qbs:5" "4" "timelinenotesrenderpass.qbs:5" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13848,8 +13726,6 @@
"tst_timelinenotesrenderpass.cpp" "5" "tst_timelinenotesrenderpass.cpp" "5"
"TimelineOverviewRenderer autotest" "3" "TimelineOverviewRenderer autotest" "3"
"timelineoverviewrenderer.qbs:4" "4" "timelineoverviewrenderer.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13863,8 +13739,6 @@
"tst_timelineoverviewrenderer.cpp" "5" "tst_timelineoverviewrenderer.cpp" "5"
"TimelineRenderer autotest" "3" "TimelineRenderer autotest" "3"
"timelinerenderer.qbs:4" "4" "timelinerenderer.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13878,8 +13752,6 @@
"tst_timelinerenderer.cpp" "5" "tst_timelinerenderer.cpp" "5"
"TimelineRenderPass autotest" "3" "TimelineRenderPass autotest" "3"
"timelinerenderpass.qbs:5" "4" "timelinerenderpass.qbs:5" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13893,8 +13765,6 @@
"tst_timelinerenderpass.cpp" "5" "tst_timelinerenderpass.cpp" "5"
"TimelineRenderState autotest" "3" "TimelineRenderState autotest" "3"
"timelinerenderstate.qbs:5" "4" "timelinerenderstate.qbs:5" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13908,8 +13778,6 @@
"tst_timelinerenderstate.cpp" "5" "tst_timelinerenderstate.cpp" "5"
"TimelineSelectionRenderPass autotest" "3" "TimelineSelectionRenderPass autotest" "3"
"timelineselectionrenderpass.qbs:5" "4" "timelineselectionrenderpass.qbs:5" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13923,8 +13791,6 @@
"tst_timelineselectionrenderpass.cpp" "5" "tst_timelineselectionrenderpass.cpp" "5"
"TimelineZoomcontrol autotest" "3" "TimelineZoomcontrol autotest" "3"
"timelinezoomcontrol.qbs:4" "4" "timelinezoomcontrol.qbs:4" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13938,8 +13804,6 @@
"tst_timelinezoomcontrol.cpp" "5" "tst_timelinezoomcontrol.cpp" "5"
"TreeViewFind autotest" "2" "TreeViewFind autotest" "2"
"treeviewfind.qbs:3" "3" "treeviewfind.qbs:3" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13951,8 +13815,6 @@
"tst_treeviewfind.cpp" "3" "tst_treeviewfind.cpp" "3"
"UpdateInfo autotest" "2" "UpdateInfo autotest" "2"
"updateinfo.qbs:1" "3" "updateinfo.qbs:1" "3"
"Group 1" "3"
"QtcProduct.qbs:68" "4"
"standard pch file (gui)" "3" "standard pch file (gui)" "3"
"QtcProduct.qbs:83" "4" "QtcProduct.qbs:83" "4"
"." "4" "." "4"
@@ -13966,8 +13828,6 @@
"utils.qbs:3" "3" "utils.qbs:3" "3"
"ANSI autotest" "3" "ANSI autotest" "3"
"ansiescapecodehandler.qbs:3" "4" "ansiescapecodehandler.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13979,8 +13839,6 @@
"tst_ansiescapecodehandler.cpp" "4" "tst_ansiescapecodehandler.cpp" "4"
"Async autotest" "3" "Async autotest" "3"
"async.qbs:3" "4" "async.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -13994,8 +13852,6 @@
"commandline.qbs:1" "4" "commandline.qbs:1" "4"
"CommandLine autotest" "4" "CommandLine autotest" "4"
"commandline.qbs:2" "5" "commandline.qbs:2" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -14009,8 +13865,6 @@
"deviceshell.qbs:1" "4" "deviceshell.qbs:1" "4"
"DeviceShell autotest" "4" "DeviceShell autotest" "4"
"deviceshell.qbs:2" "5" "deviceshell.qbs:2" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -14022,8 +13876,6 @@
"tst_deviceshell.cpp" "5" "tst_deviceshell.cpp" "5"
"Expected autotest" "3" "Expected autotest" "3"
"expected.qbs:3" "4" "expected.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14035,8 +13887,6 @@
"tst_expected.cpp" "4" "tst_expected.cpp" "4"
"FilePath autotest" "3" "FilePath autotest" "3"
"filepath.qbs:3" "4" "filepath.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14048,8 +13898,6 @@
"tst_filepath.cpp" "4" "tst_filepath.cpp" "4"
"FileUtils autotest" "3" "FileUtils autotest" "3"
"fileutils.qbs:3" "4" "fileutils.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14061,8 +13909,6 @@
"tst_fileutils.cpp" "4" "tst_fileutils.cpp" "4"
"FSEngine autotest" "3" "FSEngine autotest" "3"
"fsengine.qbs:3" "4" "fsengine.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14074,8 +13920,6 @@
"tst_fsengine.cpp" "4" "tst_fsengine.cpp" "4"
"FuzzyMatcher autotest" "3" "FuzzyMatcher autotest" "3"
"fuzzymatcher.qbs:3" "4" "fuzzymatcher.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14087,8 +13931,6 @@
"tst_fuzzymatcher.cpp" "4" "tst_fuzzymatcher.cpp" "4"
"IndexedContainerProxyConstIterator autotest" "3" "IndexedContainerProxyConstIterator autotest" "3"
"indexedcontainerproxyconstiterator.qbs:3" "4" "indexedcontainerproxyconstiterator.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14100,8 +13942,6 @@
"tst_indexedcontainerproxyconstiterator.cpp" "4" "tst_indexedcontainerproxyconstiterator.cpp" "4"
"MathUtils autotest" "3" "MathUtils autotest" "3"
"mathutils.qbs:3" "4" "mathutils.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14113,8 +13953,6 @@
"tst_mathutils.cpp" "4" "tst_mathutils.cpp" "4"
"MultiTextCursor autotest" "3" "MultiTextCursor autotest" "3"
"multicursor.qbs:3" "4" "multicursor.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14126,8 +13964,6 @@
"tst_multicursor.cpp" "4" "tst_multicursor.cpp" "4"
"PersistentSettings autotest" "3" "PersistentSettings autotest" "3"
"persistentsettings.qbs:3" "4" "persistentsettings.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14141,8 +13977,6 @@
"process.qbs:3" "4" "process.qbs:3" "4"
"Process autotest" "4" "Process autotest" "4"
"process.qbs:4" "5" "process.qbs:4" "5"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"standard pch file (gui)" "5" "standard pch file (gui)" "5"
"QtcProduct.qbs:83" "6" "QtcProduct.qbs:83" "6"
"." "6" "." "6"
@@ -14162,8 +13996,6 @@
"processtestapp.h" "5" "processtestapp.h" "5"
"Settings autotest" "3" "Settings autotest" "3"
"settings.qbs:3" "4" "settings.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14175,8 +14007,6 @@
"tst_settings.cpp" "4" "tst_settings.cpp" "4"
"StringUtils autotest" "3" "StringUtils autotest" "3"
"stringutils.qbs:3" "4" "stringutils.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14188,8 +14018,6 @@
"tst_stringutils.cpp" "4" "tst_stringutils.cpp" "4"
"TemplateEngine autotest" "3" "TemplateEngine autotest" "3"
"templateengine.qbs:3" "4" "templateengine.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14201,8 +14029,6 @@
"tst_templateengine.cpp" "4" "tst_templateengine.cpp" "4"
"Text autotest" "3" "Text autotest" "3"
"text.qbs:3" "4" "text.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14214,8 +14040,6 @@
"tst_text.cpp" "4" "tst_text.cpp" "4"
"TreeModel autotest" "3" "TreeModel autotest" "3"
"treemodel.qbs:3" "4" "treemodel.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14227,8 +14051,6 @@
"tst_treemodel.cpp" "4" "tst_treemodel.cpp" "4"
"UnixDeviceFileAccess autotest" "3" "UnixDeviceFileAccess autotest" "3"
"unixdevicefileaccess.qbs:3" "4" "unixdevicefileaccess.qbs:3" "4"
"Group 1" "4"
"QtcProduct.qbs:68" "5"
"standard pch file (gui)" "4" "standard pch file (gui)" "4"
"QtcProduct.qbs:83" "5" "QtcProduct.qbs:83" "5"
"." "5" "." "5"
@@ -14269,8 +14091,6 @@
"callgrindproxymodel.h" "6" "callgrindproxymodel.h" "6"
"callgrindstackbrowser.cpp" "6" "callgrindstackbrowser.cpp" "6"
"callgrindstackbrowser.h" "6" "callgrindstackbrowser.h" "6"
"Group 1" "5"
"QtcProduct.qbs:68" "6"
"Memcheck runner files from plugin" "5" "Memcheck runner files from plugin" "5"
"valgrindautotest.qbs:20" "6" "valgrindautotest.qbs:20" "6"
"Other files from plugin" "5" "Other files from plugin" "5"
@@ -14430,8 +14250,6 @@
"plugin3.h" "4" "plugin3.h" "4"
"Manual ProParser test" "2" "Manual ProParser test" "2"
"testreader.qbs:1" "3" "testreader.qbs:1" "3"
"Porting Helper" "3"
"testreader.qbs:51" "4"
"ProParser files" "3" "ProParser files" "3"
"testreader.qbs:23" "4" "testreader.qbs:23" "4"
"." "4" "." "4"
1 text nestinglevel
7678 mesonprojectmanager.qbs:3 3
7679 mesoninfoparser 3
7680 mesonprojectmanager.qbs:113 4
Group 1 4
QtcProduct.qbs:68 5
7681 standard pch file (gui) 4
7682 QtcProduct.qbs:83 5
7683 . 5
7697 toolwrapper.h 4
7698 mesonparser 3
7699 mesonprojectmanager.qbs:151 4
Group 1 4
QtcProduct.qbs:68 5
7700 standard pch file (gui) 4
7701 QtcProduct.qbs:83 5
7702 . 5
7797 versionhelper.h 4
7798 mesonwrapper 3
7799 mesonprojectmanager.qbs:93 4
Group 1 4
QtcProduct.qbs:68 5
7800 standard pch file (gui) 4
7801 QtcProduct.qbs:83 5
7802 . 5
7815 toolwrapper.h 4
7816 ninjaparser 3
7817 mesonprojectmanager.qbs:134 4
Group 1 4
QtcProduct.qbs:68 5
7818 standard pch file (gui) 4
7819 QtcProduct.qbs:83 5
7820 . 5
11721 proparser.qbs:3 2
11722 qtcjson 1
11723 json.qbs:3 2
Group 1 2
Library.qbs:81 3
11724 json.cpp 2
11725 json.h 2
11726 qtcreator 1
12857 auto.qbs:3 2
12858 Aggregation autotest 2
12859 aggregation.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
12860 standard pch file (gui) 3
12861 QtcProduct.qbs:83 4
12862 . 4
12868 tst_aggregate.cpp 3
12869 Algorithm autotest 2
12870 algorithm.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
12871 standard pch file (gui) 3
12872 QtcProduct.qbs:83 4
12873 . 4
12879 tst_algorithm.cpp 3
12880 Android AVD Manager autotest 2
12881 android.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
12882 Resource files 3
12883 android.qbs:25 4
12884 Test.avd 4
12904 tst_avdmanageroutputparser.cpp 4
12905 ChangeSet autotest 2
12906 changeset.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
12907 standard pch file (gui) 3
12908 QtcProduct.qbs:83 4
12909 . 4
12920 Data Files 4
12921 c99.qbs:11 5
12922 designatedInitializer.1.c 5
Group 1 4
QtcProduct.qbs:68 5
12923 Source Files 4
12924 c99.qbs:6 5
12925 tst_c99.cpp 5
12933 qtcreator_pch.h 6
12934 CPlusPlus AST autotest 3
12935 ast.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12936 standard pch file (gui) 4
12937 QtcProduct.qbs:83 5
12938 . 5
12944 tst_ast.cpp 4
12945 CPlusPlus check symbols autotest 3
12946 checksymbols.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12947 standard pch file (gui) 4
12948 QtcProduct.qbs:83 5
12949 . 5
12957 tst_checksymbols.cpp 4
12958 CPlusPlus code formatter autotest 3
12959 codeformatter.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12960 standard pch file (gui) 4
12961 QtcProduct.qbs:83 5
12962 . 5
12968 tst_codeformatter.cpp 4
12969 CPlusPlus fileiterationorder autotest 3
12970 fileiterationorder.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12971 standard pch file (gui) 4
12972 QtcProduct.qbs:83 5
12973 . 5
12979 tst_fileiterationorder.cpp 4
12980 CPlusPlus find usages autotest 3
12981 findusages.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12982 standard pch file (gui) 4
12983 QtcProduct.qbs:83 5
12984 . 5
12992 tst_findusages.cpp 4
12993 CPlusPlus lexer autotest 3
12994 lexer.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
12995 standard pch file (gui) 4
12996 QtcProduct.qbs:83 5
12997 . 5
13005 tst_lexer.cpp 4
13006 CPlusPlus lookup autotest 3
13007 lookup.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13008 standard pch file (gui) 4
13009 QtcProduct.qbs:83 5
13010 . 5
13016 tst_lookup.cpp 4
13017 CPlusPlus miscellaneous autotest 3
13018 misc.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13019 standard pch file (gui) 4
13020 QtcProduct.qbs:83 5
13021 . 5
13056 recursive.1.out.cpp 5
13057 reserved.1.cpp 5
13058 reserved.1.out.cpp 5
Group 1 4
QtcProduct.qbs:68 5
13059 Source Files 4
13060 preprocessor.qbs:6 5
13061 tst_preprocessor.cpp 5
13069 qtcreator_pch.h 6
13070 CPlusPlus pretty printer autotest 3
13071 typeprettyprinter.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13072 standard pch file (gui) 4
13073 QtcProduct.qbs:83 5
13074 . 5
13083 Data Files 4
13084 cppselectionchanger.qbs:12 5
13085 testCppFile.cpp 5
Group 1 4
QtcProduct.qbs:68 5
13086 Source Files 4
13087 cppselectionchanger.qbs:7 5
13088 tst_cppselectionchangertest.cpp 5
13096 qtcreator_pch.h 6
13097 CPlusPlus semantic autotest 3
13098 semantic.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13099 standard pch file (gui) 4
13100 QtcProduct.qbs:83 5
13101 . 5
13107 tst_semantic.cpp 4
13108 CPlusPlus translation unit autotest 3
13109 translationunit.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13110 standard pch file (gui) 4
13111 QtcProduct.qbs:83 5
13112 . 5
13128 noExcept.1.errors.txt 5
13129 staticAssert.1.cpp 5
13130 staticAssert.1.errors.txt 5
Group 1 4
QtcProduct.qbs:68 5
13131 Source Files 4
13132 cxx11.qbs:6 5
13133 tst_cxx11.cpp 5
13141 qtcreator_pch.h 6
13142 declaration comments autotest 3
13143 declarationcomments.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13144 standard pch file (gui) 4
13145 QtcProduct.qbs:83 5
13146 . 5
13154 debugger.qbs:3 3
13155 Debugger dumpers autotest 3
13156 dumpers.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13157 Sources from Debugger plugin 4
13158 dumpers.qbs:8 5
13159 debuggerprotocol.cpp 5
13178 tst_dumpers.cpp 5
13179 debugger protocol autotest 3
13180 protocol.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13181 Sources from Debugger plugin 4
13182 protocol.qbs:7 5
13183 debuggerprotocol.cpp 5
13195 tst_protocol.cpp 5
13196 disassembler autotest 3
13197 disassembler.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13198 Sources from Debugger plugin 4
13199 disassembler.qbs:5 5
13200 disassemblerlines.cpp 5
13211 tst_disassembler.cpp 5
13212 gdb autotest 3
13213 gdb.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13214 Sources from Debugger plugin 4
13215 gdb.qbs:7 5
13216 debuggerprotocol.cpp 5
13228 tst_gdb.cpp 5
13229 offsets autotest 3
13230 offsets.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13231 standard pch file (gui) 4
13232 QtcProduct.qbs:83 5
13233 . 5
13241 tst_offsets.cpp 5
13242 simplifytypes autotest 3
13243 simplifytypes.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13244 Sources from Debugger plugin 4
13245 simplifytypes.qbs:6 5
13246 simplifytype.cpp 5
13259 diff.qbs:3 3
13260 Differ autotest 3
13261 differ.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13262 standard pch file (gui) 4
13263 QtcProduct.qbs:83 5
13264 . 5
13270 tst_differ.cpp 4
13271 Environment autotest 2
13272 environment.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13273 standard pch file (gui) 3
13274 QtcProduct.qbs:83 4
13275 . 4
13281 tst_environment.cpp 3
13282 Examples autotest 2
13283 examples.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13284 standard pch file (gui) 3
13285 QtcProduct.qbs:83 4
13286 . 4
13296 pluginspec.qbs:3 4
13297 ExtensionSystem pluginspec autotest 4
13298 test.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13299 Sources 5
13300 test.qbs:7 6
13301 tst_pluginspec.cpp 6
13365 plugin3.h 6
13366 PluginManager autotest 4
13367 test.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13368 standard pch file (gui) 5
13369 QtcProduct.qbs:83 6
13370 . 6
13376 tst_pluginmanager.cpp 5
13377 ExternalTool autotest 2
13378 externaltool.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13379 standard pch file (gui) 3
13380 QtcProduct.qbs:83 4
13381 . 4
13389 tst_externaltooltest.cpp 4
13390 File search autotest 2
13391 filesearch.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13392 standard pch file (gui) 3
13393 QtcProduct.qbs:83 4
13394 . 4
13404 testfile.txt 5
13405 json autotest 2
13406 json.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13407 standard pch file (gui) 3
13408 QtcProduct.qbs:83 4
13409 . 4
13422 tst_json.cpp 3
13423 Language Server Protocol autotest 2
13424 languageserverprotocol.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13425 standard pch file (gui) 3
13426 QtcProduct.qbs:83 4
13427 . 4
13433 tst_languageserverprotocol.cpp 3
13434 ProFileWriter autotest 2
13435 profilewriter.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13436 Sources from ProParser 3
13437 profilewriter.qbs:7 4
13438 ioutils.cpp 4
13471 codemodel.qbs:3 4
13472 QML code model check autotest 4
13473 check.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13474 standard pch file (gui) 5
13475 QtcProduct.qbs:83 6
13476 . 6
13482 tst_check.cpp 5
13483 QML code model dependencies autotest 4
13484 dependencies.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13485 standard pch file (gui) 5
13486 QtcProduct.qbs:83 6
13487 . 6
13493 tst_dependencies.cpp 5
13494 QML code model imports check autotest 4
13495 importscheck.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13496 standard pch file (gui) 5
13497 QtcProduct.qbs:83 6
13498 . 6
13506 qmleditor.qbs:3 4
13507 QML code formatter autotest 4
13508 qmlcodeformatter.qbs:3 5
Group 1 5
QtcProduct.qbs:68 6
13509 standard pch file (gui) 5
13510 QtcProduct.qbs:83 6
13511 . 6
13517 tst_qmlcodeformatter.cpp 5
13518 QML persistenttrie autotest 3
13519 persistenttrie.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13520 standard pch file (gui) 4
13521 QtcProduct.qbs:83 5
13522 . 5
13529 tst_testtrie.h 4
13530 QML reformatter autotest 3
13531 reformatter.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13532 standard pch file (gui) 4
13533 QtcProduct.qbs:83 5
13534 . 5
13540 tst_reformatter.cpp 4
13541 QMLJS simple reader autotest 3
13542 qmljssimplereader.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13543 standard pch file (gui) 4
13544 QtcProduct.qbs:83 5
13545 . 5
13551 tst_qmljssimplereader.cpp 4
13552 qrc parser autotest 3
13553 qrcparser.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13554 standard pch file (gui) 4
13555 QtcProduct.qbs:83 5
13556 . 5
13562 tst_qrcparser.cpp 4
13563 sdktool autotest 2
13564 sdktool.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13565 standard pch file (gui) 3
13566 QtcProduct.qbs:83 4
13567 . 4
13577 solutions.qbs:3 3
13578 Tasking autotest 3
13579 tasking.qbs:1 4
Group 1 4
QtcProduct.qbs:68 5
13580 standard pch file (gui) 4
13581 QtcProduct.qbs:83 5
13582 . 5
13590 texteditor.qbs:3 3
13591 Highlighter autotest 3
13592 highlighter.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13593 Source Files 4
13594 highlighter.qbs:11 5
13595 tst_highlighter.cpp 5
13603 qtcreator_pch.h 6
13604 ToolChainCache autotest 2
13605 toolchaincache.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13606 standard pch file (gui) 3
13607 QtcProduct.qbs:83 4
13608 . 4
13618 tracing.qbs:3 3
13619 FlameGraph autotest 3
13620 flamegraph.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13621 standard pch file (gui) 4
13622 QtcProduct.qbs:83 5
13623 . 5
13631 tst_flamegraph.cpp 5
13632 FlameGraphView autotest 3
13633 flamegraphview.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13634 Qml Files 4
13635 flamegraphview.qbs:18 5
13636 TestFlameGraphView.qml 5
13648 tst_flamegraphview.cpp 5
13649 TimelineAbstractRenderer autotest 3
13650 timelineabstractrenderer.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13651 standard pch file (gui) 4
13652 QtcProduct.qbs:83 5
13653 . 5
13661 tst_timelineabstractrenderer.cpp 5
13662 TimelineItemsRenderPass autotest 3
13663 timelineitemsrenderpass.qbs:5 4
Group 1 4
QtcProduct.qbs:68 5
13664 standard pch file (gui) 4
13665 QtcProduct.qbs:83 5
13666 . 5
13674 tst_timelineitemsrenderpass.cpp 5
13675 TimelineModel autotest 3
13676 timelinemodel.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13677 standard pch file (gui) 4
13678 QtcProduct.qbs:83 5
13679 . 5
13687 tst_timelinemodel.cpp 5
13688 TimelineModelAggregator autotest 3
13689 timelinemodelaggregator.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13690 standard pch file (gui) 4
13691 QtcProduct.qbs:83 5
13692 . 5
13700 tst_timelinemodelaggregator.cpp 5
13701 TimelineNotesModel autotest 3
13702 timelinenotesmodel.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13703 standard pch file (gui) 4
13704 QtcProduct.qbs:83 5
13705 . 5
13713 tst_timelinenotesmodel.cpp 5
13714 TimelineNotesRenderPass autotest 3
13715 timelinenotesrenderpass.qbs:5 4
Group 1 4
QtcProduct.qbs:68 5
13716 standard pch file (gui) 4
13717 QtcProduct.qbs:83 5
13718 . 5
13726 tst_timelinenotesrenderpass.cpp 5
13727 TimelineOverviewRenderer autotest 3
13728 timelineoverviewrenderer.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13729 standard pch file (gui) 4
13730 QtcProduct.qbs:83 5
13731 . 5
13739 tst_timelineoverviewrenderer.cpp 5
13740 TimelineRenderer autotest 3
13741 timelinerenderer.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13742 standard pch file (gui) 4
13743 QtcProduct.qbs:83 5
13744 . 5
13752 tst_timelinerenderer.cpp 5
13753 TimelineRenderPass autotest 3
13754 timelinerenderpass.qbs:5 4
Group 1 4
QtcProduct.qbs:68 5
13755 standard pch file (gui) 4
13756 QtcProduct.qbs:83 5
13757 . 5
13765 tst_timelinerenderpass.cpp 5
13766 TimelineRenderState autotest 3
13767 timelinerenderstate.qbs:5 4
Group 1 4
QtcProduct.qbs:68 5
13768 standard pch file (gui) 4
13769 QtcProduct.qbs:83 5
13770 . 5
13778 tst_timelinerenderstate.cpp 5
13779 TimelineSelectionRenderPass autotest 3
13780 timelineselectionrenderpass.qbs:5 4
Group 1 4
QtcProduct.qbs:68 5
13781 standard pch file (gui) 4
13782 QtcProduct.qbs:83 5
13783 . 5
13791 tst_timelineselectionrenderpass.cpp 5
13792 TimelineZoomcontrol autotest 3
13793 timelinezoomcontrol.qbs:4 4
Group 1 4
QtcProduct.qbs:68 5
13794 standard pch file (gui) 4
13795 QtcProduct.qbs:83 5
13796 . 5
13804 tst_timelinezoomcontrol.cpp 5
13805 TreeViewFind autotest 2
13806 treeviewfind.qbs:3 3
Group 1 3
QtcProduct.qbs:68 4
13807 standard pch file (gui) 3
13808 QtcProduct.qbs:83 4
13809 . 4
13815 tst_treeviewfind.cpp 3
13816 UpdateInfo autotest 2
13817 updateinfo.qbs:1 3
Group 1 3
QtcProduct.qbs:68 4
13818 standard pch file (gui) 3
13819 QtcProduct.qbs:83 4
13820 . 4
13828 utils.qbs:3 3
13829 ANSI autotest 3
13830 ansiescapecodehandler.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13831 standard pch file (gui) 4
13832 QtcProduct.qbs:83 5
13833 . 5
13839 tst_ansiescapecodehandler.cpp 4
13840 Async autotest 3
13841 async.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13842 standard pch file (gui) 4
13843 QtcProduct.qbs:83 5
13844 . 5
13852 commandline.qbs:1 4
13853 CommandLine autotest 4
13854 commandline.qbs:2 5
Group 1 5
QtcProduct.qbs:68 6
13855 standard pch file (gui) 5
13856 QtcProduct.qbs:83 6
13857 . 6
13865 deviceshell.qbs:1 4
13866 DeviceShell autotest 4
13867 deviceshell.qbs:2 5
Group 1 5
QtcProduct.qbs:68 6
13868 standard pch file (gui) 5
13869 QtcProduct.qbs:83 6
13870 . 6
13876 tst_deviceshell.cpp 5
13877 Expected autotest 3
13878 expected.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13879 standard pch file (gui) 4
13880 QtcProduct.qbs:83 5
13881 . 5
13887 tst_expected.cpp 4
13888 FilePath autotest 3
13889 filepath.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13890 standard pch file (gui) 4
13891 QtcProduct.qbs:83 5
13892 . 5
13898 tst_filepath.cpp 4
13899 FileUtils autotest 3
13900 fileutils.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13901 standard pch file (gui) 4
13902 QtcProduct.qbs:83 5
13903 . 5
13909 tst_fileutils.cpp 4
13910 FSEngine autotest 3
13911 fsengine.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13912 standard pch file (gui) 4
13913 QtcProduct.qbs:83 5
13914 . 5
13920 tst_fsengine.cpp 4
13921 FuzzyMatcher autotest 3
13922 fuzzymatcher.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13923 standard pch file (gui) 4
13924 QtcProduct.qbs:83 5
13925 . 5
13931 tst_fuzzymatcher.cpp 4
13932 IndexedContainerProxyConstIterator autotest 3
13933 indexedcontainerproxyconstiterator.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13934 standard pch file (gui) 4
13935 QtcProduct.qbs:83 5
13936 . 5
13942 tst_indexedcontainerproxyconstiterator.cpp 4
13943 MathUtils autotest 3
13944 mathutils.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13945 standard pch file (gui) 4
13946 QtcProduct.qbs:83 5
13947 . 5
13953 tst_mathutils.cpp 4
13954 MultiTextCursor autotest 3
13955 multicursor.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13956 standard pch file (gui) 4
13957 QtcProduct.qbs:83 5
13958 . 5
13964 tst_multicursor.cpp 4
13965 PersistentSettings autotest 3
13966 persistentsettings.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13967 standard pch file (gui) 4
13968 QtcProduct.qbs:83 5
13969 . 5
13977 process.qbs:3 4
13978 Process autotest 4
13979 process.qbs:4 5
Group 1 5
QtcProduct.qbs:68 6
13980 standard pch file (gui) 5
13981 QtcProduct.qbs:83 6
13982 . 6
13996 processtestapp.h 5
13997 Settings autotest 3
13998 settings.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
13999 standard pch file (gui) 4
14000 QtcProduct.qbs:83 5
14001 . 5
14007 tst_settings.cpp 4
14008 StringUtils autotest 3
14009 stringutils.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
14010 standard pch file (gui) 4
14011 QtcProduct.qbs:83 5
14012 . 5
14018 tst_stringutils.cpp 4
14019 TemplateEngine autotest 3
14020 templateengine.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
14021 standard pch file (gui) 4
14022 QtcProduct.qbs:83 5
14023 . 5
14029 tst_templateengine.cpp 4
14030 Text autotest 3
14031 text.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
14032 standard pch file (gui) 4
14033 QtcProduct.qbs:83 5
14034 . 5
14040 tst_text.cpp 4
14041 TreeModel autotest 3
14042 treemodel.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
14043 standard pch file (gui) 4
14044 QtcProduct.qbs:83 5
14045 . 5
14051 tst_treemodel.cpp 4
14052 UnixDeviceFileAccess autotest 3
14053 unixdevicefileaccess.qbs:3 4
Group 1 4
QtcProduct.qbs:68 5
14054 standard pch file (gui) 4
14055 QtcProduct.qbs:83 5
14056 . 5
14091 callgrindproxymodel.h 6
14092 callgrindstackbrowser.cpp 6
14093 callgrindstackbrowser.h 6
Group 1 5
QtcProduct.qbs:68 6
14094 Memcheck runner files from plugin 5
14095 valgrindautotest.qbs:20 6
14096 Other files from plugin 5
14250 plugin3.h 4
14251 Manual ProParser test 2
14252 testreader.qbs:1 3
Porting Helper 3
testreader.qbs:51 4
14253 ProParser files 3
14254 testreader.qbs:23 4
14255 . 4