summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdebug.cpp
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:45:40 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:54:01 +0200
commit77da617dc8e378a631ee8c15b1b414f16b87f147 (patch)
tree563f4f8e64e416774ea2b1599b896b589385168c /src/corelib/io/qdebug.cpp
parentc17134e2db4d364855aa78a0d3c47cb9ef964dd9 (diff)
parent01f3530650f9f6f4c08520263a3c62281d81e3fc (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: doc/global/qt-cpp-defines.qdocconf src/3rdparty/forkfd/forkfd.c src/corelib/codecs/qtextcodec.cpp src/corelib/kernel/qmetatype.cpp src/corelib/tools/qset.qdoc src/gui/accessible/qaccessible.cpp src/gui/image/qpixmapcache.cpp src/opengl/qgl.cpp src/tools/qdoc/generator.cpp src/widgets/kernel/qwidget.cpp tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp Change-Id: I4fbe1fa756a54c6843aa75f4ef70a1069ba7b085
Diffstat (limited to 'src/corelib/io/qdebug.cpp')
-rw-r--r--src/corelib/io/qdebug.cpp146
1 files changed, 125 insertions, 21 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 8676fe0259..54a705b72b 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -174,6 +174,16 @@ void QDebug::putUcs4(uint ucs4)
maybeQuote('\'');
}
+// These two functions return true if the character should be printed by QDebug.
+// For QByteArray, this is technically identical to US-ASCII isprint();
+// for QString, we use QChar::isPrint, which requires a full UCS-4 decode.
+static inline bool isPrintable(uint ucs4)
+{ return QChar::isPrint(ucs4); }
+static inline bool isPrintable(ushort uc)
+{ return QChar::isPrint(uc); }
+static inline bool isPrintable(uchar c)
+{ return c >= ' ' && c < 0x7f; }
+
template <typename Char>
static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, int length, bool isUnicode = true)
{
@@ -194,22 +204,23 @@ static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, in
}
if (sizeof(Char) == sizeof(QChar)) {
+ // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them
int runLength = 0;
while (p + runLength != end &&
- p[runLength] < 0x7f && p[runLength] >= 0x20 && p[runLength] != '\\' && p[runLength] != '"')
+ isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"')
++runLength;
if (runLength) {
d->write(reinterpret_cast<const QChar *>(p), runLength);
p += runLength - 1;
continue;
}
- } else if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') {
+ } else if (isPrintable(*p) && *p != '\\' && *p != '"') {
QChar c = QLatin1Char(*p);
d->write(&c, 1);
continue;
}
- // print as an escape sequence
+ // print as an escape sequence (maybe, see below for surrogate pairs)
int buflen = 2;
ushort buf[sizeof "\\U12345678" - 1];
buf[0] = '\\';
@@ -248,17 +259,23 @@ static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, in
if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
// properly-paired surrogates
uint ucs4 = QChar::surrogateToUcs4(*p, p[1]);
+ if (isPrintable(ucs4)) {
+ buf[0] = *p;
+ buf[1] = p[1];
+ buflen = 2;
+ } else {
+ buf[1] = 'U';
+ buf[2] = '0'; // toHexUpper(ucs4 >> 32);
+ buf[3] = '0'; // toHexUpper(ucs4 >> 28);
+ buf[4] = toHexUpper(ucs4 >> 20);
+ buf[5] = toHexUpper(ucs4 >> 16);
+ buf[6] = toHexUpper(ucs4 >> 12);
+ buf[7] = toHexUpper(ucs4 >> 8);
+ buf[8] = toHexUpper(ucs4 >> 4);
+ buf[9] = toHexUpper(ucs4);
+ buflen = 10;
+ }
++p;
- buf[1] = 'U';
- buf[2] = '0'; // toHexUpper(ucs4 >> 32);
- buf[3] = '0'; // toHexUpper(ucs4 >> 28);
- buf[4] = toHexUpper(ucs4 >> 20);
- buf[5] = toHexUpper(ucs4 >> 16);
- buf[6] = toHexUpper(ucs4 >> 12);
- buf[7] = toHexUpper(ucs4 >> 8);
- buf[8] = toHexUpper(ucs4 >> 4);
- buf[9] = toHexUpper(ucs4);
- buflen = 10;
break;
}
// improperly-paired surrogates, fall through
@@ -409,6 +426,9 @@ QDebug &QDebug::resetFormat()
Disables automatic insertion of quotation characters around QChar, QString and QByteArray
contents and returns a reference to the stream.
+ When quoting is disabled, these types are printed without quotation
+ characters and without escaping of non-printable characters.
+
\sa quote(), maybeQuote()
*/
@@ -454,7 +474,11 @@ QDebug &QDebug::resetFormat()
\fn QDebug &QDebug::operator<<(QChar t)
Writes the character, \a t, to the stream and returns a reference to the
- stream.
+ stream. Normally, QDebug prints control characters and non-US-ASCII
+ characters as their C escape sequences or their Unicode value (\\u1234). To
+ print non-printable characters without transformation, enable the noquote()
+ functionality, but note that some QDebug backends may not be 8-bit clean
+ and may not be able to represent \c t.
*/
/*!
@@ -545,34 +569,114 @@ QDebug &QDebug::resetFormat()
\fn QDebug &QDebug::operator<<(const char *s)
Writes the '\\0'-terminated string, \a s, to the stream and returns a
- reference to the stream.
+ reference to the stream. The string is never quoted nor transformed to the
+ output, but note that some QDebug backends might not be 8-bit clean.
*/
/*!
\fn QDebug &QDebug::operator<<(const QString &s)
- Writes the string, \a s, to the stream and returns a reference to the stream.
+ Writes the string, \a s, to the stream and returns a reference to the
+ stream. Normally, QDebug prints the string inside quotes and transforms
+ non-printable characters to their Unicode values (\\u1234).
+
+ To print non-printable characters without transformation, enable the
+ noquote() functionality. Note that some QDebug backends might not be 8-bit
+ clean.
+
+ Output examples:
+ \code
+ QString s;
+
+ s = "a";
+ qDebug().noquote() << s; // prints: a
+ qDebug() << s; // prints: "a"
+
+ s = "\"a\r\n\"";
+ qDebug() << s; // prints: "\"a\r\n\""
+
+ s = "\033"; // escape character
+ qDebug() << s; // prints: "\u001B"
+
+ s = "\u00AD"; // SOFT HYPHEN
+ qDebug() << s; // prints: "\u00AD"
+
+ s = "\u00E1"; // LATIN SMALL LETTER A WITH ACUTE
+ qDebug() << s; // prints: "á"
+
+ s = "a\u0301"; // "a" followed by COMBINING ACUTE ACCENT
+ qDebug() << s; // prints: "á";
+
+ s = "\u0430\u0301"; // CYRILLIC SMALL LETTER A followed by COMBINING ACUTE ACCENT
+ qDebug() << s; // prints: "а́"
+ \endcode
*/
/*!
\fn QDebug &QDebug::operator<<(const QStringRef &s)
- Writes the string reference, \a s, to the stream and returns a reference to
- the stream.
+ Writes the string, \a s, to the stream and returns a reference to the
+ stream. Normally, QDebug prints the string inside quotes and transforms
+ non-printable characters to their Unicode values (\\u1234).
+
+ To print non-printable characters without transformation, enable the
+ noquote() functionality. Note that some QDebug backends might not be 8-bit
+ clean.
+
+ See the QString overload for examples.
*/
/*!
\fn QDebug &QDebug::operator<<(QLatin1String s)
- Writes the Latin1-encoded string, \a s, to the stream and returns a reference
- to the stream.
+ Writes the string, \a s, to the stream and returns a reference to the
+ stream. Normally, QDebug prints the string inside quotes and transforms
+ non-printable characters to their Unicode values (\\u1234).
+
+ To print non-printable characters without transformation, enable the
+ noquote() functionality. Note that some QDebug backends might not be 8-bit
+ clean.
+
+ See the QString overload for examples.
*/
/*!
\fn QDebug &QDebug::operator<<(const QByteArray &b)
Writes the byte array, \a b, to the stream and returns a reference to the
- stream.
+ stream. Normally, QDebug prints the array inside quotes and transforms
+ control or non-US-ASCII characters to their C escape sequences (\\xAB). This
+ way, the output is always 7-bit clean and the string can be copied from the
+ output and pasted back into C++ sources, if necessary.
+
+ To print non-printable characters without transformation, enable the
+ noquote() functionality. Note that some QDebug backends might not be 8-bit
+ clean.
+
+ Output examples:
+ \code
+ QByteArray ba;
+
+ ba = "a";
+ qDebug().noquote() << ba; // prints: a
+ qDebug() << ba; // prints: "a"
+
+ ba = "\"a\r\n\"";
+ qDebug() << ba; // prints: "\"a\r\n\""
+
+ ba = "\033"; // escape character
+ qDebug() << ba; // prints: "\x1B"
+
+ ba = "\xC3\xA1";
+ qDebug() << ba; // prints: "\xC3\xA1"
+
+ ba = QByteArray("a\0b", 3);
+ qDebug() << ba // prints: "\a\x00""b"
+ \endcode
+
+ Note how QDebug needed to close and reopen the string in the way C and C++
+ languages concatenate string literals so that the letter 'b' is not
+ interpreted as part of the previous hexadecimal escape sequence.
*/
/*!