Reshuffle code between qglobal, qlogging

Make the content of the .h, .cpp files match.

Change-Id: Ib2506aeff74281ec4bcbf04d21da451038391203
Reviewed-by: David Faure <faure@kde.org>
This commit is contained in:
Kai Koehne 2012-02-10 15:54:50 +01:00 committed by Qt by Nokia
parent d4441b0148
commit 23688d8942
4 changed files with 473 additions and 477 deletions

View File

@ -45,15 +45,12 @@
#include "qlist.h"
#include "qthreadstorage.h"
#include "qdir.h"
#include "qstringlist.h"
#include "qdatetime.h"
#include "qdebug.h"
#ifndef QT_NO_QOBJECT
#include <private/qthread_p.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
@ -677,34 +674,6 @@ QT_BEGIN_NAMESPACE
\sa quintptr, qint32, qint64
*/
/*!
\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
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>
@ -1726,9 +1695,6 @@ 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 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
namespace {
@ -1808,439 +1774,6 @@ 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
(which may be 0).
The message handler is a function that prints out debug messages,
warnings, critical and fatal error messages. The Qt library (debug
mode) contains hundreds of warning messages that are printed
when internal errors (usually invalid function arguments)
occur. Qt built in release mode also contains such warnings unless
QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during
compilation. If you implement your own message handler, you get total
control of these messages.
The default message handler prints the message to the standard
output under X11 or to the debugger under Windows. If it is a
fatal message, the application aborts immediately.
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 qInstallMessageHandler(0).
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23
\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 qWinMessageHandler(QtMsgType t, const QMessageLogContext &context,
const char *str);
#endif
// defined in qlogging.cpp
extern Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context,
const char *str);
/*!
\internal
*/
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const char *buf)
{
QByteArray logMessage = qMessageFormatString(type, context, buf);
#if defined(Q_OS_WINCE)
QString fstr = QString::fromLocal8Bit(logMessage);
OutputDebugString(reinterpret_cast<const wchar_t *> (fstr.utf16()));
#else
fprintf(stderr, "%s", logMessage.constData());
fflush(stderr);
#endif
}
/*!
\internal
*/
static void qDefaultMsgHandler(QtMsgType type, const char *buf)
{
QMessageLogContext emptyContext;
qDefaultMessageHandler(type, emptyContext, 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 (!msgHandler)
msgHandler = qDefaultMsgHandler;
QtMsgHandler old = msgHandler;
msgHandler = h;
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
if (!msgHandler && usingWinMain)
msgHandler = qWinMsgHandler;
#endif
return old;
}
/*!
\internal
*/
void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const char *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
&& (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) {
#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
// get the current report mode
int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
_CrtSetReportMode(_CRT_ERROR, reportMode);
#if !defined(Q_OS_WINCE)
int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf);
#else
int ret = _CrtDbgReportW(_CRT_ERROR, _CRT_WIDE(__FILE__),
__LINE__, _CRT_WIDE(QT_VERSION_STR), reinterpret_cast<const wchar_t *> (QString::fromLatin1(buf).utf16()));
#endif
if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW)
return; // ignore
else if (ret == 1)
_CrtDbgBreak();
#endif
#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW))
abort(); // trap; generates core dump
#else
exit(1); // goodbye cruel world
#endif
}
}
#if !defined(QT_NO_EXCEPTIONS)
/*!
\internal
Uses a local buffer to output the message. Not locale safe + cuts off
everything after character 255, but will work in out of memory situations.
*/
static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap)
{
char emergency_buf[256] = { '\0' };
emergency_buf[255] = '\0';
if (msg)
qvsnprintf(emergency_buf, 255, msg, ap);
QMessageLogContext context;
qt_message_output(msgType, context, emergency_buf);
}
#endif
/*!
\internal
*/
static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap)
{
#if !defined(QT_NO_EXCEPTIONS)
if (std::uncaught_exception()) {
qEmergencyOut(msgType, msg, ap);
return;
}
#endif
QByteArray buf;
if (msg) {
QT_TRY {
buf = QString().vsprintf(msg, ap).toLocal8Bit();
} QT_CATCH(const std::bad_alloc &) {
#if !defined(QT_NO_EXCEPTIONS)
qEmergencyOut(msgType, msg, ap);
// don't rethrow - we use qWarning and friends in destructors.
return;
#endif
}
}
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the console, if it is a
console application; otherwise, it is sent to the debugger. This
function does nothing if \c QT_NO_DEBUG_OUTPUT was defined
during compilation.
If you pass the function a format string and a list of arguments,
it works in similar way to the C printf() function. The format
should be a Latin-1 string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24
If you include \c <QtDebug>, a more convenient syntax is also
available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25
With this syntax, the function returns a QDebug object that is
configured to use the QtDebugMsg message type. It automatically
puts a single space between each item, and outputs a newline at
the end. It supports many C++ and Qt types.
To suppress the output at run-time, install your own message handler
with qInstallMessageHandler().
\sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::debug(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger. This
function does nothing if \c QT_NO_WARNING_OUTPUT was defined
during compilation; it exits if the environment variable \c
QT_FATAL_WARNINGS is defined.
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26
If you include <QtDebug>, a more convenient syntax is
also available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27
This syntax inserts a space between each item, and
appends a newline at the end.
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::warning(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28
If you include <QtDebug>, a more convenient syntax is
also available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29
A space is inserted between the items, and a newline is
appended at the end.
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::critical(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
// to be careful here (like we do in plain qWarning())
QString buf;
va_list ap;
va_start(ap, msg);
if (msg)
buf.vsprintf(msg, ap);
va_end(ap);
QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(),
qt_error_string(-1).toLocal8Bit().constData());
}
void qErrnoWarning(int code, const char *msg, ...)
{
// qt_error_string() will allocate anyway, so we don't have
// to be careful here (like we do in plain qWarning())
QString buf;
va_list ap;
va_start(ap, msg);
if (msg)
buf.vsprintf(msg, ap);
va_end(ap);
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
If you are using the \bold{default message handler} this function will
abort on Unix systems to create a core dump. On Windows, for debug builds,
this function will report a _CRT_ERROR enabling you to connect a debugger
to the application.
This function takes a format string and a list of arguments,
similar to the C printf() function.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::fatal(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
qt_message(QtFatalMsg, context, msg, ap);
va_end(ap);
}
// getenv is declared as deprecated in VS2005. This function
// makes use of the new secure getenv function.
/*!

View File

@ -992,10 +992,6 @@ inline void qUnused(T &x) { (void)x; }
class QString;
Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...);
Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...);
Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line);
#if !defined(Q_ASSERT)

View File

@ -44,6 +44,7 @@
#include "qbytearray.h"
#include "qstring.h"
#include "qvarlengtharray.h"
#include "qdebug.h"
#include <stdio.h>
@ -79,6 +80,254 @@ QT_BEGIN_NAMESPACE
\sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal()
*/
#if !defined(QT_NO_EXCEPTIONS)
/*!
\internal
Uses a local buffer to output the message. Not locale safe + cuts off
everything after character 255, but will work in out of memory situations.
*/
static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap)
{
char emergency_buf[256] = { '\0' };
emergency_buf[255] = '\0';
if (msg)
qvsnprintf(emergency_buf, 255, msg, ap);
QMessageLogContext context;
qt_message_output(msgType, context, emergency_buf);
}
#endif
/*!
\internal
*/
static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg,
va_list ap)
{
#if !defined(QT_NO_EXCEPTIONS)
if (std::uncaught_exception()) {
qEmergencyOut(msgType, msg, ap);
return;
}
#endif
QByteArray buf;
if (msg) {
QT_TRY {
buf = QString().vsprintf(msg, ap).toLocal8Bit();
} QT_CATCH(const std::bad_alloc &) {
#if !defined(QT_NO_EXCEPTIONS)
qEmergencyOut(msgType, msg, ap);
// don't rethrow - we use qWarning and friends in destructors.
return;
#endif
}
}
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the console, if it is a
console application; otherwise, it is sent to the debugger. This
function does nothing if \c QT_NO_DEBUG_OUTPUT was defined
during compilation.
If you pass the function a format string and a list of arguments,
it works in similar way to the C printf() function. The format
should be a Latin-1 string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 24
If you include \c <QtDebug>, a more convenient syntax is also
available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25
With this syntax, the function returns a QDebug object that is
configured to use the QtDebugMsg message type. It automatically
puts a single space between each item, and outputs a newline at
the end. It supports many C++ and Qt types.
To suppress the output at run-time, install your own message handler
with qInstallMessageHandler().
\sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::debug(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger. This
function does nothing if \c QT_NO_WARNING_OUTPUT was defined
during compilation; it exits if the environment variable \c
QT_FATAL_WARNINGS is defined.
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26
If you include <QtDebug>, a more convenient syntax is
also available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 27
This syntax inserts a space between each item, and
appends a newline at the end.
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::warning(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
string.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28
If you include <QtDebug>, a more convenient syntax is
also available:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 29
A space is inserted between the items, and a newline is
appended at the end.
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::critical(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
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
#undef qFatal
/*!
\fn qFatal(const char *message, ...)
\relates <QtGlobal>
Calls the message handler with the fatal message \a msg. If no
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
If you are using the \bold{default message handler} this function will
abort on Unix systems to create a core dump. On Windows, for debug builds,
this function will report a _CRT_ERROR enabling you to connect a debugger
to the application.
This function takes a format string and a list of arguments,
similar to the C printf() function.
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 30
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
\sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(),
{Debugging Techniques}
*/
void QMessageLogger::fatal(const char *msg, ...)
{
va_list ap;
va_start(ap, msg); // use variable arg list
qt_message(QtFatalMsg, context, msg, ap);
va_end(ap);
}
/*!
\internal
*/
@ -345,7 +594,7 @@ Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
\internal
*/
Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogContext &context,
const char *str)
const char *str)
{
QByteArray message;
@ -389,4 +638,218 @@ Q_CORE_EXPORT QByteArray qMessageFormatString(QtMsgType type, const QMessageLogC
return message;
}
static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context)
static QMessageHandler messageHandler = 0; // pointer to debug handler (with context)
/*!
\internal
*/
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context,
const char *buf)
{
QByteArray logMessage = qMessageFormatString(type, context, buf);
#if defined(Q_OS_WINCE)
QString fstr = QString::fromLocal8Bit(logMessage);
OutputDebugString(reinterpret_cast<const wchar_t *> (fstr.utf16()));
#else
fprintf(stderr, "%s", logMessage.constData());
fflush(stderr);
#endif
}
/*!
\internal
*/
static void qDefaultMsgHandler(QtMsgType type, const char *buf)
{
QMessageLogContext emptyContext;
qDefaultMessageHandler(type, emptyContext, buf);
}
/*!
\internal
*/
void qt_message_output(QtMsgType msgType, const QMessageLogContext &context, const char *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
&& (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) {
#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
// get the current report mode
int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
_CrtSetReportMode(_CRT_ERROR, reportMode);
#if !defined(Q_OS_WINCE)
int ret = _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, QT_VERSION_STR, buf);
#else
int ret = _CrtDbgReportW(_CRT_ERROR, _CRT_WIDE(__FILE__),
__LINE__, _CRT_WIDE(QT_VERSION_STR),
reinterpret_cast<const wchar_t *> (
QString::fromLatin1(buf).utf16()));
#endif
if (ret == 0 && reportMode & _CRTDBG_MODE_WNDW)
return; // ignore
else if (ret == 1)
_CrtDbgBreak();
#endif
#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW))
abort(); // trap; generates core dump
#else
exit(1); // goodbye cruel world
#endif
}
}
void qErrnoWarning(const char *msg, ...)
{
// qt_error_string() will allocate anyway, so we don't have
// to be careful here (like we do in plain qWarning())
QString buf;
va_list ap;
va_start(ap, msg);
if (msg)
buf.vsprintf(msg, ap);
va_end(ap);
QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(),
qt_error_string(-1).toLocal8Bit().constData());
}
void qErrnoWarning(int code, const char *msg, ...)
{
// qt_error_string() will allocate anyway, so we don't have
// to be careful here (like we do in plain qWarning())
QString buf;
va_list ap;
va_start(ap, msg);
if (msg)
buf.vsprintf(msg, ap);
va_end(ap);
QMessageLogger().critical("%s (%s)", buf.toLocal8Bit().constData(),
qt_error_string(code).toLocal8Bit().constData());
}
#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 qWinMessageHandler(QtMsgType t, const QMessageLogContext &context,
const char *str);
#endif
/*!
\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
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()
*/
/*!
\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
(which may be 0).
The message handler is a function that prints out debug messages,
warnings, critical and fatal error messages. The Qt library (debug
mode) contains hundreds of warning messages that are printed
when internal errors (usually invalid function arguments)
occur. Qt built in release mode also contains such warnings unless
QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during
compilation. If you implement your own message handler, you get total
control of these messages.
The default message handler prints the message to the standard
output under X11 or to the debugger under Windows. If it is a
fatal message, the application aborts immediately.
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 qInstallMessageHandler(0).
Example:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23
\sa qDebug(), qWarning(), qCritical(), qFatal(), QtMsgType,
{Debugging Techniques}
*/
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;
}
/*!
\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
*/
QtMsgHandler qInstallMsgHandler(QtMsgHandler h)
{
//if handler is 0, set it to the
//default message handler
if (!msgHandler)
msgHandler = qDefaultMsgHandler;
QtMsgHandler old = msgHandler;
msgHandler = h;
#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
if (!msgHandler && usingWinMain)
msgHandler = qWinMsgHandler;
#endif
return old;
}
QT_END_NAMESPACE

View File

@ -67,7 +67,8 @@ class QMessageLogContext
Q_DISABLE_COPY(QMessageLogContext)
public:
QMessageLogContext() : version(1), line(0), file(0), function(0) {}
Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName)
Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber,
const char *functionName)
: version(1), line(lineNumber), file(fileName), function(functionName) {}
int version;
@ -126,8 +127,6 @@ 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
*/
@ -139,15 +138,20 @@ Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &contex
#define QT_NO_QDEBUG_MACRO while (false) QMessageLogger().noDebug
#define QT_NO_QWARNING_MACRO while (false) QMessageLogger().noDebug
#ifdef QT_NO_DEBUG_OUTPUT
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qDebug
# define qDebug QT_NO_QDEBUG_MACRO
#endif
#ifdef QT_NO_WARNING_OUTPUT
#if defined(QT_NO_WARNING_OUTPUT)
# undef qWarning
# define qWarning QT_NO_QWARNING_MACRO
#endif
Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, const char *buf);
Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...);
Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...);
// deprecated. Use qInstallMessageHandler instead!
typedef void (*QtMsgHandler)(QtMsgType, const char *);
Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);