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>
This commit is contained in:
parent
ea783ff51f
commit
d394ca7f27
@ -246,27 +246,27 @@ const TInputType &myMin(const TInputType &value1, const TInputType &value2)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void myMessageOutput(QtMsgType type, const char *msg)
|
||||
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const char *msg)
|
||||
{
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
fprintf(stderr, "Debug: %s\n", msg);
|
||||
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", msg, context.file, context.line, context.function);
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
fprintf(stderr, "Warning: %s\n", msg);
|
||||
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", msg, context.file, context.line, context.function);
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
fprintf(stderr, "Critical: %s\n", msg);
|
||||
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", msg, context.file, context.line, context.function);
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
fprintf(stderr, "Fatal: %s\n", msg);
|
||||
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", msg, context.file, context.line, context.function);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
qInstallMsgHandler(myMessageOutput);
|
||||
qInstallMessageHandler(myMessageOutput);
|
||||
QApplication app(argc, argv);
|
||||
...
|
||||
return app.exec();
|
||||
@ -532,6 +532,11 @@ class MyClass : public QObject
|
||||
CApaApplication *myApplicationFactory();
|
||||
//! [47]
|
||||
|
||||
|
||||
//! [49]
|
||||
void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *);
|
||||
//! [49]
|
||||
|
||||
//! [qlikely]
|
||||
// the condition inside the "if" will be successful most of the times
|
||||
for (int i = 1; i <= 365; i++) {
|
||||
|
54
doc/src/snippets/qlogging/qloggingsnippet.cpp
Normal file
54
doc/src/snippets/qlogging/qloggingsnippet.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the documentation 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 Nokia Corporation 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 <QtGui>
|
||||
#include <QtDebug>
|
||||
#include <QDeclarativeComponent>
|
||||
|
||||
//! [1]
|
||||
void statusChanged(QDeclarativeComponent::Status status) {
|
||||
if (status == QDeclarativeComponent::Error) {
|
||||
foreach (const QDeclarativeError &error, component->errors()) {
|
||||
const QByteArray file = error.url().toEncoded();
|
||||
QMessageLogger(file.constData(), error.line(), 0).debug() << error.description();
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [1]
|
@ -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
|
||||
|
@ -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,15 +680,31 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
76
src/corelib/global/qlogging.cpp
Normal file
76
src/corelib/global/qlogging.cpp
Normal file
@ -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
|
161
src/corelib/global/qlogging.h
Normal file
161
src/corelib/global/qlogging.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -5,4 +5,5 @@ SUBDIRS=\
|
||||
qgetputenv \
|
||||
qglobal \
|
||||
qnumeric \
|
||||
qrand
|
||||
qrand \
|
||||
qmessagehandler
|
||||
|
@ -0,0 +1,4 @@
|
||||
CONFIG += testcase parallel_test
|
||||
TARGET = tst_qmessagehandler
|
||||
QT = core testlib
|
||||
SOURCES = tst_qmessagehandler.cpp
|
@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the test suite 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 <qdebug.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
class tst_qmessagehandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void cleanup();
|
||||
|
||||
void defaultHandler();
|
||||
void installMessageHandler();
|
||||
void installMsgHandler();
|
||||
void installBothHandler();
|
||||
};
|
||||
|
||||
static QtMsgType s_type;
|
||||
const char *s_file;
|
||||
int s_line;
|
||||
const char *s_function;
|
||||
static QString s_message;
|
||||
|
||||
void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *msg)
|
||||
{
|
||||
s_type = type;
|
||||
s_file = context.file;
|
||||
s_line = context.line;
|
||||
s_function = context.function;
|
||||
s_message = QString::fromLocal8Bit(msg);
|
||||
}
|
||||
|
||||
void customMsgHandler(QtMsgType type, const char *msg)
|
||||
{
|
||||
s_type = type;
|
||||
s_file = 0;
|
||||
s_line = 0;
|
||||
s_function = 0;
|
||||
s_message = QString::fromLocal8Bit(msg);
|
||||
}
|
||||
|
||||
void tst_qmessagehandler::cleanup()
|
||||
{
|
||||
qInstallMsgHandler(0);
|
||||
qInstallMessageHandler(0);
|
||||
s_type = QtFatalMsg;
|
||||
s_file = 0;
|
||||
s_line = 0;
|
||||
s_function = 0;
|
||||
}
|
||||
|
||||
void tst_qmessagehandler::defaultHandler()
|
||||
{
|
||||
// check that the default works
|
||||
QTest::ignoreMessage(QtDebugMsg, "defaultHandler");
|
||||
qDebug("defaultHandler");
|
||||
}
|
||||
|
||||
void tst_qmessagehandler::installMessageHandler()
|
||||
{
|
||||
QMessageHandler oldHandler = qInstallMessageHandler(customMessageHandler);
|
||||
|
||||
qDebug("installMessageHandler"); int line = __LINE__;
|
||||
|
||||
QCOMPARE(s_type, QtDebugMsg);
|
||||
QCOMPARE(s_message, QString::fromLocal8Bit("installMessageHandler"));
|
||||
QCOMPARE(s_file, __FILE__);
|
||||
QCOMPARE(s_function, Q_FUNC_INFO);
|
||||
QCOMPARE(s_line, line);
|
||||
|
||||
QMessageHandler myHandler = qInstallMessageHandler(oldHandler);
|
||||
QCOMPARE((void*)myHandler, (void*)customMessageHandler);
|
||||
}
|
||||
|
||||
void tst_qmessagehandler::installMsgHandler()
|
||||
{
|
||||
QtMsgHandler oldHandler = qInstallMsgHandler(customMsgHandler);
|
||||
|
||||
qDebug("installMsgHandler");
|
||||
|
||||
QCOMPARE(s_type, QtDebugMsg);
|
||||
QCOMPARE(s_message, QString::fromLocal8Bit("installMsgHandler"));
|
||||
QCOMPARE(s_file, (const char*)0);
|
||||
QCOMPARE(s_function, (const char*)0);
|
||||
QCOMPARE(s_line, 0);
|
||||
|
||||
QtMsgHandler myHandler = qInstallMsgHandler(oldHandler);
|
||||
QCOMPARE((void*)myHandler, (void*)customMsgHandler);
|
||||
}
|
||||
|
||||
void tst_qmessagehandler::installBothHandler()
|
||||
{
|
||||
qInstallMessageHandler(customMessageHandler);
|
||||
qInstallMsgHandler(customMsgHandler);
|
||||
|
||||
qDebug("installBothHandler"); int line = __LINE__;
|
||||
|
||||
QCOMPARE(s_type, QtDebugMsg);
|
||||
QCOMPARE(s_message, QString::fromLocal8Bit("installBothHandler"));
|
||||
QCOMPARE(s_file, __FILE__);
|
||||
QCOMPARE(s_function, Q_FUNC_INFO);
|
||||
QCOMPARE(s_line, line);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qmessagehandler)
|
||||
#include "tst_qmessagehandler.moc"
|
@ -74,11 +74,17 @@ void tst_QDebug::assignment() const
|
||||
|
||||
static QtMsgType s_msgType;
|
||||
static QByteArray s_msg;
|
||||
static QByteArray s_file;
|
||||
static int s_line;
|
||||
static QByteArray s_function;
|
||||
|
||||
static void myMessageHandler(QtMsgType type, const char *msg)
|
||||
static void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *msg)
|
||||
{
|
||||
s_msg = msg;
|
||||
s_msgType = type;
|
||||
s_file = context.file;
|
||||
s_line = context.line;
|
||||
s_function = context.function;
|
||||
}
|
||||
|
||||
// Helper class to ensure that the testlib message handler gets
|
||||
@ -87,17 +93,17 @@ static void myMessageHandler(QtMsgType type, const char *msg)
|
||||
class MessageHandlerSetter
|
||||
{
|
||||
public:
|
||||
MessageHandlerSetter(QtMsgHandler newMsgHandler)
|
||||
: oldMsgHandler(qInstallMsgHandler(newMsgHandler))
|
||||
MessageHandlerSetter(QMessageHandler newMessageHandler)
|
||||
: oldMessageHandler(qInstallMessageHandler(newMessageHandler))
|
||||
{ }
|
||||
|
||||
~MessageHandlerSetter()
|
||||
{
|
||||
qInstallMsgHandler(oldMsgHandler);
|
||||
qInstallMessageHandler(oldMessageHandler);
|
||||
}
|
||||
|
||||
private:
|
||||
QtMsgHandler oldMsgHandler;
|
||||
QMessageHandler oldMessageHandler;
|
||||
};
|
||||
|
||||
/*! \internal
|
||||
@ -107,8 +113,12 @@ void tst_QDebug::warningWithoutDebug() const
|
||||
{
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{ qWarning() << "A qWarning() message"; }
|
||||
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtWarningMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg.data()), QString::fromLatin1("A qWarning() message "));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
@ -118,16 +128,24 @@ void tst_QDebug::criticalWithoutDebug() const
|
||||
{
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{ qCritical() << "A qCritical() message"; }
|
||||
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtCriticalMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("A qCritical() message "));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
void tst_QDebug::debugWithBool() const
|
||||
{
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{ qDebug() << false << true; }
|
||||
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtDebugMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("false true "));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
void tst_QDebug::veryLongWarningMessage() const
|
||||
@ -140,8 +158,12 @@ void tst_QDebug::veryLongWarningMessage() const
|
||||
test.append(part);
|
||||
qWarning("Test output:\n%s\nend", qPrintable(test));
|
||||
}
|
||||
QString file = __FILE__; int line = __LINE__ - 2; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtWarningMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("Test output:\n")+test+QString::fromLatin1("\nend"));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
void tst_QDebug::qDebugQStringRef() const
|
||||
@ -153,8 +175,12 @@ void tst_QDebug::qDebugQStringRef() const
|
||||
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{ qDebug() << inRef; }
|
||||
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtDebugMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("\"input\" "));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
/* Use a null QStringRef. */
|
||||
@ -163,19 +189,23 @@ void tst_QDebug::qDebugQStringRef() const
|
||||
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{ qDebug() << inRef; }
|
||||
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
|
||||
QCOMPARE(s_msgType, QtDebugMsg);
|
||||
QCOMPARE(QString::fromLatin1(s_msg), QString::fromLatin1("\"\" "));
|
||||
QCOMPARE(QString::fromLatin1(s_file), file);
|
||||
QCOMPARE(s_line, line);
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDebug::defaultMessagehandler() const
|
||||
{
|
||||
MessageHandlerSetter mhs(0);
|
||||
QtMsgHandler defaultMessageHandler1 = qInstallMsgHandler(0);
|
||||
QtMsgHandler defaultMessageHandler2 = qInstallMsgHandler(myMessageHandler);
|
||||
QMessageHandler defaultMessageHandler1 = qInstallMessageHandler(0);
|
||||
QMessageHandler defaultMessageHandler2 = qInstallMessageHandler(myMessageHandler);
|
||||
bool same = (*defaultMessageHandler1 == *defaultMessageHandler2);
|
||||
QVERIFY(same);
|
||||
QtMsgHandler messageHandler = qInstallMsgHandler(0);
|
||||
QMessageHandler messageHandler = qInstallMessageHandler(0);
|
||||
same = (*messageHandler == *myMessageHandler);
|
||||
QVERIFY(same);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user