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)
|
||||
//! [to-int]
|
||||
|
||||
//! [int-value_or]
|
||||
qEnvironmentVariableIntegerValue(varName).value_or(0)
|
||||
//! [int-value_or]
|
||||
|
||||
//! [int-eq0]
|
||||
qEnvironmentVariableIntegerValue(varName) == 0
|
||||
//! [int-eq0]
|
||||
|
||||
//! [is-null]
|
||||
!qgetenv(varName).isNull()
|
||||
//! [is-null]
|
||||
|
@ -38,7 +38,7 @@ Q_CONSTINIT static QBasicMutex environmentMutex;
|
||||
On Unix systems, this function is lossless.
|
||||
|
||||
\sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(),
|
||||
qEnvironmentVariableIsEmpty()
|
||||
qEnvironmentVariableIsEmpty(), qEnvironmentVariableIntegerValue()
|
||||
*/
|
||||
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.
|
||||
|
||||
\sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty()
|
||||
\sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty(),
|
||||
qEnvironmentVariableIntegerValue()
|
||||
*/
|
||||
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
|
||||
{
|
||||
@ -192,6 +193,45 @@ bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
|
||||
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
|
||||
*/
|
||||
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 MaxDigitsForOctalInt =
|
||||
@ -205,21 +245,19 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
|
||||
// we provide a buffer that can hold any int value:
|
||||
char buffer[MaxDigitsForOctalInt + 1]; // +1 for the terminating null
|
||||
size_t dummy;
|
||||
if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0)
|
||||
return std::nullopt;
|
||||
size = strlen(buffer);
|
||||
#else
|
||||
const char * const buffer = ::getenv(varName);
|
||||
if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt)
|
||||
return std::nullopt;
|
||||
#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
|
||||
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
|
||||
{
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <QtCore/qtcoreexports.h>
|
||||
#include <QtCore/qtdeprecationmarkers.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#if 0
|
||||
#pragma qt_class(QtEnvironmentVariables)
|
||||
#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 qEnvironmentVariableIsSet(const char *varName) 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
|
||||
|
||||
|
@ -40,14 +40,6 @@ static std::optional<QByteArray> qEnvironmentVariableOptionalByteArray(const cha
|
||||
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)
|
||||
{
|
||||
const QByteArray val = qgetenv(name);
|
||||
@ -402,7 +394,7 @@ void QHighDpiScaling::initHighDpiScaling()
|
||||
|
||||
// Read environment variables
|
||||
static const char* envDebugStr = "environment variable set:";
|
||||
std::optional<int> envEnableHighDpiScaling = qEnvironmentVariableOptionalInt(enableHighDpiScalingEnvVar);
|
||||
std::optional<int> envEnableHighDpiScaling = qEnvironmentVariableIntegerValue(enableHighDpiScalingEnvVar);
|
||||
if (envEnableHighDpiScaling.has_value())
|
||||
qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value();
|
||||
|
||||
@ -414,7 +406,7 @@ void QHighDpiScaling::initHighDpiScaling()
|
||||
if (envScreenFactors.has_value())
|
||||
qCDebug(lcHighDpi) << envDebugStr << screenFactorsEnvVar << envScreenFactors.value();
|
||||
|
||||
std::optional<int> envUsePhysicalDpi = qEnvironmentVariableOptionalInt(usePhysicalDpiEnvVar);
|
||||
std::optional<int> envUsePhysicalDpi = qEnvironmentVariableIntegerValue(usePhysicalDpiEnvVar);
|
||||
if (envUsePhysicalDpi.has_value())
|
||||
qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value();
|
||||
|
||||
|
@ -28,6 +28,7 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
|
||||
QVERIFY(!qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
@ -44,6 +45,7 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
|
||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
@ -68,6 +70,7 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
|
||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(!qEnvironmentVariableIsEmpty(varName));
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
@ -85,6 +88,7 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
QVERIFY(qunsetenv(varName));
|
||||
QVERIFY(!qEnvironmentVariableIsSet(varName)); // note: might fail on some systems!
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
@ -210,6 +214,10 @@ void tst_QGetPutEnv::intValue()
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), expected);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected);
|
||||
QCOMPARE(actualOk, ok);
|
||||
if (actualOk)
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), expected);
|
||||
else
|
||||
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGetPutEnv)
|
||||
|
Loading…
x
Reference in New Issue
Block a user