summaryrefslogtreecommitdiffstats
path: root/qmake/library
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/library')
-rw-r--r--qmake/library/ioutils.cpp7
-rw-r--r--qmake/library/proitems.h8
-rw-r--r--qmake/library/qmakebuiltins.cpp43
-rw-r--r--qmake/library/qmakeevaluator.cpp2
-rw-r--r--qmake/library/qmakevfs.cpp12
-rw-r--r--qmake/library/qmakevfs.h6
-rw-r--r--qmake/library/registry.cpp158
-rw-r--r--qmake/library/registry_p.h73
8 files changed, 291 insertions, 18 deletions
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index 2b2c6d0078..3e49a99cd5 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -77,7 +77,12 @@ bool IoUtils::isRelativePath(const QString &path)
&& (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\'))) {
return false;
}
- // (... unless, of course, they're UNC, which qmake fails on anyway)
+ // ... unless, of course, they're UNC:
+ if (path.length() >= 2
+ && (path.at(0).unicode() == '\\' || path.at(0).unicode() == '/')
+ && path.at(1) == path.at(0)) {
+ return false;
+ }
#else
if (path.startsWith(QLatin1Char('/')))
return false;
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 2b09fc2074..6882f2802f 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -133,7 +133,7 @@ public:
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
- int toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringRef().toLongLong(ok, base); }
+ qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringRef().toLongLong(ok, base); }
int toInt(bool *ok = nullptr, int base = 10) const { return toQStringRef().toInt(ok, base); }
short toShort(bool *ok = nullptr, int base = 10) const { return toQStringRef().toShort(ok, base); }
@@ -429,7 +429,7 @@ class ProFunctionDef {
public:
ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
- ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW
+ ProFunctionDef(ProFunctionDef &&other) noexcept
: m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; }
~ProFunctionDef() { m_pro->deref(); }
ProFunctionDef &operator=(const ProFunctionDef &o)
@@ -442,13 +442,13 @@ public:
}
return *this;
}
- ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW
+ ProFunctionDef &operator=(ProFunctionDef &&other) noexcept
{
ProFunctionDef moved(std::move(other));
swap(moved);
return *this;
}
- void swap(ProFunctionDef &other) Q_DECL_NOTHROW
+ void swap(ProFunctionDef &other) noexcept
{
qSwap(m_pro, other.m_pro);
qSwap(m_offset, other.m_offset);
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index f81bec158b..3c4e509fc6 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -52,6 +52,9 @@
# include <qthreadpool.h>
#endif
#include <qversionnumber.h>
+#ifdef Q_OS_WIN
+# include <registry_p.h>
+#endif
#include <algorithm>
@@ -93,7 +96,7 @@ enum ExpandFunc {
E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
- E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV
+ E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV, E_READ_REGISTRY
};
enum TestFunc {
@@ -190,6 +193,7 @@ void QMakeEvaluator::initFunctionStatics()
{ "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" },
{ "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" },
{ "getenv", E_GETENV, 1, 1, "arg" },
+ { "read_registry", E_READ_REGISTRY, 2, 3, "tree, key, [wow64]" },
};
statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0])));
for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
@@ -878,8 +882,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
ret += values(map(args.at(0)));
break;
case E_LIST: {
- QString tmp;
- tmp.sprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++);
+ QString tmp(QString::asprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++));
ret = ProStringList(ProString(tmp));
ProStringList lst;
for (const ProString &arg : args)
@@ -1214,6 +1217,40 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
ret << ProString(m_option->getEnv(u1.str()));
break;
}
+#ifdef Q_OS_WIN
+ case E_READ_REGISTRY: {
+ HKEY tree;
+ const auto par = args.at(0);
+ if (!par.compare(QLatin1String("HKCU"), Qt::CaseInsensitive)
+ || !par.compare(QLatin1String("HKEY_CURRENT_USER"), Qt::CaseInsensitive)) {
+ tree = HKEY_CURRENT_USER;
+ } else if (!par.compare(QLatin1String("HKLM"), Qt::CaseInsensitive)
+ || !par.compare(QLatin1String("HKEY_LOCAL_MACHINE"), Qt::CaseInsensitive)) {
+ tree = HKEY_LOCAL_MACHINE;
+ } else {
+ evalError(fL1S("read_registry(): invalid or unsupported registry tree %1.")
+ .arg(par.toQStringView()));
+ goto allfail;
+ }
+ int flags = 0;
+ if (args.count() > 2) {
+ const auto opt = args.at(2);
+ if (opt == "32"
+ || !opt.compare(QLatin1String("wow64_32key"), Qt::CaseInsensitive)) {
+ flags = KEY_WOW64_32KEY;
+ } else if (opt == "64"
+ || !opt.compare(QLatin1String("wow64_64key"), Qt::CaseInsensitive)) {
+ flags = KEY_WOW64_64KEY;
+ } else {
+ evalError(fL1S("read_registry(): invalid option %1.")
+ .arg(opt.toQStringView()));
+ goto allfail;
+ }
+ }
+ ret << ProString(qt_readRegistryKey(tree, args.at(1).toQString(m_tmp1), flags));
+ break;
+ }
+#endif
default:
evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView()));
break;
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 432339d48e..ade8e15a39 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -1190,7 +1190,7 @@ bool QMakeEvaluator::loadSpecInternal()
# ifdef Q_OS_UNIX
if (m_qmakespec.endsWith(QLatin1String("/default-host"))
|| m_qmakespec.endsWith(QLatin1String("/default"))) {
- QString rspec = QFileInfo(m_qmakespec).readLink();
+ QString rspec = QFileInfo(m_qmakespec).symLinkTarget();
if (!rspec.isEmpty())
m_qmakespec = QDir::cleanPath(QDir(m_qmakespec).absoluteFilePath(rspec));
}
diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp
index 3a54ef4023..1f77595535 100644
--- a/qmake/library/qmakevfs.cpp
+++ b/qmake/library/qmakevfs.cpp
@@ -35,7 +35,7 @@ using namespace QMakeInternal;
#include <qfile.h>
#include <qfileinfo.h>
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
#include <qtextcodec.h>
#endif
@@ -49,7 +49,7 @@ QMakeVfs::QMakeVfs()
, m_magicExisting(fL1S("existing"))
#endif
{
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
m_textCodec = 0;
#endif
ref();
@@ -109,10 +109,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags)
return id;
}
#endif
- if (!(flags & VfsAccessedOnly)) {
#ifdef PROPARSER_THREAD_SAFE
- QMutexLocker locker(&s_mutex);
+ QMutexLocker locker(&s_mutex);
#endif
+ if (!(flags & VfsAccessedOnly)) {
int &id = s_fileIdMap[fn];
if (!id) {
id = ++s_fileIdCounter;
@@ -236,7 +236,7 @@ QMakeVfs::ReadResult QMakeVfs::readFile(int id, QString *contents, QString *errS
return ReadOtherError;
}
*contents =
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
m_textCodec ? m_textCodec->toUnicode(bcont) :
#endif
QString::fromLocal8Bit(bcont);
@@ -290,7 +290,7 @@ void QMakeVfs::invalidateContents()
}
#endif
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void QMakeVfs::setTextCodec(const QTextCodec *textCodec)
{
m_textCodec = textCodec;
diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h
index 68c21a3d37..fccbcfb765 100644
--- a/qmake/library/qmakevfs.h
+++ b/qmake/library/qmakevfs.h
@@ -38,7 +38,7 @@
# include <qmutex.h>
#endif
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QT_FORWARD_DECLARE_CLASS(QTextCodec)
#endif
@@ -92,7 +92,7 @@ public:
void invalidateContents();
#endif
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void setTextCodec(const QTextCodec *textCodec);
#endif
@@ -129,7 +129,7 @@ private:
QString m_magicMissing;
QString m_magicExisting;
#endif
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
const QTextCodec *m_textCodec;
#endif
};
diff --git a/qmake/library/registry.cpp b/qmake/library/registry.cpp
new file mode 100644
index 0000000000..3391ab9512
--- /dev/null
+++ b/qmake/library/registry.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake application of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstringlist.h>
+#include "registry_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN32
+/*
+ Returns the path part of a registry key.
+ e.g.
+ For a key
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"
+ it returns
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\"
+*/
+static QString keyPath(const QString &rKey)
+{
+ int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ if (idx == -1)
+ return QString();
+ return rKey.left(idx + 1);
+}
+
+/*
+ Returns the name part of a registry key.
+ e.g.
+ For a key
+ "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"
+ it returns
+ "ProductDir"
+*/
+static QString keyName(const QString &rKey)
+{
+ int idx = rKey.lastIndexOf(QLatin1Char('\\'));
+ if (idx == -1)
+ return rKey;
+
+ QString res(rKey.mid(idx + 1));
+ if (res == QLatin1String("Default") || res == QLatin1String("."))
+ res = QString();
+ return res;
+}
+#endif
+
+QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned long options)
+{
+ QString result;
+
+#ifdef Q_OS_WIN32
+ QString rSubkeyName = keyName(rSubkey);
+ QString rSubkeyPath = keyPath(rSubkey);
+
+ HKEY handle = nullptr;
+ LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0,
+ KEY_READ | options, &handle);
+
+ if (res != ERROR_SUCCESS)
+ return QString();
+
+ // get the size and type of the value
+ DWORD dataType;
+ DWORD dataSize;
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, &dataType, nullptr, &dataSize);
+ if (res != ERROR_SUCCESS) {
+ RegCloseKey(handle);
+ return QString();
+ }
+
+ // get the value
+ QByteArray data(dataSize, 0);
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, nullptr,
+ reinterpret_cast<unsigned char*>(data.data()), &dataSize);
+ if (res != ERROR_SUCCESS) {
+ RegCloseKey(handle);
+ return QString();
+ }
+
+ switch (dataType) {
+ case REG_EXPAND_SZ:
+ case REG_SZ: {
+ result = QString::fromWCharArray(((const wchar_t *)data.constData()));
+ break;
+ }
+
+ case REG_MULTI_SZ: {
+ QStringList l;
+ int i = 0;
+ for (;;) {
+ QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
+ i += s.length() + 1;
+
+ if (s.isEmpty())
+ break;
+ l.append(s);
+ }
+ result = l.join(QLatin1String(", "));
+ break;
+ }
+
+ case REG_NONE:
+ case REG_BINARY: {
+ result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
+ break;
+ }
+
+ case REG_DWORD_BIG_ENDIAN:
+ case REG_DWORD: {
+ Q_ASSERT(data.size() == sizeof(int));
+ int i;
+ memcpy((char*)&i, data.constData(), sizeof(int));
+ result = QString::number(i);
+ break;
+ }
+
+ default:
+ qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType));
+ break;
+ }
+
+ RegCloseKey(handle);
+#else
+ Q_UNUSED(parentHandle);
+ Q_UNUSED(rSubkey)
+ Q_UNUSED(options);
+#endif
+
+ return result;
+}
+
+QT_END_NAMESPACE
+
diff --git a/qmake/library/registry_p.h b/qmake/library/registry_p.h
new file mode 100644
index 0000000000..f9e8bba016
--- /dev/null
+++ b/qmake/library/registry_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake application of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_WINDOWS_REGISTRY_H
+#define QT_WINDOWS_REGISTRY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WIN32
+ #include <QtCore/qt_windows.h>
+#else
+ typedef void* HKEY;
+#endif
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * Read a value from the Windows registry.
+ *
+ * If the key is not found, or the registry cannot be accessed (for example
+ * if this code is compiled for a platform other than Windows), a null
+ * string is returned.
+ *
+ * 32-bit code reads from the registry's 32 bit view (Wow6432Node),
+ * 64 bit code reads from the 64 bit view.
+ * Pass KEY_WOW64_32KEY to access the 32 bit view regardless of the
+ * application's architecture, KEY_WOW64_64KEY respectively.
+ */
+QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey,
+ unsigned long options = 0);
+
+QT_END_NAMESPACE
+
+#endif // QT_WINDOWS_REGISTRY_H
+