diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-08-06 10:45:40 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-08-06 10:54:01 +0200 |
commit | 77da617dc8e378a631ee8c15b1b414f16b87f147 (patch) | |
tree | 563f4f8e64e416774ea2b1599b896b589385168c /src/corelib/io/qdebug.cpp | |
parent | c17134e2db4d364855aa78a0d3c47cb9ef964dd9 (diff) | |
parent | 01f3530650f9f6f4c08520263a3c62281d81e3fc (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.cpp | 146 |
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. */ /*! |