diff options
-rw-r--r-- | src/corelib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/corelib/global/qenvironmentvariables.cpp | 341 | ||||
-rw-r--r-- | src/corelib/global/qenvironmentvariables.h | 30 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 328 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 13 | ||||
-rw-r--r-- | src/corelib/tools/qcontainerfwd.h | 1 | ||||
-rw-r--r-- | src/tools/bootstrap/CMakeLists.txt | 1 |
7 files changed, 375 insertions, 340 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 2fcc5b5b98..7759b07d8f 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -49,6 +49,7 @@ qt_internal_add_module(Core global/qcompilerdetection.h global/qcontainerinfo.h global/qendian.cpp global/qendian.h global/qendian_p.h + global/qenvironmentvariables.cpp global/qenvironmentvariables.h global/qflags.h global/qfloat16.cpp global/qfloat16.h global/qforeach.h diff --git a/src/corelib/global/qenvironmentvariables.cpp b/src/corelib/global/qenvironmentvariables.cpp new file mode 100644 index 0000000000..7b50de6ec1 --- /dev/null +++ b/src/corelib/global/qenvironmentvariables.cpp @@ -0,0 +1,341 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qenvironmentvariables.h" + +#include <qplatformdefs.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qmutex.h> +#include <QtCore/qstring.h> +#include <QtCore/qvarlengtharray.h> + +#include <QtCore/private/qlocking_p.h> + +QT_BEGIN_NAMESPACE + +// In the C runtime on all platforms access to the environment is not thread-safe. We +// add thread-safety for the Qt wrappers. +Q_CONSTINIT static QBasicMutex environmentMutex; + +/*! + \relates <QEnvironmentVariables> + \threadsafe + + Returns the value of the environment variable with name \a varName as a + QByteArray. If no variable by that name is found in the environment, this + function returns a default-constructed QByteArray. + + The Qt environment manipulation functions are thread-safe, but this + requires that the C library equivalent functions like getenv and putenv are + not directly called. + + To convert the data to a QString use QString::fromLocal8Bit(). + + \note on desktop Windows, qgetenv() may produce data loss if the + original string contains Unicode characters not representable in the + ANSI encoding. Use qEnvironmentVariable() instead. + On Unix systems, this function is lossless. + + \sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(), + qEnvironmentVariableIsEmpty() +*/ +QByteArray qgetenv(const char *varName) +{ + const auto locker = qt_scoped_lock(environmentMutex); +#ifdef Q_CC_MSVC + size_t requiredSize = 0; + QByteArray buffer; + getenv_s(&requiredSize, 0, 0, varName); + if (requiredSize == 0) + return buffer; + buffer.resize(int(requiredSize)); + getenv_s(&requiredSize, buffer.data(), requiredSize, varName); + // requiredSize includes the terminating null, which we don't want. + Q_ASSERT(buffer.endsWith('\0')); + buffer.chop(1); + return buffer; +#else + return QByteArray(::getenv(varName)); +#endif +} + +/*! + \fn QString qEnvironmentVariable(const char *varName, const QString &defaultValue) + \fn QString qEnvironmentVariable(const char *varName) + + \relates <QEnvironmentVariables> + \since 5.10 + + These functions return the value of the environment variable, \a varName, as a + QString. If no variable \a varName is found in the environment and \a defaultValue + is provided, \a defaultValue is returned. Otherwise QString() is returned. + + The Qt environment manipulation functions are thread-safe, but this + requires that the C library equivalent functions like getenv and putenv are + not directly called. + + The following table describes how to choose between qgetenv() and + qEnvironmentVariable(): + \table + \header \li Condition \li Recommendation + \row + \li Variable contains file paths or user text + \li qEnvironmentVariable() + \row + \li Windows-specific code + \li qEnvironmentVariable() + \row + \li Unix-specific code, destination variable is not QString and/or is + used to interface with non-Qt APIs + \li qgetenv() + \row + \li Destination variable is a QString + \li qEnvironmentVariable() + \row + \li Destination variable is a QByteArray or std::string + \li qgetenv() + \endtable + + \note on Unix systems, this function may produce data loss if the original + string contains arbitrary binary data that cannot be decoded by the locale + codec. Use qgetenv() instead for that case. On Windows, this function is + lossless. + + \note the variable name \a varName must contain only US-ASCII characters. + + \sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty() +*/ +QString qEnvironmentVariable(const char *varName, const QString &defaultValue) +{ +#if defined(Q_OS_WIN) + const auto locker = qt_scoped_lock(environmentMutex); + QVarLengthArray<wchar_t, 32> wname(int(strlen(varName)) + 1); + for (int i = 0; i < wname.size(); ++i) // wname.size() is correct: will copy terminating null + wname[i] = uchar(varName[i]); + size_t requiredSize = 0; + QString buffer; + _wgetenv_s(&requiredSize, 0, 0, wname.data()); + if (requiredSize == 0) + return defaultValue; + buffer.resize(int(requiredSize)); + _wgetenv_s(&requiredSize, reinterpret_cast<wchar_t *>(buffer.data()), requiredSize, + wname.data()); + // requiredSize includes the terminating null, which we don't want. + Q_ASSERT(buffer.endsWith(QChar(u'\0'))); + buffer.chop(1); + return buffer; +#else + QByteArray value = qgetenv(varName); + if (value.isNull()) + return defaultValue; +// duplicated in qfile.h (QFile::decodeName) +#if defined(Q_OS_DARWIN) + return QString::fromUtf8(value).normalized(QString::NormalizationForm_C); +#else // other Unix + return QString::fromLocal8Bit(value); +#endif +#endif +} + +QString qEnvironmentVariable(const char *varName) +{ + return qEnvironmentVariable(varName, QString()); +} + +/*! + \relates <QEnvironmentVariables> + \since 5.1 + + Returns whether the environment variable \a varName is empty. + + Equivalent to + \snippet code/src_corelib_global_qglobal.cpp is-empty + except that it's potentially much faster, and can't throw exceptions. + + \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() +*/ +bool qEnvironmentVariableIsEmpty(const char *varName) noexcept +{ + const auto locker = qt_scoped_lock(environmentMutex); +#ifdef Q_CC_MSVC + // we provide a buffer that can only hold the empty string, so + // when the env.var isn't empty, we'll get an ERANGE error (buffer + // too small): + size_t dummy; + char buffer = '\0'; + return getenv_s(&dummy, &buffer, 1, varName) != ERANGE; +#else + const char * const value = ::getenv(varName); + return !value || !*value; +#endif +} + +/*! + \relates <QEnvironmentVariables> + \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 + \snippet code/src_corelib_global_qglobal.cpp to-int + except that it's much faster, and can't throw exceptions. + + \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 set \a ok to \c + false. + + \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() +*/ +int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept +{ + static const int NumBinaryDigitsPerOctalDigit = 3; + static const int MaxDigitsForOctalInt = + (std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit; + + const auto locker = qt_scoped_lock(environmentMutex); + size_t size; +#ifdef Q_CC_MSVC + // we provide a buffer that can hold any int value: + 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; + } + size = strlen(buffer); +#else + const char * const buffer = ::getenv(varName); + if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt + 2) { + if (ok) + *ok = false; + return 0; + } +#endif + return QByteArrayView(buffer, size).toInt(ok, 0); +} + +/*! + \relates <QEnvironmentVariables> + \since 5.1 + + Returns whether the environment variable \a varName is set. + + Equivalent to + \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() +*/ +bool qEnvironmentVariableIsSet(const char *varName) noexcept +{ + const auto locker = qt_scoped_lock(environmentMutex); +#ifdef Q_CC_MSVC + size_t requiredSize = 0; + (void)getenv_s(&requiredSize, 0, 0, varName); + return requiredSize != 0; +#else + return ::getenv(varName) != nullptr; +#endif +} + +/*! + \relates <QEnvironmentVariables> + + This function sets the \a value of the environment variable named + \a varName. It will create the variable if it does not exist. It + returns 0 if the variable could not be set. + + Calling qputenv with an empty value removes the environment variable on + Windows, and makes it set (but empty) on Unix. Prefer using qunsetenv() + for fully portable behavior. + + \note qputenv() was introduced because putenv() from the standard + C library was deprecated in VC2005 (and later versions). qputenv() + uses the replacement function in VC, and calls the standard C + library's implementation on all other platforms. + + \sa qgetenv(), qEnvironmentVariable() +*/ +bool qputenv(const char *varName, const QByteArray &value) +{ + const auto locker = qt_scoped_lock(environmentMutex); +#if defined(Q_CC_MSVC) + return _putenv_s(varName, value.constData()) == 0; +#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU) + // POSIX.1-2001 has setenv + return setenv(varName, value.constData(), true) == 0; +#else + QByteArray buffer(varName); + buffer += '='; + buffer += value; + char *envVar = qstrdup(buffer.constData()); + int result = putenv(envVar); + if (result != 0) // error. we have to delete the string. + delete[] envVar; + return result == 0; +#endif +} + +/*! + \relates <QEnvironmentVariables> + + This function deletes the variable \a varName from the environment. + + Returns \c true on success. + + \since 5.1 + + \sa qputenv(), qgetenv(), qEnvironmentVariable() +*/ +bool qunsetenv(const char *varName) +{ + const auto locker = qt_scoped_lock(environmentMutex); +#if defined(Q_CC_MSVC) + return _putenv_s(varName, "") == 0; +#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4) || defined(Q_OS_HAIKU) + // POSIX.1-2001, BSD and Haiku have unsetenv + return unsetenv(varName) == 0; +#elif defined(Q_CC_MINGW) + // On mingw, putenv("var=") removes "var" from the environment + QByteArray buffer(varName); + buffer += '='; + return putenv(buffer.constData()) == 0; +#else + // Fallback to putenv("var=") which will insert an empty var into the + // environment and leak it + QByteArray buffer(varName); + buffer += '='; + char *envVar = qstrdup(buffer.constData()); + return putenv(envVar) == 0; +#endif +} + +/* + Wraps tzset(), which accesses the environment, so should only be called while + we hold the lock on the environment mutex. +*/ +void qTzSet() +{ + const auto locker = qt_scoped_lock(environmentMutex); +#if defined(Q_OS_WIN) + _tzset(); +#else + tzset(); +#endif // Q_OS_WIN +} + +/* + Wrap mktime(), which is specified to behave as if it called tzset(), hence + shares its implicit environment-dependence. +*/ +time_t qMkTime(struct tm *when) +{ + const auto locker = qt_scoped_lock(environmentMutex); + return mktime(when); +} + +QT_END_NAMESPACE diff --git a/src/corelib/global/qenvironmentvariables.h b/src/corelib/global/qenvironmentvariables.h new file mode 100644 index 0000000000..cde51c9ba1 --- /dev/null +++ b/src/corelib/global/qenvironmentvariables.h @@ -0,0 +1,30 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QENVIRONMENTVARIABLES_H +#define QENVIRONMENTVARIABLES_H + +#include <QtCore/qglobal.h> + +#if 0 +#pragma qt_class(QEnvironmentVariables) +#pragma qt_sync_stop_processing +#endif + +QT_BEGIN_NAMESPACE + +class QByteArray; +Q_CORE_EXPORT QByteArray qgetenv(const char *varName); +// need it as two functions because QString is only forward-declared here +Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName); +Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName, const QString &defaultValue); +Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray &value); +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; + +QT_END_NAMESPACE + +#endif /* QENVIRONMENTVARIABLES_H */ diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 796749c146..9811a6003a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -18,9 +18,6 @@ #include "qnativeinterface.h" #include "qnativeinterface_p.h" -#include <qmutex.h> -#include <QtCore/private/qlocking_p.h> - #include <stdlib.h> #include <limits.h> #include <stdarg.h> @@ -3255,34 +3252,6 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n) return p; } -// In the C runtime on all platforms access to the environment is not thread-safe. We -// add thread-safety for the Qt wrappers. -Q_CONSTINIT static QBasicMutex environmentMutex; - -/* - Wraps tzset(), which accesses the environment, so should only be called while - we hold the lock on the environment mutex. -*/ -void qTzSet() -{ - const auto locker = qt_scoped_lock(environmentMutex); -#if defined(Q_OS_WIN) - _tzset(); -#else - tzset(); -#endif // Q_OS_WIN -} - -/* - Wrap mktime(), which is specified to behave as if it called tzset(), hence - shares its implicit environment-dependence. -*/ -time_t qMkTime(struct tm *when) -{ - const auto locker = qt_scoped_lock(environmentMutex); - return mktime(when); -} - void qAbort() { #ifdef Q_OS_WIN @@ -3317,303 +3286,6 @@ void qAbort() // strftime() -- not used (except in tests) /*! - \relates <QtGlobal> - \threadsafe - - Returns the value of the environment variable with name \a varName as a - QByteArray. If no variable by that name is found in the environment, this - function returns a default-constructed QByteArray. - - The Qt environment manipulation functions are thread-safe, but this - requires that the C library equivalent functions like getenv and putenv are - not directly called. - - To convert the data to a QString use QString::fromLocal8Bit(). - - \note on desktop Windows, qgetenv() may produce data loss if the - original string contains Unicode characters not representable in the - ANSI encoding. Use qEnvironmentVariable() instead. - On Unix systems, this function is lossless. - - \sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(), - qEnvironmentVariableIsEmpty() -*/ -QByteArray qgetenv(const char *varName) -{ - const auto locker = qt_scoped_lock(environmentMutex); -#ifdef Q_CC_MSVC - size_t requiredSize = 0; - QByteArray buffer; - getenv_s(&requiredSize, 0, 0, varName); - if (requiredSize == 0) - return buffer; - buffer.resize(int(requiredSize)); - getenv_s(&requiredSize, buffer.data(), requiredSize, varName); - // requiredSize includes the terminating null, which we don't want. - Q_ASSERT(buffer.endsWith('\0')); - buffer.chop(1); - return buffer; -#else - return QByteArray(::getenv(varName)); -#endif -} - -/*! - \fn QString qEnvironmentVariable(const char *varName, const QString &defaultValue) - \fn QString qEnvironmentVariable(const char *varName) - - \relates <QtGlobal> - \since 5.10 - - These functions return the value of the environment variable, \a varName, as a - QString. If no variable \a varName is found in the environment and \a defaultValue - is provided, \a defaultValue is returned. Otherwise QString() is returned. - - The Qt environment manipulation functions are thread-safe, but this - requires that the C library equivalent functions like getenv and putenv are - not directly called. - - The following table describes how to choose between qgetenv() and - qEnvironmentVariable(): - \table - \header \li Condition \li Recommendation - \row - \li Variable contains file paths or user text - \li qEnvironmentVariable() - \row - \li Windows-specific code - \li qEnvironmentVariable() - \row - \li Unix-specific code, destination variable is not QString and/or is - used to interface with non-Qt APIs - \li qgetenv() - \row - \li Destination variable is a QString - \li qEnvironmentVariable() - \row - \li Destination variable is a QByteArray or std::string - \li qgetenv() - \endtable - - \note on Unix systems, this function may produce data loss if the original - string contains arbitrary binary data that cannot be decoded by the locale - codec. Use qgetenv() instead for that case. On Windows, this function is - lossless. - - \note the variable name \a varName must contain only US-ASCII characters. - - \sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty() -*/ -QString qEnvironmentVariable(const char *varName, const QString &defaultValue) -{ -#if defined(Q_OS_WIN) - const auto locker = qt_scoped_lock(environmentMutex); - QVarLengthArray<wchar_t, 32> wname(int(strlen(varName)) + 1); - for (int i = 0; i < wname.size(); ++i) // wname.size() is correct: will copy terminating null - wname[i] = uchar(varName[i]); - size_t requiredSize = 0; - QString buffer; - _wgetenv_s(&requiredSize, 0, 0, wname.data()); - if (requiredSize == 0) - return defaultValue; - buffer.resize(int(requiredSize)); - _wgetenv_s(&requiredSize, reinterpret_cast<wchar_t *>(buffer.data()), requiredSize, - wname.data()); - // requiredSize includes the terminating null, which we don't want. - Q_ASSERT(buffer.endsWith(QChar(u'\0'))); - buffer.chop(1); - return buffer; -#else - QByteArray value = qgetenv(varName); - if (value.isNull()) - return defaultValue; -// duplicated in qfile.h (QFile::decodeName) -#if defined(Q_OS_DARWIN) - return QString::fromUtf8(value).normalized(QString::NormalizationForm_C); -#else // other Unix - return QString::fromLocal8Bit(value); -#endif -#endif -} - -QString qEnvironmentVariable(const char *varName) -{ - return qEnvironmentVariable(varName, QString()); -} - -/*! - \relates <QtGlobal> - \since 5.1 - - Returns whether the environment variable \a varName is empty. - - Equivalent to - \snippet code/src_corelib_global_qglobal.cpp is-empty - except that it's potentially much faster, and can't throw exceptions. - - \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() -*/ -bool qEnvironmentVariableIsEmpty(const char *varName) noexcept -{ - const auto locker = qt_scoped_lock(environmentMutex); -#ifdef Q_CC_MSVC - // we provide a buffer that can only hold the empty string, so - // when the env.var isn't empty, we'll get an ERANGE error (buffer - // too small): - size_t dummy; - char buffer = '\0'; - return getenv_s(&dummy, &buffer, 1, varName) != ERANGE; -#else - const char * const value = ::getenv(varName); - return !value || !*value; -#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 - \snippet code/src_corelib_global_qglobal.cpp to-int - except that it's much faster, and can't throw exceptions. - - \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 set \a ok to \c - false. - - \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() -*/ -int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept -{ - static const int NumBinaryDigitsPerOctalDigit = 3; - static const int MaxDigitsForOctalInt = - (std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit; - - const auto locker = qt_scoped_lock(environmentMutex); - size_t size; -#ifdef Q_CC_MSVC - // we provide a buffer that can hold any int value: - 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; - } - size = strlen(buffer); -#else - const char * const buffer = ::getenv(varName); - if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt + 2) { - if (ok) - *ok = false; - return 0; - } -#endif - return QByteArrayView(buffer, size).toInt(ok, 0); -} - -/*! - \relates <QtGlobal> - \since 5.1 - - Returns whether the environment variable \a varName is set. - - Equivalent to - \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() -*/ -bool qEnvironmentVariableIsSet(const char *varName) noexcept -{ - const auto locker = qt_scoped_lock(environmentMutex); -#ifdef Q_CC_MSVC - size_t requiredSize = 0; - (void)getenv_s(&requiredSize, 0, 0, varName); - return requiredSize != 0; -#else - return ::getenv(varName) != nullptr; -#endif -} - -/*! - \relates <QtGlobal> - - This function sets the \a value of the environment variable named - \a varName. It will create the variable if it does not exist. It - returns 0 if the variable could not be set. - - Calling qputenv with an empty value removes the environment variable on - Windows, and makes it set (but empty) on Unix. Prefer using qunsetenv() - for fully portable behavior. - - \note qputenv() was introduced because putenv() from the standard - C library was deprecated in VC2005 (and later versions). qputenv() - uses the replacement function in VC, and calls the standard C - library's implementation on all other platforms. - - \sa qgetenv(), qEnvironmentVariable() -*/ -bool qputenv(const char *varName, const QByteArray &value) -{ - const auto locker = qt_scoped_lock(environmentMutex); -#if defined(Q_CC_MSVC) - return _putenv_s(varName, value.constData()) == 0; -#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU) - // POSIX.1-2001 has setenv - return setenv(varName, value.constData(), true) == 0; -#else - QByteArray buffer(varName); - buffer += '='; - buffer += value; - char *envVar = qstrdup(buffer.constData()); - int result = putenv(envVar); - if (result != 0) // error. we have to delete the string. - delete[] envVar; - return result == 0; -#endif -} - -/*! - \relates <QtGlobal> - - This function deletes the variable \a varName from the environment. - - Returns \c true on success. - - \since 5.1 - - \sa qputenv(), qgetenv(), qEnvironmentVariable() -*/ -bool qunsetenv(const char *varName) -{ - const auto locker = qt_scoped_lock(environmentMutex); -#if defined(Q_CC_MSVC) - return _putenv_s(varName, "") == 0; -#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4) || defined(Q_OS_HAIKU) - // POSIX.1-2001, BSD and Haiku have unsetenv - return unsetenv(varName) == 0; -#elif defined(Q_CC_MINGW) - // On mingw, putenv("var=") removes "var" from the environment - QByteArray buffer(varName); - buffer += '='; - return putenv(buffer.constData()) == 0; -#else - // Fallback to putenv("var=") which will insert an empty var into the - // environment and leak it - QByteArray buffer(varName); - buffer += '='; - char *envVar = qstrdup(buffer.constData()); - return putenv(envVar) == 0; -#endif -} - -/*! \macro forever \relates <QForeach> diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index c24bb6e198..a161170c99 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1213,18 +1213,6 @@ template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype #define Q_D(Class) Class##Private * const d = d_func() #define Q_Q(Class) Class * const q = q_func() -class QByteArray; -Q_CORE_EXPORT QByteArray qgetenv(const char *varName); -// need it as two functions because QString is only forward-declared here -Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName); -Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName, const QString &defaultValue); -Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value); -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; - #define QT_MODULE(x) // This macro can be used to calculate member offsets for types with a non standard layout. @@ -1249,6 +1237,7 @@ QT_END_NAMESPACE #include <QtCore/qflags.h> #include <QtCore/qatomic.h> +#include <QtCore/qenvironmentvariables.h> #include <QtCore/qforeach.h> #include <QtCore/qglobalstatic.h> #include <QtCore/qnumeric.h> diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index 1f0d36428a..73e8896472 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.h @@ -30,6 +30,7 @@ template <typename T> class QList; #ifndef Q_CLANG_QDOC template<typename T> using QVector = QList<T>; using QStringList = QList<QString>; +class QByteArray; using QByteArrayList = QList<QByteArray>; #else template<typename T> class QVector; diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt index 35e62b6764..fa6037dc20 100644 --- a/src/tools/bootstrap/CMakeLists.txt +++ b/src/tools/bootstrap/CMakeLists.txt @@ -12,6 +12,7 @@ qt_add_library(Bootstrap STATIC) qt_internal_extend_target(Bootstrap SOURCES ../../corelib/global/qendian.cpp + ../../corelib/global/qenvironmentvariables.cpp ../../corelib/global/qfloat16.cpp ../../corelib/global/qglobal.cpp ../../corelib/global/qlogging.cpp |