Add qEnvironmentVariableIntValue()
A lot of code in Qt uses VAR=1 for enabling or disabling some feature or other, ignoring qEnvironmentVariableIsSet(), which was added for that purpose. Other code actually reads numerical values from environment variables. For both use-cases, provide a non-throwing, non-memory-allocating way to get the numerical (int) value of an environment variable, complementing qEnvironmentVariableIs{Set,Empty}(). [ChangeLog][QtCore] Added qEnvironmentVariableIntValue(). Change-Id: I81c85287ea10d355c1bbf8d7807ec9a0e477bce0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6be26d9051
commit
bb56586e32
@ -47,6 +47,7 @@
|
||||
#include "qthreadstorage.h"
|
||||
#include "qdir.h"
|
||||
#include "qdatetime.h"
|
||||
#include <private/qlocale_tools_p.h>
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
#include <private/qthread_p.h>
|
||||
@ -3011,6 +3012,53 @@ bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\relates <QtGlobal>
|
||||
\since 5.5
|
||||
|
||||
Returns the numerical value of the environment variable \a varName.
|
||||
If \a ok is not null, sets \c{*ok} to \c true or \c false depending
|
||||
on the success of the conversion.
|
||||
|
||||
Equivalent to
|
||||
\code
|
||||
qgetenv(varName).toInt()
|
||||
\endcode
|
||||
except that it's much faster, and can't throw exceptions.
|
||||
|
||||
\sa qgetenv(), qEnvironmentVariableIsSet()
|
||||
*/
|
||||
int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
// we provide a buffer that can hold any int value:
|
||||
static const int NumBinaryDigitsPerOctalDigit = 3;
|
||||
static const int MaxDigitsForOctalInt =
|
||||
(std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit;
|
||||
char buffer[MaxDigitsForOctalInt + 2]; // +1 for NUL +1 for optional '-'
|
||||
size_t dummy;
|
||||
if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
const char * const buffer = ::getenv(varName);
|
||||
if (!buffer || !*buffer) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
const qlonglong value = qstrtoll(buffer, Q_NULLPTR, 0, ok);
|
||||
if (int(value) != value) { // this is the check in QByteArray::toInt(), keep it in sync
|
||||
if (ok)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
return int(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\relates <QtGlobal>
|
||||
\since 5.1
|
||||
|
@ -1035,6 +1035,7 @@ Q_CORE_EXPORT bool qunsetenv(const char *varName);
|
||||
|
||||
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT;
|
||||
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT;
|
||||
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=0) Q_DECL_NOEXCEPT;
|
||||
|
||||
inline int qIntCast(double f) { return int(f); }
|
||||
inline int qIntCast(float f) { return int(f); }
|
||||
|
@ -49,14 +49,22 @@ class tst_QGetPutEnv : public QObject
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void getSetCheck();
|
||||
void intValue_data();
|
||||
void intValue();
|
||||
};
|
||||
|
||||
void tst_QGetPutEnv::getSetCheck()
|
||||
{
|
||||
const char varName[] = "should_not_exist";
|
||||
|
||||
bool ok;
|
||||
|
||||
QVERIFY(!qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
QVERIFY(!ok);
|
||||
QByteArray result = qgetenv(varName);
|
||||
QCOMPARE(result, QByteArray());
|
||||
|
||||
@ -65,12 +73,20 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
|
||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
QVERIFY(!ok);
|
||||
#endif
|
||||
|
||||
QVERIFY(qputenv(varName, QByteArray("supervalue")));
|
||||
|
||||
QVERIFY(qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(!qEnvironmentVariableIsEmpty(varName));
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
QVERIFY(!ok);
|
||||
result = qgetenv(varName);
|
||||
QVERIFY(result == "supervalue");
|
||||
|
||||
@ -80,9 +96,61 @@ void tst_QGetPutEnv::getSetCheck()
|
||||
QVERIFY(qunsetenv(varName));
|
||||
QVERIFY(!qEnvironmentVariableIsSet(varName));
|
||||
QVERIFY(qEnvironmentVariableIsEmpty(varName));
|
||||
ok = true;
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), 0);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &ok), 0);
|
||||
QVERIFY(!ok);
|
||||
result = qgetenv(varName);
|
||||
QCOMPARE(result, QByteArray());
|
||||
}
|
||||
|
||||
void tst_QGetPutEnv::intValue_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("value");
|
||||
QTest::addColumn<int>("expected");
|
||||
QTest::addColumn<bool>("ok");
|
||||
|
||||
// most non-success cases already tested in getSetCheck()
|
||||
|
||||
#define ROW(x, i, b) \
|
||||
QTest::newRow(#x) << QByteArray(#x) << (i) << (b)
|
||||
ROW(auto, 0, false);
|
||||
ROW(0, 0, true);
|
||||
ROW(1, 1, true);
|
||||
ROW(010, 8, true);
|
||||
ROW(0x10, 16, true);
|
||||
ROW(-1, -1, true);
|
||||
ROW(-010, -8, true);
|
||||
// ROW(0xffffffff, -1, true); // could be expected, but not how QByteArray::toInt() works
|
||||
ROW(0xffffffff, 0, false);
|
||||
const int bases[] = {10, 8, 16};
|
||||
for (size_t i = 0; i < sizeof bases / sizeof *bases; ++i) {
|
||||
QTest::newRow(qPrintable(QString().sprintf("INT_MAX, base %d", bases[i])))
|
||||
<< QByteArray::number(INT_MAX) << INT_MAX << true;
|
||||
QTest::newRow(qPrintable(QString().sprintf("INT_MAX+1, base %d", bases[i])))
|
||||
<< QByteArray::number(qlonglong(INT_MAX) + 1) << 0 << false;
|
||||
QTest::newRow(qPrintable(QString().sprintf("INT_MIN, base %d", bases[i])))
|
||||
<< QByteArray::number(INT_MIN) << INT_MIN << true;
|
||||
QTest::newRow(qPrintable(QString().sprintf("INT_MIN-1, base %d", bases[i])))
|
||||
<< QByteArray::number(qlonglong(INT_MIN) - 1) << 0 << false;
|
||||
};
|
||||
}
|
||||
|
||||
void tst_QGetPutEnv::intValue()
|
||||
{
|
||||
const char varName[] = "should_not_exist";
|
||||
|
||||
QFETCH(QByteArray, value);
|
||||
QFETCH(int, expected);
|
||||
QFETCH(bool, ok);
|
||||
|
||||
bool actualOk = !ok;
|
||||
|
||||
QVERIFY(qputenv(varName, value));
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName), expected);
|
||||
QCOMPARE(qEnvironmentVariableIntValue(varName, &actualOk), expected);
|
||||
QCOMPARE(actualOk, ok);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGetPutEnv)
|
||||
#include "tst_qgetputenv.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user