From ceb859bf036dfdd1c54eec403006eac62a0d09b8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 3 Aug 2016 16:12:32 -0700 Subject: Implement a counted QT_FATAL_WARNINGS [ChangeLog][QtCore][Logging] If you set QT_FATAL_WARNINGS to a number greater than 1, Qt will stop the application at that nth warning, instead of on the first one. For compatibility reasons with previous versions, if the variable is set to any non-empty and non-numeric value different from 0, Qt will understand as "stop on first warning". Change-Id: I0031aa609e714ae983c3fffd14676f1826f34600 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qglobal.cpp | 7 +++++-- src/corelib/global/qlogging.cpp | 28 ++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 6dba733fb4..871810e5a3 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4419,8 +4419,11 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) stderr. Under Windows, the message is sent to the debugger. On QNX the message is sent to slogger2. 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 not empty. + during compilation; it exits if at the nth warning corresponding to the + counter in environment variable \c QT_FATAL_WARNINGS. That is, if the + environment variable contains the value 1, it will exit on the 1st message; + if it contains the value 10, it will exit on the 10th message. Any + non-numeric value is equivalent to 1. This function takes a format string and a list of arguments, similar to the C printf() function. The format should be a Latin-1 diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 6573e0a53e..927c1bb76b 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -153,19 +153,39 @@ Q_NORETURN static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const QString &message); static void qt_message_print(QtMsgType, const QMessageLogContext &context, const QString &message); +static int checked_var_value(const char *varname) +{ + // qEnvironmentVariableIntValue returns 0 on both parsing failure and on + // empty, but we need to distinguish between the two for backwards + // compatibility reasons. + QByteArray str = qgetenv(varname); + if (str.isEmpty()) + return 0; + + bool ok; + int value = str.toInt(&ok, 0); + return ok ? value : 1; +} + static bool isFatal(QtMsgType msgType) { if (msgType == QtFatalMsg) return true; if (msgType == QtCriticalMsg) { - static bool fatalCriticals = !qEnvironmentVariableIsEmpty("QT_FATAL_CRITICALS"); - return fatalCriticals; + static QAtomicInt fatalCriticals = checked_var_value("QT_FATAL_CRITICALS"); + + // it's fatal if the current value is exactly 1, + // otherwise decrement if it's non-zero + return fatalCriticals.load() && fatalCriticals.fetchAndAddRelaxed(-1) == 1; } if (msgType == QtWarningMsg || msgType == QtCriticalMsg) { - static bool fatalWarnings = !qEnvironmentVariableIsEmpty("QT_FATAL_WARNINGS"); - return fatalWarnings; + static QAtomicInt fatalWarnings = checked_var_value("QT_FATAL_WARNINGS"); + + // it's fatal if the current value is exactly 1, + // otherwise decrement if it's non-zero + return fatalWarnings.load() && fatalWarnings.fetchAndAddRelaxed(-1) == 1; } return false; -- cgit v1.2.3