summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
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
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')
-rw-r--r--src/corelib/io/qbuffer.cpp2
-rw-r--r--src/corelib/io/qdebug.cpp146
-rw-r--r--src/corelib/io/qdebug.h14
-rw-r--r--src/corelib/io/qfsfileengine.cpp4
-rw-r--r--src/corelib/io/qloggingregistry.cpp8
-rw-r--r--src/corelib/io/qprocess.cpp12
-rw-r--r--src/corelib/io/qresource.cpp6
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;