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) <ogoffart@woboq.com>
This commit is contained in:
Thiago Macieira 2016-08-03 16:12:32 -07:00
parent 6445aa4b06
commit ceb859bf03
2 changed files with 29 additions and 6 deletions

View File

@ -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

View File

@ -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;