summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/qtracer/ftracer.cpp180
-rw-r--r--src/corelib/doc/snippets/qtracer/main.cpp59
-rw-r--r--src/corelib/doc/snippets/qtracer/qtracer.pro2
-rw-r--r--src/corelib/doc/src/external-resources.qdoc20
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp1
-rw-r--r--src/corelib/global/qlogging.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp9
-rw-r--r--src/corelib/io/qloggingcategory.cpp293
-rw-r--r--src/corelib/io/qloggingcategory.h74
-rw-r--r--src/corelib/io/qloggingregistry.cpp8
-rw-r--r--src/corelib/io/qprocess_unix.cpp3
-rw-r--r--src/corelib/io/qurlidna.cpp5
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp17
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h1
-rw-r--r--src/corelib/kernel/qjni.cpp24
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp20
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h1
-rw-r--r--src/corelib/tools/qarraydata.cpp2
-rw-r--r--src/corelib/tools/qlocale_mac.mm105
-rw-r--r--src/corelib/tools/qstring.cpp2
-rw-r--r--src/corelib/tools/qstring.h4
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp2
23 files changed, 763 insertions, 75 deletions
diff --git a/src/corelib/doc/snippets/qtracer/ftracer.cpp b/src/corelib/doc/snippets/qtracer/ftracer.cpp
new file mode 100644
index 0000000000..b12e3ed9c3
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/ftracer.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <QCoreApplication>
+#include <QLoggingCategory>
+
+
+//![1]
+QLoggingCategory theFooArea("foo");
+QLoggingCategory theBarArea("bar");
+QLoggingCategory theBazArea("baz");
+//![1]
+
+// Note: These locations are Ubuntu specific.
+
+// Note: To make the example work with user permissions, make sure
+// the files are user-writable and the path leading there accessible.
+
+const char traceSwitch[] = "/sys/kernel/debug/tracing/tracing_on";
+const char traceSink[] = "/sys/kernel/debug/tracing/trace_marker";
+
+// The base class only serves as a facility to share code
+// between the "single line" data logging aspect and the
+// scoped "measuring" aspect.
+
+// Both aspects and the base class could be combined into
+// a single tracer serving both purposes, but are split
+// here for clarity.
+
+// Error handling is left as an exercise.
+
+//![2]
+class MyTracerBase : public QTracer
+{
+public:
+ MyTracerBase() {
+ enable = ::open(traceSwitch, O_WRONLY);
+ marker = ::open(traceSink, O_WRONLY);
+ }
+
+ ~MyTracerBase() {
+ ::close(enable);
+ ::close(marker);
+ }
+
+protected:
+ int enable;
+ int marker;
+};
+//![2]
+
+
+//![2]
+class MyTracer : public MyTracerBase
+{
+public:
+ void start() { ::write(marker, "B", 1); }
+ void end() { ::write(marker, "E", 1); }
+};
+//![2]
+
+
+//![3]
+class MyDataLogger : public MyTracerBase
+{
+public:
+ MyDataLogger() {
+ buf[0] = 0;
+ pos = 0;
+ }
+
+ void record(int i) { pos += sprintf(buf + pos, "%d", i); }
+ void record(const char *msg) { pos += sprintf(buf + pos, "%s", msg); }
+ void end() { ::write(marker, buf, pos); pos = 0; }
+
+private:
+ char buf[100];
+ int pos;
+};
+//![3]
+
+// Simplest possible example for "measuring".
+//![4]
+int foo(int i)
+{
+ qCTraceGuard(theFooArea);
+ // Here could be some lengthy code.
+ return i * i;
+}
+//![4]
+
+// We can switch on/off tracing dynamically.
+// The tracer will be temporarily switched off at the third call
+// and re-enabled at the eighth.
+//![5]
+int bar(int i)
+{
+ static int n = 0;
+ ++n;
+ if (n == 3)
+ theBarArea.setEnabled(QtTraceMsg, false);
+ if (n == 8)
+ theBarArea.setEnabled(QtTraceMsg, true);
+
+ qCTraceGuard(theBarArea);
+ return i * i;
+}
+//![5]
+
+// An example to create "complex" log messages.
+//![6]
+int baz(int i)
+{
+ qCTrace(theBazArea) << 32 << "some stuff";
+
+ return i * i;
+}
+//![6]
+
+
+
+//![7]
+namespace {
+static struct Init
+{
+ Init() {
+ tracer.addToCategory(theFooArea);
+ tracer.addToCategory(theBarArea);
+ logger.addToCategory(theBazArea);
+ }
+
+ MyTracer tracer;
+ MyDataLogger logger;
+
+} initializer;
+}
+//![7]
diff --git a/src/corelib/doc/snippets/qtracer/main.cpp b/src/corelib/doc/snippets/qtracer/main.cpp
new file mode 100644
index 0000000000..758a2bbdb8
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+int foo(int i);
+int bar(int i);
+int baz(int i);
+
+int main()
+{
+ int s = 0;
+ for (int i = 0; i != 10; ++i)
+ s += foo(i);
+
+ for (int i = 0; i != 10; ++i)
+ s += bar(i);
+
+ for (int i = 0; i != 10; ++i)
+ s += baz(i);
+
+ return s;
+}
+
diff --git a/src/corelib/doc/snippets/qtracer/qtracer.pro b/src/corelib/doc/snippets/qtracer/qtracer.pro
new file mode 100644
index 0000000000..254e22be76
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/qtracer.pro
@@ -0,0 +1,2 @@
+
+SOURCES += ftracer.cpp main.cpp
diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc
index d1c7eb5d1b..a4f1b8723a 100644
--- a/src/corelib/doc/src/external-resources.qdoc
+++ b/src/corelib/doc/src/external-resources.qdoc
@@ -47,26 +47,6 @@
*/
/*!
- \externalpage http://www.ietf.org/rfc/rfc3986.txt
- \title RFC 3986
-*/
-
-/*!
- \externalpage http://www.ietf.org/rfc/rfc1738.txt
- \title RFC 1738
-*/
-
-/*!
- \externalpage http://www.ietf.org/rfc/rfc3941.txt
- \title RFC 3491
-*/
-
-/*!
- \externalpage http://www.ietf.org/rfc/rfc2045.txt
- \title RFC 2045
-*/
-
-/*!
\externalpage http://www.ietf.org/rfc/rfc4648.txt
\title RFC 4648
*/
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 5b1a7dbbcb..41a9c0d950 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -717,6 +717,10 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
A message generated by the qCritical() function.
\value QtFatalMsg
A message generated by the qFatal() function.
+ \value QtTraceMsg
+ Used by the qCTrace() macro. Trace events are usually passed only
+ to dedicated \a QTracer objects, and do not appear in the installed
+ message handler.
\value QtSystemMsg
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 4d564b09c3..c0709ce258 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -814,6 +814,7 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
case QtWarningMsg: message.append(QLatin1String("warning")); break;
case QtCriticalMsg:message.append(QLatin1String("critical")); break;
case QtFatalMsg: message.append(QLatin1String("fatal")); break;
+ case QtTraceMsg: message.append(QLatin1String("trace")); break;
}
} else if (token == fileTokenC) {
if (context.file)
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 2b798f9ea0..68a24d0397 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QNoDebug;
-enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtTraceMsg, QtSystemMsg = QtCriticalMsg };
class QMessageLogContext
{
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index a7517b4c7f..46d8101e20 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -511,7 +511,14 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
if (slash) {
const QByteArray chunk = QFile::encodeName(dirName.left(slash));
if (QT_MKDIR(chunk.constData(), 0777) != 0) {
- if (errno == EEXIST) {
+ if (errno == EEXIST
+#if defined(Q_OS_QNX)
+ // On QNX the QNet (VFS paths of other hosts mounted under a directory
+ // such as /net) mountpoint returns ENOENT, despite existing. stat()
+ // on the QNet mountpoint returns successfully and reports S_IFDIR.
+ || errno == ENOENT
+#endif
+ ) {
QT_STATBUF st;
if (QT_STAT(chunk.constData(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR)
continue;
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 562cf25964..80acee6ad1 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -107,7 +107,8 @@ QLoggingCategory::QLoggingCategory(const char *category)
: name(0),
enabledDebug(false),
enabledWarning(true),
- enabledCritical(true)
+ enabledCritical(true),
+ enabledTrace(false)
{
bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -122,7 +123,8 @@ QLoggingCategory::QLoggingCategory(const char *category)
}
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
- reg->registerCategory(this);}
+ reg->registerCategory(this);
+}
/*!
Destructs a QLoggingCategory object
@@ -164,6 +166,7 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
case QtDebugMsg: return enabledDebug;
case QtWarningMsg: return enabledWarning;
case QtCriticalMsg: return enabledCritical;
+ case QtTraceMsg: return enabledTrace;
case QtFatalMsg: return true;
default: break;
}
@@ -177,6 +180,10 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
change e.g. the settings of another objects for the same category name.
\note QtFatalMsg cannot be changed. It will always return true.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 5
*/
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
@@ -184,6 +191,7 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
case QtDebugMsg: enabledDebug = enable; break;
case QtWarningMsg: enabledWarning = enable; break;
case QtCriticalMsg: enabledCritical = enable; break;
+ case QtTraceMsg: enabledTrace = enable; break;
case QtFatalMsg:
default: break;
}
@@ -319,12 +327,61 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp 12
\note Arguments are not processed if critical output for the category is not
- enabled, so do not reply on any side effects.
+ enabled, so do not rely on any side effects.
\sa qCritical()
*/
/*!
+ \relates QLoggingCategory
+ \macro qCTrace(category)
+ \since 5.2
+
+ Returns an output stream for trace messages in the logging category
+ \a category.
+
+ The macro expands to code that first checks whether
+ \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}.
+ If so, the stream arguments are processed and sent to the tracers
+ registered with the category.
+
+ \note Arguments are not processed if trace output for the category is not
+ enabled, so do not rely on any side effects.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 6
+
+ \sa qCTraceGuard()
+*/
+
+/*!
+ \relates QLoggingCategory
+ \macro qCTraceGuard(category)
+ \since 5.2
+
+ The macro expands to code that creates a guard object with automatic
+ storage. The guard constructor checks whether
+ \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}.
+ If so, the stream arguments are processed and the \c{start()}
+ functions of the tracers registered with the \a category are called.
+
+ The guard destructor also checks whether the category is enabled for
+ tracing and if so, the \c{end()}
+ functions of the tracers registered with the \a category are called.
+
+ \note Arguments are always processed, even if trace output for the
+ category is disabled. They will, however, in that case not be passed
+ to the \c{record()} functions of the registered tracers.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 4
+
+ \sa qCTrace()
+*/
+
+/*!
\macro Q_DECLARE_LOGGING_CATEGORY(name)
\relates QLoggingCategory
\since 5.2
@@ -349,4 +406,234 @@ void QLoggingCategory::setFilterRules(const QString &rules)
This macro must be used outside of a class or method.
*/
+
+/*!
+ \class QTracer
+ \inmodule QtCore
+ \since 5.2
+
+ \brief The QTracer class provides an interface for handling
+ trace events associated with a logging category.
+
+ \c QTracer objects are registered with logging categories.
+ Multiple \c QTracer objects
+ can be registered with the same category, and the same
+ \c QTracer object can be registered with different categories.
+
+ If code containing \c qCTrace is executed, and the associated
+ logging category is enabled for tracing, all \c QTracer objects
+ that are registered with the category are notified.
+
+ \c QTracer objects
+*/
+
+/*!
+ \fn QTracer::QTracer()
+
+ Constructs a tracer object.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 2
+*/
+
+/*!
+ \fn QTracer::~QTracer()
+
+ Destroys the tracer object.
+*/
+
+/*!
+ Registers this tracer for the \a category.
+
+ The tracer will later be notified of messages of type
+ \c QtTraceMsg, as long as that message type
+ is enabled in the category.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 1
+ \codeline
+ \snippet qtracer/ftracer.cpp 7
+*/
+
+void QTracer::addToCategory(QLoggingCategory &category)
+{
+ category.tracers.append(this);
+}
+
+/*!
+ \fn void QTracer::start()
+
+ This function is invoked when a tracing activity starts,
+ typically from the constructor of a \c QTraceGuard object
+ defined by \c qCTrace() or \c qCTraceGuard().
+
+ The base implementation does nothing. \c QTracer subclasses
+ are advised to override it if needed.
+
+ \sa qCTrace(), qCTraceGuard()
+*/
+
+/*!
+ \fn void QTracer::end()
+
+ This function is invoked when a tracing activity ends,
+ typically from the destructor of a \c QTraceGuard object
+ defined by \c qCTrace() or \c qCTraceGuard().
+
+ The base implementation does nothing. It is common for
+ \c QTracer subclasses to override it to perform flushing
+ of collected data.
+
+ \sa qCTrace(), qCTraceGuard()
+*/
+
+/*!
+ \fn void QTracer::record(int data)
+
+ This function is invoked during a tracing activity to
+ pass integer \a data to the \c QTracer object.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 3
+*/
+
+/*!
+ \fn void QTracer::record(const char *data)
+
+ This function is invoked during a tracing activity to
+ pass string \a data to the \c QTracer object.
+*/
+
+/*!
+ \fn void QTracer::record(const QVariant &data)
+
+ This function is invoked during a tracing activity to
+ pass abitrary (non-integer, non-string) \a data to
+ the \c QTracer object.
+*/
+
+/*!
+ \class QTraceGuard
+ \since 5.2
+ \inmodule QtCore
+
+ \brief The QTraceGuard class facilitates notifications to
+ \c QTracer objects.
+
+ \c QTraceGuard objects are typically implicitly created on the
+ stack when using the \c qCTrace or \c qCTraceGuard macros and
+ are associated to a \c QLoggingCategory.
+
+ The constructor of a \c QTraceGuard objects checks whether
+ its associated category is enabled, and if so, informs all
+ \c QTracer objects registered with the category that a
+ tracing activity starts.
+
+ The destructor of a \c QTraceGuard objects checks whether
+ its associated category is enabled, and if so, informs all
+ \c QTracer objects registered with the category that a
+ tracing activity ended.
+
+ A \c QTraceGuard object created by \c qCTrace will be destroyed
+ at the end of the full expression, a guard created by
+ \c qCTraceGuard at the end of the block containing the macro.
+
+ During the lifetime of a QTraceGuard object, its \c operator<<()
+ can be used to pass additional data to the active tracers.
+ The fast path handles only \c int and \c{const char *} data,
+ but it is possible to use arbitrary values wrapped in \c QVariants.
+
+ \sa QTracer
+*/
+
+/*!
+ \fn QTraceGuard::QTraceGuard(QLoggingCategory &category)
+ \internal
+
+ Constructs a trace guard object relaying to \a category.
+*/
+
+/*!
+ \fn QTraceGuard::~QTraceGuard()
+ \internal
+
+ Destroys the trace guard object.
+*/
+
+/*!
+ \internal
+
+ Calls \c start() on all registered tracers.
+*/
+
+void QTraceGuard::start()
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->start();
+}
+
+/*!
+ \internal
+
+ Calls \c end() on all registered tracers.
+*/
+
+void QTraceGuard::end()
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->end();
+}
+
+
+/*!
+ \internal
+
+ This function is called for int parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(int msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
+/*!
+ \internal
+
+ This function is called for string parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(const char *msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
+
+/*!
+ \internal
+
+ This function is called for QVariant parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(const QVariant &msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 90111c96fa..23b25b5e3f 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -44,9 +44,13 @@
#include <QtCore/qglobal.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
+class QTracer;
+class QTraceGuard;
+
class Q_CORE_EXPORT QLoggingCategory
{
Q_DISABLE_COPY(QLoggingCategory)
@@ -76,13 +80,18 @@ public:
static void setFilterRules(const QString &rules);
private:
+ friend class QLoggingRegistry;
+ friend class QTraceGuard;
+ friend class QTracer;
+
const char *name;
bool enabledDebug;
bool enabledWarning;
bool enabledCritical;
-
- friend class QLoggingRegistry;
+ bool enabledTrace;
+ typedef QVector<QTracer *> Tracers;
+ Tracers tracers;
};
template <>
@@ -103,6 +112,56 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const
return enabledCritical;
}
+template <>
+inline bool QLoggingCategory::isEnabled<QtTraceMsg>() const
+{
+ return enabledTrace;
+}
+
+class Q_CORE_EXPORT QTracer
+{
+ Q_DISABLE_COPY(QTracer)
+public:
+ QTracer() {}
+ virtual ~QTracer() {}
+
+ void addToCategory(QLoggingCategory &category);
+
+ virtual void start() {}
+ virtual void end() {}
+ virtual void record(int) {}
+ virtual void record(const char *) {}
+ virtual void record(const QVariant &) {}
+};
+
+class Q_CORE_EXPORT QTraceGuard
+{
+ Q_DISABLE_COPY(QTraceGuard)
+public:
+ QTraceGuard(QLoggingCategory &category)
+ {
+ target = category.isEnabled<QtTraceMsg>() ? &category : 0;
+ if (target)
+ start();
+ }
+
+ ~QTraceGuard()
+ {
+ if (target)
+ end();
+ }
+
+ QTraceGuard &operator<<(int msg);
+ QTraceGuard &operator<<(const char *msg);
+ QTraceGuard &operator<<(const QVariant &msg);
+
+private:
+ void start();
+ void end();
+
+ QLoggingCategory *target;
+};
+
#define Q_DECLARE_LOGGING_CATEGORY(name) \
extern QLoggingCategory &name();
@@ -123,6 +182,17 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const
#define qCCritical(category) \
for (bool enabled = category().isEnabled<QtCriticalMsg>(); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical()
+#define qCTrace(category) \
+ for (bool enabled = category.isEnabled<QtTraceMsg>(); enabled; enabled = false) \
+ QTraceGuard(category)
+
+
+#define Q_TRACE_GUARD_NAME_HELPER(line) qTraceGuard ## line
+#define Q_TRACE_GUARD_NAME(line) Q_TRACE_GUARD_NAME_HELPER(line)
+
+#define qCTraceGuard(category) \
+ QTraceGuard Q_TRACE_GUARD_NAME(__LINE__)(category);
+
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qCDebug
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index a82e6f65f4..885b51709d 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -86,6 +86,9 @@ int QLoggingRule::pass(const QString &categoryName, QtMsgType msgType) const
case QtCriticalMsg:
fullCategory += QLatin1String(".critical");
break;
+ case QtTraceMsg:
+ fullCategory += QLatin1String(".trace");
+ break;
default:
break;
}
@@ -288,6 +291,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
bool debug = (cat->categoryName() == qtDefaultCategoryName);
bool warning = true;
bool critical = true;
+ bool trace = true;
QString categoryName = QLatin1String(cat->categoryName());
QLoggingRegistry *reg = QLoggingRegistry::instance();
@@ -301,11 +305,15 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
filterpass = item.pass(categoryName, QtCriticalMsg);
if (filterpass != 0)
critical = (filterpass > 0);
+ filterpass = item.pass(categoryName, QtTraceMsg);
+ if (filterpass != 0)
+ trace = (filterpass > 0);
}
cat->setEnabled(QtDebugMsg, debug);
cat->setEnabled(QtWarningMsg, warning);
cat->setEnabled(QtCriticalMsg, critical);
+ cat->setEnabled(QtTraceMsg, trace);
}
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index eab3890beb..3c6d294916 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -141,7 +141,8 @@ static void qt_sa_sigchld_sigaction(int signum, siginfo_t *info, void *context)
if (qt_sa_old_sigchld_handler.sa_flags & SA_SIGINFO) {
void (*oldAction)(int, siginfo_t *, void *) = vsa->sa_sigaction;
- oldAction(signum, info, context);
+ if (oldAction)
+ oldAction(signum, info, context);
} else {
void (*oldAction)(int) = vsa->sa_handler;
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index ee95e590f9..988d076025 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -61,6 +61,11 @@ struct NameprepCaseFoldingEntry {
ushort mapping[4];
};
+#if defined(Q_CC_MSVC) && _MSC_VER < 1600
+inline bool operator<(const NameprepCaseFoldingEntry &one, const NameprepCaseFoldingEntry &other)
+{ return one.uc < other.uc; }
+#endif
+
inline bool operator<(uint one, const NameprepCaseFoldingEntry &other)
{ return one < other.uc; }
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 1799cf6a24..8617b17419 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -150,15 +150,20 @@ QString QCoreApplicationPrivate::macMenuBarName()
#endif
QString QCoreApplicationPrivate::appName() const
{
- static QString applName;
+ static QBasicMutex applicationNameMutex;
+ QMutexLocker locker(&applicationNameMutex);
+
+ if (applicationName.isNull()) {
#ifdef Q_OS_MAC
- applName = macMenuBarName();
+ applicationName = macMenuBarName();
#endif
- if (applName.isEmpty() && argv[0]) {
- char *p = strrchr(argv[0], '/');
- applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
+ if (applicationName.isEmpty() && argv[0]) {
+ char *p = strrchr(argv[0], '/');
+ applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
+ }
}
- return applName;
+
+ return applicationName;
}
#endif
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 6a3bea9c9e..477b8cfcfe 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -83,6 +83,7 @@ public:
~QCoreApplicationPrivate();
QString appName() const;
+ mutable QString applicationName;
#ifdef Q_OS_MAC
static QString macMenuBarName();
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 17678fcbba..d1113e4eae 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -70,16 +70,24 @@ static jclass getCachedClass(JNIEnv *env, const char *className)
QString key = QLatin1String(className);
QHash<QString, jclass>::iterator it = cachedClasses->find(key);
if (it == cachedClasses->end()) {
- jclass c = env->FindClass(className);
+ QJNIObjectPrivate classLoader = QtAndroidPrivate::classLoader();
+ if (!classLoader.isValid())
+ return 0;
+
+ QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(QLatin1String(className));
+ QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;",
+ stringName.object());
if (env->ExceptionCheck()) {
- c = 0;
#ifdef QT_DEBUG
env->ExceptionDescribe();
#endif // QT_DEBUG
env->ExceptionClear();
}
- if (c)
- clazz = static_cast<jclass>(env->NewGlobalRef(c));
+
+ if (classObject.isValid())
+ clazz = static_cast<jclass>(env->NewGlobalRef(classObject.object()));
+
cachedClasses->insert(key, clazz);
} else {
clazz = it.value();
@@ -160,10 +168,12 @@ QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
: jniEnv(0)
{
JavaVM *vm = QtAndroidPrivate::javaVM();
- if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) != JNI_EDETACHED)
- return;
+ if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
+ if (vm->AttachCurrentThread(&jniEnv, 0) < 0)
+ return;
+ }
- if (vm->AttachCurrentThread(&jniEnv, 0) < 0)
+ if (!jniEnv)
return;
if (!refCount->hasLocalData())
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index a95194b66a..fbcd0606e6 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
static JavaVM *g_javaVM = Q_NULLPTR;
static jobject g_jActivity = Q_NULLPTR;
+static jobject g_jClassLoader = Q_NULLPTR;
static inline bool exceptionCheck(JNIEnv *env)
{
@@ -79,6 +80,20 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
if (exceptionCheck(env))
return JNI_ERR;
+
+
+ jmethodID classLoaderMethodID = env->GetStaticMethodID(jQtNative,
+ "classLoader",
+ "()Ljava/lang/ClassLoader;");
+
+ if (exceptionCheck(env))
+ return JNI_ERR;
+
+ jobject classLoader = env->CallStaticObjectMethod(jQtNative, classLoaderMethodID);
+ if (exceptionCheck(env))
+ return JNI_ERR;
+
+ g_jClassLoader = env->NewGlobalRef(classLoader);
g_jActivity = env->NewGlobalRef(activity);
g_javaVM = vm;
@@ -96,4 +111,9 @@ JavaVM *QtAndroidPrivate::javaVM()
return g_javaVM;
}
+jobject QtAndroidPrivate::classLoader()
+{
+ return g_jClassLoader;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index 8719ae044b..39059db215 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -63,6 +63,7 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT jobject activity();
Q_CORE_EXPORT JavaVM *javaVM();
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
+ jobject classLoader();
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index a61147ad9c..825b3289c7 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -91,7 +91,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
// Allocate additional space if array is growing
if (options & Grow)
- capacity = qAllocMore(objectSize * capacity, headerSize) / int(objectSize);
+ capacity = qAllocMore(int(objectSize * capacity), int(headerSize)) / int(objectSize);
size_t allocSize = headerSize + objectSize * capacity;
diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm
index 43a0d67e74..deb5d5eb1d 100644
--- a/src/corelib/tools/qlocale_mac.mm
+++ b/src/corelib/tools/qlocale_mac.mm
@@ -166,6 +166,11 @@ static QString macTimeToString(const QTime &time, bool short_format)
return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
}
+// Mac uses the Unicode CLDR format codes
+// http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
+// See also qtbase/util/local_database/dateconverter.py
+// Makes the assumption that input formats are always well formed and consecutive letters
+// never exceed the maximum for the format code.
static QString macToQtFormat(const QString &sys_fmt)
{
QString result;
@@ -185,55 +190,97 @@ static QString macToQtFormat(const QString &sys_fmt)
int repeat = qt_repeatCount(sys_fmt, i);
switch (c.unicode()) {
- case 'G': // Qt doesn't support these :(
- case 'Y':
- case 'D':
- case 'F':
- case 'w':
- case 'W':
- case 'g':
+ // Qt does not support the following options
+ case 'G': // Era (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'Y': // Year of Week (1..n): 1..n = padded number
+ case 'U': // Cyclic Yar Name (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'Q': // Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
+ case 'q': // Standalone Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
+ case 'w': // Week of Year (1..2): 1..2 = padded number
+ case 'W': // Week of Month (1): 1 = number
+ case 'D': // Day of Year (1..3): 1..3 = padded number
+ case 'F': // Day of Week in Month (1): 1 = number
+ case 'g': // Modified Julian Day (1..n): 1..n = padded number
+ case 'A': // Milliseconds in Day (1..n): 1..n = padded number
break;
- case 'u': // extended year - use 'y'
- if (repeat < 4)
+ case 'y': // Year (1..n): 2 = short year, 1 & 3..n = padded number
+ case 'u': // Extended Year (1..n): 2 = short year, 1 & 3..n = padded number
+ // Qt only supports long (4) or short (2) year, use long for all others
+ if (repeat == 2)
result += QLatin1String("yy");
else
result += QLatin1String("yyyy");
break;
- case 'S': // fractional second
- if (repeat < 3)
- result += QLatin1Char('z');
+ case 'M': // Month (1..5): 4 = long, 3 = short, 1..2 = number, 5 = narrow
+ case 'L': // Standalone Month (1..5): 4 = long, 3 = short, 1..2 = number, 5 = narrow
+ // Qt only supports long, short and number, use short for narrow
+ if (repeat == 5)
+ result += QLatin1String("MMM");
else
- result += QLatin1String("zzz");
+ result += QString(repeat, QLatin1Char('M'));
break;
- case 'E':
- if (repeat <= 3)
- result += QLatin1String("ddd");
- else
+ case 'd': // Day of Month (1..2): 1..2 padded number
+ result += QString(repeat, c);
+ break;
+ case 'E': // Day of Week (1..6): 4 = long, 1..3 = short, 5..6 = narrow
+ // Qt only supports long, short and padded number, use short for narrow
+ if (repeat == 4)
result += QLatin1String("dddd");
+ else
+ result += QLatin1String("ddd");
break;
- case 'e':
- if (repeat >= 2)
- result += QLatin1String("dd");
+ case 'e': // Local Day of Week (1..6): 4 = long, 3 = short, 5..6 = narrow, 1..2 padded number
+ case 'c': // Standalone Local Day of Week (1..6): 4 = long, 3 = short, 5..6 = narrow, 1..2 padded number
+ // Qt only supports long, short and padded number, use short for narrow
+ if (repeat >= 5)
+ result += QLatin1String("ddd");
else
- result += QLatin1Char('d');
+ result += QString(repeat, QLatin1Char('d'));
break;
- case 'a':
+ case 'a': // AM/PM (1): 1 = short
+ // Translate to Qt uppercase AM/PM
result += QLatin1String("AP");
break;
- case 'k':
+ case 'h': // Hour [1..12] (1..2): 1..2 = padded number
+ case 'K': // Hour [0..11] (1..2): 1..2 = padded number
+ case 'j': // Local Hour [12 or 24] (1..2): 1..2 = padded number
+ // Qt h is local hour
+ result += QString(repeat, QLatin1Char('h'));
+ break;
+ case 'H': // Hour [0..23] (1..2): 1..2 = padded number
+ case 'k': // Hour [1..24] (1..2): 1..2 = padded number
+ // Qt H is 0..23 hour
result += QString(repeat, QLatin1Char('H'));
break;
- case 'K':
- result += QString(repeat, QLatin1Char('h'));
+ case 'm': // Minutes (1..2): 1..2 = padded number
+ case 's': // Seconds (1..2): 1..2 = padded number
+ result += QString(repeat, c);
+ break;
+ case 'S': // Fractional second (1..n): 1..n = tuncates to decimal places
+ // Qt uses msecs either unpadded or padded to 3 places
+ if (repeat < 3)
+ result += QLatin1Char('z');
+ else
+ result += QLatin1String("zzz");
break;
- case 'z':
- case 'Z':
- case 'v':
+ case 'z': // Time Zone (1..4)
+ case 'Z': // Time Zone (1..5)
+ case 'O': // Time Zone (1, 4)
+ case 'v': // Time Zone (1, 4)
+ case 'V': // Time Zone (1..4)
+ case 'X': // Time Zone (1..5)
+ case 'x': // Time Zone (1..5)
result += QLatin1Char('t');
break;
default:
- result += QString(repeat, c);
+ // a..z and A..Z are reserved for format codes, so any occurrence of these not
+ // already processed are not known and so unsupported formats to be ignored.
+ // All other chars are allowed as literals.
+ if (c < QLatin1Char('A') || c > QLatin1Char('z') ||
+ (c > QLatin1Char('Z') && c < QLatin1Char('a'))) {
+ result += QString(repeat, c);
+ }
break;
}
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 9625737d7f..239cf0446a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3895,7 +3895,7 @@ static inline __m128i mergeQuestionMarks(__m128i chunk)
# else
// SSE has no compare instruction for unsigned comparison.
// The variables must be shiffted + 0x8000 to be compared
- const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
+ const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 701082c7e6..2eaed65148 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -934,8 +934,8 @@ inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }
inline void QString::reserve(int asize)
{
- if (d->ref.isShared() || uint(asize) + 1u > d->alloc)
- reallocData(uint(asize) + 1u);
+ if (d->ref.isShared() || uint(asize) >= d->alloc)
+ reallocData(qMax(asize, d->size) + 1u);
if (!d->capacityReserved) {
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index d8b8ee81da..62b8f5f7b6 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -618,7 +618,7 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
// Offsets are stored as total offset, want to know separate UTC and DST offsets
// so find the first non-dst transition to use as base UTC Offset
- int utcOffset;
+ int utcOffset = 0;
foreach (const QTzTransition &tran, tranList) {
if (!typeList.at(tran.tz_typeind).tz_isdst) {
utcOffset = typeList.at(tran.tz_typeind).tz_gmtoff;