summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjk <hjk121@nokiamail.com>2014-02-05 10:43:21 +0100
committerEike Ziller <eike.ziller@digia.com>2014-02-19 09:19:28 +0100
commitc68ebeed2e47c7a78d790bb732a080edaf07d9ba (patch)
treeab861674989f5b4aaf8f8f70275d53a2e075b0f2
parenta0d29eeb03cfe51ed929a83374c18e3301fefdaf (diff)
downloadqt-creator-c68ebeed2e47c7a78d790bb732a080edaf07d9ba.tar.gz
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>
-rw-r--r--src/libs/utils/consoleprocess_unix.cpp34
-rw-r--r--src/libs/utils/consoleprocess_win.cpp5
-rw-r--r--src/libs/utils/qtcprocess.cpp1311
-rw-r--r--src/libs/utils/qtcprocess.h63
-rw-r--r--src/plugins/coreplugin/fileutils.cpp7
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp25
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp12
-rw-r--r--src/plugins/git/gitclient.cpp2
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp33
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp9
-rw-r--r--src/plugins/projectexplorer/processparameters.cpp14
-rw-r--r--src/plugins/remotelinux/linuxdeviceprocess.cpp2
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.cpp2
-rw-r--r--tests/auto/qtcprocess/tst_qtcprocess.cpp912
14 files changed, 1246 insertions, 1185 deletions
diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp
index 331e65a0ae..cc9474dbb5 100644
--- a/src/libs/utils/consoleprocess_unix.cpp
+++ b/src/libs/utils/consoleprocess_unix.cpp
@@ -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,12 +92,15 @@ 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,
- &d->m_environment, &d->m_workingDir);
+ 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
? tr("Quoting error in terminal command.")
@@ -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 "
diff --git a/src/libs/utils/consoleprocess_win.cpp b/src/libs/utils/consoleprocess_win.cpp
index 646cf11806..9c6df8104b 100644
--- a/src/libs/utils/consoleprocess_win.cpp
+++ b/src/libs/utils/consoleprocess_win.cpp
@@ -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();
diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp
index fed14afa90..b6e13b1cca 100644
--- a/src/libs/utils/qtcprocess.cpp
+++ b/src/libs/utils/qtcprocess.cpp
@@ -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,
- const Environment *env, const QString *pwd)
+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,
- const Environment *env, const QString *pwd)
+
+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,8 +317,9 @@ 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,
- const Environment *env, const QString *pwd)
+static QStringList splitArgsUnix(const QString &args, bool abortOnMeta,
+ QtcProcess::SplitError *err,
+ const Environment *env, const QString *pwd)
{
static const QString pwdName = QLatin1String("PWD");
QStringList ret;
@@ -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,
- const Environment *env, const QString *pwd)
-{
- QtcProcess::SplitError err;
- *outArgs = QtcProcess::prepareArgs(arguments, &err, env, pwd);
- if (err == QtcProcess::SplitOk) {
- *outCmd = command;
- } else {
- *outCmd = QString::fromLatin1(qgetenv("COMSPEC"));
- *outArgs = 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,
+ 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 (err != QtcProcess::FoundMeta)
- return false;
- *outCmd = QLatin1String("/bin/sh");
- *outArgs << QLatin1String("-c") << (quoteArg(command) + QLatin1Char(' ') + arguments);
+ if (osType == OsTypeWindows) {
+ *outCmd = QString::fromLatin1(qgetenv("COMSPEC"));
+ *outArgs = Arguments::createWindowsArgs(QLatin1String("/v:off /s /c \"")
+ + quoteArg(QDir::toNativeSeparators(command)) + QLatin1Char(' ') + arguments
+ + QLatin1Char('"'));
+ } else {
+ if (err != QtcProcess::FoundMeta)
+ return false;
+ *outCmd = QLatin1String("/bin/sh");
+ *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 (env.constFind(libraryPath) == env.constEnd())
- env.set(libraryPath, QString());
-#endif
+ 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());
+ }
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);
- if (m_useCtrlCStub) {
- argList << 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)) {
- 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);
+ setNativeArguments(args);
#endif
+ if (m_useCtrlCStub) {
+ args = QDir::toNativeSeparators(command);
+ command = QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_ctrlc_stub.exe");
+ }
+ 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.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,319 +876,320 @@ bool QtcProcess::expandMacros(QString *cmd, AbstractMacroExpander *mx)
int pos = 0;
-#ifdef Q_OS_WIN
- enum { // cmd.exe parsing state
- ShellBasic, // initial state
- ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
- ShellEscaped // circumflex-escaped state => next char is not interpreted
- } shellState = ShellBasic;
- enum { // CommandLineToArgv() parsing state and some more
- CrtBasic, // initial state
- CrtNeedWord, // after empty expando; insert empty argument if whitespace follows
- CrtInWord, // in non-whitespace
- CrtClosed, // previous char closed the double-quoting
- CrtHadQuote, // closed double-quoting after an expando
- // The remaining two need to be numerically higher
- CrtQuoted, // double-quoted state => spaces don't split tokens
- CrtNeedQuote // expando opened quote; close if no expando follows
- } crtState = CrtBasic;
- int bslashes = 0; // previous chars were manual backslashes
- int rbslashes = 0; // trailing backslashes in replacement
+ if (osType == OsTypeWindows) {
+ enum { // cmd.exe parsing state
+ ShellBasic, // initial state
+ ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
+ ShellEscaped // circumflex-escaped state => next char is not interpreted
+ } shellState = ShellBasic;
+ enum { // CommandLineToArgv() parsing state and some more
+ CrtBasic, // initial state
+ CrtNeedWord, // after empty expando; insert empty argument if whitespace follows
+ CrtInWord, // in non-whitespace
+ CrtClosed, // previous char closed the double-quoting
+ CrtHadQuote, // closed double-quoting after an expando
+ // The remaining two need to be numerically higher
+ CrtQuoted, // double-quoted state => spaces don't split tokens
+ CrtNeedQuote // expando opened quote; close if no expando follows
+ } crtState = CrtBasic;
+ int bslashes = 0; // previous chars were manual backslashes
+ int rbslashes = 0; // trailing backslashes in replacement
- forever {
- if (pos == varPos) {
- if (shellState == ShellEscaped)
- return false; // Circumflex'd quoted expando would be Bad (TM).
- if ((shellState == ShellQuoted) != (crtState == CrtQuoted))
- return false; // CRT quoting out of sync with shell quoting. Ahoy to Redmond.
- rbslashes += bslashes;
- bslashes = 0;
- if (crtState < CrtQuoted) {
- if (rsts.isEmpty()) {
- if (crtState == CrtBasic) {
- // Outside any quoting and the string is empty, so put
- // a pair of quotes. Delaying that is just pedantry.
- crtState = CrtNeedWord;
- }
- } else {
- if (hasSpecialChars(rsts)) {
- if (crtState == CrtClosed) {
- // Quoted expando right after closing quote. Can't do that.
- return false;
+ forever {
+ if (pos == varPos) {
+ if (shellState == ShellEscaped)
+ return false; // Circumflex'd quoted expando would be Bad (TM).
+ if ((shellState == ShellQuoted) != (crtState == CrtQuoted))
+ return false; // CRT quoting out of sync with shell quoting. Ahoy to Redmond.
+ rbslashes += bslashes;
+ bslashes = 0;
+ if (crtState < CrtQuoted) {
+ if (rsts.isEmpty()) {
+ if (crtState == CrtBasic) {
+ // Outside any quoting and the string is empty, so put
+ // a pair of quotes. Delaying that is just pedantry.
+ crtState = CrtNeedWord;
}
- int tbslashes = quoteArgInternal(rsts, 0);
- rsts.prepend(QLatin1Char('"'));
- if (rbslashes)
- rsts.prepend(QString(rbslashes, QLatin1Char('\\')));
- crtState = CrtNeedQuote;
- rbslashes = tbslashes;
} else {
- 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);
+ if (hasSpecialCharsWin(rsts)) {
+ if (crtState == CrtClosed) {
+ // Quoted expando right after closing quote. Can't do that.
+ return false;
+ }
+ int tbslashes = quoteArgInternalWin(rsts, 0);
+ rsts.prepend(QLatin1Char('"'));
+ if (rbslashes)
+ rsts.prepend(QString(rbslashes, QLatin1Char('\\')));
+ crtState = CrtNeedQuote;
+ rbslashes = tbslashes;
+ } else {
+ 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 = quoteArgInternalWin(rsts, rbslashes);
+ }
}
+ } else {
+ rbslashes = quoteArgInternalWin(rsts, rbslashes);
}
- } else {
- rbslashes = quoteArgInternal(rsts, rbslashes);
- }
- str.replace(pos, varLen, rsts);
- pos += rsts.length();
- varPos = pos;
- if (!(varLen = mx->findMacro(str, &varPos, &rsts))) {
- // Don't leave immediately, as we may be in CrtNeedWord state which could
- // be still resolved, or we may have inserted trailing backslashes.
- varPos = INT_MAX;
- }
- continue;
- }
- if (crtState == CrtNeedQuote) {
- if (rbslashes) {
- str.insert(pos, QString(rbslashes, QLatin1Char('\\')));
- pos += rbslashes;
- varPos += rbslashes;
- rbslashes = 0;
+ str.replace(pos, varLen, rsts);
+ pos += rsts.length();
+ varPos = pos;
+ if (!(varLen = mx->findMacro(str, &varPos, &rsts))) {
+ // Don't leave immediately, as we may be in CrtNeedWord state which could
+ // be still resolved, or we may have inserted trailing backslashes.
+ varPos = INT_MAX;
+ }
+ continue;
}
- str.insert(pos, QLatin1Char('"'));
- pos++;
- varPos++;
- crtState = CrtHadQuote;
- }
- ushort cc = str.unicode()[pos].unicode();
- if (shellState == ShellBasic && cc == '^') {
- shellState = ShellEscaped;
- } else {
- if (!cc || cc == ' ' || cc == '\t') {
- if (crtState < CrtQuoted) {
- if (crtState == CrtNeedWord) {
- str.insert(pos, QLatin1String("\"\""));
- pos += 2;
- varPos += 2;
- }
- crtState = CrtBasic;
+ if (crtState == CrtNeedQuote) {
+ if (rbslashes) {
+ str.insert(pos, QString(rbslashes, QLatin1Char('\\')));
+ pos += rbslashes;
+ varPos += rbslashes;
+ rbslashes = 0;
}
- if (!cc)
- break;
- bslashes = 0;
- rbslashes = 0;
+ str.insert(pos, QLatin1Char('"'));
+ pos++;
+ varPos++;
+ crtState = CrtHadQuote;
+ }
+ ushort cc = str.unicode()[pos].unicode();
+ if (shellState == ShellBasic && cc == '^') {
+ shellState = ShellEscaped;
} else {
- if (cc == '\\') {
- bslashes++;
- if (crtState < CrtQuoted)
- crtState = CrtInWord;
- } else {
- if (cc == '"') {
- if (shellState != ShellEscaped)
- shellState = (shellState == ShellQuoted) ? ShellBasic : ShellQuoted;
- if (rbslashes) {
- // Offset -1: skip possible circumflex. We have at least
- // one backslash, so a fixed offset is ok.
- str.insert(pos - 1, QString(rbslashes, QLatin1Char('\\')));
- pos += rbslashes;
- varPos += rbslashes;
+ if (!cc || cc == ' ' || cc == '\t') {
+ if (crtState < CrtQuoted) {
+ if (crtState == CrtNeedWord) {
+ str.insert(pos, QLatin1String("\"\""));
+ pos += 2;
+ varPos += 2;
}
- if (!(bslashes & 1)) {
- // Even number of backslashes, so the quote is not escaped.
- switch (crtState) {
- case CrtQuoted:
- // Closing quote
- crtState = CrtClosed;
- break;
- case CrtClosed:
- // Two consecutive quotes make a literal quote - and
- // still close quoting. See QtcProcess::quoteArg().
+ crtState = CrtBasic;
+ }
+ if (!cc)
+ break;
+ bslashes = 0;
+ rbslashes = 0;
+ } else {
+ if (cc == '\\') {
+ bslashes++;
+ if (crtState < CrtQuoted)
+ crtState = CrtInWord;
+ } else {
+ if (cc == '"') {
+ if (shellState != ShellEscaped)
+ shellState = (shellState == ShellQuoted) ? ShellBasic : ShellQuoted;
+ if (rbslashes) {
+ // Offset -1: skip possible circumflex. We have at least
+ // one backslash, so a fixed offset is ok.
+ str.insert(pos - 1, QString(rbslashes, QLatin1Char('\\')));
+ pos += rbslashes;
+ varPos += rbslashes;
+ }
+ if (!(bslashes & 1)) {
+ // Even number of backslashes, so the quote is not escaped.
+ switch (crtState) {
+ case CrtQuoted:
+ // Closing quote
+ crtState = CrtClosed;
+ break;
+ case CrtClosed:
+ // Two consecutive quotes make a literal quote - and
+ // still close quoting. See QtcProcess::quoteArg().
+ crtState = CrtInWord;
+ break;
+ case CrtHadQuote:
+ // Opening quote right after quoted expando. Can't do that.
+ return false;
+ default:
+ // Opening quote
+ crtState = CrtQuoted;
+ break;
+ }
+ } else if (crtState < CrtQuoted) {
crtState = CrtInWord;
- break;
- case CrtHadQuote:
- // Opening quote right after quoted expando. Can't do that.
- return false;
- default:
- // Opening quote
- crtState = CrtQuoted;
- break;
}
} else if (crtState < CrtQuoted) {
crtState = CrtInWord;
}
- } else if (crtState < CrtQuoted) {
- crtState = CrtInWord;
+ bslashes = 0;
+ rbslashes = 0;
}
- bslashes = 0;
- rbslashes = 0;
}
+ if (varPos == INT_MAX && !rbslashes)
+ break;
+ if (shellState == ShellEscaped)
+ shellState = ShellBasic;
}
- if (varPos == INT_MAX && !rbslashes)
- break;
- if (shellState == ShellEscaped)
- shellState = ShellBasic;
- }
- pos++;
- }
-#else
- MxState state = { MxBasic, false };
- QStack<MxState> sstack;
- QStack<MxSave> ostack;
-
- while (pos < str.length()) {
- if (pos == varPos) {
- // Our expansion rules trigger in any context
- if (state.dquote) {
- // We are within a double-quoted string. Escape relevant meta characters.
- rsts.replace(QRegExp(QLatin1String("([$`\"\\\\])")), QLatin1String("\\\\1"));
- } else if (state.current == MxSingleQuote) {
- // We are within a single-quoted string. "Suspend" single-quoting and put a
- // single escaped quote for each single quote inside the string.
- rsts.replace(QLatin1Char('\''), QLatin1String("'\\''"));
- } else if (rsts.isEmpty() || hasSpecialCharsUnix(rsts)) {
- // String contains "quote-worthy" characters. Use single quoting - but
- // that choice is arbitrary.
- rsts.replace(QLatin1Char('\''), QLatin1String("'\\''"));
- rsts.prepend(QLatin1Char('\''));
- rsts.append(QLatin1Char('\''));
- } // Else just use the string verbatim.
- str.replace(pos, varLen, rsts);
- pos += rsts.length();
- varPos = pos;
- if (!(varLen = mx->findMacro(str, &varPos, &rsts)))
- break;
- continue;
+ pos++;
}
- ushort cc = str.unicode()[pos].unicode();
- if (state.current == MxSingleQuote) {
- // Single quoted context - only the single quote has any special meaning.
- if (cc == '\'')
- state = sstack.pop();
- } else if (cc == '\\') {
- // In any other context, the backslash starts an escape.
- pos += 2;
- if (varPos < pos)
- return false; // Backslash'd quoted expando would be Bad (TM).
- continue;
- } else if (cc == '$') {
- cc = str.unicode()[++pos].unicode();
- if (cc == '(') {
- sstack.push(state);
- if (str.unicode()[pos + 1].unicode() == '(') {
- // $(( starts a math expression. This may also be a $( ( in fact,
- // so we push the current string and offset on a stack so we can retry.
- MxSave sav = { str, pos + 2, varPos };
- ostack.push(sav);
- state.current = MxMath;
- pos += 2;
- continue;
- } else {
- // $( starts a command substitution. This actually "opens a new context"
- // which overrides surrounding double quoting.
- state.current = MxParen;
- state.dquote = false;
- }
- } else if (cc == '{') {
- // ${ starts a "braced" variable substitution.
- sstack.push(state);
- state.current = MxSubst;
- } // Else assume that a "bare" variable substitution has started
- } else if (cc == '`') {
- // Backticks are evil, as every shell interprets escapes within them differently,
- // which is a danger for the quoting of our own expansions.
- // So we just apply *our* rules (which match bash) and transform it into a POSIX
- // command substitution which has clear semantics.
- str.replace(pos, 1, QLatin1String("$( " )); // add space -> avoid creating $((
- varPos += 2;
- int pos2 = pos += 3;
- forever {
- if (pos2 >= str.length())
- return false; // Syntax error - unterminated backtick expression.
- cc = str.unicode()[pos2].unicode();
- if (cc == '`')
+ } else {
+ // !Windows
+ MxState state = { MxBasic, false };
+ QStack<MxState> sstack;
+ QStack<MxSave> ostack;
+
+ while (pos < str.length()) {
+ if (pos == varPos) {
+ // Our expansion rules trigger in any context
+ if (state.dquote) {
+ // We are within a double-quoted string. Escape relevant meta characters.
+ rsts.replace(QRegExp(QLatin1String("([$`\"\\\\])")), QLatin1String("\\\\1"));
+ } else if (state.current == MxSingleQuote) {
+ // We are within a single-quoted string. "Suspend" single-quoting and put a
+ // single escaped quote for each single quote inside the string.
+ rsts.replace(QLatin1Char('\''), QLatin1String("'\\''"));
+ } else if (rsts.isEmpty() || hasSpecialCharsUnix(rsts)) {
+ // String contains "quote-worthy" characters. Use single quoting - but
+ // that choice is arbitrary.
+ rsts.replace(QLatin1Char('\''), QLatin1String("'\\''"));
+ rsts.prepend(QLatin1Char('\''));
+ rsts.append(QLatin1Char('\''));
+ } // Else just use the string verbatim.
+ str.replace(pos, varLen, rsts);
+ pos += rsts.length();
+ varPos = pos;
+ if (!(varLen = mx->findMacro(str, &varPos, &rsts)))
break;
- if (cc == '\\') {
- cc = str.unicode()[++pos2].unicode();
- if (cc == '$' || cc == '`' || cc == '\\' ||
- (cc == '"' && state.dquote))
- {
- str.remove(pos2 - 1, 1);
- if (varPos >= pos2)
- varPos--;
+ continue;
+ }
+ ushort cc = str.unicode()[pos].unicode();
+ if (state.current == MxSingleQuote) {
+ // Single quoted context - only the single quote has any special meaning.
+ if (cc == '\'')
+ state = sstack.pop();
+ } else if (cc == '\\') {
+ // In any other context, the backslash starts an escape.
+ pos += 2;
+ if (varPos < pos)
+ return false; // Backslash'd quoted expando would be Bad (TM).
+ continue;
+ } else if (cc == '$') {
+ cc = str.unicode()[++pos].unicode();
+ if (cc == '(') {
+ sstack.push(state);
+ if (str.unicode()[pos + 1].unicode() == '(') {
+ // $(( starts a math expression. This may also be a $( ( in fact,
+ // so we push the current string and offset on a stack so we can retry.
+ MxSave sav = { str, pos + 2, varPos };
+ ostack.push(sav);
+ state.current = MxMath;
+ pos += 2;
continue;
+ } else {
+ // $( starts a command substitution. This actually "opens a new context"
+ // which overrides surrounding double quoting.
+ state.current = MxParen;
+ state.dquote = false;
+ }
+ } else if (cc == '{') {
+ // ${ starts a "braced" variable substitution.
+ sstack.push(state);
+ state.current = MxSubst;
+ } // Else assume that a "bare" variable substitution has started
+ } else if (cc == '`') {
+ // Backticks are evil, as every shell interprets escapes within them differently,
+ // which is a danger for the quoting of our own expansions.
+ // So we just apply *our* rules (which match bash) and transform it into a POSIX
+ // command substitution which has clear semantics.
+ str.replace(pos, 1, QLatin1String("$( " )); // add space -> avoid creating $((
+ varPos += 2;
+ int pos2 = pos += 3;
+ forever {
+ if (pos2 >= str.length())
+ return false; // Syntax error - unterminated backtick expression.
+ cc = str.unicode()[pos2].unicode();
+ if (cc == '`')
+ break;
+ if (cc == '\\') {
+ cc = str.unicode()[++pos2].unicode();
+ if (cc == '$' || cc == '`' || cc == '\\' ||
+ (cc == '"' && state.dquote))
+ {
+ str.remove(pos2 - 1, 1);
+ if (varPos >= pos2)
+ varPos--;
+ continue;
+ }
}
+ pos2++;
}
- pos2++;
- }
- str[pos2] = QLatin1Char(')');
- sstack.push(state);
- state.current = MxParen;
- state.dquote = false;
- continue;
- } else if (state.current == MxDoubleQuote) {
- // (Truly) double quoted context - only remaining special char is the closing quote.
- if (cc == '"')
- state = sstack.pop();
- } else if (cc == '\'') {
- // Start single quote if we are not in "inherited" double quoted context.
- if (!state.dquote) {
- sstack.push(state);
- state.current = MxSingleQuote;
- }
- } else if (cc == '"') {
- // Same for double quoting.
- if (!state.dquote) {
+ str[pos2] = QLatin1Char(')');
sstack.push(state);
- state.current = MxDoubleQuote;
- state.dquote = true;
- }
- } else if (state.current == MxSubst) {
- // "Braced" substitution context - only remaining special char is the closing brace.
- if (cc == '}')
- state = sstack.pop();
- } else if (cc == ')') {
- if (state.current == MxMath) {
- if (str.unicode()[pos + 1].unicode() == ')') {
+ state.current = MxParen;
+ state.dquote = false;
+ continue;
+ } else if (state.current == MxDoubleQuote) {
+ // (Truly) double quoted context - only remaining special char is the closing quote.
+ if (cc == '"')
state = sstack.pop();
- pos += 2;
- } else {
- // False hit: the $(( was a $( ( in fact.
- // ash does not care (and will complain), but bash actually parses it.
- varPos = ostack.top().varPos;
- pos = ostack.top().pos;
- str = ostack.top().str;
- ostack.pop();
- state.current = MxParen;
- state.dquote = false;
+ } else if (cc == '\'') {
+ // Start single quote if we are not in "inherited" double quoted context.
+ if (!state.dquote) {
sstack.push(state);
+ state.current = MxSingleQuote;
}
- continue;
- } else if (state.current == MxParen) {
- state = sstack.pop();
- } else {
- break; // Syntax error - excess closing parenthesis.
+ } else if (cc == '"') {
+ // Same for double quoting.
+ if (!state.dquote) {
+ sstack.push(state);
+ state.current = MxDoubleQuote;
+ state.dquote = true;
+ }
+ } else if (state.current == MxSubst) {
+ // "Braced" substitution context - only remaining special char is the closing brace.
+ if (cc == '}')
+ state = sstack.pop();
+ } else if (cc == ')') {
+ if (state.current == MxMath) {
+ if (str.unicode()[pos + 1].unicode() == ')') {
+ state = sstack.pop();
+ pos += 2;
+ } else {
+ // False hit: the $(( was a $( ( in fact.
+ // ash does not care (and will complain), but bash actually parses it.
+ varPos = ostack.top().varPos;
+ pos = ostack.top().pos;
+ str = ostack.top().str;
+ ostack.pop();
+ state.current = MxParen;
+ state.dquote = false;
+ sstack.push(state);
+ }
+ continue;
+ } else if (state.current == MxParen) {
+ state = sstack.pop();
+ } else {
+ break; // Syntax error - excess closing parenthesis.
+ }
+ } else if (cc == '}') {
+ if (state.current == MxGroup)
+ state = sstack.pop();
+ else
+ break; // Syntax error - excess closing brace.
+ } else if (cc == '(') {
+ // Context-saving command grouping.
+ sstack.push(state);
+ state.current = MxParen;
+ } else if (cc == '{') {
+ // Plain command grouping.
+ sstack.push(state);
+ state.current = MxGroup;
}
- } else if (cc == '}') {
- if (state.current == MxGroup)
- state = sstack.pop();
- else
- break; // Syntax error - excess closing brace.
- } else if (cc == '(') {
- // Context-saving command grouping.
- sstack.push(state);
- state.current = MxParen;
- } else if (cc == '{') {
- // Plain command grouping.
- sstack.push(state);
- state.current = MxGroup;
+ pos++;
}
- pos++;
+ // FIXME? May complain if (!sstack.empty()), but we don't really care anyway.
}
- // 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,252 +1202,252 @@ bool QtcProcess::ArgIterator::next()
m_simple = true;
m_value.clear();
-#ifdef Q_OS_WIN
- enum { // cmd.exe parsing state
- ShellBasic, // initial state
- ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
- ShellEscaped // circumflex-escaped state => next char is not interpreted
- } shellState = ShellBasic;
- enum { // CommandLineToArgv() parsing state and some more
- CrtBasic, // initial state
- CrtInWord, // in non-whitespace
- CrtClosed, // previous char closed the double-quoting
- CrtQuoted // double-quoted state => spaces don't split tokens
- } crtState = CrtBasic;
- enum { NoVar, NewVar, FullVar } varState = NoVar; // inside a potential env variable expansion
- int bslashes = 0; // number of preceding backslashes
-
- for (;; m_pos++) {
- ushort cc = m_pos < m_str->length() ? m_str->unicode()[m_pos].unicode() : 0;
- if (shellState == ShellBasic && cc == '^') {
- varState = NoVar;
- shellState = ShellEscaped;
- } else if ((shellState == ShellBasic && isMetaChar(cc)) || !cc) { // A "bit" simplistic ...
- // We ignore crtQuote state here. Whatever ...
- doReturn:
- if (m_simple)
- while (--bslashes >= 0)
- m_value += QLatin1Char('\\');
- else
- m_value.clear();
- if (crtState != CrtBasic) {
- m_prev = prev;
- return true;
- }
- return false;
- } else {
- if (crtState != CrtQuoted && (cc == ' ' || cc == '\t')) {
+ if (m_osType == OsTypeWindows) {
+ enum { // cmd.exe parsing state
+ ShellBasic, // initial state
+ ShellQuoted, // double-quoted state => *no* other meta chars are interpreted
+ ShellEscaped // circumflex-escaped state => next char is not interpreted
+ } shellState = ShellBasic;
+ enum { // CommandLineToArgv() parsing state and some more
+ CrtBasic, // initial state
+ CrtInWord, // in non-whitespace
+ CrtClosed, // previous char closed the double-quoting
+ CrtQuoted // double-quoted state => spaces don't split tokens
+ } crtState = CrtBasic;
+ enum { NoVar, NewVar, FullVar } varState = NoVar; // inside a potential env variable expansion
+ int bslashes = 0; // number of preceding backslashes
+
+ for (;; m_pos++) {
+ ushort cc = m_pos < m_str->length() ? m_str->unicode()[m_pos].unicode() : 0;
+ if (shellState == ShellBasic && cc == '^') {
+ varState = NoVar;
+ shellState = ShellEscaped;
+ } else if ((shellState == ShellBasic && isMetaCharWin(cc)) || !cc) { // A "bit" simplistic ...
+ // We ignore crtQuote state here. Whatever ...
+ doReturn:
+ if (m_simple)
+ while (--bslashes >= 0)
+ m_value += QLatin1Char('\\');
+ else
+ m_value.clear();
if (crtState != CrtBasic) {
- // We'll lose shellQuote state here. Whatever ...
- goto doReturn;
+ m_prev = prev;
+ return true;
}
+ return false;
} else {
- if (cc == '\\') {
- bslashes++;
- if (crtState != CrtQuoted)
- crtState = CrtInWord;
- varState = NoVar;
+ if (crtState != CrtQuoted && (cc == ' ' || cc == '\t')) {
+ if (crtState != CrtBasic) {
+ // We'll lose shellQuote state here. Whatever ...
+ goto doReturn;
+ }
} else {
- if (cc == '"') {
- varState = NoVar;
- if (shellState != ShellEscaped)
- shellState = (shellState == ShellQuoted) ? ShellBasic : ShellQuoted;
- int obslashes = bslashes;
- bslashes >>= 1;
- if (!(obslashes & 1)) {
- // Even number of backslashes, so the quote is not escaped.
- switch (crtState) {
- case CrtQuoted:
- // Closing quote
- crtState = CrtClosed;
- continue;
- case CrtClosed:
- // Two consecutive quotes make a literal quote - and
- // still close quoting. See quoteArg().
- crtState = CrtInWord;
- break;
- default:
- // Opening quote
- crtState = CrtQuoted;
- continue;
- }
- } else if (crtState != CrtQuoted) {
+ if (cc == '\\') {
+ bslashes++;
+ if (crtState != CrtQuoted)
crtState = CrtInWord;
- }
+ varState = NoVar;
} else {
- if (cc == '%') {
- if (varState == FullVar) {
- m_simple = false;
- varState = NoVar;
- } else {
- varState = NewVar;
+ if (cc == '"') {
+ varState = NoVar;
+ if (shellState != ShellEscaped)
+ shellState = (shellState == ShellQuoted) ? ShellBasic : ShellQuoted;
+ int obslashes = bslashes;
+ bslashes >>= 1;
+ if (!(obslashes & 1)) {
+ // Even number of backslashes, so the quote is not escaped.
+ switch (crtState) {
+ case CrtQuoted:
+ // Closing quote
+ crtState = CrtClosed;
+ continue;
+ case CrtClosed:
+ // Two consecutive quotes make a literal quote - and
+ // still close quoting. See quoteArg().
+ crtState = CrtInWord;
+ break;
+ default:
+ // Opening quote
+ crtState = CrtQuoted;
+ continue;
+ }
+ } else if (crtState != CrtQuoted) {
+ crtState = CrtInWord;
}
- } else if (varState != NoVar) {
- // This check doesn't really reflect cmd reality, but it is an
- // approximation of what would be sane.
- varState = (cc == '_' || cc == '-' || cc == '.'
- || QChar(cc).isLetterOrNumber()) ? FullVar : NoVar;
+ } else {
+ if (cc == '%') {
+ if (varState == FullVar) {
+ m_simple = false;
+ varState = NoVar;
+ } else {
+ varState = NewVar;
+ }
+ } else if (varState != NoVar) {
+ // This check doesn't really reflect cmd reality, but it is an
+ // approximation of what would be sane.
+ varState = (cc == '_' || cc == '-' || cc == '.'
+ || QChar(cc).isLetterOrNumber()) ? FullVar : NoVar;
+ }
+ if (crtState != CrtQuoted)
+ crtState = CrtInWord;
}
- if (crtState != CrtQuoted)
- crtState = CrtInWord;
+ for (; bslashes > 0; bslashes--)
+ m_value += QLatin1Char('\\');
+ m_value += QChar(cc);
}
- for (; bslashes > 0; bslashes--)
- m_value += QLatin1Char('\\');
- m_value += QChar(cc);
}
+ if (shellState == ShellEscaped)
+ shellState = ShellBasic;
}
- if (shellState == ShellEscaped)
- shellState = ShellBasic;
}
- }
-#else
- MxState state = { MxBasic, false };
- QStack<MxState> sstack;
- QStack<int> ostack;
- bool hadWord = false;
-
- for (; m_pos < m_str->length(); m_pos++) {
- ushort cc = m_str->unicode()[m_pos].unicode();
- if (state.current == MxSingleQuote) {
- if (cc == '\'') {
- state = sstack.pop();
- continue;
- }
- } else if (cc == '\\') {
- if (++m_pos >= m_str->length())
- break;
- cc = m_str->unicode()[m_pos].unicode();
- if (state.dquote && cc != '"' && cc != '\\' && cc != '$' && cc != '`')
- m_value += QLatin1Char('\\');
- } else if (cc == '$') {
- if (++m_pos >= m_str->length())
- break;
- cc = m_str->unicode()[m_pos].unicode();
- if (cc == '(') {
- sstack.push(state);
+ } else {
+ MxState state = { MxBasic, false };
+ QStack<MxState> sstack;
+ QStack<int> ostack;
+ bool hadWord = false;
+
+ for (; m_pos < m_str->length(); m_pos++) {
+ ushort cc = m_str->unicode()[m_pos].unicode();
+ if (state.current == MxSingleQuote) {
+ if (cc == '\'') {
+ state = sstack.pop();
+ continue;
+ }
+ } else if (cc == '\\') {
+ if (++m_pos >= m_str->length())
+ break;
+ cc = m_str->unicode()[m_pos].unicode();
+ if (state.dquote && cc != '"' && cc != '\\' && cc != '$' && cc != '`')
+ m_value += QLatin1Char('\\');
+ } else if (cc == '$') {
if (++m_pos >= m_str->length())
break;
- if (m_str->unicode()[m_pos].unicode() == '(') {
- ostack.push(m_pos);
- state.current = MxMath;
+ cc = m_str->unicode()[m_pos].unicode();
+ if (cc == '(') {
+ sstack.push(state);
+ if (++m_pos >= m_str->length())
+ break;
+ if (m_str->unicode()[m_pos].unicode() == '(') {
+ ostack.push(m_pos);
+ state.current = MxMath;
+ } else {
+ state.dquote = false;
+ state.current = MxParen;
+ // m_pos too far by one now - whatever.
+ }
+ } else if (cc == '{') {
+ sstack.push(state);
+ state.current = MxSubst;
} else {
- state.dquote = false;
- state.current = MxParen;
// m_pos too far by one now - whatever.
}
- } else if (cc == '{') {
- sstack.push(state);
- state.current = MxSubst;
- } else {
- // m_pos too far by one now - whatever.
- }
- m_simple = false;
- hadWord = true;
- continue;
- } else if (cc == '`') {
- forever {
- if (++m_pos >= m_str->length()) {
- m_simple = false;
- m_prev = prev;
- return true;
- }
- cc = m_str->unicode()[m_pos].unicode();
- if (cc == '`')
- break;
- if (cc == '\\')
- m_pos++; // m_pos may be too far by one now - whatever.
- }
- m_simple = false;
- hadWord = true;
- continue;
- } else if (state.current == MxDoubleQuote) {
- if (cc == '"') {
- state = sstack.pop();
- continue;
- }
- } else if (cc == '\'') {
- if (!state.dquote) {
- sstack.push(state);
- state.current = MxSingleQuote;
+ m_simple = false;
hadWord = true;
continue;
- }
- } else if (cc == '"') {
- if (!state.dquote) {
- sstack.push(state);
- state.dquote = true;
- state.current = MxDoubleQuote;
+ } else if (cc == '`') {
+ forever {
+ if (++m_pos >= m_str->length()) {
+ m_simple = false;
+ m_prev = prev;
+ return true;
+ }
+ cc = m_str->unicode()[m_pos].unicode();
+ if (cc == '`')
+ break;
+ if (cc == '\\')
+ m_pos++; // m_pos may be too far by one now - whatever.
+ }
+ m_simple = false;
hadWord = true;
continue;
- }
- } else if (state.current == MxSubst) {
- if (cc == '}')
- state = sstack.pop();
- continue; // Not simple anyway
- } else if (cc == ')') {
- if (state.current == MxMath) {
- if (++m_pos >= m_str->length())
- break;
- if (m_str->unicode()[m_pos].unicode() == ')') {
- ostack.pop();
+ } else if (state.current == MxDoubleQuote) {
+ if (cc == '"') {
state = sstack.pop();
- } else {
- // false hit: the $(( was a $( ( in fact.
- // ash does not care, but bash does.
- m_pos = ostack.pop();
- state.current = MxParen;
- state.dquote = false;
+ continue;
+ }
+ } else if (cc == '\'') {
+ if (!state.dquote) {
sstack.push(state);
+ state.current = MxSingleQuote;
+ hadWord = true;
+ continue;
+ }
+ } else if (cc == '"') {
+ if (!state.dquote) {
+ sstack.push(state);
+ state.dquote = true;
+ state.current = MxDoubleQuote;
+ hadWord = true;
+ continue;
+ }
+ } else if (state.current == MxSubst) {
+ if (cc == '}')
+ state = sstack.pop();
+ continue; // Not simple anyway
+ } else if (cc == ')') {
+ if (state.current == MxMath) {
+ if (++m_pos >= m_str->length())
+ break;
+ if (m_str->unicode()[m_pos].unicode() == ')') {
+ ostack.pop();
+ state = sstack.pop();
+ } else {
+ // false hit: the $(( was a $( ( in fact.
+ // ash does not care, but bash does.
+ m_pos = ostack.pop();
+ state.current = MxParen;
+ state.dquote = false;
+ sstack.push(state);
+ }
+ continue;
+ } else if (state.current == MxParen) {
+ state = sstack.pop();
+ continue;
+ } else {
+ break;
}
- continue;
- } else if (state.current == MxParen) {
- state = sstack.pop();
- continue;
- } else {
- break;
- }
#if 0 // MxGroup is impossible, see below.
- } else if (cc == '}') {
- if (state.current == MxGroup) {
- state = sstack.pop();
- continue;
- }
+ } else if (cc == '}') {
+ if (state.current == MxGroup) {
+ state = sstack.pop();
+ continue;
+ }
#endif
- } else if (cc == '(') {
- sstack.push(state);
- state.current = MxParen;
- m_simple = false;
- hadWord = true;
+ } else if (cc == '(') {
+ sstack.push(state);
+ state.current = MxParen;
+ m_simple = false;
+ hadWord = true;
#if 0 // Should match only at the beginning of a command, which we never have currently.
- } else if (cc == '{') {
- sstack.push(state);
- state.current = MxGroup;
- m_simple = false;
- hadWord = true;
- continue;
-#endif
- } else if (cc == '<' || cc == '>' || cc == '&' || cc == '|' || cc == ';') {
- if (sstack.isEmpty())
- break;
- } else if (cc == ' ' || cc == '\t') {
- if (!hadWord)
+ } else if (cc == '{') {
+ sstack.push(state);
+ state.current = MxGroup;
+ m_simple = false;
+ hadWord = true;
continue;
- if (sstack.isEmpty())
- break;
+#endif
+ } else if (cc == '<' || cc == '>' || cc == '&' || cc == '|' || cc == ';') {
+ if (sstack.isEmpty())
+ break;
+ } else if (cc == ' ' || cc == '\t') {
+ if (!hadWord)
+ continue;
+ if (sstack.isEmpty())
+ break;
+ }
+ m_value += QChar(cc);
+ hadWord = true;
}
- m_value += QChar(cc);
- hadWord = true;
- }
- // TODO: Possibly complain here if (!sstack.empty())
- if (!m_simple)
- m_value.clear();
- if (hadWord) {
- m_prev = prev;
- return true;
+ // TODO: Possibly complain here if (!sstack.empty())
+ if (!m_simple)
+ m_value.clear();
+ if (hadWord) {
+ m_prev = prev;
+ return true;
+ }
+ return false;
}
- 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
diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h
index 66cbcbda5b..ca1dff19fc 100644
--- a/src/libs/utils/qtcprocess.h
+++ b/src/libs/utils/qtcprocess.h
@@ -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,
- const Environment *env = 0, const QString *pwd = 0);
+ 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(); }
diff --git a/src/plugins/coreplugin/fileutils.cpp b/src/plugins/coreplugin/fileutils.cpp
index 296beb336d..214ad3a66d 100644
--- a/src/plugins/coreplugin/fileutils.cpp
+++ b/src/plugins/coreplugin/fileutils.cpp
@@ -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")));
}
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index f8ef1af82e..b828ceaac0 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -4771,19 +4771,20 @@ 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 (perr != Utils::QtcProcess::SplitOk) {
- // perr == BadQuoting is never returned on Windows
- // FIXME? QTCREATORBUG-2809
- handleAdapterStartFailed(QCoreApplication::translate("DebuggerEngine", // Same message in CdbEngine
- "Debugging complex command lines is currently not supported on Windows."), Core::Id());
- return false;
+ 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
+ handleAdapterStartFailed(QCoreApplication::translate("DebuggerEngine", // Same message in CdbEngine
+ "Debugging complex command lines is currently not supported on Windows."), Core::Id());
+ return false;
+ }
}
-#endif
return true;
}
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index 54ac32b28e..f4a7e1da21 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -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
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 953033ca35..fbe39458f6 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -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);
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index b097c490df..4042c4b478 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -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;
}
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index ca63fc800d..59647310cc 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -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;
diff --git a/src/plugins/projectexplorer/processparameters.cpp b/src/plugins/projectexplorer/processparameters.cpp
index e702292c5c..711209b872 100644
--- a/src/plugins/projectexplorer/processparameters.cpp
+++ b/src/plugins/projectexplorer/processparameters.cpp
@@ -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
diff --git a/src/plugins/remotelinux/linuxdeviceprocess.cpp b/src/plugins/remotelinux/linuxdeviceprocess.cpp
index c6ec627708..cf60d6a2e0 100644
--- a/src/plugins/remotelinux/linuxdeviceprocess.cpp
+++ b/src/plugins/remotelinux/linuxdeviceprocess.cpp
@@ -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;
}
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
index 2e5d1b7d37..90bfa3123e 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
@@ -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
diff --git a/tests/auto/qtcprocess/tst_qtcprocess.cpp b/tests/auto/qtcprocess/tst_qtcprocess.cpp
index 797f08bdb2..a68b278d13 100644
--- a/tests/auto/qtcprocess/tst_qtcprocess.cpp
+++ b/tests/auto/qtcprocess/tst_qtcprocess.cpp
@@ -28,6 +28,7 @@
****************************************************************************/
#include <utils/qtcprocess.h>
+#include <utils/hostosinfo.h>
#include <utils/stringutils.h>
#include <utils/environment.h>
@@ -57,6 +58,7 @@ class tst_QtcProcess : public QObject
private slots:
void initTestCase();
+
void splitArgs_data();
void splitArgs();
void prepareArgs_data();
@@ -67,120 +69,123 @@ private slots:
void expandMacros();
void iterations_data();
void iterations();
- void iteratorEdits();
+ void iteratorEditsWindows();
+ void iteratorEditsLinux();
private:
- Environment env;
- MacroMapExpander mx;
-#ifdef Q_OS_UNIX
+ void iteratorEditsHelper(OsType osType);
+
+ Environment envWindows;
+ Environment envLinux;
+
+ MacroMapExpander mxWin;
+ MacroMapExpander mxUnix;
QString homeStr;
QString home;
-#endif
};
void tst_QtcProcess::initTestCase()
{
-#ifdef Q_OS_UNIX
homeStr = QLatin1String("@HOME@");
home = QDir::homePath();
-#endif
-
- env.set("empty", "");
- env.set("word", "hi");
- env.set("words", "hi ho");
- env.set("spacedwords", " hi ho sucker ");
-
-#ifdef Q_OS_WIN
- mx.insert("a", "hi");
- mx.insert("aa", "hi ho");
-
- mx.insert("b", "h\\i");
- mx.insert("c", "\\hi");
- mx.insert("d", "hi\\");
- mx.insert("ba", "h\\i ho");
- mx.insert("ca", "\\hi ho");
- mx.insert("da", "hi ho\\");
-
- mx.insert("e", "h\"i");
- mx.insert("f", "\"hi");
- mx.insert("g", "hi\"");
-
- mx.insert("h", "h\\\"i");
- mx.insert("i", "\\\"hi");
- mx.insert("j", "hi\\\"");
-
- mx.insert("k", "&special;");
-
- mx.insert("x", "\\");
- mx.insert("y", "\"");
-#else
- mx.insert("a", "hi");
- mx.insert("b", "hi ho");
- mx.insert("c", "&special;");
- mx.insert("d", "h\\i");
- mx.insert("e", "h\"i");
- mx.insert("f", "h'i");
-#endif
- mx.insert("z", "");
+
+ QStringList env;
+ env << "empty=" << "word=hi" << "words=hi ho" << "spacedwords= hi ho sucker ";
+ envWindows = Environment(env, OsTypeWindows);
+ 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", "");
}
+
Q_DECLARE_METATYPE(QtcProcess::SplitError)
+Q_DECLARE_METATYPE(Utils::OsType)
void tst_QtcProcess::splitArgs_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
QTest::addColumn<QtcProcess::SplitError>("err");
+ QTest::addColumn<Utils::OsType>("os");
static const struct {
const char * const in;
const char * const out;
const QtcProcess::SplitError err;
+ const OsType os;
} vals[] = {
-#ifdef Q_OS_WIN
- { "", "", QtcProcess::SplitOk },
- { " ", "", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", "hi ho", QtcProcess::SplitOk },
- { "\"hi ho\" \"hi\" ho ", "\"hi ho\" hi ho", QtcProcess::SplitOk },
- { "\\", "\\", QtcProcess::SplitOk },
- { "\\\"", "\"\"\\^\"\"\"", QtcProcess::SplitOk },
- { "\"hi\"\"\"ho\"", "\"hi\"\\^\"\"ho\"", QtcProcess::SplitOk },
- { "\\\\\\\"", "\"\"\\\\\\^\"\"\"", QtcProcess::SplitOk },
- { " ^^ ", "\"^^\"", QtcProcess::SplitOk },
- { "hi\"", "", QtcProcess::BadQuoting },
- { "hi\"dood", "", QtcProcess::BadQuoting },
- { "%var%", "%var%", QtcProcess::SplitOk },
-#else
- { "", "", QtcProcess::SplitOk },
- { " ", "", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", "hi ho", QtcProcess::SplitOk },
- { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk },
- { " \\ ", "' '", QtcProcess::SplitOk },
- { " \\\" ", "'\"'", QtcProcess::SplitOk },
- { " '\"' ", "'\"'", QtcProcess::SplitOk },
- { " \"\\\"\" ", "'\"'", QtcProcess::SplitOk },
- { "hi'", "", QtcProcess::BadQuoting },
- { "hi\"dood", "", QtcProcess::BadQuoting },
- { "$var", "'$var'", QtcProcess::SplitOk },
- { "~", "@HOME@", QtcProcess::SplitOk },
- { "~ foo", "@HOME@ foo", QtcProcess::SplitOk },
- { "foo ~", "foo @HOME@", QtcProcess::SplitOk },
- { "~/foo", "@HOME@/foo", QtcProcess::SplitOk },
- { "~foo", "'~foo'", QtcProcess::SplitOk },
-#endif
+ { "", "", QtcProcess::SplitOk, OsTypeWindows },
+ { " ", "", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { " hi ho ", "hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi ho\" \"hi\" ho ", "\"hi ho\" hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\", "\\", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\"", "\"\"\\^\"\"\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi\"\"\"ho\"", "\"hi\"\\^\"\"ho\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\\\\\"", "\"\"\\\\\\^\"\"\"", QtcProcess::SplitOk, OsTypeWindows },
+ { " ^^ ", "\"^^\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi\"", "", QtcProcess::BadQuoting, OsTypeWindows },
+ { "hi\"dood", "", QtcProcess::BadQuoting, OsTypeWindows },
+ { "%var%", "%var%", QtcProcess::SplitOk, OsTypeWindows },
+
+ { "", "", QtcProcess::SplitOk, OsTypeLinux },
+ { " ", "", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " hi ho ", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " \\ ", "' '", QtcProcess::SplitOk, OsTypeLinux },
+ { " \\\" ", "'\"'", QtcProcess::SplitOk, OsTypeLinux },
+ { " '\"' ", "'\"'", QtcProcess::SplitOk, OsTypeLinux },
+ { " \"\\\"\" ", "'\"'", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi'", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "hi\"dood", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "$var", "'$var'", QtcProcess::SplitOk, OsTypeLinux },
+ { "~", "@HOME@", QtcProcess::SplitOk, OsTypeLinux },
+ { "~ foo", "@HOME@ foo", QtcProcess::SplitOk, OsTypeLinux },
+ { "foo ~", "foo @HOME@", QtcProcess::SplitOk, OsTypeLinux },
+ { "~/foo", "@HOME@/foo", QtcProcess::SplitOk, OsTypeLinux },
+ { "~foo", "'~foo'", QtcProcess::SplitOk, OsTypeLinux }
};
- for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
+ for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
+ QString out = QString::fromLatin1(vals[i].out);
+ if (vals[i].os == OsTypeLinux)
+ out.replace(homeStr, home);
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
- << QString::fromLatin1(vals[i].out)
-#ifdef Q_OS_UNIX
- .replace(homeStr, home)
-#endif
- << vals[i].err;
+ << out << vals[i].err << vals[i].os;
+ }
}
void tst_QtcProcess::splitArgs()
@@ -188,9 +193,10 @@ void tst_QtcProcess::splitArgs()
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(QtcProcess::SplitError, err);
+ QFETCH(Utils::OsType, os);
QtcProcess::SplitError outerr;
- QString outstr = QtcProcess::joinArgs(QtcProcess::splitArgs(in, false, &outerr));
+ QString outstr = QtcProcess::joinArgs(QtcProcess::splitArgs(in, os, false, &outerr), os);
QCOMPARE(outerr, err);
if (err == QtcProcess::SplitOk)
QCOMPARE(outstr, out);
@@ -201,53 +207,53 @@ void tst_QtcProcess::prepareArgs_data()
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
QTest::addColumn<QtcProcess::SplitError>("err");
+ QTest::addColumn<OsType>("os");
static const struct {
const char * const in;
const char * const out;
const QtcProcess::SplitError err;
+ const OsType os;
} vals[] = {
-#ifdef Q_OS_WIN
- { "", "", QtcProcess::SplitOk },
- { " ", " ", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", " hi ho ", QtcProcess::SplitOk },
- { "\"hi ho\" \"hi\" ho ", "\"hi ho\" \"hi\" ho ", QtcProcess::SplitOk },
- { "\\", "\\", QtcProcess::SplitOk },
- { "\\\"", "\\\"", QtcProcess::SplitOk },
- { "\"hi\"\"ho\"", "\"hi\"\"ho\"", QtcProcess::SplitOk },
- { "\\\\\\\"", "\\\\\\\"", QtcProcess::SplitOk },
- { "^^", "^", QtcProcess::SplitOk },
- { "hi\"", "hi\"", QtcProcess::SplitOk },
- { "hi\"dood", "hi\"dood", QtcProcess::SplitOk },
- { "%var%", "", QtcProcess::FoundMeta },
- { "echo hi > file", "", QtcProcess::FoundMeta },
-#else
- { "", "", QtcProcess::SplitOk },
- { " ", "", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", "hi ho", QtcProcess::SplitOk },
- { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk },
- { " \\ ", "' '", QtcProcess::SplitOk },
- { "hi'", "", QtcProcess::BadQuoting },
- { "hi\"dood", "", QtcProcess::BadQuoting },
- { "$var", "", QtcProcess::FoundMeta },
- { "~", "@HOME@", QtcProcess::SplitOk },
- { "~ foo", "@HOME@ foo", QtcProcess::SplitOk },
- { "~/foo", "@HOME@/foo", QtcProcess::SplitOk },
- { "~foo", "", QtcProcess::FoundMeta },
-#endif
+ { " ", " ", QtcProcess::SplitOk, OsTypeWindows },
+ { "", "", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { " hi ho ", " hi ho ", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi ho\" \"hi\" ho ", "\"hi ho\" \"hi\" ho ", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\", "\\", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\"", "\\\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi\"\"ho\"", "\"hi\"\"ho\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\\\\\"", "\\\\\\\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "^^", "^", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi\"", "hi\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi\"dood", "hi\"dood", QtcProcess::SplitOk, OsTypeWindows },
+ { "%var%", "", QtcProcess::FoundMeta, OsTypeWindows },
+ { "echo hi > file", "", QtcProcess::FoundMeta, OsTypeWindows },
+
+ { "", "", QtcProcess::SplitOk, OsTypeLinux },
+ { " ", "", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " hi ho ", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " \\ ", "' '", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi'", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "hi\"dood", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "$var", "", QtcProcess::FoundMeta, OsTypeLinux },
+ { "~", "@HOME@", QtcProcess::SplitOk, OsTypeLinux },
+ { "~ foo", "@HOME@ foo", QtcProcess::SplitOk, OsTypeLinux },
+ { "~/foo", "@HOME@/foo", QtcProcess::SplitOk, OsTypeLinux },
+ { "~foo", "", QtcProcess::FoundMeta, OsTypeLinux }
};
- for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
+ for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
+ QString out = QString::fromLatin1(vals[i].out);
+ if (vals[i].os == OsTypeLinux)
+ out.replace(homeStr, home);
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
- << QString::fromLatin1(vals[i].out)
-#ifdef Q_OS_UNIX
- .replace(homeStr, home)
-#endif
- << vals[i].err;
+ << out << vals[i].err << vals[i].os;
+ }
}
void tst_QtcProcess::prepareArgs()
@@ -255,14 +261,12 @@ void tst_QtcProcess::prepareArgs()
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(QtcProcess::SplitError, err);
+ QFETCH(OsType, os);
QtcProcess::SplitError outerr;
- QString outstr;
-#ifdef Q_OS_WIN
- outstr = QtcProcess::prepareArgs(in, &outerr);
-#else
- outstr = QtcProcess::joinArgs(QtcProcess::prepareArgs(in, &outerr));
-#endif
+ QtcProcess::Arguments args = QtcProcess::prepareArgs(in, &outerr, os);
+ QString outstr = args.toString();
+
QCOMPARE(outerr, err);
if (err == QtcProcess::SplitOk)
QCOMPARE(outstr, out);
@@ -273,70 +277,73 @@ void tst_QtcProcess::prepareArgsEnv_data()
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
QTest::addColumn<QtcProcess::SplitError>("err");
+ QTest::addColumn<OsType>("os");
static const struct {
const char * const in;
const char * const out;
const QtcProcess::SplitError err;
+ const OsType os;
} vals[] = {
-#ifdef Q_OS_WIN
- { "", "", QtcProcess::SplitOk },
- { " ", " ", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", " hi ho ", QtcProcess::SplitOk },
- { "\"hi ho\" \"hi\" ho ", "\"hi ho\" \"hi\" ho ", QtcProcess::SplitOk },
- { "\\", "\\", QtcProcess::SplitOk },
- { "\\\"", "\\\"", QtcProcess::SplitOk },
- { "\"hi\"\"ho\"", "\"hi\"\"ho\"", QtcProcess::SplitOk },
- { "\\\\\\\"", "\\\\\\\"", QtcProcess::SplitOk },
- { "^^", "^", QtcProcess::SplitOk },
- { "hi\"", "hi\"", QtcProcess::SplitOk },
- { "hi\"dood", "hi\"dood", QtcProcess::SplitOk },
- { "%empty%", "%empty%", QtcProcess::SplitOk }, // Yep, no empty variables on Windows.
- { "%word%", "hi", QtcProcess::SplitOk },
- { " %word% ", " hi ", QtcProcess::SplitOk },
- { "%words%", "hi ho", QtcProcess::SplitOk },
- { "%nonsense%words%", "%nonsensehi ho", QtcProcess::SplitOk },
- { "fail%nonsense%words%", "fail%nonsensehi ho", QtcProcess::SplitOk },
- { "%words%words%", "hi howords%", QtcProcess::SplitOk },
- { "%words%%words%", "hi hohi ho", QtcProcess::SplitOk },
- { "echo hi > file", "", QtcProcess::FoundMeta },
-#else
- { "", "", QtcProcess::SplitOk },
- { " ", "", QtcProcess::SplitOk },
- { "hi", "hi", QtcProcess::SplitOk },
- { "hi ho", "hi ho", QtcProcess::SplitOk },
- { " hi ho ", "hi ho", QtcProcess::SplitOk },
- { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk },
- { " \\ ", "' '", QtcProcess::SplitOk },
- { "hi'", "", QtcProcess::BadQuoting },
- { "hi\"dood", "", QtcProcess::BadQuoting },
- { "$empty", "", QtcProcess::SplitOk },
- { "$word", "hi", QtcProcess::SplitOk },
- { " $word ", "hi", QtcProcess::SplitOk },
- { "${word}", "hi", QtcProcess::SplitOk },
- { " ${word} ", "hi", QtcProcess::SplitOk },
- { "$words", "hi ho", QtcProcess::SplitOk },
- { "$spacedwords", "hi ho sucker", QtcProcess::SplitOk },
- { "hi${empty}ho", "hiho", QtcProcess::SplitOk },
- { "hi${words}ho", "hihi hoho", QtcProcess::SplitOk },
- { "hi${spacedwords}ho", "hi hi ho sucker ho", QtcProcess::SplitOk },
- { "${", "", QtcProcess::BadQuoting },
- { "${var", "", QtcProcess::BadQuoting },
- { "${var ", "", QtcProcess::FoundMeta },
- { "\"hi${words}ho\"", "'hihi hoho'", QtcProcess::SplitOk },
- { "\"hi${spacedwords}ho\"", "'hi hi ho sucker ho'", QtcProcess::SplitOk },
- { "\"${", "", QtcProcess::BadQuoting },
- { "\"${var", "", QtcProcess::BadQuoting },
- { "\"${var ", "", QtcProcess::FoundMeta },
-#endif
+ { " ", " ", QtcProcess::SplitOk, OsTypeWindows },
+ { "", "", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { " hi ho ", " hi ho ", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi ho\" \"hi\" ho ", "\"hi ho\" \"hi\" ho ", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\", "\\", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\"", "\\\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\"hi\"\"ho\"", "\"hi\"\"ho\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "\\\\\\\"", "\\\\\\\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "^^", "^", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi\"", "hi\"", QtcProcess::SplitOk, OsTypeWindows },
+ { "hi\"dood", "hi\"dood", QtcProcess::SplitOk, OsTypeWindows },
+ { "%empty%", "%empty%", QtcProcess::SplitOk, OsTypeWindows }, // Yep, no empty variables on Windows.
+ { "%word%", "hi", QtcProcess::SplitOk, OsTypeWindows },
+ { " %word% ", " hi ", QtcProcess::SplitOk, OsTypeWindows },
+ { "%words%", "hi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "%nonsense%words%", "%nonsensehi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "fail%nonsense%words%", "fail%nonsensehi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "%words%words%", "hi howords%", QtcProcess::SplitOk, OsTypeWindows },
+ { "%words%%words%", "hi hohi ho", QtcProcess::SplitOk, OsTypeWindows },
+ { "echo hi > file", "", QtcProcess::FoundMeta, OsTypeWindows },
+
+ { "", "", QtcProcess::SplitOk, OsTypeLinux },
+ { " ", "", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi ho", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " hi ho ", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { "'hi ho' \"hi\" ho ", "'hi ho' hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { " \\ ", "' '", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi'", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "hi\"dood", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "$empty", "", QtcProcess::SplitOk, OsTypeLinux },
+ { "$word", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { " $word ", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { "${word}", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { " ${word} ", "hi", QtcProcess::SplitOk, OsTypeLinux },
+ { "$words", "hi ho", QtcProcess::SplitOk, OsTypeLinux },
+ { "$spacedwords", "hi ho sucker", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi${empty}ho", "hiho", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi${words}ho", "hihi hoho", QtcProcess::SplitOk, OsTypeLinux },
+ { "hi${spacedwords}ho", "hi hi ho sucker ho", QtcProcess::SplitOk, OsTypeLinux },
+ { "${", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "${var", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "${var ", "", QtcProcess::FoundMeta, OsTypeLinux },
+ { "\"hi${words}ho\"", "'hihi hoho'", QtcProcess::SplitOk, OsTypeLinux },
+ { "\"hi${spacedwords}ho\"", "'hi hi ho sucker ho'", QtcProcess::SplitOk, OsTypeLinux },
+ { "\"${", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "\"${var", "", QtcProcess::BadQuoting, OsTypeLinux },
+ { "\"${var ", "", QtcProcess::FoundMeta, OsTypeLinux },
};
- for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
+ for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
+ QString out = QString::fromLatin1(vals[i].out);
+ if (vals[i].os == OsTypeLinux)
+ out.replace(homeStr, home);
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
- << QString::fromLatin1(vals[i].out)
- << vals[i].err;
+ << out << vals[i].err << vals[i].os;
+ }
}
void tst_QtcProcess::prepareArgsEnv()
@@ -344,14 +351,12 @@ void tst_QtcProcess::prepareArgsEnv()
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(QtcProcess::SplitError, err);
+ QFETCH(OsType, os);
QtcProcess::SplitError outerr;
- QString outstr;
-#ifdef Q_OS_WIN
- outstr = QtcProcess::prepareArgs(in, &outerr, &env);
-#else
- outstr = QtcProcess::joinArgs(QtcProcess::prepareArgs(in, &outerr, &env));
-#endif
+ QtcProcess::Arguments args = QtcProcess::prepareArgs(in, &outerr, os, os == OsTypeLinux ? &envLinux : &envWindows);
+ QString outstr = args.toString();
+
QCOMPARE(outerr, err);
if (err == QtcProcess::SplitOk)
QCOMPARE(outstr, out);
@@ -362,215 +367,215 @@ void tst_QtcProcess::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[] = {
-#ifdef Q_OS_WIN
- { "plain", 0 },
- { "%{a}", "hi" },
- { "%{aa}", "\"hi ho\"" },
- { "%{b}", "h\\i" },
- { "%{c}", "\\hi" },
- { "%{d}", "hi\\" },
- { "%{ba}", "\"h\\i ho\"" },
- { "%{ca}", "\"\\hi ho\"" },
- { "%{da}", "\"hi ho\\\\\"" }, // or "\"hi ho\"\\"
- { "%{e}", "\"h\"\\^\"\"i\"" },
- { "%{f}", "\"\"\\^\"\"hi\"" },
- { "%{g}", "\"hi\"\\^\"\"\"" },
- { "%{h}", "\"h\\\\\"\\^\"\"i\"" },
- { "%{i}", "\"\\\\\"\\^\"\"hi\"" },
- { "%{j}", "\"hi\\\\\"\\^\"\"\"" },
- { "%{k}", "\"&special;\"" },
- { "%{x}", "\\" },
- { "%{y}", "\"\"\\^\"\"\"" },
- { "%{z}", "\"\"" },
- { "^%{z}%{z}", "^%{z}%{z}" }, // stupid user check
-
- { "quoted", 0 },
- { "\"%{a}\"", "\"hi\"" },
- { "\"%{aa}\"", "\"hi ho\"" },
- { "\"%{b}\"", "\"h\\i\"" },
- { "\"%{c}\"", "\"\\hi\"" },
- { "\"%{d}\"", "\"hi\\\\\"" },
- { "\"%{ba}\"", "\"h\\i ho\"" },
- { "\"%{ca}\"", "\"\\hi ho\"" },
- { "\"%{da}\"", "\"hi ho\\\\\"" },
- { "\"%{e}\"", "\"h\"\\^\"\"i\"" },
- { "\"%{f}\"", "\"\"\\^\"\"hi\"" },
- { "\"%{g}\"", "\"hi\"\\^\"\"\"" },
- { "\"%{h}\"", "\"h\\\\\"\\^\"\"i\"" },
- { "\"%{i}\"", "\"\\\\\"\\^\"\"hi\"" },
- { "\"%{j}\"", "\"hi\\\\\"\\^\"\"\"" },
- { "\"%{k}\"", "\"&special;\"" },
- { "\"%{x}\"", "\"\\\\\"" },
- { "\"%{y}\"", "\"\"\\^\"\"\"" },
- { "\"%{z}\"", "\"\"" },
-
- { "leading bs", 0 },
- { "\\%{a}", "\\hi" },
- { "\\%{aa}", "\\\\\"hi ho\"" },
- { "\\%{b}", "\\h\\i" },
- { "\\%{c}", "\\\\hi" },
- { "\\%{d}", "\\hi\\" },
- { "\\%{ba}", "\\\\\"h\\i ho\"" },
- { "\\%{ca}", "\\\\\"\\hi ho\"" },
- { "\\%{da}", "\\\\\"hi ho\\\\\"" },
- { "\\%{e}", "\\\\\"h\"\\^\"\"i\"" },
- { "\\%{f}", "\\\\\"\"\\^\"\"hi\"" },
- { "\\%{g}", "\\\\\"hi\"\\^\"\"\"" },
- { "\\%{h}", "\\\\\"h\\\\\"\\^\"\"i\"" },
- { "\\%{i}", "\\\\\"\\\\\"\\^\"\"hi\"" },
- { "\\%{j}", "\\\\\"hi\\\\\"\\^\"\"\"" },
- { "\\%{x}", "\\\\" },
- { "\\%{y}", "\\\\\"\"\\^\"\"\"" },
- { "\\%{z}", "\\" },
-
- { "trailing bs", 0 },
- { "%{a}\\", "hi\\" },
- { "%{aa}\\", "\"hi ho\"\\" },
- { "%{b}\\", "h\\i\\" },
- { "%{c}\\", "\\hi\\" },
- { "%{d}\\", "hi\\\\" },
- { "%{ba}\\", "\"h\\i ho\"\\" },
- { "%{ca}\\", "\"\\hi ho\"\\" },
- { "%{da}\\", "\"hi ho\\\\\"\\" },
- { "%{e}\\", "\"h\"\\^\"\"i\"\\" },
- { "%{f}\\", "\"\"\\^\"\"hi\"\\" },
- { "%{g}\\", "\"hi\"\\^\"\"\"\\" },
- { "%{h}\\", "\"h\\\\\"\\^\"\"i\"\\" },
- { "%{i}\\", "\"\\\\\"\\^\"\"hi\"\\" },
- { "%{j}\\", "\"hi\\\\\"\\^\"\"\"\\" },
- { "%{x}\\", "\\\\" },
- { "%{y}\\", "\"\"\\^\"\"\"\\" },
- { "%{z}\\", "\\" },
-
- { "bs-enclosed", 0 },
- { "\\%{a}\\", "\\hi\\" },
- { "\\%{aa}\\", "\\\\\"hi ho\"\\" },
- { "\\%{b}\\", "\\h\\i\\" },
- { "\\%{c}\\", "\\\\hi\\" },
- { "\\%{d}\\", "\\hi\\\\" },
- { "\\%{ba}\\", "\\\\\"h\\i ho\"\\" },
- { "\\%{ca}\\", "\\\\\"\\hi ho\"\\" },
- { "\\%{da}\\", "\\\\\"hi ho\\\\\"\\" },
- { "\\%{e}\\", "\\\\\"h\"\\^\"\"i\"\\" },
- { "\\%{f}\\", "\\\\\"\"\\^\"\"hi\"\\" },
- { "\\%{g}\\", "\\\\\"hi\"\\^\"\"\"\\" },
- { "\\%{h}\\", "\\\\\"h\\\\\"\\^\"\"i\"\\" },
- { "\\%{i}\\", "\\\\\"\\\\\"\\^\"\"hi\"\\" },
- { "\\%{j}\\", "\\\\\"hi\\\\\"\\^\"\"\"\\" },
- { "\\%{x}\\", "\\\\\\" },
- { "\\%{y}\\", "\\\\\"\"\\^\"\"\"\\" },
- { "\\%{z}\\", "\\\\" },
-
- { "bs-enclosed and trailing literal quote", 0 },
- { "\\%{a}\\\\\\^\"", "\\hi\\\\\\^\"" },
- { "\\%{aa}\\\\\\^\"", "\\\\\"hi ho\"\\\\\\^\"" },
- { "\\%{b}\\\\\\^\"", "\\h\\i\\\\\\^\"" },
- { "\\%{c}\\\\\\^\"", "\\\\hi\\\\\\^\"" },
- { "\\%{d}\\\\\\^\"", "\\hi\\\\\\\\\\^\"" },
- { "\\%{ba}\\\\\\^\"", "\\\\\"h\\i ho\"\\\\\\^\"" },
- { "\\%{ca}\\\\\\^\"", "\\\\\"\\hi ho\"\\\\\\^\"" },
- { "\\%{da}\\\\\\^\"", "\\\\\"hi ho\\\\\"\\\\\\^\"" },
- { "\\%{e}\\\\\\^\"", "\\\\\"h\"\\^\"\"i\"\\\\\\^\"" },
- { "\\%{f}\\\\\\^\"", "\\\\\"\"\\^\"\"hi\"\\\\\\^\"" },
- { "\\%{g}\\\\\\^\"", "\\\\\"hi\"\\^\"\"\"\\\\\\^\"" },
- { "\\%{h}\\\\\\^\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\\^\"" },
- { "\\%{i}\\\\\\^\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\\^\"" },
- { "\\%{j}\\\\\\^\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\\^\"" },
- { "\\%{x}\\\\\\^\"", "\\\\\\\\\\\\\\^\"" },
- { "\\%{y}\\\\\\^\"", "\\\\\"\"\\^\"\"\"\\\\\\^\"" },
- { "\\%{z}\\\\\\^\"", "\\\\\\\\\\^\"" },
-
- { "bs-enclosed and trailing unclosed quote", 0 },
- { "\\%{a}\\\\\"", "\\hi\\\\\"" },
- { "\\%{aa}\\\\\"", "\\\\\"hi ho\"\\\\\"" },
- { "\\%{b}\\\\\"", "\\h\\i\\\\\"" },
- { "\\%{c}\\\\\"", "\\\\hi\\\\\"" },
- { "\\%{d}\\\\\"", "\\hi\\\\\\\\\"" },
- { "\\%{ba}\\\\\"", "\\\\\"h\\i ho\"\\\\\"" },
- { "\\%{ca}\\\\\"", "\\\\\"\\hi ho\"\\\\\"" },
- { "\\%{da}\\\\\"", "\\\\\"hi ho\\\\\"\\\\\"" },
- { "\\%{e}\\\\\"", "\\\\\"h\"\\^\"\"i\"\\\\\"" },
- { "\\%{f}\\\\\"", "\\\\\"\"\\^\"\"hi\"\\\\\"" },
- { "\\%{g}\\\\\"", "\\\\\"hi\"\\^\"\"\"\\\\\"" },
- { "\\%{h}\\\\\"", "\\\\\"h\\\\\"\\^\"\"i\"\\\\\"" },
- { "\\%{i}\\\\\"", "\\\\\"\\\\\"\\^\"\"hi\"\\\\\"" },
- { "\\%{j}\\\\\"", "\\\\\"hi\\\\\"\\^\"\"\"\\\\\"" },
- { "\\%{x}\\\\\"", "\\\\\\\\\\\\\"" },
- { "\\%{y}\\\\\"", "\\\\\"\"\\^\"\"\"\\\\\"" },
- { "\\%{z}\\\\\"", "\\\\\\\\\"" },
-
- { "multi-var", 0 },
- { "%{x}%{y}%{z}", "\\\\\"\"\\^\"\"\"" },
- { "%{x}%{z}%{y}%{z}", "\\\\\"\"\\^\"\"\"" },
- { "%{x}%{z}%{y}", "\\\\\"\"\\^\"\"\"" },
- { "%{x}\\^\"%{z}", "\\\\\\^\"" },
- { "%{x}%{z}\\^\"%{z}", "\\\\\\^\"" },
- { "%{x}%{z}\\^\"", "\\\\\\^\"" },
- { "%{x}\\%{z}", "\\\\" },
- { "%{x}%{z}\\%{z}", "\\\\" },
- { "%{x}%{z}\\", "\\\\" },
- { "%{aa}%{a}", "\"hi hohi\"" },
- { "%{aa}%{aa}", "\"hi hohi ho\"" },
- { "%{aa}:%{aa}", "\"hi ho\":\"hi ho\"" },
- { "hallo ^|%{aa}^|", "hallo ^|\"hi ho\"^|" },
-
- { "quoted multi-var", 0 },
- { "\"%{x}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"" },
- { "\"%{x}%{z}%{y}%{z}\"", "\"\\\\\"\\^\"\"\"" },
- { "\"%{x}%{z}%{y}\"", "\"\\\\\"\\^\"\"\"" },
- { "\"%{x}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"" },
- { "\"%{x}%{z}\"^\"\"%{z}\"", "\"\\\\\"^\"\"\"" },
- { "\"%{x}%{z}\"^\"\"\"", "\"\\\\\"^\"\"\"" },
- { "\"%{x}\\%{z}\"", "\"\\\\\\\\\"" },
- { "\"%{x}%{z}\\%{z}\"", "\"\\\\\\\\\"" },
- { "\"%{x}%{z}\\\\\"", "\"\\\\\\\\\"" },
- { "\"%{aa}%{a}\"", "\"hi hohi\"" },
- { "\"%{aa}%{aa}\"", "\"hi hohi ho\"" },
- { "\"%{aa}:%{aa}\"", "\"hi ho:hi ho\"" },
-#else
- { "plain", 0 },
- { "%{a}", "hi" },
- { "%{b}", "'hi ho'" },
- { "%{c}", "'&special;'" },
- { "%{d}", "'h\\i'" },
- { "%{e}", "'h\"i'" },
- { "%{f}", "'h'\\''i'" },
- { "%{z}", "''" },
- { "\\%{z}%{z}", "\\%{z}%{z}" }, // stupid user check
-
- { "single-quoted", 0 },
- { "'%{a}'", "'hi'" },
- { "'%{b}'", "'hi ho'" },
- { "'%{c}'", "'&special;'" },
- { "'%{d}'", "'h\\i'" },
- { "'%{e}'", "'h\"i'" },
- { "'%{f}'", "'h'\\''i'" },
- { "'%{z}'", "''" },
-
- { "double-quoted", 0 },
- { "\"%{a}\"", "\"hi\"" },
- { "\"%{b}\"", "\"hi ho\"" },
- { "\"%{c}\"", "\"&special;\"" },
- { "\"%{d}\"", "\"h\\\\i\"" },
- { "\"%{e}\"", "\"h\\\"i\"" },
- { "\"%{f}\"", "\"h'i\"" },
- { "\"%{z}\"", "\"\"" },
-
- { "complex", 0 },
- { "echo \"$(echo %{a})\"", "echo \"$(echo hi)\"" },
- { "echo \"$(echo %{b})\"", "echo \"$(echo 'hi ho')\"" },
- { "echo \"$(echo \"%{a}\")\"", "echo \"$(echo \"hi\")\"" },
+ { "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}\"" },
- { "echo \"%{echo %{b}}\"", "echo \"%{echo hi ho}\"" },
- { "echo \"%{echo \"%{a}\"}\"", "echo \"%{echo \"hi\"}\"" },
-#endif
+ { "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;
@@ -581,10 +586,12 @@ void tst_QtcProcess::expandMacros_data()
char buf[80];
sprintf(buf, "%s: %s", title, vals[i].in);
QTest::newRow(buf) << QString::fromLatin1(vals[i].in)
- << QString::fromLatin1(vals[i].out);
+ << QString::fromLatin1(vals[i].out)
+ << vals[i].os;
sprintf(buf, "padded %s: %s", title, vals[i].in);
QTest::newRow(buf) << (sp + QString::fromLatin1(vals[i].in) + sp)
- << (sp + QString::fromLatin1(vals[i].out) + sp);
+ << (sp + QString::fromLatin1(vals[i].out) + sp)
+ << vals[i].os;
}
}
}
@@ -593,8 +600,12 @@ void tst_QtcProcess::expandMacros()
{
QFETCH(QString, in);
QFETCH(QString, out);
+ QFETCH(OsType, os);
- QtcProcess::expandMacros(&in, &mx);
+ if (os == OsTypeWindows)
+ QtcProcess::expandMacros(&in, &mxWin, os);
+ else
+ QtcProcess::expandMacros(&in, &mxUnix, os);
QCOMPARE(in, out);
}
@@ -602,75 +613,78 @@ void tst_QtcProcess::iterations_data()
{
QTest::addColumn<QString>("in");
QTest::addColumn<QString>("out");
+ QTest::addColumn<OsType>("os");
static const struct {
const char * const in;
const char * const out;
+ OsType os;
} vals[] = {
-#ifdef Q_OS_WIN
- { "", "" },
- { "hi", "hi" },
- { " hi ", "hi" },
- { "hi ho", "hi ho" },
- { "\"hi ho\" sucker", "\"hi ho\" sucker" },
- { "\"hi\"^\"\"ho\" sucker", "\"hi\"\\^\"\"ho\" sucker" },
- { "\"hi\"\\^\"\"ho\" sucker", "\"hi\"\\^\"\"ho\" sucker" },
- { "hi^|ho", "\"hi|ho\"" },
- { "c:\\", "c:\\" },
- { "\"c:\\\\\"", "c:\\" },
- { "\\hi\\ho", "\\hi\\ho" },
- { "hi null%", "hi null%" },
- { "hi null% ho", "hi null% ho" },
- { "hi null%here ho", "hi null%here ho" },
- { "hi null%here%too ho", "hi {} ho" },
- { "echo hello | more", "echo hello" },
- { "echo hello| more", "echo hello" },
-#else
- { "", "" },
- { " ", "" },
- { "hi", "hi" },
- { " hi ", "hi" },
- { "'hi'", "hi" },
- { "hi ho", "hi ho" },
- { "\"hi ho\" sucker", "'hi ho' sucker" },
- { "\"hi\\\"ho\" sucker", "'hi\"ho' sucker" },
- { "\"hi'ho\" sucker", "'hi'\\''ho' sucker" },
- { "'hi ho' sucker", "'hi ho' sucker" },
- { "\\\\", "'\\'" },
- { "'\\'", "'\\'" },
- { "hi 'null${here}too' ho", "hi 'null${here}too' ho" },
- { "hi null${here}too ho", "hi {} ho" },
- { "hi $(echo $dollar cent) ho", "hi {} ho" },
- { "hi `echo $dollar \\`echo cent\\` | cat` ho", "hi {} ho" },
- { "echo hello | more", "echo hello" },
- { "echo hello| more", "echo hello" },
-#endif
+ { "", "", OsTypeWindows },
+ { "hi", "hi", OsTypeWindows },
+ { " hi ", "hi", OsTypeWindows },
+ { "hi ho", "hi ho", OsTypeWindows },
+ { "\"hi ho\" sucker", "\"hi ho\" sucker", OsTypeWindows },
+ { "\"hi\"^\"\"ho\" sucker", "\"hi\"\\^\"\"ho\" sucker", OsTypeWindows },
+ { "\"hi\"\\^\"\"ho\" sucker", "\"hi\"\\^\"\"ho\" sucker", OsTypeWindows },
+ { "hi^|ho", "\"hi|ho\"", OsTypeWindows },
+ { "c:\\", "c:\\", OsTypeWindows },
+ { "\"c:\\\\\"", "c:\\", OsTypeWindows },
+ { "\\hi\\ho", "\\hi\\ho", OsTypeWindows },
+ { "hi null%", "hi null%", OsTypeWindows },
+ { "hi null% ho", "hi null% ho", OsTypeWindows },
+ { "hi null%here ho", "hi null%here ho", OsTypeWindows },
+ { "hi null%here%too ho", "hi {} ho", OsTypeWindows },
+ { "echo hello | more", "echo hello", OsTypeWindows },
+ { "echo hello| more", "echo hello", OsTypeWindows },
+
+ { "", "", OsTypeLinux },
+ { " ", "", OsTypeLinux },
+ { "hi", "hi", OsTypeLinux },
+ { " hi ", "hi", OsTypeLinux },
+ { "'hi'", "hi", OsTypeLinux },
+ { "hi ho", "hi ho", OsTypeLinux },
+ { "\"hi ho\" sucker", "'hi ho' sucker", OsTypeLinux },
+ { "\"hi\\\"ho\" sucker", "'hi\"ho' sucker", OsTypeLinux },
+ { "\"hi'ho\" sucker", "'hi'\\''ho' sucker", OsTypeLinux },
+ { "'hi ho' sucker", "'hi ho' sucker", OsTypeLinux },
+ { "\\\\", "'\\'", OsTypeLinux },
+ { "'\\'", "'\\'", OsTypeLinux },
+ { "hi 'null${here}too' ho", "hi 'null${here}too' ho", OsTypeLinux },
+ { "hi null${here}too ho", "hi {} ho", OsTypeLinux },
+ { "hi $(echo $dollar cent) ho", "hi {} ho", OsTypeLinux },
+ { "hi `echo $dollar \\`echo cent\\` | cat` ho", "hi {} ho", OsTypeLinux },
+ { "echo hello | more", "echo hello", OsTypeLinux },
+ { "echo hello| more", "echo hello", OsTypeLinux },
};
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);
+ << QString::fromLatin1(vals[i].out)
+ << vals[i].os;
}
void tst_QtcProcess::iterations()
{
QFETCH(QString, in);
QFETCH(QString, out);
+ QFETCH(OsType, os);
QString outstr;
- for (QtcProcess::ArgIterator ait(&in); ait.next(); )
+ for (QtcProcess::ArgIterator ait(&in, os); ait.next(); ) {
if (ait.isSimple())
- QtcProcess::addArg(&outstr, ait.value());
+ QtcProcess::addArg(&outstr, ait.value(), os);
else
QtcProcess::addArgs(&outstr, "{}");
+ }
QCOMPARE(outstr, out);
}
-void tst_QtcProcess::iteratorEdits()
+void tst_QtcProcess::iteratorEditsHelper(OsType osType)
{
QString in1 = "one two three", in2 = in1, in3 = in1, in4 = in1, in5 = in1;
- QtcProcess::ArgIterator ait1(&in1);
+ QtcProcess::ArgIterator ait1(&in1, osType);
QVERIFY(ait1.next());
ait1.deleteArg();
QVERIFY(ait1.next());
@@ -680,7 +694,7 @@ void tst_QtcProcess::iteratorEdits()
ait1.appendArg("four");
QCOMPARE(in1, QString::fromLatin1("two three four"));
- QtcProcess::ArgIterator ait2(&in2);
+ QtcProcess::ArgIterator ait2(&in2, osType);
QVERIFY(ait2.next());
QVERIFY(ait2.next());
ait2.deleteArg();
@@ -689,7 +703,7 @@ void tst_QtcProcess::iteratorEdits()
QVERIFY(!ait2.next());
QCOMPARE(in2, QString::fromLatin1("one three four"));
- QtcProcess::ArgIterator ait3(&in3);
+ QtcProcess::ArgIterator ait3(&in3, osType);
QVERIFY(ait3.next());
ait3.appendArg("one-b");
QVERIFY(ait3.next());
@@ -698,7 +712,7 @@ void tst_QtcProcess::iteratorEdits()
QVERIFY(!ait3.next());
QCOMPARE(in3, QString::fromLatin1("one one-b two"));
- QtcProcess::ArgIterator ait4(&in4);
+ QtcProcess::ArgIterator ait4(&in4, osType);
ait4.appendArg("pre-one");
QVERIFY(ait4.next());
QVERIFY(ait4.next());
@@ -707,7 +721,7 @@ void tst_QtcProcess::iteratorEdits()
QVERIFY(!ait4.next());
QCOMPARE(in4, QString::fromLatin1("pre-one one two"));
- QtcProcess::ArgIterator ait5(&in5);
+ QtcProcess::ArgIterator ait5(&in5, osType);
QVERIFY(ait5.next());
QVERIFY(ait5.next());
QVERIFY(ait5.next());
@@ -717,6 +731,16 @@ void tst_QtcProcess::iteratorEdits()
QCOMPARE(in5, QString::fromLatin1("one two"));
}
+void tst_QtcProcess::iteratorEditsWindows()
+{
+ iteratorEditsHelper(OsTypeWindows);
+}
+
+void tst_QtcProcess::iteratorEditsLinux()
+{
+ iteratorEditsHelper(OsTypeLinux);
+}
+
QTEST_MAIN(tst_QtcProcess)
#include "tst_qtcprocess.moc"