summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKai Koehne <kai.koehne@nokia.com>2012-01-17 16:20:45 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-01 02:16:32 +0100
commitd394ca7f27197cfbfc28eb9a08eb0db261dd9d3d (patch)
treee75e133531101682473f91f5feca6c88c3e38c6c /src
parentea783ff51f25af89b7219154d7be5de1fd138664 (diff)
QtDebug: Include file, line, function information
Record the file, line, and function where a qDebug, qWarning, qCritical or qFatal call happens, and make this information available in a custom message handler. The patch uses the C preprocessor to replace qDebug, qWarning, ... with a line that also records the current file, line, and function. Custom message handlers can access this information via a new QMessageLogContext argument. Change-Id: I0a9b89c1d137e41775932d3b1a35da4ebf12d18d Reviewed-by: David Faure <faure@kde.org>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/global.pri6
-rw-r--r--src/corelib/global/qglobal.cpp205
-rw-r--r--src/corelib/global/qglobal.h62
-rw-r--r--src/corelib/global/qlogging.cpp76
-rw-r--r--src/corelib/global/qlogging.h161
-rw-r--r--src/corelib/io/qdebug.h27
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp4
-rw-r--r--src/tools/bootstrap/bootstrap.pro1
8 files changed, 418 insertions, 124 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 027542c6ea..fca9969db0 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -5,13 +5,15 @@ HEADERS += \
global/qnamespace.h \
global/qendian.h \
global/qnumeric_p.h \
- global/qnumeric.h
+ global/qnumeric.h \
+ global/qlogging.h
SOURCES += \
global/qglobal.cpp \
global/qlibraryinfo.cpp \
global/qmalloc.cpp \
- global/qnumeric.cpp
+ global/qnumeric.cpp \
+ global/qlogging.cpp
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 75bc1ec06f..01b3e2ec32 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -47,6 +47,7 @@
#include "qdir.h"
#include "qstringlist.h"
#include "qdatetime.h"
+#include "qdebug.h"
#ifndef QT_NO_QOBJECT
#include <private/qthread_p.h>
@@ -442,8 +443,12 @@ QT_BEGIN_NAMESPACE
Finally, the QtMsgType definition identifies the various messages
that can be generated and sent to a Qt message handler;
- QtMsgHandler is a type definition for a pointer to a function with
- the signature \c {void myMsgHandler(QtMsgType, const char *)}.
+ QMessageHandler is a type definition for a pointer to a function with
+ the signature
+ \c {void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *)}.
+ QMessageLogContext class contains the line, file, and function the
+ message was logged at. This information is created by the QMessageLogger
+ class.
\section1 Functions
@@ -473,8 +478,8 @@ QT_BEGIN_NAMESPACE
The remaining functions are qRound() and qRound64(), which both
accept a \l qreal value as their argument returning the value
rounded up to the nearest integer and 64-bit integer respectively,
- the qInstallMsgHandler() function which installs the given
- QtMsgHandler, and the qVersion() function which returns the
+ the qInstallMessageHandler() function which installs the given
+ QMessageHandler, and the qVersion() function which returns the
version number of Qt at run-time as a string.
\section1 Macros
@@ -675,16 +680,32 @@ QT_BEGIN_NAMESPACE
/*!
\typedef QtMsgHandler
\relates <QtGlobal>
+ \deprecated
This is a typedef for a pointer to a function with the following
signature:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7
- \sa QtMsgType, qInstallMsgHandler()
+ This typedef is deprecated, you should use QMessageHandler instead.
+ \sa QtMsgType, QMessageHandler, qInstallMsgHandler(), qInstallMessageHandler()
*/
/*!
+ \typedef QMessageHandler
+ \relates <QtGlobal>
+ \since 5.0
+
+ This is a typedef for a pointer to a function with the following
+ signature:
+
+ \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49
+
+ \sa QtMsgType, qInstallMessageHandler()
+*/
+
+
+/*!
\enum QtMsgType
\relates <QtGlobal>
@@ -704,7 +725,7 @@ QT_BEGIN_NAMESPACE
\value QtSystemMsg
- \sa QtMsgHandler, qInstallMsgHandler()
+ \sa QMessageHandler, qInstallMessageHandler()
*/
/*! \typedef QFunctionPointer
@@ -1705,7 +1726,8 @@ Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n)
void *qMemCopy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); }
void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); }
-static QtMsgHandler handler = 0; // pointer to debug handler
+static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context)
+static QMessageHandler messageHandler = 0; // pointer to debug handler (with context)
#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
@@ -1786,10 +1808,22 @@ QString qt_error_string(int errorCode)
return ret.trimmed();
}
-
/*!
\fn QtMsgHandler qInstallMsgHandler(QtMsgHandler handler)
\relates <QtGlobal>
+ \deprecated
+
+ Installs a Qt message \a handler which has been defined
+ previously. This method is deprecated, use qInstallMessageHandler
+ instead.
+
+ \sa QtMsgHandler, qInstallMessageHandler
+*/
+
+/*!
+ \fn QMessageHandler qInstallMessageHandler(QMessageHandler handler)
+ \relates <QtGlobal>
+ \since 5.0
Installs a Qt message \a handler which has been defined
previously. Returns a pointer to the previous message handler
@@ -1811,7 +1845,7 @@ QString qt_error_string(int errorCode)
Only one message handler can be defined, since this is usually
done on an application-wide basis to control debug output.
- To restore the message handler, call \c qInstallMsgHandler(0).
+ To restore the message handler, call \c qInstallMessageHandler(0).
Example:
@@ -1820,9 +1854,12 @@ QString qt_error_string(int errorCode)
\sa qDebug(), qWarning(), qCritical(), qFatal(), QtMsgType,
{Debugging Techniques}
*/
+
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
extern bool usingWinMain;
-extern Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str);
+extern Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char *str);
+extern Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &context,
+ const char *str);
#endif
/*!
@@ -1840,17 +1877,38 @@ static void qDefaultMsgHandler(QtMsgType, const char *buf)
#endif
}
+/*!
+ \internal
+*/
+static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &, const char *buf)
+{
+ qDefaultMsgHandler(type, buf);
+}
+
+QMessageHandler qInstallMessageHandler(QMessageHandler h)
+{
+ if (!messageHandler)
+ messageHandler = qDefaultMessageHandler;
+ QMessageHandler old = messageHandler;
+ messageHandler = h;
+#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
+ if (!messageHandler && usingWinMain)
+ messageHandler = qWinMessageHandler;
+#endif
+ return old;
+}
+
QtMsgHandler qInstallMsgHandler(QtMsgHandler h)
{
//if handler is 0, set it to the
//default message handler
- if (!handler)
- handler = qDefaultMsgHandler;
- QtMsgHandler old = handler;
- handler = h;
+ if (!msgHandler)
+ msgHandler = qDefaultMsgHandler;
+ QtMsgHandler old = msgHandler;
+ msgHandler = h;
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
- if (!handler && usingWinMain)
- handler = qWinMsgHandler;
+ if (!msgHandler && usingWinMain)
+ msgHandler = qWinMsgHandler;
#endif
return old;
}
@@ -1858,11 +1916,20 @@ QtMsgHandler qInstallMsgHandler(QtMsgHandler h)
/*!
\internal
*/
-void qt_message_output(QtMsgType msgType, const char *buf)
+void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const char *buf)
{
- if (!handler)
- handler = qDefaultMsgHandler;
- (*handler)(msgType, buf);
+ if (!msgHandler)
+ msgHandler = qDefaultMsgHandler;
+ if (!messageHandler)
+ messageHandler = qDefaultMessageHandler;
+
+ // prefer new message handler over the old one
+ if (msgHandler == qDefaultMsgHandler
+ || messageHandler != qDefaultMessageHandler) {
+ (*messageHandler)(msgType, context, buf);
+ } else {
+ (*msgHandler)(msgType, buf);
+ }
if (msgType == QtFatalMsg
|| (msgType == QtWarningMsg
@@ -1904,14 +1971,15 @@ static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap)
emergency_buf[255] = '\0';
if (msg)
qvsnprintf(emergency_buf, 255, msg, ap);
- qt_message_output(msgType, emergency_buf);
+ QMessageLogContext context;
+ qt_message_output(msgType, context, emergency_buf);
}
#endif
/*!
\internal
*/
-static void qt_message(QtMsgType msgType, const char *msg, va_list ap)
+static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap)
{
#if !defined(QT_NO_EXCEPTIONS)
if (std::uncaught_exception()) {
@@ -1931,11 +1999,12 @@ static void qt_message(QtMsgType msgType, const char *msg, va_list ap)
#endif
}
}
- qt_message_output(msgType, buf.constData());
+ qt_message_output(msgType, context, buf.constData());
}
#undef qDebug
/*!
+ \fn qDebug(const char *message, ...)
\relates <QtGlobal>
Calls the message handler with the debug message \a msg. If no
@@ -1964,21 +2033,42 @@ static void qt_message(QtMsgType msgType, const char *msg, va_list ap)
the end. It supports many C++ and Qt types.
To suppress the output at run-time, install your own message handler
- with qInstallMsgHandler().
+ with qInstallMessageHandler().
- \sa qWarning(), qCritical(), qFatal(), qInstallMsgHandler(),
+ \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
-void qDebug(const char *msg, ...)
+
+void QMessageLogger::debug(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
- qt_message(QtDebugMsg, msg, ap);
+ qt_message(QtDebugMsg, context, msg, ap);
va_end(ap);
}
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug QMessageLogger::debug()
+{
+ QDebug dbg = QDebug(QtDebugMsg);
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.file = context.file;
+ ctxt.line = context.line;
+ ctxt.function = context.function;
+ return dbg;
+}
+
+QNoDebug QMessageLogger::noDebug()
+{
+ return QNoDebug();
+}
+
+#endif
+
#undef qWarning
/*!
+ \fn qWarning(const char *message, ...)
\relates <QtGlobal>
Calls the message handler with the warning message \a msg. If no
@@ -2004,20 +2094,35 @@ void qDebug(const char *msg, ...)
appends a newline at the end.
To suppress the output at runtime, install your own message handler
- with qInstallMsgHandler().
+ with qInstallMessageHandler().
- \sa qDebug(), qCritical(), qFatal(), qInstallMsgHandler(),
+ \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
-void qWarning(const char *msg, ...)
+
+void QMessageLogger::warning(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
- qt_message(QtWarningMsg, msg, ap);
+ qt_message(QtWarningMsg, context, msg, ap);
va_end(ap);
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug QMessageLogger::warning()
+{
+ QDebug dbg = QDebug(QtWarningMsg);
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.file = context.file;
+ ctxt.line = context.line;
+ ctxt.function = context.function;
+ return dbg;
+}
+#endif
+
+#undef qCritical
/*!
+ \fn qCritical(const char *message, ...)
\relates <QtGlobal>
Calls the message handler with the critical message \a msg. If no
@@ -2040,19 +2145,32 @@ void qWarning(const char *msg, ...)
appended at the end.
To suppress the output at runtime, install your own message handler
- with qInstallMsgHandler().
+ with qInstallMessageHandler().
- \sa qDebug(), qWarning(), qFatal(), qInstallMsgHandler(),
+ \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
-void qCritical(const char *msg, ...)
+
+void QMessageLogger::critical(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
- qt_message(QtCriticalMsg, msg, ap);
+ qt_message(QtCriticalMsg, context, msg, ap);
va_end(ap);
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug QMessageLogger::critical()
+{
+ QDebug dbg = QDebug(QtCriticalMsg);
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.file = context.file;
+ ctxt.line = context.line;
+ ctxt.function = context.function;
+ return dbg;
+}
+#endif
+
void qErrnoWarning(const char *msg, ...)
{
// qt_error_string() will allocate anyway, so we don't have
@@ -2064,7 +2182,8 @@ void qErrnoWarning(const char *msg, ...)
buf.vsprintf(msg, ap);
va_end(ap);
- qCritical("%s (%s)", buf.toLocal8Bit().constData(), qt_error_string(-1).toLocal8Bit().constData());
+ QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(),
+ qt_error_string(-1).toLocal8Bit().constData());
}
void qErrnoWarning(int code, const char *msg, ...)
@@ -2078,10 +2197,13 @@ void qErrnoWarning(int code, const char *msg, ...)
buf.vsprintf(msg, ap);
va_end(ap);
- qCritical("%s (%s)", buf.toLocal8Bit().constData(), qt_error_string(code).toLocal8Bit().constData());
+ QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(),
+ qt_error_string(code).toLocal8Bit().constData());
}
+#undef qFatal
/*!
+ \fn qFatal(const char *message, ...)
\relates <QtGlobal>
Calls the message handler with the fatal message \a msg. If no
@@ -2100,16 +2222,17 @@ void qErrnoWarning(int code, const char *msg, ...)
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30
To suppress the output at runtime, install your own message handler
- with qInstallMsgHandler().
+ with qInstallMessageHandler().
- \sa qDebug(), qCritical(), qWarning(), qInstallMsgHandler(),
+ \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(),
{Debugging Techniques}
*/
-void qFatal(const char *msg, ...)
+
+void QMessageLogger::fatal(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
- qt_message(QtFatalMsg, msg, ap);
+ qt_message(QtFatalMsg, context, msg, ap);
va_end(ap);
}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 2e6f6c32a8..681cd55bb0 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1637,65 +1637,12 @@ inline void qUnused(T &x) { (void)x; }
# define qPrintable(string) QString(string).toLocal8Bit().constData()
#endif
-Q_CORE_EXPORT void qDebug(const char *, ...) /* print debug message */
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
- __attribute__ ((format (printf, 1, 2)))
-#endif
-;
-
-Q_CORE_EXPORT void qWarning(const char *, ...) /* print warning message */
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
- __attribute__ ((format (printf, 1, 2)))
-#endif
-;
-
class QString;
Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
-Q_CORE_EXPORT void qCritical(const char *, ...) /* print critical message */
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
- __attribute__ ((format (printf, 1, 2)))
-#endif
-;
-Q_CORE_EXPORT void qFatal(const char *, ...) /* print fatal message and exit */
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
- __attribute__ ((format (printf, 1, 2)))
-#endif
-;
Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...);
Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...);
-/*
- Forward declarations only.
-
- In order to use the qDebug() stream, you must #include<QDebug>
-*/
-class QDebug;
-class QNoDebug;
-#if !defined(QT_NO_DEBUG_OUTPUT) && !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qDebug();
-#else
-inline QNoDebug qDebug();
-#endif
-#if !defined(QT_NO_WARNING_OUTPUT) && !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qWarning();
-#else
-inline QNoDebug qWarning();
-#endif
-#if !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qCritical();
-#endif
-
-#define QT_NO_QDEBUG_MACRO while (false) qDebug
-#ifdef QT_NO_DEBUG_OUTPUT
-# define qDebug QT_NO_QDEBUG_MACRO
-#endif
-#define QT_NO_QWARNING_MACRO while (false) qWarning
-#ifdef QT_NO_WARNING_OUTPUT
-# define qWarning QT_NO_QWARNING_MACRO
-#endif
-
-
Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line);
#if !defined(Q_ASSERT)
@@ -1774,12 +1721,6 @@ inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
# endif
#endif
-enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
-
-Q_CORE_EXPORT void qt_message_output(QtMsgType, const char *buf);
-
-typedef void (*QtMsgHandler)(QtMsgType, const char *);
-Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
typedef void (*QFunctionPointer)();
@@ -2499,6 +2440,9 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; };
QT_END_NAMESPACE
QT_END_HEADER
+// qDebug and friends
+#include "qlogging.h"
+
#endif /* __cplusplus */
#endif /* QGLOBAL_H */
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
new file mode 100644
index 0000000000..bc26c9b6b7
--- /dev/null
+++ b/src/corelib/global/qlogging.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qlogging.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMessageLogContext
+ \relates <QtGlobal>
+ \brief The QMessageLogContext class provides additional information about a log message.
+ \since 5.0
+
+ The class provides information about the source code location a qDebug(), qWarning(),
+ qCritical() or qFatal() message was generated.
+
+ \sa QMessageLogger, QMessageHandler, qInstallMessageHandler()
+*/
+
+/*!
+ \class QMessageLogger
+ \relates <QtGlobal>
+ \brief The QMessageLogger class generates log messages.
+ \since 5.0
+
+ QMessageLogger is used to generate messages for the Qt logging framework. Most of the time
+ is transparently used through the qDebug(), qWarning(), qCritical, or qFatal() functions,
+ which are actually macros that expand to QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
+ et al.
+
+ One example of direct use is to forward errors that stem from a scripting language, e.g. QML:
+
+ \snippet doc/src/snippets/code/qlogging/qlogging.cpp 1
+
+ \sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
new file mode 100644
index 0000000000..c6edc7bc48
--- /dev/null
+++ b/src/corelib/global/qlogging.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+
+#ifndef QLOGGING_H
+#define QLOGGING_H
+
+#if 0
+// header is automatically included in qglobal.h
+#pragma qt_no_master_include
+#endif
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+/*
+ Forward declarations only.
+
+ In order to use the qDebug() stream, you must #include<QDebug>
+*/
+class QDebug;
+class QNoDebug;
+
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
+
+class QMessageLogContext
+{
+ Q_DISABLE_COPY(QMessageLogContext)
+public:
+ QMessageLogContext() : version(1), line(0), file(0), function(0) {}
+ Q_DECL_CONSTEXPR QMessageLogContext(const char *file, int line, const char *function)
+ : version(1), line(line), file(file), function(function) {}
+
+ int version;
+ int line;
+ const char *file;
+ const char *function;
+
+private:
+ friend class QMessageLogger;
+ friend class QDebug;
+};
+
+class Q_CORE_EXPORT QMessageLogger
+{
+ Q_DISABLE_COPY(QMessageLogger)
+public:
+ QMessageLogger() : context() {}
+ Q_DECL_CONSTEXPR QMessageLogger(const char *file, int line, const char *function)
+ : context(file, line, function) {}
+
+ void debug(const char *msg, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+ void noDebug(const char *, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ {}
+ void warning(const char *msg, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+ void critical(const char *msg, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+ void fatal(const char *msg, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug debug();
+ QDebug warning();
+ QDebug critical();
+
+ QNoDebug noDebug();
+#endif // QT_NO_DEBUG_STREAM
+
+private:
+ QMessageLogContext context;
+};
+
+Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, const char *buf);
+
+/*
+ qDebug, qWarning, qCritical, qFatal are redefined to automatically include context information
+ */
+#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug
+#define qWarning QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warning
+#define qCritical QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).critical
+#define qFatal QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).fatal
+
+#define QT_NO_QDEBUG_MACRO while (false) QMessageLogger().noDebug
+#define QT_NO_QWARNING_MACRO while (false) QMessageLogger().noDebug
+
+#ifdef QT_NO_DEBUG_OUTPUT
+# undef qDebug
+# define qDebug QT_NO_QDEBUG_MACRO
+#endif
+#ifdef QT_NO_WARNING_OUTPUT
+# undef qWarning
+# define qWarning QT_NO_QWARNING_MACRO
+#endif
+
+// deprecated. Use qInstallMessageHandler instead!
+typedef void (*QtMsgHandler)(QtMsgType, const char *);
+Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
+
+typedef void (*QMessageHandler)(QtMsgType, const QMessageLogContext &, const char *);
+Q_CORE_EXPORT QMessageHandler qInstallMessageHandler(QMessageHandler);
+
+QT_END_HEADER
+QT_END_NAMESPACE
+
+#endif // QLOGGING_H
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 5c38fcfbbb..c268660573 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QDebug
{
+ friend class QMessageLogger;
struct Stream {
Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
@@ -70,6 +71,7 @@ class Q_CORE_EXPORT QDebug
QtMsgType type;
bool space;
bool message_output;
+ QMessageLogContext context;
} *stream;
public:
inline QDebug(QIODevice *device) : stream(new Stream(device)) {}
@@ -81,7 +83,9 @@ public:
if (!--stream->ref) {
if(stream->message_output) {
QT_TRY {
- qt_message_output(stream->type, stream->buffer.toLocal8Bit().data());
+ qt_message_output(stream->type,
+ stream->context,
+ stream->buffer.toLocal8Bit().data());
} QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ }
}
delete stream;
@@ -269,27 +273,6 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
return debug.space();
}
-#if !defined(QT_NO_DEBUG_OUTPUT) && !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qDebug() { return QDebug(QtDebugMsg); }
-#else
-#undef qDebug
-inline QNoDebug qDebug() { return QNoDebug(); }
-#define qDebug QT_NO_QDEBUG_MACRO
-#endif
-
-#if !defined(QT_NO_WARNING_OUTPUT) && !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qWarning() { return QDebug(QtWarningMsg); }
-#else
-#undef qWarning
-inline QNoDebug qWarning() { return QNoDebug(); }
-#define qWarning QT_NO_QWARNING_MACRO
-#endif
-
-#if !defined(QT_NO_DEBUG_STREAM)
-Q_CORE_EXPORT_INLINE QDebug qCritical() { return QDebug(QtCriticalMsg); }
-#endif
-
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 137f8baf5e..e087174d8b 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -161,6 +161,10 @@ Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str)
staticCriticalSection.unlock();
}
+Q_CORE_EXPORT void qWinMessageHandler(QtMsgType t, const QMessageLogContext &, const char* str)
+{
+ qWinMsgHandler(t, str);
+}
/*****************************************************************************
qWinMain() - Initializes Windows. Called from WinMain() in qtmain_win.cpp
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index b5869d826c..fdf41c55c2 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -51,6 +51,7 @@ SOURCES += \
../../corelib/codecs/qtextcodec.cpp \
../../corelib/codecs/qutfcodec.cpp \
../../corelib/global/qglobal.cpp \
+ ../../corelib/global/qlogging.cpp \
../../corelib/global/qmalloc.cpp \
../../corelib/global/qnumeric.cpp \
../../corelib/io/qabstractfileengine.cpp \