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>
This commit is contained in:
parent
27797cb37a
commit
6d166c8822
@ -65,9 +65,9 @@ class QMessageLogContext
|
|||||||
{
|
{
|
||||||
Q_DISABLE_COPY(QMessageLogContext)
|
Q_DISABLE_COPY(QMessageLogContext)
|
||||||
public:
|
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)
|
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);
|
void copy(const QMessageLogContext &logContext);
|
||||||
|
|
||||||
|
@ -202,6 +202,41 @@ QDebug::~QDebug()
|
|||||||
\sa QDebugStateSaver
|
\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)
|
\fn QDebug &QDebug::operator<<(QChar t)
|
||||||
|
|
||||||
@ -368,19 +403,25 @@ public:
|
|||||||
QDebugStateSaverPrivate(QDebug &dbg)
|
QDebugStateSaverPrivate(QDebug &dbg)
|
||||||
: m_dbg(dbg),
|
: m_dbg(dbg),
|
||||||
m_spaces(dbg.autoInsertSpaces()),
|
m_spaces(dbg.autoInsertSpaces()),
|
||||||
|
m_flags(0),
|
||||||
m_streamParams(dbg.stream->ts.d_ptr->params)
|
m_streamParams(dbg.stream->ts.d_ptr->params)
|
||||||
{
|
{
|
||||||
|
if (m_dbg.stream->context.version > 1)
|
||||||
|
m_flags = m_dbg.stream->flags;
|
||||||
}
|
}
|
||||||
void restoreState()
|
void restoreState()
|
||||||
{
|
{
|
||||||
m_dbg.setAutoInsertSpaces(m_spaces);
|
m_dbg.setAutoInsertSpaces(m_spaces);
|
||||||
m_dbg.stream->ts.d_ptr->params = m_streamParams;
|
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 &m_dbg;
|
||||||
|
|
||||||
// QDebug state
|
// QDebug state
|
||||||
const bool m_spaces;
|
const bool m_spaces;
|
||||||
|
int m_flags;
|
||||||
|
|
||||||
// QTextStream state
|
// QTextStream state
|
||||||
const QTextStreamPrivate::Params m_streamParams;
|
const QTextStreamPrivate::Params m_streamParams;
|
||||||
|
@ -61,9 +61,9 @@ class Q_CORE_EXPORT QDebug
|
|||||||
friend class QMessageLogger;
|
friend class QMessageLogger;
|
||||||
friend class QDebugStateSaverPrivate;
|
friend class QDebugStateSaverPrivate;
|
||||||
struct Stream {
|
struct Stream {
|
||||||
Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
|
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) {}
|
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) {}
|
Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true), flags(0) {}
|
||||||
QTextStream ts;
|
QTextStream ts;
|
||||||
QString buffer;
|
QString buffer;
|
||||||
int ref;
|
int ref;
|
||||||
@ -71,6 +71,18 @@ class Q_CORE_EXPORT QDebug
|
|||||||
bool space;
|
bool space;
|
||||||
bool message_output;
|
bool message_output;
|
||||||
QMessageLogContext context;
|
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;
|
} *stream;
|
||||||
public:
|
public:
|
||||||
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
|
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
|
||||||
@ -88,7 +100,11 @@ public:
|
|||||||
bool autoInsertSpaces() const { return stream->space; }
|
bool autoInsertSpaces() const { return stream->space; }
|
||||||
void setAutoInsertSpaces(bool b) { stream->space = b; }
|
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<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
|
||||||
inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
|
inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
|
||||||
inline QDebug &operator<<(signed short 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<<(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 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<<(const QStringRef & t) { return operator<<(t.toString()); }
|
||||||
inline QDebug &operator<<(QLatin1String t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); }
|
inline QDebug &operator<<(QLatin1String t) { maybeQuote(); stream->ts << t; maybeQuote(); return maybeSpace(); }
|
||||||
inline QDebug &operator<<(const QByteArray & t) { stream->ts << '\"' << t << '\"'; 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<<(const void * t) { stream->ts << t; return maybeSpace(); }
|
||||||
inline QDebug &operator<<(QTextStreamFunction f) {
|
inline QDebug &operator<<(QTextStreamFunction f) {
|
||||||
stream->ts << f;
|
stream->ts << f;
|
||||||
@ -137,6 +153,9 @@ public:
|
|||||||
inline QNoDebug &space() { return *this; }
|
inline QNoDebug &space() { return *this; }
|
||||||
inline QNoDebug &nospace() { return *this; }
|
inline QNoDebug &nospace() { return *this; }
|
||||||
inline QNoDebug &maybeSpace() { 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>
|
template<typename T>
|
||||||
inline QNoDebug &operator<<(const T &) { return *this; }
|
inline QNoDebug &operator<<(const T &) { return *this; }
|
||||||
|
@ -56,10 +56,13 @@ private slots:
|
|||||||
void criticalWithoutDebug() const;
|
void criticalWithoutDebug() const;
|
||||||
void debugWithBool() const;
|
void debugWithBool() const;
|
||||||
void debugSpaceHandling() const;
|
void debugSpaceHandling() const;
|
||||||
|
void debugNoQuotes() const;
|
||||||
void stateSaver() const;
|
void stateSaver() const;
|
||||||
void veryLongWarningMessage() const;
|
void veryLongWarningMessage() const;
|
||||||
|
void qDebugQChar() const;
|
||||||
void qDebugQStringRef() const;
|
void qDebugQStringRef() const;
|
||||||
void qDebugQLatin1String() const;
|
void qDebugQLatin1String() const;
|
||||||
|
void qDebugQByteArray() const;
|
||||||
void textStreamModifiers() const;
|
void textStreamModifiers() const;
|
||||||
void defaultMessagehandler() const;
|
void defaultMessagehandler() const;
|
||||||
void threadSafety() const;
|
void threadSafety() const;
|
||||||
@ -219,6 +222,32 @@ void tst_QDebug::debugSpaceHandling() const
|
|||||||
QCOMPARE(s_msg, QString::fromLatin1("QMimeType(invalid) QMimeType(\"application/pdf\") foo"));
|
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
|
void tst_QDebug::stateSaver() const
|
||||||
{
|
{
|
||||||
MessageHandlerSetter mhs(myMessageHandler);
|
MessageHandlerSetter mhs(myMessageHandler);
|
||||||
@ -231,6 +260,16 @@ void tst_QDebug::stateSaver() const
|
|||||||
d << 42;
|
d << 42;
|
||||||
}
|
}
|
||||||
QCOMPARE(s_msg, QString::fromLatin1("02a 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
|
void tst_QDebug::veryLongWarningMessage() const
|
||||||
@ -251,6 +290,23 @@ void tst_QDebug::veryLongWarningMessage() const
|
|||||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
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
|
void tst_QDebug::qDebugQStringRef() const
|
||||||
{
|
{
|
||||||
/* Use a basic string. */
|
/* Use a basic string. */
|
||||||
@ -286,10 +342,30 @@ void tst_QDebug::qDebugQStringRef() const
|
|||||||
void tst_QDebug::qDebugQLatin1String() const
|
void tst_QDebug::qDebugQLatin1String() const
|
||||||
{
|
{
|
||||||
MessageHandlerSetter mhs(myMessageHandler);
|
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_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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\" baz"));
|
||||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||||
QCOMPARE(s_line, line);
|
QCOMPARE(s_line, line);
|
||||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user