QDebug: add operator<<(const char16_t *)

Avoids the conversion from UTF-8 for uses that are not dumping a string.

Mass conversion of Qt sources left for future opportunity.

Fixes: QTBUG-85811
Change-Id: I4ca4a35b687b46c39030fffd1626ae6c3294cacf
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2020-07-30 17:21:37 -07:00
parent 31c232d3b7
commit f2abfb39d7
3 changed files with 67 additions and 10 deletions

View File

@ -597,9 +597,24 @@ QDebug &QDebug::resetFormat()
/*! /*!
\fn QDebug &QDebug::operator<<(const char *t) \fn QDebug &QDebug::operator<<(const char *t)
Writes the '\\0'-terminated string, \a t, to the stream and returns a Writes the '\\0'-terminated UTF-8 string, \a t, to the stream and returns a
reference to the stream. The string is never quoted nor transformed to the reference to the stream. The string is never quoted or escaped for the
output, but note that some QDebug backends might not be 8-bit clean. output. Note that QDebug buffers internally as UTF-16 and may need to
transform to 8-bit using the locale's codec in order to use some backends,
which may cause garbled output (mojibake). Restricting to US-ASCII strings
is recommended.
*/
/*!
\fn QDebug &QDebug::operator<<(const char16_t *t)
\since 6.0
Writes the u'\\0'-terminated UTF-16 string, \a t, to the stream and returns
a reference to the stream. The string is never quoted or escaped for the
output. Note that QDebug buffers internally as UTF-16 and may need to
transform to 8-bit using the locale's codec in order to use some backends,
which may cause garbled output (mojibake). Restricting to US-ASCII strings
is recommended.
*/ */
/*! /*!
@ -950,18 +965,18 @@ QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *met
const int verbosity = dbg.verbosity(); const int verbosity = dbg.verbosity();
if (verbosity >= QDebug::DefaultVerbosity) { if (verbosity >= QDebug::DefaultVerbosity) {
if (const char *scope = me.scope()) if (const char *scope = me.scope())
dbg << scope << "::"; dbg << scope << u"::";
} }
const char *key = me.valueToKey(value); const char *key = me.valueToKey(value);
const bool scoped = me.isScoped() || verbosity & 1; const bool scoped = me.isScoped() || verbosity & 1;
if (scoped || !key) if (scoped || !key)
dbg << me.enumName() << (!key ? "(" : "::"); dbg << me.enumName() << (!key ? u"(" : u"::");
if (key) if (key)
dbg << key; dbg << key;
else else
dbg << value << ")"; dbg << value << ')';
return dbg; return dbg;
} }
@ -1008,18 +1023,18 @@ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaO
const bool classScope = verbosity >= QDebug::DefaultVerbosity; const bool classScope = verbosity >= QDebug::DefaultVerbosity;
if (classScope) { if (classScope) {
debug << "QFlags<"; debug << u"QFlags<";
if (const char *scope = me.scope()) if (const char *scope = me.scope())
debug << scope << "::"; debug << scope << u"::";
} }
const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity; const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
if (enumScope) { if (enumScope) {
debug << me.enumName(); debug << me.enumName();
if (classScope) if (classScope)
debug << ">"; debug << '>';
debug << "("; debug << '(';
} }
debug << me.valueToKeys(value); debug << me.valueToKeys(value);

View File

@ -155,6 +155,7 @@ public:
inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(double 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 char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); }
inline QDebug &operator<<(const char16_t *t) { stream->ts << QStringView(t); return maybeSpace(); }
#if QT_STRINGVIEW_LEVEL < 2 #if QT_STRINGVIEW_LEVEL < 2
inline QDebug &operator<<(const QString & t) { putString(t.constData(), uint(t.length())); return maybeSpace(); } inline QDebug &operator<<(const QString & t) { putString(t.constData(), uint(t.length())); return maybeSpace(); }
#endif #endif

View File

@ -49,6 +49,7 @@ private slots:
void assignment() const; void assignment() const;
void warningWithoutDebug() const; void warningWithoutDebug() const;
void criticalWithoutDebug() const; void criticalWithoutDebug() const;
void basics() const;
void debugWithBool() const; void debugWithBool() const;
void debugSpaceHandling() const; void debugSpaceHandling() const;
void debugNoQuotes() const; void debugNoQuotes() const;
@ -156,6 +157,46 @@ void tst_QDebug::criticalWithoutDebug() const
QCOMPARE(QString::fromLatin1(s_function), function); QCOMPARE(QString::fromLatin1(s_function), function);
} }
void tst_QDebug::basics() const
{
// test simple types, without quoting or other modifications
// (bool tested in the next function)
MessageHandlerSetter mhs(myMessageHandler);
qDebug() << 'X';
QCOMPARE(s_msg, "X");
qDebug() << 123;
QCOMPARE(s_msg, "123");
qDebug() << 456U;
QCOMPARE(s_msg, "456");
qDebug() << -123L;
QCOMPARE(s_msg, "-123");
qDebug() << 456UL;
QCOMPARE(s_msg, "456");
qDebug() << Q_INT64_C(-123);
QCOMPARE(s_msg, "-123");
qDebug() << Q_UINT64_C(456);
QCOMPARE(s_msg, "456");
qDebug() << "Hello";
QCOMPARE(s_msg, "Hello");
qDebug() << u"World";
QCOMPARE(s_msg, "World");
qDebug() << (void *)0xfff;
QCOMPARE(s_msg, "0xfff");
qDebug() << nullptr;
QCOMPARE(s_msg, "(nullptr)");
}
void tst_QDebug::debugWithBool() const void tst_QDebug::debugWithBool() const
{ {
QString file, function; QString file, function;