forked from qt-creator/qt-creator
Utils: Add a CommandLine::splitArguments() convenience function
... and use it from within new SynchronousProcess functions taking CommandLine arguments. Change-Id: I5d7f83727cbb22f03b1a79b1645db95514c66033 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -95,6 +95,11 @@ QString CommandLine::toUserOutput() const
|
|||||||
return m_executable.toUserOutput() + ' ' + m_arguments;
|
return m_executable.toUserOutput() + ' ' + m_arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList CommandLine::splitArguments(OsType osType) const
|
||||||
|
{
|
||||||
|
return QtcProcess::splitArgs(m_arguments, osType);
|
||||||
|
}
|
||||||
|
|
||||||
/*! \class Utils::FileUtils
|
/*! \class Utils::FileUtils
|
||||||
|
|
||||||
\brief The FileUtils class contains file and directory related convenience
|
\brief The FileUtils class contains file and directory related convenience
|
||||||
|
@@ -145,6 +145,7 @@ public:
|
|||||||
|
|
||||||
FilePath executable() const { return m_executable; }
|
FilePath executable() const { return m_executable; }
|
||||||
QString arguments() const { return m_arguments; }
|
QString arguments() const { return m_arguments; }
|
||||||
|
QStringList splitArguments(OsType osType = HostOsInfo::hostOs()) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilePath m_executable;
|
FilePath m_executable;
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "synchronousprocess.h"
|
#include "synchronousprocess.h"
|
||||||
#include "qtcassert.h"
|
#include "qtcassert.h"
|
||||||
#include "hostosinfo.h"
|
#include "hostosinfo.h"
|
||||||
|
#include "fileutils.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -266,7 +267,7 @@ public:
|
|||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
QEventLoop m_eventLoop;
|
QEventLoop m_eventLoop;
|
||||||
SynchronousProcessResponse m_result;
|
SynchronousProcessResponse m_result;
|
||||||
QString m_binary;
|
FilePath m_binary;
|
||||||
ChannelBuffer m_stdOut;
|
ChannelBuffer m_stdOut;
|
||||||
ChannelBuffer m_stdErr;
|
ChannelBuffer m_stdErr;
|
||||||
ExitCodeInterpreter m_exitCodeInterpreter = defaultExitCodeInterpreter;
|
ExitCodeInterpreter m_exitCodeInterpreter = defaultExitCodeInterpreter;
|
||||||
@@ -288,7 +289,7 @@ void SynchronousProcessPrivate::clearForRun()
|
|||||||
m_result.clear();
|
m_result.clear();
|
||||||
m_result.codec = m_codec;
|
m_result.codec = m_codec;
|
||||||
m_startFailure = false;
|
m_startFailure = false;
|
||||||
m_binary.clear();
|
m_binary = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------- SynchronousProcess
|
// ----------- SynchronousProcess
|
||||||
@@ -444,21 +445,29 @@ static bool isGuiThread()
|
|||||||
SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
|
SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
|
||||||
const QStringList &args,
|
const QStringList &args,
|
||||||
const QByteArray &writeData)
|
const QByteArray &writeData)
|
||||||
|
{
|
||||||
|
CommandLine cmd(FilePath::fromString(binary), {});
|
||||||
|
cmd.addArgs(args);
|
||||||
|
return run(cmd, writeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
SynchronousProcessResponse SynchronousProcess::run(const CommandLine &cmd,
|
||||||
|
const QByteArray &writeData)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << '>' << Q_FUNC_INFO << binary << args;
|
qDebug() << '>' << Q_FUNC_INFO << cmd.toUserOutput();
|
||||||
|
|
||||||
d->clearForRun();
|
d->clearForRun();
|
||||||
|
|
||||||
// On Windows, start failure is triggered immediately if the
|
// On Windows, start failure is triggered immediately if the
|
||||||
// executable cannot be found in the path. Do not start the
|
// executable cannot be found in the path. Do not start the
|
||||||
// event loop in that case.
|
// event loop in that case.
|
||||||
d->m_binary = binary;
|
d->m_binary = cmd.executable();
|
||||||
// using QProcess::start() and passing program, args and OpenMode results in a different
|
// using QProcess::start() and passing program, args and OpenMode results in a different
|
||||||
// quoting of arguments than using QProcess::setArguments() beforehand and calling start()
|
// quoting of arguments than using QProcess::setArguments() beforehand and calling start()
|
||||||
// only with the OpenMode
|
// only with the OpenMode
|
||||||
d->m_process.setProgram(binary);
|
d->m_process.setProgram(cmd.executable().toString());
|
||||||
d->m_process.setArguments(args);
|
d->m_process.setArguments(cmd.splitArguments());
|
||||||
connect(&d->m_process, &QProcess::started, this, [this, writeData] {
|
connect(&d->m_process, &QProcess::started, this, [this, writeData] {
|
||||||
if (!writeData.isEmpty()) {
|
if (!writeData.isEmpty()) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
@@ -493,19 +502,27 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << '<' << Q_FUNC_INFO << binary << d->m_result;
|
qDebug() << '<' << Q_FUNC_INFO << cmd.executable().toString() << d->m_result;
|
||||||
return d->m_result;
|
return d->m_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronousProcessResponse SynchronousProcess::runBlocking(const QString &binary, const QStringList &args)
|
SynchronousProcessResponse
|
||||||
|
SynchronousProcess::runBlocking(const QString &binary, const QStringList &args)
|
||||||
|
{
|
||||||
|
CommandLine cmd(FilePath::fromString(binary), {});
|
||||||
|
cmd.addArgs(args);
|
||||||
|
return runBlocking(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
SynchronousProcessResponse SynchronousProcess::runBlocking(const CommandLine &cmd)
|
||||||
{
|
{
|
||||||
d->clearForRun();
|
d->clearForRun();
|
||||||
|
|
||||||
// On Windows, start failure is triggered immediately if the
|
// On Windows, start failure is triggered immediately if the
|
||||||
// executable cannot be found in the path. Do not start the
|
// executable cannot be found in the path. Do not start the
|
||||||
// event loop in that case.
|
// event loop in that case.
|
||||||
d->m_binary = binary;
|
d->m_binary = cmd.executable();
|
||||||
d->m_process.start(binary, args, QIODevice::ReadOnly);
|
d->m_process.start(cmd.executable().toString(), cmd.splitArguments(), QIODevice::ReadOnly);
|
||||||
if (!d->m_process.waitForStarted(d->m_maxHangTimerCount * 1000)
|
if (!d->m_process.waitForStarted(d->m_maxHangTimerCount * 1000)
|
||||||
&& d->m_process.state() == QProcess::NotRunning) {
|
&& d->m_process.state() == QProcess::NotRunning) {
|
||||||
d->m_result.result = SynchronousProcessResponse::StartFailed;
|
d->m_result.result = SynchronousProcessResponse::StartFailed;
|
||||||
@@ -573,7 +590,7 @@ void SynchronousProcess::slotTimeout()
|
|||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << Q_FUNC_INFO << "HANG detected, killing";
|
qDebug() << Q_FUNC_INFO << "HANG detected, killing";
|
||||||
d->m_waitingForUser = true;
|
d->m_waitingForUser = true;
|
||||||
const bool terminate = !d->m_timeOutMessageBoxEnabled || askToKill(d->m_binary);
|
const bool terminate = !d->m_timeOutMessageBoxEnabled || askToKill(d->m_binary.toString());
|
||||||
d->m_waitingForUser = false;
|
d->m_waitingForUser = false;
|
||||||
if (terminate) {
|
if (terminate) {
|
||||||
SynchronousProcess::stopProcess(d->m_process);
|
SynchronousProcess::stopProcess(d->m_process);
|
||||||
|
@@ -38,6 +38,7 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
|
|||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
class SynchronousProcessPrivate;
|
class SynchronousProcessPrivate;
|
||||||
|
class CommandLine;
|
||||||
|
|
||||||
/* Result of SynchronousProcess execution */
|
/* Result of SynchronousProcess execution */
|
||||||
class QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
|
class QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
|
||||||
@@ -126,10 +127,16 @@ public:
|
|||||||
void setExitCodeInterpreter(const ExitCodeInterpreter &interpreter);
|
void setExitCodeInterpreter(const ExitCodeInterpreter &interpreter);
|
||||||
ExitCodeInterpreter exitCodeInterpreter() const;
|
ExitCodeInterpreter exitCodeInterpreter() const;
|
||||||
|
|
||||||
// Starts an nested event loop and runs the binary with the arguments
|
// Starts a nested event loop and runs the binary with the arguments
|
||||||
|
// FIXME: Use the CommandLine overload below.
|
||||||
SynchronousProcessResponse run(const QString &binary, const QStringList &args, const QByteArray &writeData = {});
|
SynchronousProcessResponse run(const QString &binary, const QStringList &args, const QByteArray &writeData = {});
|
||||||
|
// Starts a nested event loop and runs the command
|
||||||
|
SynchronousProcessResponse run(const CommandLine &cmd, const QByteArray &writeData = {});
|
||||||
// Starts the binary with the arguments blocking the UI fully
|
// Starts the binary with the arguments blocking the UI fully
|
||||||
|
// FIXME: Use the CommandLine overload below.
|
||||||
SynchronousProcessResponse runBlocking(const QString &binary, const QStringList &args);
|
SynchronousProcessResponse runBlocking(const QString &binary, const QStringList &args);
|
||||||
|
// Starts the command blocking the UI fully
|
||||||
|
SynchronousProcessResponse runBlocking(const CommandLine &cmd);
|
||||||
|
|
||||||
// Create a (derived) processes with flags applied.
|
// Create a (derived) processes with flags applied.
|
||||||
static QSharedPointer<QProcess> createProcess(unsigned flags);
|
static QSharedPointer<QProcess> createProcess(unsigned flags);
|
||||||
|
Reference in New Issue
Block a user