forked from qt-creator/qt-creator
add Utils::QtcProcess
this is a wrapper around QProcess with these features: - setEnvironment() takes a Utils::Environment instead of a QStringList - instead of taking a stringlist with arguments, take a single shell command string which is fully compatible with the system's native shell (the bourne shell on unix and cmd.exe on windows) - with support for environment variable expansion, and subject to the shell's splitting and quoting rules. if the command is too complex (e.g., contains redirections), it is transparently executed through a real shell. - additionally, the class contains a set of helper functions for manipulating (constructing, splitting, etc.) shell command lines. in particular, it contains a shell-safe macro expander and the nested class ArgIterator which can be used for inspecting and manipulating a shell command line without going through the stringlist indirection (which is potentially lossy). some of this is based on KDE code (KShell and KMacroExpander) which i have written myself.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,149 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef QTCPROCESS_H
|
||||
#define QTCPROCESS_H
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include "environment.h"
|
||||
|
||||
namespace Utils {
|
||||
class AbstractMacroExpander;
|
||||
|
||||
/*!
|
||||
This class provides functionality for dealing with shell-quoted process arguments.
|
||||
*/
|
||||
class QTCREATOR_UTILS_EXPORT QtcProcess : public QProcess
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtcProcess(QObject *parent = 0) : QProcess(parent), m_haveEnv(false) {}
|
||||
void setEnvironment(const Environment &env)
|
||||
{ m_environment = env; m_haveEnv = true; }
|
||||
void setCommand(const QString &command, const QString &arguments)
|
||||
{ m_command = command; m_arguments = arguments; }
|
||||
void start();
|
||||
|
||||
enum SplitError {
|
||||
SplitOk = 0, //! All went just fine
|
||||
BadQuoting, //! Command contains quoting errors
|
||||
FoundMeta //! Command contains complex shell constructs
|
||||
};
|
||||
|
||||
//! 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);
|
||||
//! Quote a single argument and append it to a shell command
|
||||
static void addArg(QString *args, const QString &arg);
|
||||
//! Join an argument list into a shell command
|
||||
static QString joinArgs(const QStringList &args);
|
||||
//! 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);
|
||||
//! 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,
|
||||
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,
|
||||
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);
|
||||
|
||||
/*! Iterate over arguments from a command line.
|
||||
* Assumes that the name of the actual command is *not* part of the line.
|
||||
* Terminates after the first command if the command line is complex.
|
||||
*/
|
||||
class QTCREATOR_UTILS_EXPORT ArgIterator {
|
||||
public:
|
||||
ArgIterator(QString *str) : m_str(str), m_pos(0), m_prev(-1) {}
|
||||
//! 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.
|
||||
bool isSimple() const { return m_simple; }
|
||||
//! Return the string value of the current argument if it is simple, otherwise empty.
|
||||
QString value() const { return m_value; }
|
||||
//! Delete the last argument fetched via next() from the command line.
|
||||
void deleteArg();
|
||||
//! Insert argument into the command line after the last one fetched via next().
|
||||
//! This may be used before the first call to next() to insert at the front.
|
||||
void appendArg(const QString &str);
|
||||
private:
|
||||
QString *m_str, m_value;
|
||||
int m_pos, m_prev;
|
||||
bool m_simple;
|
||||
};
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT ConstArgIterator {
|
||||
public:
|
||||
ConstArgIterator(const QString &str) : m_str(str), m_ait(&m_str) {}
|
||||
bool next() { return m_ait.next(); }
|
||||
bool isSimple() const { return m_ait.isSimple(); }
|
||||
QString value() const { return m_ait.value(); }
|
||||
private:
|
||||
QString m_str;
|
||||
ArgIterator m_ait;
|
||||
};
|
||||
|
||||
private:
|
||||
QString m_command;
|
||||
QString m_arguments;
|
||||
Environment m_environment;
|
||||
bool m_haveEnv;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // QTCPROCESS_H
|
||||
@@ -8,6 +8,7 @@ INCLUDEPATH += $$PWD
|
||||
QT += network
|
||||
|
||||
SOURCES += $$PWD/environment.cpp \
|
||||
$$PWD/qtcprocess.cpp \
|
||||
$$PWD/reloadpromptutils.cpp \
|
||||
$$PWD/stringutils.cpp \
|
||||
$$PWD/filesearch.cpp \
|
||||
@@ -66,6 +67,7 @@ unix:!macx {
|
||||
SOURCES += $$PWD/unixutils.cpp
|
||||
}
|
||||
HEADERS += $$PWD/environment.h \
|
||||
$$PWD/qtcprocess.h \
|
||||
$$PWD/utils_global.h \
|
||||
$$PWD/reloadpromptutils.h \
|
||||
$$PWD/stringutils.h \
|
||||
|
||||
@@ -12,6 +12,7 @@ SUBDIRS += \
|
||||
# icheckbuild \
|
||||
# profilewriter \
|
||||
ioutils \
|
||||
qtcprocess \
|
||||
utils_stringutils \
|
||||
filesearch
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
CONFIG += qtestlib testcase
|
||||
TEMPLATE = app
|
||||
CONFIG -= app_bundle
|
||||
DEFINES += QTCREATOR_UTILS_LIB
|
||||
|
||||
UTILS_PATH = ../../../src/libs/utils
|
||||
|
||||
INCLUDEPATH += $$UTILS_PATH/..
|
||||
DEPENDPATH += $$UTILS_PATH/..
|
||||
|
||||
SOURCES += \
|
||||
tst_qtcprocess.cpp \
|
||||
$$UTILS_PATH/qtcprocess.cpp \
|
||||
$$UTILS_PATH/stringutils.cpp \
|
||||
$$UTILS_PATH/environment.cpp
|
||||
HEADERS += \
|
||||
$$UTILS_PATH/qtcprocess.h \
|
||||
$$UTILS_PATH/environment.h \
|
||||
$$UTILS_PATH/stringutils.h \
|
||||
$$UTILS_PATH/utils_global.h
|
||||
|
||||
TARGET = tst_$$TARGET
|
||||
@@ -0,0 +1,698 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/stringutils.h>
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
class MacroMapExpander : public AbstractQtcMacroExpander {
|
||||
public:
|
||||
virtual bool resolveMacro(const QString &name, QString *ret)
|
||||
{
|
||||
QHash<QString, QString>::const_iterator it = m_map.constFind(name);
|
||||
if (it != m_map.constEnd()) {
|
||||
*ret = it.value();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void insert(const QString &key, const QString &value) { m_map.insert(key, value); }
|
||||
private:
|
||||
QHash<QString, QString> m_map;
|
||||
};
|
||||
|
||||
class tst_QtcProcess : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void splitArgs_data();
|
||||
void splitArgs();
|
||||
void prepareArgs_data();
|
||||
void prepareArgs();
|
||||
void prepareArgsEnv_data();
|
||||
void prepareArgsEnv();
|
||||
void expandMacros_data();
|
||||
void expandMacros();
|
||||
void iterations_data();
|
||||
void iterations();
|
||||
void iteratorEdits();
|
||||
|
||||
private:
|
||||
Environment env;
|
||||
MacroMapExpander mx;
|
||||
};
|
||||
|
||||
void tst_QtcProcess::initTestCase()
|
||||
{
|
||||
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", "");
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QtcProcess::SplitError)
|
||||
|
||||
void tst_QtcProcess::splitArgs_data()
|
||||
{
|
||||
QTest::addColumn<QString>("in");
|
||||
QTest::addColumn<QString>("out");
|
||||
QTest::addColumn<QtcProcess::SplitError>("err");
|
||||
|
||||
static const struct {
|
||||
const char * const in;
|
||||
const char * const out;
|
||||
const QtcProcess::SplitError err;
|
||||
} 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 },
|
||||
#endif
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
|
||||
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
|
||||
<< QString::fromLatin1(vals[i].out)
|
||||
<< vals[i].err;
|
||||
}
|
||||
|
||||
void tst_QtcProcess::splitArgs()
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
QFETCH(QString, out);
|
||||
QFETCH(QtcProcess::SplitError, err);
|
||||
|
||||
QtcProcess::SplitError outerr;
|
||||
QString outstr = QtcProcess::joinArgs(QtcProcess::splitArgs(in, false, &outerr));
|
||||
QCOMPARE(outerr, err);
|
||||
if (err == QtcProcess::SplitOk)
|
||||
QCOMPARE(outstr, out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::prepareArgs_data()
|
||||
{
|
||||
QTest::addColumn<QString>("in");
|
||||
QTest::addColumn<QString>("out");
|
||||
QTest::addColumn<QtcProcess::SplitError>("err");
|
||||
|
||||
static const struct {
|
||||
const char * const in;
|
||||
const char * const out;
|
||||
const QtcProcess::SplitError err;
|
||||
} 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 },
|
||||
#endif
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
|
||||
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
|
||||
<< QString::fromLatin1(vals[i].out)
|
||||
<< vals[i].err;
|
||||
}
|
||||
|
||||
void tst_QtcProcess::prepareArgs()
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
QFETCH(QString, out);
|
||||
QFETCH(QtcProcess::SplitError, err);
|
||||
|
||||
QtcProcess::SplitError outerr;
|
||||
QString outstr;
|
||||
#ifdef Q_OS_WIN
|
||||
outstr = QtcProcess::prepareArgs(in, &outerr);
|
||||
#else
|
||||
outstr = QtcProcess::joinArgs(QtcProcess::prepareArgs(in, &outerr));
|
||||
#endif
|
||||
QCOMPARE(outerr, err);
|
||||
if (err == QtcProcess::SplitOk)
|
||||
QCOMPARE(outstr, out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::prepareArgsEnv_data()
|
||||
{
|
||||
QTest::addColumn<QString>("in");
|
||||
QTest::addColumn<QString>("out");
|
||||
QTest::addColumn<QtcProcess::SplitError>("err");
|
||||
|
||||
static const struct {
|
||||
const char * const in;
|
||||
const char * const out;
|
||||
const QtcProcess::SplitError err;
|
||||
} 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
|
||||
};
|
||||
|
||||
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)
|
||||
<< vals[i].err;
|
||||
}
|
||||
|
||||
void tst_QtcProcess::prepareArgsEnv()
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
QFETCH(QString, out);
|
||||
QFETCH(QtcProcess::SplitError, err);
|
||||
|
||||
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
|
||||
QCOMPARE(outerr, err);
|
||||
if (err == QtcProcess::SplitOk)
|
||||
QCOMPARE(outstr, out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::expandMacros_data()
|
||||
|
||||
{
|
||||
QTest::addColumn<QString>("in");
|
||||
QTest::addColumn<QString>("out");
|
||||
QChar sp(QLatin1Char(' '));
|
||||
|
||||
static const struct {
|
||||
const char * const in;
|
||||
const char * const out;
|
||||
} 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\")\"" },
|
||||
// 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
|
||||
};
|
||||
|
||||
const char *title = 0;
|
||||
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
|
||||
if (!vals[i].out) {
|
||||
title = vals[i].in;
|
||||
} else {
|
||||
char buf[80];
|
||||
sprintf(buf, "%s: %s", title, vals[i].in);
|
||||
QTest::newRow(buf) << QString::fromLatin1(vals[i].in)
|
||||
<< QString::fromLatin1(vals[i].out);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QtcProcess::expandMacros()
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
QFETCH(QString, out);
|
||||
|
||||
QtcProcess::expandMacros(&in, &mx);
|
||||
QCOMPARE(in, out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::iterations_data()
|
||||
{
|
||||
QTest::addColumn<QString>("in");
|
||||
QTest::addColumn<QString>("out");
|
||||
|
||||
static const struct {
|
||||
const char * const in;
|
||||
const char * const out;
|
||||
} vals[] = {
|
||||
#ifdef Q_OS_WIN
|
||||
{ "", "" },
|
||||
{ "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
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++)
|
||||
QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in)
|
||||
<< QString::fromLatin1(vals[i].out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::iterations()
|
||||
{
|
||||
QFETCH(QString, in);
|
||||
QFETCH(QString, out);
|
||||
|
||||
QString outstr;
|
||||
for (QtcProcess::ArgIterator ait(&in); ait.next(); )
|
||||
if (ait.isSimple())
|
||||
QtcProcess::addArg(&outstr, ait.value());
|
||||
else
|
||||
QtcProcess::addArgs(&outstr, "{}");
|
||||
QCOMPARE(outstr, out);
|
||||
}
|
||||
|
||||
void tst_QtcProcess::iteratorEdits()
|
||||
{
|
||||
QString in1 = "one two three", in2 = in1, in3 = in1, in4 = in1, in5 = in1;
|
||||
|
||||
QtcProcess::ArgIterator ait1(&in1);
|
||||
QVERIFY(ait1.next());
|
||||
ait1.deleteArg();
|
||||
QVERIFY(ait1.next());
|
||||
QVERIFY(ait1.next());
|
||||
QVERIFY(!ait1.next());
|
||||
QCOMPARE(in1, QString::fromLatin1("two three"));
|
||||
ait1.appendArg("four");
|
||||
QCOMPARE(in1, QString::fromLatin1("two three four"));
|
||||
|
||||
QtcProcess::ArgIterator ait2(&in2);
|
||||
QVERIFY(ait2.next());
|
||||
QVERIFY(ait2.next());
|
||||
ait2.deleteArg();
|
||||
QVERIFY(ait2.next());
|
||||
ait2.appendArg("four");
|
||||
QVERIFY(!ait2.next());
|
||||
QCOMPARE(in2, QString::fromLatin1("one three four"));
|
||||
|
||||
QtcProcess::ArgIterator ait3(&in3);
|
||||
QVERIFY(ait3.next());
|
||||
ait3.appendArg("one-b");
|
||||
QVERIFY(ait3.next());
|
||||
QVERIFY(ait3.next());
|
||||
ait3.deleteArg();
|
||||
QVERIFY(!ait3.next());
|
||||
QCOMPARE(in3, QString::fromLatin1("one one-b two"));
|
||||
|
||||
QtcProcess::ArgIterator ait4(&in4);
|
||||
ait4.appendArg("pre-one");
|
||||
QVERIFY(ait4.next());
|
||||
QVERIFY(ait4.next());
|
||||
QVERIFY(ait4.next());
|
||||
ait4.deleteArg();
|
||||
QVERIFY(!ait4.next());
|
||||
QCOMPARE(in4, QString::fromLatin1("pre-one one two"));
|
||||
|
||||
QtcProcess::ArgIterator ait5(&in5);
|
||||
QVERIFY(ait5.next());
|
||||
QVERIFY(ait5.next());
|
||||
QVERIFY(ait5.next());
|
||||
QVERIFY(!ait5.next());
|
||||
ait5.deleteArg();
|
||||
QVERIFY(!ait5.next());
|
||||
QCOMPARE(in5, QString::fromLatin1("one two"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QtcProcess)
|
||||
|
||||
#include "tst_qtcprocess.moc"
|
||||
Reference in New Issue
Block a user