summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qglobal.cpp')
-rw-r--r--src/corelib/global/qglobal.cpp298
1 files changed, 213 insertions, 85 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 997e804579..ac2f72d573 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1,8 +1,8 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2014 Intel Corporation
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -11,9 +11,9 @@
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -24,8 +24,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -39,6 +39,7 @@
#include "qthreadstorage.h"
#include "qdir.h"
#include "qdatetime.h"
+#include <private/qlocale_tools_p.h>
#include <private/qsystemlibrary_p.h>
@@ -548,9 +549,9 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
\snippet code/src_corelib_global_qglobal.cpp 3
<QtGlobal> also contains functions that generate messages from the
- given string argument: qCritical(), qDebug(), qFatal() and
- qWarning(). These functions call the message handler with the
- given message.
+ given string argument: qDebug(), qInfo(), qWarning(), qCritical(),
+ and qFatal(). These functions call the message handler
+ with the given message.
Example:
@@ -769,6 +770,8 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
\value QtDebugMsg
A message generated by the qDebug() function.
+ \value QtInfoMsg
+ A message generated by the qInfo() function.
\value QtWarningMsg
A message generated by the qWarning() function.
\value QtCriticalMsg
@@ -777,6 +780,7 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
A message generated by the qFatal() function.
\value QtSystemMsg
+ \c QtInfoMsg was added in Qt 5.5.
\sa QtMessageHandler, qInstallMessageHandler()
*/
@@ -986,9 +990,9 @@ bool qSharedBuild() Q_DECL_NOTHROW
\li \l ByteOrder specifies whether the platform is big-endian or
little-endian.
\li \l WindowsVersion specifies the version of the Windows operating
- system on which the application is run (Windows only)
+ system on which the application is run.
\li \l MacintoshVersion specifies the version of the Macintosh
- operating system on which the application is run (Mac only).
+ operating system on which the application is run.
\endlist
Some constants are defined only on certain platforms. You can use
@@ -1011,7 +1015,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
/*!
\variable QSysInfo::WindowsVersion
\brief the version of the Windows operating system on which the
- application is run (Windows only)
+ application is run.
*/
/*!
@@ -1019,19 +1023,22 @@ bool qSharedBuild() Q_DECL_NOTHROW
\since 4.4
Returns the version of the Windows operating system on which the
- application is run (Windows only).
+ application is run, or WV_None if the operating system is not
+ Windows.
*/
/*!
\variable QSysInfo::MacintoshVersion
\brief the version of the Macintosh operating system on which
- the application is run (Mac only).
+ the application is run.
*/
/*!
\fn QSysInfo::MacVersion QSysInfo::macVersion()
- Returns the version of Darwin (OS X or iOS) on which the application is run.
+ Returns the version of Darwin (OS X or iOS) on which the
+ application is run, or MV_None if the operating system
+ is not a version of Darwin.
*/
/*!
@@ -1068,6 +1075,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_WINDOWS7 Windows 7, Windows Server 2008 R2 (operating system version 6.1)
\value WV_WINDOWS8 Windows 8 (operating system version 6.2)
\value WV_WINDOWS8_1 Windows 8.1 (operating system version 6.3), introduced in Qt 5.2
+ \value WV_WINDOWS10 Windows 10 (operating system version 10.0), introduced in Qt 5.5
Alternatively, you may use the following macros which correspond directly to the Windows operating system version number:
@@ -1079,6 +1087,7 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_6_1 Operating system version 6.1, corresponds to Windows 7 and Windows Server 2008 R2
\value WV_6_2 Operating system version 6.2, corresponds to Windows 8
\value WV_6_3 Operating system version 6.3, corresponds to Windows 8.1, introduced in Qt 5.2
+ \value WV_10_0 Operating system version 10.0, corresponds to Windows 10, introduced in Qt 5.5
CE-based versions:
@@ -1094,6 +1103,8 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value WV_NT_based NT-based version of Windows
\value WV_CE_based CE-based version of Windows
+ \value WV_None Operating system other than Windows.
+
\sa MacVersion
*/
@@ -1141,6 +1152,8 @@ bool qSharedBuild() Q_DECL_NOTHROW
\value MV_IOS_7_1 iOS 7.1
\value MV_IOS_8_0 iOS 8.0
+ \value MV_None Not a Darwin operating system
+
\sa WinVersion
*/
@@ -1847,16 +1860,14 @@ Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
QSysInfo::MacVersion QSysInfo::macVersion()
{
+ const QAppleOperatingSystemVersion version = qt_apple_os_version(); // qtcore_mac_objc.mm
#if defined(Q_OS_OSX)
- SInt32 gestalt_version;
- if (Gestalt(gestaltSystemVersionMinor, &gestalt_version) == noErr) {
- // add 2 because OS X 10.0 is 0x02 in the enum
- return QSysInfo::MacVersion(gestalt_version + 2);
- }
+ return QSysInfo::MacVersion(Q_MV_OSX(version.major, version.minor));
#elif defined(Q_OS_IOS)
- return qt_ios_version(); // qtcore_mac_objc.mm
-#endif
+ return QSysInfo::MacVersion(Q_MV_IOS(version.major, version.minor));
+#else
return QSysInfo::MV_Unknown;
+#endif
}
const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion();
@@ -2024,6 +2035,8 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
winver = QSysInfo::WV_WINDOWS8;
} else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3) {
winver = QSysInfo::WV_WINDOWS8_1;
+ } else if (osver.dwMajorVersion == 10 && osver.dwMinorVersion == 0) {
+ winver = QSysInfo::WV_WINDOWS10;
} else {
qWarning("Qt: Untested Windows version %d.%d detected!",
int(osver.dwMajorVersion), int(osver.dwMinorVersion));
@@ -2107,10 +2120,10 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
# define USE_ETC_OS_RELEASE
struct QUnixOSVersion
{
- // from /etc/os-release
- QString productType; // $ID
- QString productVersion; // $VERSION_ID
- QString prettyName; // $PRETTY_NAME
+ // from /etc/os-release older /etc/lsb-release
+ QString productType; // $ID $DISTRIB_ID
+ QString productVersion; // $VERSION_ID $DISTRIB_RELEASE
+ QString prettyName; // $PRETTY_NAME $DISTRIB_DESCRIPTION
};
static QString unquote(const char *begin, const char *end)
@@ -2122,10 +2135,11 @@ static QString unquote(const char *begin, const char *end)
return QString::fromLatin1(begin, end - begin);
}
-static bool readEtcOsRelease(QUnixOSVersion &v)
+static bool readEtcFile(QUnixOSVersion &v, const char *filename,
+ const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey)
{
// we're avoiding QFile here
- int fd = qt_safe_open("/etc/os-release", O_RDONLY);
+ int fd = qt_safe_open(filename, O_RDONLY);
if (fd == -1)
return false;
@@ -2142,41 +2156,28 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
const char *ptr = buffer.constData();
const char *end = buffer.constEnd();
const char *eol;
+ QByteArray line;
for ( ; ptr != end; ptr = eol + 1) {
- static const char idString[] = "ID=";
- static const char prettyNameString[] = "PRETTY_NAME=";
- static const char versionIdString[] = "VERSION_ID=";
-
// find the end of the line after ptr
eol = static_cast<const char *>(memchr(ptr, '\n', end - ptr));
if (!eol)
eol = end - 1;
+ line.setRawData(ptr, eol - ptr);
- // note: we're doing a binary search here, so comparison
- // must always be sorted
- int cmp = strncmp(ptr, idString, strlen(idString));
- if (cmp < 0)
- continue;
- if (cmp == 0) {
- ptr += strlen(idString);
+ if (line.startsWith(idKey)) {
+ ptr += idKey.length();
v.productType = unquote(ptr, eol);
continue;
}
- cmp = strncmp(ptr, prettyNameString, strlen(prettyNameString));
- if (cmp < 0)
- continue;
- if (cmp == 0) {
- ptr += strlen(prettyNameString);
+ if (line.startsWith(prettyNameKey)) {
+ ptr += prettyNameKey.length();
v.prettyName = unquote(ptr, eol);
continue;
}
- cmp = strncmp(ptr, versionIdString, strlen(versionIdString));
- if (cmp < 0)
- continue;
- if (cmp == 0) {
- ptr += strlen(versionIdString);
+ if (line.startsWith(versionKey)) {
+ ptr += versionKey.length();
v.productVersion = unquote(ptr, eol);
continue;
}
@@ -2184,6 +2185,45 @@ static bool readEtcOsRelease(QUnixOSVersion &v)
return true;
}
+
+static bool readEtcOsRelease(QUnixOSVersion &v)
+{
+ return readEtcFile(v, "/etc/os-release", QByteArrayLiteral("ID="),
+ QByteArrayLiteral("VERSION_ID="), QByteArrayLiteral("PRETTY_NAME="));
+}
+
+static bool readEtcLsbRelease(QUnixOSVersion &v)
+{
+ bool ok = readEtcFile(v, "/etc/lsb-release", QByteArrayLiteral("DISTRIB_ID="),
+ QByteArrayLiteral("DISTRIB_RELEASE="), QByteArrayLiteral("DISTRIB_DESCRIPTION="));
+ if (ok && (v.prettyName.isEmpty() || v.prettyName == v.productType)) {
+ // some distributions have redundant information for the pretty name,
+ // so try /etc/<lowercasename>-release
+
+ // we're still avoiding QFile here
+ QByteArray distrorelease = "/etc/" + v.productType.toLatin1().toLower() + "-release";
+ int fd = qt_safe_open(distrorelease, O_RDONLY);
+ if (fd != -1) {
+ QT_STATBUF sbuf;
+ if (QT_FSTAT(fd, &sbuf) != -1 && sbuf.st_size > v.prettyName.length()) {
+ // file apparently contains interesting information
+ QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
+ buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
+ v.prettyName = QString::fromLatin1(buffer.trimmed());
+ }
+ qt_safe_close(fd);
+ }
+ }
+
+ return ok;
+}
+
+static bool findUnixOsVersion(QUnixOSVersion &v)
+{
+ if (readEtcOsRelease(v))
+ return true;
+ return readEtcLsbRelease(v);
+}
# endif // USE_ETC_OS_RELEASE
#endif // Q_OS_UNIX
@@ -2518,7 +2558,7 @@ QString QSysInfo::productType()
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
QUnixOSVersion unixOsVersion;
- readEtcOsRelease(unixOsVersion);
+ findUnixOsVersion(unixOsVersion);
if (!unixOsVersion.productType.isEmpty())
return unixOsVersion.productType;
#endif
@@ -2551,25 +2591,9 @@ QString QSysInfo::productType()
*/
QString QSysInfo::productVersion()
{
-#if defined(Q_OS_IOS)
- int major = (int(MacintoshVersion) >> 4) & 0xf;
- int minor = int(MacintoshVersion) & 0xf;
- if (Q_LIKELY(major < 10 && minor < 10)) {
- char buf[4] = { char(major + '0'), '.', char(minor + '0'), '\0' };
- return QString::fromLatin1(buf, 3);
- }
- return QString::number(major) + QLatin1Char('.') + QString::number(minor);
-#elif defined(Q_OS_OSX)
- int minor = int(MacintoshVersion) - 2; // we're not running on Mac OS 9
- Q_ASSERT(minor < 100);
- char buf[] = "10.0\0";
- if (Q_LIKELY(minor < 10)) {
- buf[3] += minor;
- } else {
- buf[3] += minor / 10;
- buf[4] = '0' + minor % 10;
- }
- return QString::fromLatin1(buf);
+#if defined(Q_OS_MAC)
+ const QAppleOperatingSystemVersion version = qt_apple_os_version();
+ return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor);
#elif defined(Q_OS_WIN)
const char *version = winVer_helper();
if (version)
@@ -2590,7 +2614,7 @@ QString QSysInfo::productVersion()
}
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
QUnixOSVersion unixOsVersion;
- readEtcOsRelease(unixOsVersion);
+ findUnixOsVersion(unixOsVersion);
if (!unixOsVersion.productVersion.isEmpty())
return unixOsVersion.productVersion;
#endif
@@ -2662,10 +2686,12 @@ QString QSysInfo::prettyProductName()
return QLatin1String("Android ") + productVersion();
#elif defined(Q_OS_BLACKBERRY)
return QLatin1String("BlackBerry ") + productVersion();
+#elif defined(Q_OS_HAIKU)
+ return QLatin1String("Haiku ") + productVersion();
#elif defined(Q_OS_UNIX)
# ifdef USE_ETC_OS_RELEASE
QUnixOSVersion unixOsVersion;
- readEtcOsRelease(unixOsVersion);
+ findUnixOsVersion(unixOsVersion);
if (!unixOsVersion.prettyName.isEmpty())
return unixOsVersion.prettyName;
# endif
@@ -3065,6 +3091,56 @@ bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT
/*!
\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
+ bool ok_ = true;
+ 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;
+ } else if (ok) {
+ *ok = ok_;
+ }
+ return int(value);
+}
+
+/*!
+ \relates <QtGlobal>
\since 5.1
Returns whether the environment variable \a varName is set.
@@ -3110,7 +3186,7 @@ bool qputenv(const char *varName, const QByteArray& value)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
return _putenv_s(varName, value.constData()) == 0;
-#elif defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L
+#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
@@ -3140,8 +3216,8 @@ bool qunsetenv(const char *varName)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
return _putenv_s(varName, "") == 0;
-#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4)
- // POSIX.1-2001 and BSD have unsetenv
+#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
@@ -3556,8 +3632,8 @@ int qrand()
qPrintable() is used. This is because the array returned by
QString::toLocal8Bit() will fall out of scope.
- \note qDebug(), qWarning(), qCritical(), qFatal() expect %s
- arguments to be UTF-8 encoded, while qPrintable() converts to
+ \note qDebug(), qInfo(), qWarning(), qCritical(), qFatal() expect
+ %s arguments to be UTF-8 encoded, while qPrintable() converts to
local 8-bit encoding. Therefore qUtf8Printable() should be used
for logging strings instead of qPrintable().
@@ -3580,7 +3656,7 @@ int qrand()
\snippet code/src_corelib_global_qglobal.cpp 37
- \sa qPrintable(), qDebug(), qWarning(), qCritical(), qFatal()
+ \sa qPrintable(), qDebug(), qInfo(), qWarning(), qCritical(), qFatal()
*/
/*!
@@ -3968,6 +4044,21 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
It expands to "constexpr" if your compiler supports that C++11 keyword, or to nothing
otherwise.
+
+ \sa Q_DECL_RELAXED_CONSTEXPR
+*/
+
+/*!
+ \macro Q_DECL_RELAXED_CONSTEXPR
+ \relates <QtGlobal>
+
+ This macro can be used to declare an inline function that can be computed
+ at compile-time according to the relaxed rules from C++14.
+
+ It expands to "constexpr" if your compiler supports C++14 relaxed constant
+ expressions, or to nothing otherwise.
+
+ \sa Q_DECL_CONSTEXPR
*/
/*!
@@ -3976,8 +4067,8 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the debug message \a message. If no
message handler has been installed, the message is printed to
- stderr. Under Windows, the message is sent to the console, if it is a
- console application; otherwise, it is sent to the debugger. On Blackberry the
+ stderr. Under Windows the message is sent to the console, if it is a
+ console application; otherwise, it is sent to the debugger. On Blackberry, the
message is sent to slogger2. This function does nothing if \c QT_NO_DEBUG_OUTPUT
was defined during compilation.
@@ -4002,7 +4093,44 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
To suppress the output at run-time, install your own message handler
with qInstallMessageHandler().
- \sa qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
+ \sa qInfo(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \macro qInfo(const char *message, ...)
+ \relates <QtGlobal>
+ \since 5.5
+
+ Calls the message handler with the informational message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows, the message is sent to the console, if it is a
+ console application; otherwise, it is sent to the debugger. On Blackberry the
+ message is sent to slogger2. This function does nothing if \c QT_NO_INFO_OUTPUT
+ was defined during compilation.
+
+ If you pass the function a format string and a list of arguments,
+ it works in similar way to the C printf() function. The format
+ should be a Latin-1 string.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qInfo_printf
+
+ If you include \c <QtDebug>, a more convenient syntax is also
+ available:
+
+ \snippet code/src_corelib_global_qglobal.cpp qInfo_stream
+
+ With this syntax, the function returns a QDebug object that is
+ configured to use the QtInfoMsg message type. It automatically
+ puts a single space between each item, and outputs a newline at
+ the end. It supports many C++ and Qt types.
+
+ To suppress the output at run-time, install your own message handler
+ with qInstallMessageHandler().
+
+ \sa qDebug(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
@@ -4036,7 +4164,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
- \sa qDebug(), qCritical(), qFatal(), qInstallMessageHandler(),
+ \sa qDebug(), qInfo(), qCritical(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
@@ -4069,7 +4197,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
- \sa qDebug(), qWarning(), qFatal(), qInstallMessageHandler(),
+ \sa qDebug(), qInfo(), qWarning(), qFatal(), qInstallMessageHandler(),
{Debugging Techniques}
*/
@@ -4096,7 +4224,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
To suppress the output at runtime, install your own message handler
with qInstallMessageHandler().
- \sa qDebug(), qCritical(), qWarning(), qInstallMessageHandler(),
+ \sa qDebug(), qInfo(), qWarning(), qCritical(), qInstallMessageHandler(),
{Debugging Techniques}
*/