forked from qt-creator/qt-creator
QtcProcess: Introduce a QtcProcess::Arguments class
This is used to get a platform-agnostic handle on "command line arguments". It essentially wraps a single QString on Windows, and a QStringList everywhere else. As a consequence, several occurrences of #ifdef Q_OS_* can be removed from the codebase. Change-Id: Ic93118c1bd0bce0ebb58f416d395dbaebb861772 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
@@ -75,7 +75,8 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
|
||||
return false;
|
||||
|
||||
QtcProcess::SplitError perr;
|
||||
QStringList pargs = QtcProcess::prepareArgs(args, &perr, &d->m_environment, &d->m_workingDir);
|
||||
QtcProcess::Arguments pargs = QtcProcess::prepareArgs(args, &perr, HostOsInfo::hostOs(),
|
||||
&d->m_environment, &d->m_workingDir);
|
||||
QString pcmd;
|
||||
if (perr == QtcProcess::SplitOk) {
|
||||
pcmd = program;
|
||||
@@ -91,11 +92,14 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
|
||||
return false;
|
||||
}
|
||||
pcmd = QLatin1String("/bin/sh");
|
||||
pargs << QLatin1String("-c") << (QtcProcess::quoteArg(program) + QLatin1Char(' ') + args);
|
||||
pargs = QtcProcess::Arguments::createUnixArgs(QStringList()
|
||||
<< QLatin1String("-c")
|
||||
<< (QtcProcess::quoteArg(program) + QLatin1Char(' ') + args));
|
||||
}
|
||||
|
||||
QtcProcess::SplitError qerr;
|
||||
QStringList xtermArgs = QtcProcess::prepareArgs(terminalEmulator(d->m_settings), &qerr,
|
||||
QtcProcess::Arguments xtermArgs = QtcProcess::prepareArgs(terminalEmulator(d->m_settings), &qerr,
|
||||
HostOsInfo::hostOs(),
|
||||
&d->m_environment, &d->m_workingDir);
|
||||
if (qerr != QtcProcess::SplitOk) {
|
||||
emit processError(qerr == QtcProcess::BadQuoting
|
||||
@@ -134,23 +138,23 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils::HostOsInfo::isMacHost()) {
|
||||
xtermArgs << (QCoreApplication::applicationDirPath()
|
||||
+ QLatin1String("/../Resources/qtcreator_process_stub"));
|
||||
} else {
|
||||
xtermArgs << (QCoreApplication::applicationDirPath()
|
||||
+ QLatin1String("/qtcreator_process_stub"));
|
||||
}
|
||||
xtermArgs
|
||||
QString stubPath = QCoreApplication::applicationDirPath();
|
||||
if (Utils::HostOsInfo::isMacHost())
|
||||
stubPath.append(QLatin1String("/../Resources/qtcreator_process_stub"));
|
||||
else
|
||||
stubPath.append(QLatin1String("/qtcreator_process_stub"));
|
||||
|
||||
QStringList allArgs = xtermArgs.toUnixArgs();
|
||||
allArgs << stubPath
|
||||
<< modeOption(d->m_mode)
|
||||
<< d->m_stubServer.fullServerName()
|
||||
<< msgPromptToClose()
|
||||
<< workingDirectory()
|
||||
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString())
|
||||
<< pcmd << pargs;
|
||||
<< pcmd << pargs.toUnixArgs();
|
||||
|
||||
QString xterm = xtermArgs.takeFirst();
|
||||
d->m_process.start(xterm, xtermArgs);
|
||||
QString xterm = allArgs.takeFirst();
|
||||
d->m_process.start(xterm, allArgs);
|
||||
if (!d->m_process.waitForStarted()) {
|
||||
stubServerShutdown();
|
||||
emit processError(tr("Cannot start the terminal emulator '%1', change the setting in the "
|
||||
|
@@ -75,7 +75,10 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
|
||||
pcmd = program;
|
||||
pargs = args;
|
||||
} else {
|
||||
QtcProcess::prepareCommand(program, args, &pcmd, &pargs, &d->m_environment, &d->m_workingDir);
|
||||
QtcProcess::Arguments outArgs;
|
||||
QtcProcess::prepareCommand(program, args, &pcmd, &outArgs, OsTypeWindows,
|
||||
&d->m_environment, &d->m_workingDir);
|
||||
pargs = outArgs.toWindowsArgs();
|
||||
}
|
||||
|
||||
const QString err = stubServerListen();
|
||||
|
@@ -31,16 +31,43 @@
|
||||
#include "stringutils.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QStack>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <qt_windows.h>
|
||||
#endif
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
// The main state of the Unix shell parser
|
||||
enum MxQuoting { MxBasic, MxSingleQuote, MxDoubleQuote, MxParen, MxSubst, MxGroup, MxMath };
|
||||
|
||||
struct MxState
|
||||
{
|
||||
MxQuoting current;
|
||||
// Bizarrely enough, double quoting has an impact on the behavior of some
|
||||
// complex expressions within the quoted string.
|
||||
bool dquote;
|
||||
};
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(MxState, Q_PRIMITIVE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
// Pushed state for the case where a $(()) expansion turns out bogus
|
||||
struct MxSave
|
||||
{
|
||||
QString str;
|
||||
int pos, varPos;
|
||||
};
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(MxSave, Q_MOVABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
|
||||
/*!
|
||||
\class Utils::QtcProcess
|
||||
@@ -49,9 +76,7 @@ using namespace Utils;
|
||||
shell-quoted process arguments.
|
||||
*/
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
inline static bool isMetaChar(ushort c)
|
||||
inline static bool isMetaCharWin(ushort c)
|
||||
{
|
||||
static const uchar iqm[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0x00, 0x50,
|
||||
@@ -61,7 +86,7 @@ inline static bool isMetaChar(ushort c)
|
||||
return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
|
||||
}
|
||||
|
||||
static void envExpand(QString &args, const Environment *env, const QString *pwd)
|
||||
static void envExpandWin(QString &args, const Environment *env, const QString *pwd)
|
||||
{
|
||||
static const QString cdName = QLatin1String("CD");
|
||||
int off = 0;
|
||||
@@ -82,18 +107,18 @@ static void envExpand(QString &args, const Environment *env, const QString *pwd)
|
||||
}
|
||||
}
|
||||
|
||||
QString QtcProcess::prepareArgs(const QString &_args, SplitError *err,
|
||||
static QtcProcess::Arguments prepareArgsWin(const QString &_args, QtcProcess::SplitError *err,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
QString args(_args);
|
||||
|
||||
if (env) {
|
||||
envExpand(args, env, pwd);
|
||||
envExpandWin(args, env, pwd);
|
||||
} else {
|
||||
if (args.indexOf(QLatin1Char('%')) >= 0) {
|
||||
if (err)
|
||||
*err = FoundMeta;
|
||||
return QString();
|
||||
*err = QtcProcess::FoundMeta;
|
||||
return QtcProcess::Arguments::createWindowsArgs(QString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,24 +134,24 @@ QString QtcProcess::prepareArgs(const QString &_args, SplitError *err,
|
||||
if (++p == args.length())
|
||||
break; // For cmd, this is no error.
|
||||
} while (args.unicode()[p].unicode() != '"');
|
||||
} else if (isMetaChar(c)) {
|
||||
} else if (isMetaCharWin(c)) {
|
||||
if (err)
|
||||
*err = FoundMeta;
|
||||
return QString();
|
||||
*err = QtcProcess::FoundMeta;
|
||||
return QtcProcess::Arguments::createWindowsArgs(QString());
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
*err = SplitOk;
|
||||
return args;
|
||||
*err = QtcProcess::SplitOk;
|
||||
return QtcProcess::Arguments::createWindowsArgs(args);
|
||||
}
|
||||
|
||||
inline static bool isWhiteSpace(ushort c)
|
||||
inline static bool isWhiteSpaceWin(ushort c)
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
static QStringList doSplitArgs(const QString &args, QtcProcess::SplitError *err)
|
||||
static QStringList doSplitArgsWin(const QString &args, QtcProcess::SplitError *err)
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
@@ -139,7 +164,7 @@ static QStringList doSplitArgs(const QString &args, QtcProcess::SplitError *err)
|
||||
forever {
|
||||
if (p == length)
|
||||
return ret;
|
||||
if (!isWhiteSpace(args.unicode()[p].unicode()))
|
||||
if (!isWhiteSpaceWin(args.unicode()[p].unicode()))
|
||||
break;
|
||||
++p;
|
||||
}
|
||||
@@ -181,7 +206,7 @@ static QStringList doSplitArgs(const QString &args, QtcProcess::SplitError *err)
|
||||
while (--bslashes >= 0)
|
||||
arg.append(QLatin1Char('\\'));
|
||||
|
||||
if (p == length || (!inquote && isWhiteSpace(args.unicode()[p].unicode()))) {
|
||||
if (p == length || (!inquote && isWhiteSpaceWin(args.unicode()[p].unicode()))) {
|
||||
ret.append(arg);
|
||||
if (inquote) {
|
||||
if (err)
|
||||
@@ -258,28 +283,29 @@ static QStringList doSplitArgs(const QString &args, QtcProcess::SplitError *err)
|
||||
\c{foo " bar}.
|
||||
*/
|
||||
|
||||
QStringList QtcProcess::splitArgs(const QString &_args, bool abortOnMeta, SplitError *err,
|
||||
|
||||
static QStringList splitArgsWin(const QString &_args, bool abortOnMeta,
|
||||
QtcProcess::SplitError *err,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
if (abortOnMeta) {
|
||||
SplitError perr;
|
||||
QtcProcess::SplitError perr;
|
||||
if (!err)
|
||||
err = &perr;
|
||||
QString args = prepareArgs(_args, &perr, env, pwd);
|
||||
if (*err != SplitOk)
|
||||
QString args = prepareArgsWin(_args, &perr, env, pwd).toWindowsArgs();
|
||||
if (*err != QtcProcess::SplitOk)
|
||||
return QStringList();
|
||||
return doSplitArgs(args, err);
|
||||
return doSplitArgsWin(args, err);
|
||||
} else {
|
||||
QString args = _args;
|
||||
if (env)
|
||||
envExpand(args, env, pwd);
|
||||
return doSplitArgs(args, err);
|
||||
envExpandWin(args, env, pwd);
|
||||
return doSplitArgsWin(args, err);
|
||||
}
|
||||
}
|
||||
|
||||
#else // Q_OS_WIN
|
||||
|
||||
inline static bool isMeta(QChar cUnicode)
|
||||
static bool isMetaUnix(QChar cUnicode)
|
||||
{
|
||||
static const uchar iqm[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00, 0xd8,
|
||||
@@ -291,7 +317,8 @@ inline static bool isMeta(QChar cUnicode)
|
||||
return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
|
||||
}
|
||||
|
||||
QStringList QtcProcess::splitArgs(const QString &args, bool abortOnMeta, SplitError *err,
|
||||
static QStringList splitArgsUnix(const QString &args, bool abortOnMeta,
|
||||
QtcProcess::SplitError *err,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
static const QString pwdName = QLatin1String("PWD");
|
||||
@@ -448,7 +475,7 @@ QStringList QtcProcess::splitArgs(const QString &args, bool abortOnMeta, SplitEr
|
||||
if (pos >= args.length())
|
||||
goto quoteerr;
|
||||
c = args.unicode()[pos++];
|
||||
} else if (abortOnMeta && isMeta(c)) {
|
||||
} else if (abortOnMeta && isMetaUnix(c)) {
|
||||
goto metaerr;
|
||||
}
|
||||
cret += c;
|
||||
@@ -466,22 +493,20 @@ QStringList QtcProcess::splitArgs(const QString &args, bool abortOnMeta, SplitEr
|
||||
|
||||
okret:
|
||||
if (err)
|
||||
*err = SplitOk;
|
||||
*err = QtcProcess::SplitOk;
|
||||
return ret;
|
||||
|
||||
quoteerr:
|
||||
if (err)
|
||||
*err = BadQuoting;
|
||||
*err = QtcProcess::BadQuoting;
|
||||
return QStringList();
|
||||
|
||||
metaerr:
|
||||
if (err)
|
||||
*err = FoundMeta;
|
||||
*err = QtcProcess::FoundMeta;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
inline static bool isSpecialCharUnix(ushort c)
|
||||
{
|
||||
// Chars that should be quoted (TM). This includes:
|
||||
@@ -501,6 +526,16 @@ inline static bool hasSpecialCharsUnix(const QString &arg)
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList QtcProcess::splitArgs(const QString &args, OsType osType,
|
||||
bool abortOnMeta, QtcProcess::SplitError *err,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
if (osType == OsTypeWindows)
|
||||
return splitArgsWin(args, abortOnMeta, err, env, pwd);
|
||||
else
|
||||
return splitArgsUnix(args, abortOnMeta, err, env, pwd);
|
||||
}
|
||||
|
||||
QString QtcProcess::quoteArgUnix(const QString &arg)
|
||||
{
|
||||
if (!arg.length())
|
||||
@@ -515,23 +550,7 @@ QString QtcProcess::quoteArgUnix(const QString &arg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QtcProcess::addArgUnix(QString *args, const QString &arg)
|
||||
{
|
||||
if (!args->isEmpty())
|
||||
*args += QLatin1Char(' ');
|
||||
*args += quoteArgUnix(arg);
|
||||
}
|
||||
|
||||
QString QtcProcess::joinArgsUnix(const QStringList &args)
|
||||
{
|
||||
QString ret;
|
||||
foreach (const QString &arg, args)
|
||||
addArgUnix(&ret, arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
inline static bool isSpecialChar(ushort c)
|
||||
static bool isSpecialCharWin(ushort c)
|
||||
{
|
||||
// Chars that should be quoted (TM). This includes:
|
||||
// - control chars & space
|
||||
@@ -545,21 +564,21 @@ inline static bool isSpecialChar(ushort c)
|
||||
return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
|
||||
}
|
||||
|
||||
inline static bool hasSpecialChars(const QString &arg)
|
||||
static bool hasSpecialCharsWin(const QString &arg)
|
||||
{
|
||||
for (int x = arg.length() - 1; x >= 0; --x)
|
||||
if (isSpecialChar(arg.unicode()[x].unicode()))
|
||||
if (isSpecialCharWin(arg.unicode()[x].unicode()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString QtcProcess::quoteArg(const QString &arg)
|
||||
static QString quoteArgWin(const QString &arg)
|
||||
{
|
||||
if (!arg.length())
|
||||
return QString::fromLatin1("\"\"");
|
||||
|
||||
QString ret(arg);
|
||||
if (hasSpecialChars(ret)) {
|
||||
if (hasSpecialCharsWin(ret)) {
|
||||
// Quotes are escaped and their preceding backslashes are doubled.
|
||||
// It's impossible to escape anything inside a quoted string on cmd
|
||||
// level, so the outer quoting must be "suspended".
|
||||
@@ -578,21 +597,38 @@ QString QtcProcess::quoteArg(const QString &arg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QtcProcess::addArg(QString *args, const QString &arg)
|
||||
QtcProcess::Arguments QtcProcess::prepareArgs(const QString &cmd, SplitError *err, OsType osType,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
if (osType == OsTypeWindows)
|
||||
return prepareArgsWin(cmd, err, env, pwd);
|
||||
else
|
||||
return Arguments::createUnixArgs(splitArgs(cmd, osType, true, err, env, pwd));
|
||||
}
|
||||
|
||||
|
||||
QString QtcProcess::quoteArg(const QString &arg, OsType osType)
|
||||
{
|
||||
if (osType == OsTypeWindows)
|
||||
return quoteArgWin(arg);
|
||||
else
|
||||
return quoteArgUnix(arg);
|
||||
}
|
||||
|
||||
void QtcProcess::addArg(QString *args, const QString &arg, OsType osType)
|
||||
{
|
||||
if (!args->isEmpty())
|
||||
*args += QLatin1Char(' ');
|
||||
*args += quoteArg(arg);
|
||||
*args += quoteArg(arg, osType);
|
||||
}
|
||||
|
||||
QString QtcProcess::joinArgs(const QStringList &args)
|
||||
QString QtcProcess::joinArgs(const QStringList &args, OsType osType)
|
||||
{
|
||||
QString ret;
|
||||
foreach (const QString &arg, args)
|
||||
addArg(&ret, arg);
|
||||
addArg(&ret, arg, osType);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void QtcProcess::addArgs(QString *args, const QString &inArgs)
|
||||
{
|
||||
@@ -609,44 +645,36 @@ void QtcProcess::addArgs(QString *args, const QStringList &inArgs)
|
||||
addArg(args, arg);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void QtcProcess::prepareCommand(const QString &command, const QString &arguments,
|
||||
QString *outCmd, QString *outArgs,
|
||||
bool QtcProcess::prepareCommand(const QString &command, const QString &arguments,
|
||||
QString *outCmd, Arguments *outArgs, OsType osType,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
QtcProcess::SplitError err;
|
||||
*outArgs = QtcProcess::prepareArgs(arguments, &err, env, pwd);
|
||||
*outArgs = QtcProcess::prepareArgs(arguments, &err, osType, env, pwd);
|
||||
if (err == QtcProcess::SplitOk) {
|
||||
*outCmd = command;
|
||||
} else {
|
||||
if (osType == OsTypeWindows) {
|
||||
*outCmd = QString::fromLatin1(qgetenv("COMSPEC"));
|
||||
*outArgs = QLatin1String("/v:off /s /c \"")
|
||||
*outArgs = Arguments::createWindowsArgs(QLatin1String("/v:off /s /c \"")
|
||||
+ quoteArg(QDir::toNativeSeparators(command)) + QLatin1Char(' ') + arguments
|
||||
+ QLatin1Char('"');
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool QtcProcess::prepareCommand(const QString &command, const QString &arguments,
|
||||
QString *outCmd, QStringList *outArgs,
|
||||
const Environment *env, const QString *pwd)
|
||||
{
|
||||
QtcProcess::SplitError err;
|
||||
*outArgs = QtcProcess::prepareArgs(arguments, &err, env, pwd);
|
||||
if (err == QtcProcess::SplitOk) {
|
||||
*outCmd = command;
|
||||
+ QLatin1Char('"'));
|
||||
} else {
|
||||
if (err != QtcProcess::FoundMeta)
|
||||
return false;
|
||||
*outCmd = QLatin1String("/bin/sh");
|
||||
*outArgs << QLatin1String("-c") << (quoteArg(command) + QLatin1Char(' ') + arguments);
|
||||
*outArgs = Arguments::createUnixArgs(QStringList()
|
||||
<< QLatin1String("-c")
|
||||
<< (quoteArg(command) + QLatin1Char(' ') + arguments));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void QtcProcess::start()
|
||||
{
|
||||
Environment env;
|
||||
const OsType osType = HostOsInfo::hostOs();
|
||||
if (m_haveEnv) {
|
||||
if (m_environment.size() == 0)
|
||||
qWarning("QtcProcess::start: Empty environment set when running '%s'.", qPrintable(m_command));
|
||||
@@ -655,16 +683,12 @@ void QtcProcess::start()
|
||||
// If the process environemnt has no libraryPath,
|
||||
// Qt will copy creator's libraryPath into the process environment.
|
||||
// That's brain dead, and we work around it
|
||||
#if defined(Q_OS_UNIX)
|
||||
# if defined(Q_OS_MAC)
|
||||
static const char libraryPathC[] = "DYLD_LIBRARY_PATH";
|
||||
# else
|
||||
static const char libraryPathC[] = "LD_LIBRARY_PATH";
|
||||
# endif
|
||||
const QString libraryPath = QLatin1String(libraryPathC);
|
||||
if (osType != OsTypeWindows) { // a.k.a "Unixoid"
|
||||
const QString libraryPath =
|
||||
QLatin1String(osType == OsTypeMac ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH");
|
||||
if (env.constFind(libraryPath) == env.constEnd())
|
||||
env.set(libraryPath, QString());
|
||||
#endif
|
||||
}
|
||||
QProcess::setEnvironment(env.toStringList());
|
||||
} else {
|
||||
env = Environment::systemEnvironment();
|
||||
@@ -672,27 +696,28 @@ void QtcProcess::start()
|
||||
|
||||
const QString &workDir = workingDirectory();
|
||||
QString command;
|
||||
QtcProcess::Arguments arguments;
|
||||
bool success = prepareCommand(m_command, m_arguments, &command, &arguments, osType, &env, &workDir);
|
||||
if (osType == OsTypeWindows) {
|
||||
QString args = arguments.toWindowsArgs();
|
||||
#ifdef Q_OS_WIN
|
||||
QString arguments;
|
||||
QStringList argList;
|
||||
prepareCommand(m_command, m_arguments, &command, &arguments, &env, &workDir);
|
||||
setNativeArguments(arguments);
|
||||
setNativeArguments(args);
|
||||
#endif
|
||||
if (m_useCtrlCStub) {
|
||||
argList << QDir::toNativeSeparators(command);
|
||||
args = QDir::toNativeSeparators(command);
|
||||
command = QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_ctrlc_stub.exe");
|
||||
}
|
||||
QProcess::start(command, argList);
|
||||
#else
|
||||
QStringList arguments;
|
||||
if (!prepareCommand(m_command, m_arguments, &command, &arguments, &env, &workDir)) {
|
||||
QProcess::start(command, QStringList(args));
|
||||
} else {
|
||||
if (!success) {
|
||||
setErrorString(tr("Error in command line."));
|
||||
// Should be FailedToStart, but we cannot set the process error from the outside,
|
||||
// so it would be inconsistent.
|
||||
emit error(QProcess::UnknownError);
|
||||
return;
|
||||
}
|
||||
QProcess::start(command, arguments);
|
||||
#endif
|
||||
QProcess::start(command, arguments.toUnixArgs());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -738,10 +763,9 @@ void QtcProcess::interrupt()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// This function assumes that the resulting string will be quoted.
|
||||
// That's irrelevant if it does not contain quotes itself.
|
||||
static int quoteArgInternal(QString &ret, int bslashes)
|
||||
static int quoteArgInternalWin(QString &ret, int bslashes)
|
||||
{
|
||||
// Quotes are escaped and their preceding backslashes are doubled.
|
||||
// It's impossible to escape anything inside a quoted string on cmd
|
||||
@@ -765,32 +789,6 @@ static int quoteArgInternal(QString &ret, int bslashes)
|
||||
return bslashes;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// The main state of the Unix shell parser
|
||||
enum MxQuoting { MxBasic, MxSingleQuote, MxDoubleQuote, MxParen, MxSubst, MxGroup, MxMath };
|
||||
typedef struct {
|
||||
MxQuoting current;
|
||||
// Bizarrely enough, double quoting has an impact on the behavior of some
|
||||
// complex expressions within the quoted string.
|
||||
bool dquote;
|
||||
} MxState;
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(MxState, Q_PRIMITIVE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
// Pushed state for the case where a $(()) expansion turns out bogus
|
||||
typedef struct {
|
||||
QString str;
|
||||
int pos, varPos;
|
||||
} MxSave;
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(MxSave, Q_MOVABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include <QStack>
|
||||
|
||||
#endif
|
||||
|
||||
// TODO: This documentation is relevant for end-users. Where to put it?
|
||||
/**
|
||||
@@ -864,7 +862,7 @@ QT_END_NAMESPACE
|
||||
* \return false if the string could not be parsed and therefore no safe
|
||||
* substitution was possible
|
||||
*/
|
||||
bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType osType)
|
||||
{
|
||||
QString str = *cmd;
|
||||
if (str.isEmpty())
|
||||
@@ -878,7 +876,7 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
|
||||
int pos = 0;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (osType == OsTypeWindows) {
|
||||
enum { // cmd.exe parsing state
|
||||
ShellBasic, // initial state
|
||||
ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
|
||||
@@ -913,12 +911,12 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
crtState = CrtNeedWord;
|
||||
}
|
||||
} else {
|
||||
if (hasSpecialChars(rsts)) {
|
||||
if (hasSpecialCharsWin(rsts)) {
|
||||
if (crtState == CrtClosed) {
|
||||
// Quoted expando right after closing quote. Can't do that.
|
||||
return false;
|
||||
}
|
||||
int tbslashes = quoteArgInternal(rsts, 0);
|
||||
int tbslashes = quoteArgInternalWin(rsts, 0);
|
||||
rsts.prepend(QLatin1Char('"'));
|
||||
if (rbslashes)
|
||||
rsts.prepend(QString(rbslashes, QLatin1Char('\\')));
|
||||
@@ -928,11 +926,11 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
crtState = CrtInWord; // We know that this string contains no spaces.
|
||||
// We know that this string contains no quotes,
|
||||
// so the function won't make a mess.
|
||||
rbslashes = quoteArgInternal(rsts, rbslashes);
|
||||
rbslashes = quoteArgInternalWin(rsts, rbslashes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rbslashes = quoteArgInternal(rsts, rbslashes);
|
||||
rbslashes = quoteArgInternalWin(rsts, rbslashes);
|
||||
}
|
||||
str.replace(pos, varLen, rsts);
|
||||
pos += rsts.length();
|
||||
@@ -1026,7 +1024,8 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
#else
|
||||
} else {
|
||||
// !Windows
|
||||
MxState state = { MxBasic, false };
|
||||
QStack<MxState> sstack;
|
||||
QStack<MxSave> ostack;
|
||||
@@ -1181,16 +1180,16 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
|
||||
pos++;
|
||||
}
|
||||
// FIXME? May complain if (!sstack.empty()), but we don't really care anyway.
|
||||
#endif
|
||||
}
|
||||
|
||||
*cmd = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString QtcProcess::expandMacros(const QString &str, AbstractMacroExpander *mx)
|
||||
QString QtcProcess::expandMacros(const QString &str, AbstractMacroExpander *mx, OsType osType)
|
||||
{
|
||||
QString ret = str;
|
||||
expandMacros(&ret, mx);
|
||||
expandMacros(&ret, mx, osType);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1203,7 +1202,7 @@ bool QtcProcess::ArgIterator::next()
|
||||
m_simple = true;
|
||||
m_value.clear();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (m_osType == OsTypeWindows) {
|
||||
enum { // cmd.exe parsing state
|
||||
ShellBasic, // initial state
|
||||
ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
|
||||
@@ -1223,7 +1222,7 @@ bool QtcProcess::ArgIterator::next()
|
||||
if (shellState == ShellBasic && cc == '^') {
|
||||
varState = NoVar;
|
||||
shellState = ShellEscaped;
|
||||
} else if ((shellState == ShellBasic && isMetaChar(cc)) || !cc) { // A "bit" simplistic ...
|
||||
} else if ((shellState == ShellBasic && isMetaCharWin(cc)) || !cc) { // A "bit" simplistic ...
|
||||
// We ignore crtQuote state here. Whatever ...
|
||||
doReturn:
|
||||
if (m_simple)
|
||||
@@ -1302,7 +1301,7 @@ bool QtcProcess::ArgIterator::next()
|
||||
shellState = ShellBasic;
|
||||
}
|
||||
}
|
||||
#else
|
||||
} else {
|
||||
MxState state = { MxBasic, false };
|
||||
QStack<MxState> sstack;
|
||||
QStack<int> ostack;
|
||||
@@ -1448,7 +1447,7 @@ bool QtcProcess::ArgIterator::next()
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void QtcProcess::ArgIterator::deleteArg()
|
||||
@@ -1470,8 +1469,6 @@ void QtcProcess::ArgIterator::appendArg(const QString &str)
|
||||
m_pos += qstr.length() + 1;
|
||||
}
|
||||
|
||||
namespace Utils {
|
||||
|
||||
QTCREATOR_UTILS_EXPORT unsigned long qPidToPid(const Q_PID qpid)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -1482,4 +1479,40 @@ QTCREATOR_UTILS_EXPORT unsigned long qPidToPid(const Q_PID qpid)
|
||||
#endif
|
||||
}
|
||||
|
||||
QtcProcess::Arguments QtcProcess::Arguments::createWindowsArgs(const QString &args)
|
||||
{
|
||||
Arguments result;
|
||||
result.m_windowsArgs = args;
|
||||
result.m_isWindows = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
QtcProcess::Arguments QtcProcess::Arguments::createUnixArgs(const QStringList &args)
|
||||
{
|
||||
Arguments result;
|
||||
result.m_unixArgs = args;
|
||||
result.m_isWindows = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
QString QtcProcess::Arguments::toWindowsArgs() const
|
||||
{
|
||||
QTC_CHECK(m_isWindows);
|
||||
return m_windowsArgs;
|
||||
}
|
||||
|
||||
QStringList QtcProcess::Arguments::toUnixArgs() const
|
||||
{
|
||||
QTC_CHECK(!m_isWindows);
|
||||
return m_unixArgs;
|
||||
}
|
||||
|
||||
QString QtcProcess::Arguments::toString() const
|
||||
{
|
||||
if (m_isWindows)
|
||||
return m_windowsArgs;
|
||||
else
|
||||
return QtcProcess::joinArgs(m_unixArgs, OsTypeLinux);
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -56,6 +56,22 @@ public:
|
||||
void terminate();
|
||||
void interrupt();
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT Arguments
|
||||
{
|
||||
public:
|
||||
static Arguments createWindowsArgs(const QString &args);
|
||||
static Arguments createUnixArgs(const QStringList &args);
|
||||
|
||||
QString toWindowsArgs() const;
|
||||
QStringList toUnixArgs() const;
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
QString m_windowsArgs;
|
||||
QStringList m_unixArgs;
|
||||
bool m_isWindows;
|
||||
};
|
||||
|
||||
enum SplitError {
|
||||
SplitOk = 0, //! All went just fine
|
||||
BadQuoting, //! Command contains quoting errors
|
||||
@@ -64,45 +80,33 @@ public:
|
||||
|
||||
//! Quote a single argument for usage in a unix shell command
|
||||
static QString quoteArgUnix(const QString &arg);
|
||||
//! Quote a single argument and append it to a unix shell command
|
||||
static void addArgUnix(QString *args, const QString &arg);
|
||||
//! Join an argument list into a unix shell command
|
||||
static QString joinArgsUnix(const QStringList &args);
|
||||
#ifdef Q_OS_WIN
|
||||
//! Quote a single argument for usage in a shell command
|
||||
static QString quoteArg(const QString &arg);
|
||||
static QString quoteArg(const QString &arg, OsType osType = HostOsInfo::hostOs());
|
||||
//! Quote a single argument and append it to a shell command
|
||||
static void addArg(QString *args, const QString &arg);
|
||||
static void addArg(QString *args, const QString &arg, OsType osType = HostOsInfo::hostOs());
|
||||
//! Join an argument list into a shell command
|
||||
static QString joinArgs(const QStringList &args);
|
||||
static QString joinArgs(const QStringList &args, OsType osType = HostOsInfo::hostOs());
|
||||
//! Prepare argument of a shell command for feeding into QProcess
|
||||
static QString prepareArgs(const QString &cmd, SplitError *err,
|
||||
static Arguments prepareArgs(const QString &cmd, SplitError *err,
|
||||
OsType osType = HostOsInfo::hostOs(),
|
||||
const Environment *env = 0, const QString *pwd = 0);
|
||||
//! Prepare a shell command for feeding into QProcess
|
||||
static void prepareCommand(const QString &command, const QString &arguments,
|
||||
QString *outCmd, QString *outArgs,
|
||||
const Environment *env = 0, const QString *pwd = 0);
|
||||
#else
|
||||
static QString quoteArg(const QString &arg) { return quoteArgUnix(arg); }
|
||||
static void addArg(QString *args, const QString &arg) { addArgUnix(args, arg); }
|
||||
static QString joinArgs(const QStringList &args) { return joinArgsUnix(args); }
|
||||
static QStringList prepareArgs(const QString &cmd, SplitError *err,
|
||||
const Environment *env = 0, const QString *pwd = 0)
|
||||
{ return splitArgs(cmd, true, err, env, pwd); }
|
||||
static bool prepareCommand(const QString &command, const QString &arguments,
|
||||
QString *outCmd, QStringList *outArgs,
|
||||
QString *outCmd, Arguments *outArgs, OsType osType = HostOsInfo::hostOs(),
|
||||
const Environment *env = 0, const QString *pwd = 0);
|
||||
#endif
|
||||
//! Quote and append each argument to a shell command
|
||||
static void addArgs(QString *args, const QStringList &inArgs);
|
||||
//! Append already quoted arguments to a shell command
|
||||
static void addArgs(QString *args, const QString &inArgs);
|
||||
//! Split a shell command into separate arguments. ArgIterator is usually a better choice.
|
||||
static QStringList splitArgs(const QString &cmd, bool abortOnMeta = false, SplitError *err = 0,
|
||||
static QStringList splitArgs(const QString &cmd, OsType osType = HostOsInfo::hostOs(),
|
||||
bool abortOnMeta = false, SplitError *err = 0,
|
||||
const Environment *env = 0, const QString *pwd = 0);
|
||||
//! Safely replace the expandos in a shell command
|
||||
static bool expandMacros(QString *cmd, AbstractMacroExpander *mx);
|
||||
static QString expandMacros(const QString &str, AbstractMacroExpander *mx);
|
||||
static bool expandMacros(QString *cmd, AbstractMacroExpander *mx,
|
||||
OsType osType = HostOsInfo::hostOs());
|
||||
static QString expandMacros(const QString &str, AbstractMacroExpander *mx,
|
||||
OsType osType = HostOsInfo::hostOs());
|
||||
|
||||
/*! Iterate over arguments from a command line.
|
||||
* Assumes that the name of the actual command is *not* part of the line.
|
||||
@@ -110,7 +114,9 @@ public:
|
||||
*/
|
||||
class QTCREATOR_UTILS_EXPORT ArgIterator {
|
||||
public:
|
||||
ArgIterator(QString *str) : m_str(str), m_pos(0), m_prev(-1) {}
|
||||
ArgIterator(QString *str, OsType osType = HostOsInfo::hostOs())
|
||||
: m_str(str), m_pos(0), m_prev(-1), m_osType(osType)
|
||||
{}
|
||||
//! Get the next argument. Returns false on encountering end of first command.
|
||||
bool next();
|
||||
//! True iff the argument is a plain string, possibly after unquoting.
|
||||
@@ -126,11 +132,14 @@ public:
|
||||
QString *m_str, m_value;
|
||||
int m_pos, m_prev;
|
||||
bool m_simple;
|
||||
OsType m_osType;
|
||||
};
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT ConstArgIterator {
|
||||
public:
|
||||
ConstArgIterator(const QString &str) : m_str(str), m_ait(&m_str) {}
|
||||
ConstArgIterator(const QString &str, OsType osType = HostOsInfo::hostOs())
|
||||
: m_str(str), m_ait(&m_str, osType)
|
||||
{}
|
||||
bool next() { return m_ait.next(); }
|
||||
bool isSimple() const { return m_ait.isSimple(); }
|
||||
QString value() const { return m_ait.value(); }
|
||||
|
@@ -121,13 +121,14 @@ void FileUtils::openTerminal(const QString &path)
|
||||
// Get terminal application
|
||||
QString terminalEmulator;
|
||||
QStringList args;
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
const OsType hostOs = HostOsInfo::hostOs();
|
||||
if (hostOs == OsTypeWindows) {
|
||||
terminalEmulator = ConsoleProcess::defaultTerminalEmulator();
|
||||
} else if (HostOsInfo::isMacHost()) {
|
||||
} else if (hostOs == OsTypeMac) {
|
||||
terminalEmulator = ICore::resourcePath()
|
||||
+ QLatin1String("/scripts/openTerminal.command");
|
||||
} else {
|
||||
args = QtcProcess::splitArgs(ConsoleProcess::terminalEmulator(ICore::settings()));
|
||||
args = QtcProcess::splitArgs(ConsoleProcess::terminalEmulator(ICore::settings()), hostOs);
|
||||
terminalEmulator = args.takeFirst();
|
||||
args.append(QString::fromLocal8Bit(qgetenv("SHELL")));
|
||||
}
|
||||
|
@@ -4771,11 +4771,12 @@ void GdbEngine::write(const QByteArray &data)
|
||||
|
||||
bool GdbEngine::prepareCommand()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
Utils::QtcProcess::SplitError perr;
|
||||
startParameters().processArgs = Utils::QtcProcess::prepareArgs(
|
||||
startParameters().processArgs, &perr,
|
||||
&startParameters().environment, &startParameters().workingDirectory);
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
DebuggerStartParameters &sp = startParameters();
|
||||
QtcProcess::SplitError perr;
|
||||
sp.processArgs = QtcProcess::prepareArgs(sp.processArgs, &perr,
|
||||
Utils::HostOsInfo::hostOs(),
|
||||
&sp.environment, &sp.workingDirectory).toWindowsArgs();
|
||||
if (perr != Utils::QtcProcess::SplitOk) {
|
||||
// perr == BadQuoting is never returned on Windows
|
||||
// FIXME? QTCREATORBUG-2809
|
||||
@@ -4783,7 +4784,7 @@ bool GdbEngine::prepareCommand()
|
||||
"Debugging complex command lines is currently not supported on Windows."), Core::Id());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -201,11 +201,7 @@ void LldbEngine::setupInferior()
|
||||
const DebuggerStartParameters &sp = startParameters();
|
||||
|
||||
QString executable;
|
||||
#ifdef Q_OS_WIN
|
||||
QString args;
|
||||
#else
|
||||
QStringList args;
|
||||
#endif
|
||||
Utils::QtcProcess::Arguments args;
|
||||
Utils::QtcProcess::prepareCommand(QFileInfo(sp.executable).absoluteFilePath(),
|
||||
sp.processArgs, &executable, &args);
|
||||
|
||||
@@ -213,12 +209,8 @@ void LldbEngine::setupInferior()
|
||||
cmd.arg("executable", executable);
|
||||
cmd.arg("startMode", sp.startMode); // directly relying on this is brittle wrt. insertions, so check it here
|
||||
cmd.beginList("processArgs");
|
||||
#ifdef Q_OS_WIN
|
||||
// fixme?
|
||||
#else
|
||||
foreach (const QString &arg, args)
|
||||
foreach (const QString &arg, args.toUnixArgs())
|
||||
cmd.arg(arg.toUtf8().toHex());
|
||||
#endif
|
||||
cmd.endList();
|
||||
|
||||
// it is better not to check the start mode on the python sid (as we would have to duplicate the
|
||||
|
@@ -2990,7 +2990,7 @@ bool GitClient::tryLauchingGitK(const QProcessEnvironment &env,
|
||||
VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance();
|
||||
const QString gitkOpts = settings()->stringValue(GitSettings::gitkOptionsKey);
|
||||
if (!gitkOpts.isEmpty())
|
||||
arguments.append(Utils::QtcProcess::splitArgs(gitkOpts));
|
||||
arguments.append(Utils::QtcProcess::splitArgs(gitkOpts, Utils::HostOsInfo::hostOs()));
|
||||
if (!fileName.isEmpty())
|
||||
arguments << QLatin1String("--") << fileName;
|
||||
outwin->appendCommand(workingDirectory, binary, arguments);
|
||||
|
@@ -51,6 +51,7 @@
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QmakeProjectManager;
|
||||
using namespace Utils;
|
||||
|
||||
namespace Ios {
|
||||
namespace Internal {
|
||||
@@ -341,27 +342,27 @@ QString IosRunConfigurationWidget::argListToString(const QStringList &args) cons
|
||||
|
||||
QStringList IosRunConfigurationWidget::stringToArgList(const QString &args) const
|
||||
{
|
||||
Utils::QtcProcess::SplitError err;
|
||||
QStringList res = Utils::QtcProcess::splitArgs(args, false, &err);
|
||||
QtcProcess::SplitError err;
|
||||
QStringList res = QtcProcess::splitArgs(args, OsTypeMac, false, &err);
|
||||
switch (err) {
|
||||
case Utils::QtcProcess::SplitOk:
|
||||
case QtcProcess::SplitOk:
|
||||
break;
|
||||
case Utils::QtcProcess::BadQuoting:
|
||||
case QtcProcess::BadQuoting:
|
||||
if (args.at(args.size()-1) == QLatin1Char('\\')) {
|
||||
res = Utils::QtcProcess::splitArgs(args + QLatin1Char('\\'), false, &err);
|
||||
if (err != Utils::QtcProcess::SplitOk)
|
||||
res = Utils::QtcProcess::splitArgs(args + QLatin1Char('\\') + QLatin1Char('\''),
|
||||
false, &err);
|
||||
if (err != Utils::QtcProcess::SplitOk)
|
||||
res = Utils::QtcProcess::splitArgs(args + QLatin1Char('\\') + QLatin1Char('\"'),
|
||||
false, &err);
|
||||
res = QtcProcess::splitArgs(args + QLatin1Char('\\'), OsTypeMac, false, &err);
|
||||
if (err != QtcProcess::SplitOk)
|
||||
res = QtcProcess::splitArgs(args + QLatin1Char('\\') + QLatin1Char('\''),
|
||||
OsTypeMac, false, &err);
|
||||
if (err != QtcProcess::SplitOk)
|
||||
res = QtcProcess::splitArgs(args + QLatin1Char('\\') + QLatin1Char('\"'),
|
||||
OsTypeMac, false, &err);
|
||||
}
|
||||
if (err != Utils::QtcProcess::SplitOk)
|
||||
res = Utils::QtcProcess::splitArgs(args + QLatin1Char('\''), false, &err);
|
||||
if (err != Utils::QtcProcess::SplitOk)
|
||||
res = Utils::QtcProcess::splitArgs(args + QLatin1Char('\"'), false, &err);
|
||||
if (err != QtcProcess::SplitOk)
|
||||
res = QtcProcess::splitArgs(args + QLatin1Char('\''), OsTypeMac, false, &err);
|
||||
if (err != QtcProcess::SplitOk)
|
||||
res = QtcProcess::splitArgs(args + QLatin1Char('\"'), OsTypeMac, false, &err);
|
||||
break;
|
||||
case Utils::QtcProcess::FoundMeta:
|
||||
case QtcProcess::FoundMeta:
|
||||
qDebug() << "IosRunConfigurationWidget FoundMeta (should not happen)";
|
||||
break;
|
||||
}
|
||||
|
@@ -928,13 +928,14 @@ void GccToolChainConfigWidget::makeReadOnlyImpl()
|
||||
QStringList GccToolChainConfigWidget::splitString(const QString &s)
|
||||
{
|
||||
QtcProcess::SplitError splitError;
|
||||
QStringList res = QtcProcess::splitArgs(s, false, &splitError);
|
||||
const OsType osType = HostOsInfo::hostOs();
|
||||
QStringList res = QtcProcess::splitArgs(s, osType, false, &splitError);
|
||||
if (splitError != QtcProcess::SplitOk){
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('\\'), false, &splitError);
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('\\'), osType, false, &splitError);
|
||||
if (splitError != QtcProcess::SplitOk){
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('"'), false, &splitError);
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('"'), osType, false, &splitError);
|
||||
if (splitError != QtcProcess::SplitOk)
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('\''), false, &splitError);
|
||||
res = QtcProcess::splitArgs(s + QLatin1Char('\''), osType, false, &splitError);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@@ -169,20 +169,12 @@ QString ProcessParameters::prettyArguments() const
|
||||
{
|
||||
QString margs = effectiveArguments();
|
||||
QString workDir = effectiveWorkingDirectory();
|
||||
#ifdef Q_OS_WIN
|
||||
QString args;
|
||||
#else
|
||||
QStringList args;
|
||||
#endif
|
||||
Utils::QtcProcess::SplitError err;
|
||||
args = Utils::QtcProcess::prepareArgs(margs, &err, &m_environment, &workDir);
|
||||
Utils::QtcProcess::Arguments args =
|
||||
Utils::QtcProcess::prepareArgs(margs, &err, Utils::HostOsInfo::hostOs(), &m_environment, &workDir);
|
||||
if (err != Utils::QtcProcess::SplitOk)
|
||||
return margs; // Sorry, too complex - just fall back.
|
||||
#ifdef Q_OS_WIN
|
||||
return args;
|
||||
#else
|
||||
return Utils::QtcProcess::joinArgs(args);
|
||||
#endif
|
||||
return args.toString();
|
||||
}
|
||||
|
||||
QString ProcessParameters::summary(const QString &displayName) const
|
||||
|
@@ -69,7 +69,7 @@ QString LinuxDeviceProcess::fullCommandLine() const
|
||||
fullCommandLine.append(quote(executable()));
|
||||
if (!arguments().isEmpty()) {
|
||||
fullCommandLine.append(QLatin1Char(' '));
|
||||
fullCommandLine.append(Utils::QtcProcess::joinArgsUnix(arguments()));
|
||||
fullCommandLine.append(Utils::QtcProcess::joinArgs(arguments(), Utils::OsTypeLinux));
|
||||
}
|
||||
return fullCommandLine;
|
||||
}
|
||||
|
@@ -207,7 +207,7 @@ QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const
|
||||
|
||||
void RemoteLinuxRunConfiguration::setArguments(const QString &args)
|
||||
{
|
||||
d->arguments = QtcProcess::splitArgs(args); // TODO: Widget should be list-based.
|
||||
d->arguments = QtcProcess::splitArgs(args, OsTypeLinux); // TODO: Widget should be list-based.
|
||||
}
|
||||
|
||||
QString RemoteLinuxRunConfiguration::workingDirectory() const
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user