qEnvironmentVariableIntegerValue: switch to 64-bit returns

[ChangeLog][QtCore][Editorial] Update previous statement on
qEnvironmentVariableIntegerValue to indicate it returns 64-bit.

Change-Id: I93fc5ca3455b2435bf95fffded69e086e038d14d
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
Thiago Macieira 2025-02-11 19:08:43 -08:00
parent 408959c8c8
commit 3fc00c4d5e
4 changed files with 45 additions and 27 deletions

View File

@ -174,6 +174,8 @@ bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
#endif #endif
} }
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // older GCC don't like libstdc++'s std::optional
/*! /*!
\relates <QtEnvironmentVariables> \relates <QtEnvironmentVariables>
\since 5.5 \since 5.5
@ -195,11 +197,14 @@ bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
*/ */
int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
{ {
std::optional<int> value = qEnvironmentVariableIntegerValue(varName); std::optional<qint64> value = qEnvironmentVariableIntegerValue(varName);
if (value && *value != int(*value))
value = std::nullopt;
if (ok) if (ok)
*ok = bool(value); *ok = bool(value);
return value.value_or(0); return value.value_or(0);
} }
QT_WARNING_POP
/*! /*!
\relates <QtEnvironmentVariables> \relates <QtEnvironmentVariables>
@ -232,11 +237,11 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
\sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
*/ */
std::optional<int> qEnvironmentVariableIntegerValue(const char *varName) noexcept std::optional<qint64> qEnvironmentVariableIntegerValue(const char *varName) noexcept
{ {
static const int NumBinaryDigitsPerOctalDigit = 3; static const int NumBinaryDigitsPerOctalDigit = 3;
static const int MaxDigitsForOctalInt = static const int MaxDigitsForOctalInt =
(std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit (std::numeric_limits<quint64>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit
+ 1 // sign + 1 // sign
+ 1; // "0" base prefix + 1; // "0" base prefix
@ -255,7 +260,7 @@ std::optional<int> qEnvironmentVariableIntegerValue(const char *varName) noexcep
return std::nullopt; return std::nullopt;
#endif #endif
auto r = QLocaleData::bytearrayToLongLong(QByteArrayView(buffer, size), 0); auto r = QLocaleData::bytearrayToLongLong(QByteArrayView(buffer, size), 0);
if (!r.ok() || int(r.result) != r.result) if (!r.ok())
return std::nullopt; return std::nullopt;
return r.result; return r.result;
} }

View File

@ -7,6 +7,7 @@
#include <QtCore/qtconfigmacros.h> #include <QtCore/qtconfigmacros.h>
#include <QtCore/qtcoreexports.h> #include <QtCore/qtcoreexports.h>
#include <QtCore/qtdeprecationmarkers.h> #include <QtCore/qtdeprecationmarkers.h>
#include <QtCore/qtypes.h>
#include <optional> #include <optional>
@ -34,7 +35,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; Q_CORE_EXPORT std::optional<qint64> qEnvironmentVariableIntegerValue(const char *varName) noexcept;
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -394,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 = qEnvironmentVariableIntegerValue(enableHighDpiScalingEnvVar); std::optional envEnableHighDpiScaling = qEnvironmentVariableIntegerValue(enableHighDpiScalingEnvVar);
if (envEnableHighDpiScaling.has_value()) if (envEnableHighDpiScaling.has_value())
qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value(); qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value();
@ -406,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 = qEnvironmentVariableIntegerValue(usePhysicalDpiEnvVar); std::optional envUsePhysicalDpi = qEnvironmentVariableIntegerValue(usePhysicalDpiEnvVar);
if (envUsePhysicalDpi.has_value()) if (envUsePhysicalDpi.has_value())
qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value(); qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value();

View File

@ -6,6 +6,9 @@
#include <QTest> #include <QTest>
#include <qglobal.h> #include <qglobal.h>
#include <q20utility.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <qt_windows.h> #include <qt_windows.h>
#endif #endif
@ -136,17 +139,17 @@ void tst_QGetPutEnv::encoding()
void tst_QGetPutEnv::intValue_data() void tst_QGetPutEnv::intValue_data()
{ {
QTest::addColumn<QByteArray>("value"); QTest::addColumn<QByteArray>("value");
QTest::addColumn<int>("expected"); QTest::addColumn<qint64>("expected");
QTest::addColumn<bool>("ok"); QTest::addColumn<bool>("ok");
// some repetition from what is tested in getSetCheck() // some repetition from what is tested in getSetCheck()
QTest::newRow("empty") << QByteArray() << 0 << false; QTest::newRow("empty") << QByteArray() << qint64(0) << false;
QTest::newRow("spaces-heading") << QByteArray(" \n\r\t1") << 1 << true; QTest::newRow("spaces-heading") << QByteArray(" \n\r\t1") << qint64(1) << true;
QTest::newRow("spaces-trailing") << QByteArray("1 \n\r\t") << 1 << true; QTest::newRow("spaces-trailing") << QByteArray("1 \n\r\t") << qint64(1) << true;
QTest::newRow("junk-heading") << QByteArray("x1") << 0 << false; QTest::newRow("junk-heading") << QByteArray("x1") << qint64(0) << false;
QTest::newRow("junk-trailing") << QByteArray("1x") << 0 << false; QTest::newRow("junk-trailing") << QByteArray("1x") << qint64(0) << false;
auto addRow = [](const char *text, int expected, bool ok) { auto addRow = [](const char *text, qint64 expected, bool ok) {
QTest::newRow(text) << QByteArray(text) << expected << ok; QTest::newRow(text) << QByteArray(text) << expected << ok;
}; };
addRow("auto", 0, false); addRow("auto", 0, false);
@ -168,10 +171,8 @@ void tst_QGetPutEnv::intValue_data()
addRow("-1", -1, true); addRow("-1", -1, true);
addRow("-010", -8, true); addRow("-010", -8, true);
addRow("-000000000000000000000000000000000000000000000000001", 0, false); addRow("-000000000000000000000000000000000000000000000000001", 0, false);
// addRow("0xffffffff", -1, true); // could be expected, but not how QByteArray::toInt() works
addRow("0xffffffff", 0, false);
auto addNumWithBase = [](qlonglong num, int base) { auto addNumWithBase = [](auto num, int base) {
QByteArray text; QByteArray text;
{ {
QTextStream s(&text); QTextStream s(&text);
@ -179,42 +180,53 @@ void tst_QGetPutEnv::intValue_data()
s << Qt::showbase << num; s << Qt::showbase << num;
} }
QTestData &row = QTest::addRow("%s", text.constData()) << text; QTestData &row = QTest::addRow("%s", text.constData()) << text;
if (num == int(num)) bool ok = true;
row << int(num) << true; if constexpr (std::is_same_v<decltype(num), quint64>)
ok = num <= quint64(LLONG_MAX);
if (ok)
row << qint64(num) << true;
else else
row << 0 << false; row << qint64(0) << false;
}; };
for (int base : {10, 8, 16}) { for (int base : {10, 8, 16}) {
addNumWithBase(INT_MAX, base); addNumWithBase(INT_MAX, base);
addNumWithBase(qlonglong(INT_MAX) + 1, base); addNumWithBase(qlonglong(INT_MAX) + 1, base);
addNumWithBase(UINT_MAX, base);
addNumWithBase(INT_MIN, base); addNumWithBase(INT_MIN, base);
addNumWithBase(qlonglong(INT_MIN) - 1 , base); addNumWithBase(qlonglong(INT_MIN) - 1 , base);
addNumWithBase(LLONG_MAX, base);
addNumWithBase(LLONG_MIN, base);
addNumWithBase(ULLONG_MAX, base);
}; };
} }
void tst_QGetPutEnv::intValue() void tst_QGetPutEnv::intValue()
{ {
const int maxlen = (sizeof(int) * CHAR_BIT + 2) / 3; const int maxlen = (sizeof(qint64) * CHAR_BIT + 2) / 3;
const char varName[] = "should_not_exist"; const char varName[] = "should_not_exist";
QFETCH(QByteArray, value); QFETCH(QByteArray, value);
QFETCH(int, expected); QFETCH(qint64, expected);
QFETCH(bool, ok); QFETCH(bool, ok);
bool actualOk = !ok; bool actualOk = !ok;
bool is32Bit = q20::in_range<int>(expected);
// Self-test: confirm that it was like the docs said it should be // Self-test: confirm that it was like the docs said it should be
if (value.size() < maxlen) { if (value.size() < maxlen) {
QCOMPARE(value.toInt(&actualOk, 0), expected); // 32-bit
QCOMPARE(value.toInt(&actualOk, 0), is32Bit ? expected : 0);
QCOMPARE(actualOk, ok && is32Bit);
QCOMPARE(value.toLongLong(&actualOk, 0), expected);
QCOMPARE(actualOk, ok); QCOMPARE(actualOk, ok);
} }
actualOk = !ok; actualOk = !ok;
QVERIFY(qputenv(varName, value)); QVERIFY(qputenv(varName, value));
QCOMPARE(qEnvironmentVariableIntValue(varName), expected); QCOMPARE(qEnvironmentVariableIntValue(varName), is32Bit ? expected : 0);
QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected); QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), is32Bit ? expected : 0);
QCOMPARE(actualOk, ok); QCOMPARE(actualOk, ok && is32Bit);
if (actualOk) if (ok)
QCOMPARE(qEnvironmentVariableIntegerValue(varName), expected); QCOMPARE(qEnvironmentVariableIntegerValue(varName), expected);
else else
QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt); QCOMPARE(qEnvironmentVariableIntegerValue(varName), std::nullopt);