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 | |
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')
-rw-r--r-- | src/corelib/io/qbuffer.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qdebug.cpp | 146 | ||||
-rw-r--r-- | src/corelib/io/qdebug.h | 14 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qloggingregistry.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qprocess.cpp | 12 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 6 |
7 files changed, 158 insertions, 34 deletions
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp index 680f832909..fd74681663 100644 --- a/src/corelib/io/qbuffer.cpp +++ b/src/corelib/io/qbuffer.cpp @@ -425,7 +425,7 @@ qint64 QBuffer::writeData(const char *data, qint64 len) } } - memcpy(d->buf->data() + pos(), (uchar *)data, int(len)); + memcpy(d->buf->data() + pos(), data, int(len)); #ifndef QT_NO_QOBJECT d->writtenSinceLastEmit += len; 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. */ /*! diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 9391799624..2f626dfc1f 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -293,7 +293,7 @@ template <class T> inline typename QtPrivate::QEnableIf< QtPrivate::IsQEnumHelper<T>::Value || QtPrivate::IsQEnumHelper<QFlags<T> >::Value, QDebug>::Type -operator<<(QDebug debug, const QFlags<T> &flags) +qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags) { const QMetaObject *obj = qt_getEnumMetaObject(T()); const char *name = qt_getEnumName(T()); @@ -304,10 +304,10 @@ template <class T> inline typename QtPrivate::QEnableIf< !QtPrivate::IsQEnumHelper<T>::Value && !QtPrivate::IsQEnumHelper<QFlags<T> >::Value, QDebug>::Type -operator<<(QDebug debug, const QFlags<T> &flags) +qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags) #else // !QT_NO_QOBJECT template <class T> -inline QDebug operator<<(QDebug debug, const QFlags<T> &flags) +inline QDebug qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags) #endif { QDebugStateSaver saver(debug); @@ -327,6 +327,14 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags) return debug; } +template<typename T> +inline QDebug operator<<(QDebug debug, const QFlags<T> &flags) +{ + // We have to use an indirection otherwise specialisation of some other overload of the + // operator<< the compiler would try to instantiate QFlags<T> for the QEnableIf + return qt_QMetaEnum_flagDebugOperator_helper(debug, flags); +} + #ifdef Q_OS_MAC // We provide QDebug stream operators for commonly used Core Foundation diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index ddbd24338b..429c40da1a 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -819,13 +819,13 @@ bool QFSFileEngine::extension(Extension extension, const ExtensionOption *option return feof(d->fh); if (extension == MapExtension) { - const MapExtensionOption *options = (MapExtensionOption*)(option); + const MapExtensionOption *options = (const MapExtensionOption*)(option); MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output); returnValue->address = d->map(options->offset, options->size, options->flags); return (returnValue->address != 0); } if (extension == UnMapExtension) { - UnMapExtensionOption *options = (UnMapExtensionOption*)option; + const UnMapExtensionOption *options = (const UnMapExtensionOption*)option; return d->unmap(options->address); } diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 05c41910c5..f0b72cd9be 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -398,10 +398,12 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat) Q_ASSERT(reg->categories.contains(cat)); QtMsgType enableForLevel = reg->categories.value(cat); + // NB: note that the numeric values of the Qt*Msg constants are + // not in severity order. bool debug = (enableForLevel == QtDebugMsg); - bool info = (enableForLevel <= QtInfoMsg); - bool warning = (enableForLevel <= QtWarningMsg); - bool critical = (enableForLevel <= QtCriticalMsg); + bool info = debug || (enableForLevel == QtInfoMsg); + bool warning = info || (enableForLevel == QtWarningMsg); + bool critical = warning || (enableForLevel == QtCriticalMsg); // hard-wired implementation of // qt.*.debug=false diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index f979f8e0ec..dfde5f236d 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2122,6 +2122,13 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM qWarning("QProcess::start: Process is already running"); return; } + if (program.isEmpty()) { + Q_D(QProcess); + d->processError = QProcess::FailedToStart; + setErrorString(tr("No program defined")); + emit error(d->processError); + return; + } d->program = program; d->arguments = arguments; @@ -2146,7 +2153,10 @@ void QProcess::start(OpenMode mode) return; } if (d->program.isEmpty()) { - qWarning("QProcess::start: program not set"); + Q_D(QProcess); + d->processError = QProcess::FailedToStart; + setErrorString(tr("No program defined")); + emit error(d->processError); return; } diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 345f0bd65d..4e6079306b 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -956,7 +956,7 @@ public: } else #endif { - delete [] (uchar *)mappingBuffer(); + delete [] mappingBuffer(); } } QString mappingFile() const { return fileName; } @@ -1450,13 +1450,13 @@ bool QResourceFileEngine::extension(Extension extension, const ExtensionOption * { Q_D(QResourceFileEngine); if (extension == MapExtension) { - const MapExtensionOption *options = (MapExtensionOption*)(option); + const MapExtensionOption *options = (const MapExtensionOption*)(option); MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output); returnValue->address = d->map(options->offset, options->size, options->flags); return (returnValue->address != 0); } if (extension == UnMapExtension) { - UnMapExtensionOption *options = (UnMapExtensionOption*)option; + const UnMapExtensionOption *options = (const UnMapExtensionOption*)option; return d->unmap(options->address); } return false; |