Long live qEnvironmentVariableIntegerValue() returning std::optional
That way, we won't need to pass a bool pointer to distinguish an environment variable containing zero from one that failed to parse. [ChangeLog][QtCore][QtEnvironment] Added qEnvironmentVariableIntegerValue(), which returns std::optional<int>. Fixes: QTBUG-133654 Change-Id: If0d6c3a6f7a080588fa5fffd87b9365f0f8e1089 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
b888bc09ce
commit
fd3c05cd07
@ -653,6 +653,14 @@ bool readConfiguration(const QFile &file)
|
|||||||
qgetenv(varName).toInt(ok, 0)
|
qgetenv(varName).toInt(ok, 0)
|
||||||
//! [to-int]
|
//! [to-int]
|
||||||
|
|
||||||
|
//! [int-value_or]
|
||||||
|
qEnvironmentVariableIntegerValue(varName).value_or(0)
|
||||||
|
//! [int-value_or]
|
||||||
|
|
||||||
|
//! [int-eq0]
|
||||||
|
qEnvironmentVariableIntegerValue(varName) == 0
|
||||||
|
//! [int-eq0]
|
||||||
|
|
||||||
//! [is-null]
|
//! [is-null]
|
||||||
!qgetenv(varName).isNull()
|
!qgetenv(varName).isNull()
|
||||||
//! [is-null]
|
//! [is-null]
|
||||||
|
@ -38,7 +38,7 @@ Q_CONSTINIT static QBasicMutex environmentMutex;
|
|||||||
On Unix systems, this function is lossless.
|
On Unix systems, this function is lossless.
|
||||||
|
|
||||||
\sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(),
|
\sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(),
|
||||||
qEnvironmentVariableIsEmpty()
|
qEnvironmentVariableIsEmpty(), qEnvironmentVariableIntegerValue()
|
||||||
*/
|
*/
|
||||||
QByteArray qgetenv(const char *varName)
|
QByteArray qgetenv(const char *varName)
|
||||||
{
|
{
|
||||||
@ -104,7 +104,8 @@ QByteArray qgetenv(const char *varName)
|
|||||||
|
|
||||||
\note the variable name \a varName must contain only US-ASCII characters.
|
\note the variable name \a varName must contain only US-ASCII characters.
|
||||||
|
|
||||||
\sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty()
|
\sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty(),
|
||||||
|
qEnvironmentVariableIntegerValue()
|
||||||
*/
|
*/
|
||||||
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
|
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
|
||||||
{
|
{
|
||||||
@ -192,6 +193,45 @@ bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
|
|||||||
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
|
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
|
||||||
*/
|
*/
|
||||||
int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
|
int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
|
||||||
|
{
|
||||||
|
std::optional<int> value = qEnvironmentVariableIntegerValue(varName);
|
||||||
|
if (ok)
|
||||||
|
*ok = bool(value);
|
||||||
|
return value.value_or(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\relates <QtEnvironmentVariables>
|
||||||
|
\since 6.10
|
||||||
|
|
||||||
|
Returns the numerical value of the environment variable \a varName. If the
|
||||||
|
variable is not set or could not be parsed as an integer, it returns
|
||||||
|
\c{std::nullopt}.
|
||||||
|
|
||||||
|
Similar to
|
||||||
|
\snippet code/src_corelib_global_qglobal.cpp to-int
|
||||||
|
except that it's much faster, and can't throw exceptions.
|
||||||
|
|
||||||
|
If a value of zero is semantically the same as an empty or unset variable,
|
||||||
|
applications can use
|
||||||
|
\snippet code/src_corelib_global_qglobal.cpp int-value_or
|
||||||
|
Do note in this case that failures to parse a value will also produce a
|
||||||
|
zero.
|
||||||
|
|
||||||
|
But if a value of zero can be used to disable some functionality,
|
||||||
|
applications can compare the returned \c{std::optional} to zero, which will
|
||||||
|
only be true if the variable was set and contained a number that parsed as
|
||||||
|
zero, as in:
|
||||||
|
\snippet code/src_corelib_global_qglobal.cpp int-eq0
|
||||||
|
|
||||||
|
\note there's a limit on the length of the value, which is sufficient for
|
||||||
|
all valid values of int, not counting leading zeroes or spaces. Values that
|
||||||
|
are too long will either be truncated or this function will return
|
||||||
|
\c{std::nullopt}.
|
||||||
|
|
||||||
|
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
|
||||||
|
*/
|
||||||
|
std::optional<int> qEnvironmentVariableIntegerValue(const char *varName) noexcept
|
||||||
{
|
{
|
||||||
static const int NumBinaryDigitsPerOctalDigit = 3;
|
static const int NumBinaryDigitsPerOctalDigit = 3;
|
||||||
static const int MaxDigitsForOctalInt =
|
static const int MaxDigitsForOctalInt =
|
||||||
@ -205,21 +245,19 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
|
|||||||
// we provide a buffer that can hold any int value:
|
// we provide a buffer that can hold any int value:
|
||||||
char buffer[MaxDigitsForOctalInt + 1]; // +1 for the terminating null
|
char buffer[MaxDigitsForOctalInt + 1]; // +1 for the terminating null
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0) {
|
if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0)
|
||||||
if (ok)
|
return std::nullopt;
|
||||||
*ok = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
size = strlen(buffer);
|
size = strlen(buffer);
|
||||||
#else
|
#else
|
||||||
const char * const buffer = ::getenv(varName);
|
const char * const buffer = ::getenv(varName);
|
||||||
if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt) {
|
if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt)
|
||||||
if (ok)
|
return std::nullopt;
|
||||||
*ok = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return QByteArrayView(buffer, size).toInt(ok, 0);
|
bool ok;
|
||||||
|
int value = QByteArrayView(buffer, size).toInt(&ok, 0);
|
||||||
|
if (!ok)
|
||||||
|
return std::nullopt;
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -232,7 +270,8 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
|
|||||||
\snippet code/src_corelib_global_qglobal.cpp is-null
|
\snippet code/src_corelib_global_qglobal.cpp is-null
|
||||||
except that it's potentially much faster, and can't throw exceptions.
|
except that it's potentially much faster, and can't throw exceptions.
|
||||||
|
|
||||||
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsEmpty()
|
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsEmpty(),
|
||||||
|
qEnvironmentVariableIntegerValue()
|
||||||
*/
|
*/
|
||||||
bool qEnvironmentVariableIsSet(const char *varName) noexcept
|
bool qEnvironmentVariableIsSet(const char *varName) noexcept
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <QtCore/qtcoreexports.h>
|
#include <QtCore/qtcoreexports.h>
|
||||||
#include <QtCore/qtdeprecationmarkers.h>
|
#include <QtCore/qtdeprecationmarkers.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#pragma qt_class(QtEnvironmentVariables)
|
#pragma qt_class(QtEnvironmentVariables)
|
||||||
#pragma qt_sync_stop_processing
|
#pragma qt_sync_stop_processing
|
||||||
@ -32,6 +34,7 @@ Q_CORE_EXPORT bool qunsetenv(const char *varName);
|
|||||||
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept;
|
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept;
|
||||||
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept;
|
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept;
|
||||||
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept;
|
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept;
|
||||||
|
Q_CORE_EXPORT std::optional<int> qEnvironmentVariableIntegerValue(const char *varName) noexcept;
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -40,14 +40,6 @@ static std::optional<QByteArray> qEnvironmentVariableOptionalByteArray(const cha
|
|||||||
return value.isNull() ? std::nullopt : std::optional(std::move(value));
|
return value.isNull() ? std::nullopt : std::optional(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<int> qEnvironmentVariableOptionalInt(const char *name)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
const int value = qEnvironmentVariableIntValue(name, &ok);
|
|
||||||
auto opt = ok ? std::optional(value) : std::nullopt;
|
|
||||||
return opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::optional<qreal> qEnvironmentVariableOptionalReal(const char *name)
|
static std::optional<qreal> qEnvironmentVariableOptionalReal(const char *name)
|
||||||
{
|
{
|
||||||
const QByteArray val = qgetenv(name);
|
const QByteArray val = qgetenv(name);
|
||||||
@ -402,7 +394,7 @@ void QHighDpiScaling::initHighDpiScaling()
|
|||||||
|
|
||||||
// Read environment variables
|
// Read environment variables
|
||||||
static const char* envDebugStr = "environment variable set:";
|
static const char* envDebugStr = "environment variable set:";
|
||||||
std::optional<int> envEnableHighDpiScaling = qEnvironmentVariableOptionalInt(enableHighDpiScalingEnvVar);
|
std::optional<int> envEnableHighDpiScaling = qEnvironmentVariableIntegerValue(enableHighDpiScalingEnvVar);
|
||||||
if (envEnableHighDpiScaling.has_value())
|
if (envEnableHighDpiScaling.has_value())
|
||||||
qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value();
|
qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value();
|
||||||
|
|
||||||
@ -414,7 +406,7 @@ void QHighDpiScaling::initHighDpiScaling()
|
|||||||
if (envScreenFactors.has_value())
|
if (envScreenFactors.has_value())
|
||||||
qCDebug(lcHighDpi) << envDebugStr << screenFactorsEnvVar << envScreenFactors.value();
|
qCDebug(lcHighDpi) << envDebugStr << screenFactorsEnvVar << envScreenFactors.value();
|
||||||
|
|
||||||
std::optional<int> envUsePhysicalDpi = qEnvironmentVariableOptionalInt(usePhysicalDpiEnvVar);
|
std::optional<int> envUsePhysicalDpi = qEnvironmentVariableIntegerValue(usePhysicalDpiEnvVar);
|
||||||
if (envUsePhysicalDpi.has_value())
|
if (envUsePhysicalDpi.has_value())
|
||||||
qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value();
|
qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value();
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ void tst_QGetPutEnv::getSetCheck()
|
|||||||
|
|
||||||
QVERIFY(!qEnvironmentVariableIsSet(varName));
|
QVERIFY(!qEnvironmentVariableIsSet(varName));
|
||||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||||
ok = true;
|
ok = true;
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||||
@ -44,6 +45,7 @@ void tst_QGetPutEnv::getSetCheck()
|
|||||||
|
|
||||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||||
ok = true;
|
ok = true;
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||||
@ -68,6 +70,7 @@ void tst_QGetPutEnv::getSetCheck()
|
|||||||
|
|
||||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||||
QVERIFY(!qEnvironmentVariableIsEmpty(varName));
|
QVERIFY(!qEnvironmentVariableIsEmpty(varName));
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||||
ok = true;
|
ok = true;
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||||
@ -85,6 +88,7 @@ void tst_QGetPutEnv::getSetCheck()
|
|||||||
QVERIFY(qunsetenv(varName));
|
QVERIFY(qunsetenv(varName));
|
||||||
QVERIFY(!qEnvironmentVariableIsSet(varName)); // note: might fail on some systems!
|
QVERIFY(!qEnvironmentVariableIsSet(varName)); // note: might fail on some systems!
|
||||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||||
ok = true;
|
ok = true;
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||||
@ -210,6 +214,10 @@ void tst_QGetPutEnv::intValue()
|
|||||||
QCOMPARE(qEnvironmentVariableIntValue(varName), expected);
|
QCOMPARE(qEnvironmentVariableIntValue(varName), expected);
|
||||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected);
|
QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected);
|
||||||
QCOMPARE(actualOk, ok);
|
QCOMPARE(actualOk, ok);
|
||||||
|
if (actualOk)
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), expected);
|
||||||
|
else
|
||||||
|
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QGetPutEnv)
|
QTEST_MAIN(tst_QGetPutEnv)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user