diff options
author | Kai Koehne <kai.koehne@digia.com> | 2014-06-19 11:09:47 +0200 |
---|---|---|
committer | Kai Koehne <kai.koehne@digia.com> | 2014-07-10 09:27:44 +0200 |
commit | 6d166c88220ee09821b65fb2b711fa77a5312971 (patch) | |
tree | 78f69bc74ba66f8a7d8a97db4cae8fd21b70992e | |
parent | 27797cb37a63eceed77e9b6c790eaaf9c438b360 (diff) |
Add QDebug::noquote() stream modifier
Allow the user to disable the quoting of QString, QByteArray,
QStringLiteral by passing a "noquote()" stream modifier.
This requires another flag to be added to QDebug::Stream. To
keep BC we're using the QMessageLogContext::version field
to differentiate between QDebug streams created by earlier
versions.
Task-number: QTBUG-37146
Change-Id: I9b215eabfcfd754af16ea87f3ef928d698e37d77
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/global/qlogging.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qdebug.cpp | 41 | ||||
-rw-r--r-- | src/corelib/io/qdebug.h | 33 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 82 |
4 files changed, 148 insertions, 12 deletions
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index 6ebffa3ba1..043f799414 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -65,9 +65,9 @@ class QMessageLogContext { Q_DISABLE_COPY(QMessageLogContext) public: - Q_DECL_CONSTEXPR QMessageLogContext() : version(1), line(0), file(0), function(0), category(0) {} + Q_DECL_CONSTEXPR QMessageLogContext() : version(2), line(0), file(0), function(0), category(0) {} Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName, const char *categoryName) - : version(1), line(lineNumber), file(fileName), function(functionName), category(categoryName) {} + : version(2), line(lineNumber), file(fileName), function(functionName), category(categoryName) {} void copy(const QMessageLogContext &logContext); diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 44d0a788ff..038e9cb0a3 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -202,6 +202,41 @@ QDebug::~QDebug() \sa QDebugStateSaver */ + +/*! + \fn QDebug &QDebug::quote() + \since 5.4 + + Enables automatic insertion of quotation characters around QChar, QString and QByteArray + contents and returns a reference to the stream. + + Quoting is enabled by default. + + \sa noquote(), maybeQuote() +*/ + +/*! + \fn QDebug &QDebug::noquote() + \since 5.4 + + Disables automatic insertion of quotation characters around QChar, QString and QByteArray + contents and returns a reference to the stream. + + \sa quote(), maybeQuote() +*/ + +/*! + \fn QDebug &QDebug::maybeQuote(char c) + \since 5.4 + + Writes a character \a c to the debug stream, depending on the + current setting for automatic insertion of quotes, and returns a reference to the stream. + + The default character is a double quote \c{"}. + + \sa quote(), noquote() +*/ + /*! \fn QDebug &QDebug::operator<<(QChar t) @@ -368,19 +403,25 @@ public: QDebugStateSaverPrivate(QDebug &dbg) : m_dbg(dbg), m_spaces(dbg.autoInsertSpaces()), + m_flags(0), m_streamParams(dbg.stream->ts.d_ptr->params) { + if (m_dbg.stream->context.version > 1) + m_flags = m_dbg.stream->flags; } void restoreState() { m_dbg.setAutoInsertSpaces(m_spaces); m_dbg.stream->ts.d_ptr->params = m_streamParams; + if (m_dbg.stream->context.version > 1) + m_dbg.stream->flags = m_flags; } QDebug &m_dbg; // QDebug state const bool m_spaces; + int m_flags; // QTextStream state const QTextStreamPrivate::Params m_streamParams; diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 584d6bf41f..0bbb617c1f 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -61,9 +61,9 @@ class Q_CORE_EXPORT QDebug friend class QMessageLogger; friend class QDebugStateSaverPrivate; struct Stream { - Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false) {} - Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false) {} - Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true) {} + Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {} + Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {} + Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true), flags(0) {} QTextStream ts; QString buffer; int ref; @@ -71,6 +71,18 @@ class Q_CORE_EXPORT QDebug bool space; bool message_output; QMessageLogContext context; + + enum FormatFlag { + NoQuotes = 0x1 + }; + + // ### Qt 6: unify with space, introduce own version member + bool testFlag(FormatFlag flag) const { return (context.version > 1) ? (flags & flag) : false; } + void setFlag(FormatFlag flag) { if (context.version > 1) { flags |= flag; } } + void unsetFlag(FormatFlag flag) { if (context.version > 1) { flags &= ~flag; } } + + // added in 5.4 + int flags; } *stream; public: inline QDebug(QIODevice *device) : stream(new Stream(device)) {} @@ -88,7 +100,11 @@ public: bool autoInsertSpaces() const { return stream->space; } void setAutoInsertSpaces(bool b) { stream->space = b; } - inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); } + inline QDebug "e() { stream->unsetFlag(Stream::NoQuotes); return *this; } + inline QDebug &noquote() { stream->setFlag(Stream::NoQuotes); return *this; } + inline QDebug &maybeQuote(char c = '"') { if (!(stream->testFlag(Stream::NoQuotes))) stream->ts << c; return *this; } + + inline QDebug &operator<<(QChar t) { maybeQuote('\''); stream->ts << t; maybeQuote('\''); return maybeSpace(); } inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); } @@ -102,10 +118,10 @@ public: inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(const char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); } - inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); } + inline QDebug &operator<<(const QString & t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); } inline QDebug &operator<<(const QStringRef & t) { return operator<<(t.toString()); } - inline QDebug &operator<<(QLatin1String t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); } - inline QDebug &operator<<(const QByteArray & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); } + inline QDebug &operator<<(QLatin1String t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); } + inline QDebug &operator<<(const QByteArray & t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); } inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(QTextStreamFunction f) { stream->ts << f; @@ -137,6 +153,9 @@ public: inline QNoDebug &space() { return *this; } inline QNoDebug &nospace() { return *this; } inline QNoDebug &maybeSpace() { return *this; } + inline QNoDebug "e() { return *this; } + inline QNoDebug &noquote() { return *this; } + inline QNoDebug &maybeQuote(const char = '"') { return *this; } template<typename T> inline QNoDebug &operator<<(const T &) { return *this; } diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 38b6e9ab50..9b761bc63d 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -56,10 +56,13 @@ private slots: void criticalWithoutDebug() const; void debugWithBool() const; void debugSpaceHandling() const; + void debugNoQuotes() const; void stateSaver() const; void veryLongWarningMessage() const; + void qDebugQChar() const; void qDebugQStringRef() const; void qDebugQLatin1String() const; + void qDebugQByteArray() const; void textStreamModifiers() const; void defaultMessagehandler() const; void threadSafety() const; @@ -219,6 +222,32 @@ void tst_QDebug::debugSpaceHandling() const QCOMPARE(s_msg, QString::fromLatin1("QMimeType(invalid) QMimeType(\"application/pdf\") foo")); } +void tst_QDebug::debugNoQuotes() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QStringLiteral("Hello"); + d.noquote(); + d << QStringLiteral("Hello"); + d.quote(); + d << QStringLiteral("Hello"); + } + QCOMPARE(s_msg, QString::fromLatin1("\"Hello\" Hello \"Hello\"")); + + { + QDebug d = qDebug(); + d << QChar('H'); + d << QLatin1String("Hello"); + d << QByteArray("Hello"); + d.noquote(); + d << QChar('H'); + d << QLatin1String("Hello"); + d << QByteArray("Hello"); + } + QCOMPARE(s_msg, QString::fromLatin1("'H' \"Hello\" \"Hello\" H Hello Hello")); +} + void tst_QDebug::stateSaver() const { MessageHandlerSetter mhs(myMessageHandler); @@ -231,6 +260,16 @@ void tst_QDebug::stateSaver() const d << 42; } QCOMPARE(s_msg, QString::fromLatin1("02a 42")); + + { + QDebug d = qDebug(); + { + QDebugStateSaver saver(d); + d.nospace().noquote() << QStringLiteral("Hello"); + } + d << QStringLiteral("World"); + } + QCOMPARE(s_msg, QString::fromLatin1("Hello \"World\"")); } void tst_QDebug::veryLongWarningMessage() const @@ -251,6 +290,23 @@ void tst_QDebug::veryLongWarningMessage() const QCOMPARE(QString::fromLatin1(s_function), function); } +void tst_QDebug::qDebugQChar() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QChar('f'); + d.nospace().noquote() << QChar('o') << QChar('o'); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("'f' oo")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + +} + void tst_QDebug::qDebugQStringRef() const { /* Use a basic string. */ @@ -286,10 +342,30 @@ void tst_QDebug::qDebugQStringRef() const void tst_QDebug::qDebugQLatin1String() const { MessageHandlerSetter mhs(myMessageHandler); - { qDebug() << QLatin1String("foo") << QLatin1String("") << QLatin1String("barbaz", 3); } - QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO; + { + QDebug d = qDebug(); + d << QLatin1String("foo") << QLatin1String("") << QLatin1String("barbaz", 3); + d.nospace().noquote() << QLatin1String("baz"); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + +void tst_QDebug::qDebugQByteArray() const +{ + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QByteArrayLiteral("foo") << QByteArrayLiteral("") << QByteArray("barbaz", 3); + d.nospace().noquote() << QByteArrayLiteral("baz"); + } + QString file = __FILE__; int line = __LINE__ - 4; QString function = Q_FUNC_INFO; QCOMPARE(s_msgType, QtDebugMsg); - QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\"")); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); QCOMPARE(QString::fromLatin1(s_file), file); QCOMPARE(s_line, line); QCOMPARE(QString::fromLatin1(s_function), function); |